From f0fa37f4ad6c933a551672acdcb9224b977a8034 Mon Sep 17 00:00:00 2001 From: fysx Date: Thu, 30 Jan 2014 10:19:28 +0100 Subject: [PATCH] Updated openal-soft to version 1.15.1 --- jni/Application.mk | 2 + jni/openal-soft-android/.gitignore | 5 + jni/openal-soft-android/Alc/ALc.c | 2922 ++++++++----- jni/openal-soft-android/Alc/ALu.c | 1133 ++--- jni/openal-soft-android/Alc/alcConfig.c | 305 +- jni/openal-soft-android/Alc/alcDedicated.c | 112 - jni/openal-soft-android/Alc/alcEcho.c | 191 - jni/openal-soft-android/Alc/alcModulator.c | 209 - jni/openal-soft-android/Alc/alcRing.c | 1 + jni/openal-soft-android/Alc/alcThread.c | 128 - jni/openal-soft-android/Alc/atomic.h | 180 + jni/openal-soft-android/Alc/backends/alsa.c | 1363 +++--- .../Alc/backends/android.c | 270 -- jni/openal-soft-android/Alc/backends/base.c | 230 ++ jni/openal-soft-android/Alc/backends/base.h | 133 + .../Alc/backends/coreaudio.c | 143 +- jni/openal-soft-android/Alc/backends/dsound.c | 752 +++- .../Alc/backends/loopback.c | 125 +- .../Alc/backends/mmdevapi.c | 598 ++- jni/openal-soft-android/Alc/backends/null.c | 202 +- jni/openal-soft-android/Alc/backends/opensl.c | 107 +- jni/openal-soft-android/Alc/backends/oss.c | 531 ++- .../Alc/backends/portaudio.c | 201 +- .../Alc/backends/pulseaudio.c | 2148 ++++++---- jni/openal-soft-android/Alc/backends/qsa.c | 1169 ++++++ jni/openal-soft-android/Alc/backends/sndio.c | 156 +- .../Alc/backends/solaris.c | 104 +- jni/openal-soft-android/Alc/backends/wave.c | 93 +- jni/openal-soft-android/Alc/backends/winmm.c | 661 +-- jni/openal-soft-android/Alc/bs2b.c | 20 +- jni/openal-soft-android/Alc/compat.h | 65 + jni/openal-soft-android/Alc/effects/autowah.c | 275 ++ jni/openal-soft-android/Alc/effects/chorus.c | 381 ++ .../Alc/effects/compressor.c | 223 + .../Alc/effects/dedicated.c | 167 + .../Alc/effects/distortion.c | 300 ++ jni/openal-soft-android/Alc/effects/echo.c | 296 ++ .../Alc/effects/equalizer.c | 337 ++ jni/openal-soft-android/Alc/effects/flanger.c | 380 ++ .../Alc/effects/modulator.c | 306 ++ jni/openal-soft-android/Alc/effects/null.c | 155 + .../Alc/{alcReverb.c => effects/reverb.c} | 1080 +++-- jni/openal-soft-android/Alc/evtqueue.h | 31 + jni/openal-soft-android/Alc/helpers.c | 326 +- jni/openal-soft-android/Alc/hrtf.c | 935 +++-- jni/openal-soft-android/Alc/hrtf_tables.inc | 1683 ++++---- jni/openal-soft-android/Alc/midi/base.c | 278 ++ jni/openal-soft-android/Alc/midi/base.h | 128 + jni/openal-soft-android/Alc/midi/dummy.c | 95 + jni/openal-soft-android/Alc/midi/fluidsynth.c | 843 ++++ jni/openal-soft-android/Alc/midi/sf2load.c | 1436 +++++++ jni/openal-soft-android/Alc/mixer.c | 887 ++-- jni/openal-soft-android/Alc/mixer_c.c | 125 + jni/openal-soft-android/Alc/mixer_defs.h | 33 + jni/openal-soft-android/Alc/mixer_inc.c | 140 + jni/openal-soft-android/Alc/mixer_neon.c | 130 + jni/openal-soft-android/Alc/mixer_sse.c | 164 + jni/openal-soft-android/Alc/panning.c | 424 +- jni/openal-soft-android/Alc/rwlock.h | 21 + jni/openal-soft-android/Alc/threads.c | 200 + jni/openal-soft-android/Alc/uintmap.h | 34 + jni/openal-soft-android/Android.mk | 26 +- jni/openal-soft-android/CMakeCache.txt | 498 --- .../CMakeFiles/CMakeCCompiler.cmake | 44 - .../CMakeDirectoryInformation.cmake | 26 - .../CMakeFiles/CMakeError.log | 437 -- .../CMakeFiles/CMakeOutput.log | 755 ---- .../CMakeFiles/CMakeSystem.cmake | 15 - .../CMakeFiles/CheckTypeSize/SIZEOF_LONG.bin | Bin 32731 -> 0 bytes .../CMakeFiles/CheckTypeSize/SIZEOF_LONG.c | 40 - .../CheckTypeSize/SIZEOF_LONG_LONG.bin | Bin 32736 -> 0 bytes .../CheckTypeSize/SIZEOF_LONG_LONG.c | 40 - .../CMakeFiles/CompilerIdC/CMakeCCompilerId.c | 220 - .../CMakeFiles/Makefile.cmake | 53 - jni/openal-soft-android/CMakeFiles/Makefile2 | 152 - .../CMakeFiles/TargetDirectories.txt | 2 - .../CMakeFiles/cmake.check_cache | 1 - .../CMakeFiles/openal-info.dir/C.includecache | 32 - .../openal-info.dir/DependInfo.cmake | 19 - .../CMakeFiles/openal-info.dir/build.make | 122 - .../openal-info.dir/cmake_clean.cmake | 12 - .../openal-info.dir/depend.internal | 9 - .../CMakeFiles/openal-info.dir/depend.make | 9 - .../CMakeFiles/openal-info.dir/flags.make | 8 - .../CMakeFiles/openal-info.dir/link.txt | 1 - .../CMakeFiles/openal-info.dir/progress.make | 2 - .../CMakeFiles/openal-info.dir/relink.txt | 1 - .../CMakeFiles/openal.dir/C.includecache | 684 --- .../CMakeFiles/openal.dir/DependInfo.cmake | 54 - .../CMakeFiles/openal.dir/build.make | 913 ---- .../CMakeFiles/openal.dir/cmake_clean.cmake | 43 - .../CMakeFiles/openal.dir/depend.internal | 491 --- .../CMakeFiles/openal.dir/depend.make | 491 --- .../CMakeFiles/openal.dir/flags.make | 10 - .../CMakeFiles/openal.dir/link.txt | 1 - .../CMakeFiles/openal.dir/progress.make | 29 - .../CMakeFiles/openal.dir/relink.txt | 1 - .../CMakeFiles/progress.marks | 1 - jni/openal-soft-android/CMakeLists.txt | 574 ++- jni/openal-soft-android/Makefile | 727 ---- .../OpenAL32/Include/alAuxEffectSlot.h | 105 +- .../OpenAL32/Include/alBuffer.h | 63 +- .../OpenAL32/Include/alEffect.h | 136 +- .../OpenAL32/Include/alError.h | 18 +- .../OpenAL32/Include/alFilter.h | 108 +- .../OpenAL32/Include/alListener.h | 10 +- .../OpenAL32/Include/alMain.h | 1054 ++--- .../OpenAL32/Include/alMidi.h | 166 + .../OpenAL32/Include/alSource.h | 201 +- .../OpenAL32/Include/alState.h | 14 - .../OpenAL32/Include/alu.h | 244 +- .../OpenAL32/Include/bs2b.h | 3 - .../OpenAL32/Include/threads.h | 14 + .../OpenAL32/alAuxEffectSlot.c | 760 ++-- jni/openal-soft-android/OpenAL32/alBuffer.c | 1659 ++++---- jni/openal-soft-android/OpenAL32/alEffect.c | 1496 ++----- jni/openal-soft-android/OpenAL32/alError.c | 47 +- .../OpenAL32/alExtension.c | 377 +- jni/openal-soft-android/OpenAL32/alFilter.c | 556 +-- .../OpenAL32/alFontsound.c | 972 +++++ jni/openal-soft-android/OpenAL32/alListener.c | 739 ++-- jni/openal-soft-android/OpenAL32/alMidi.c | 221 + jni/openal-soft-android/OpenAL32/alPreset.c | 340 ++ .../OpenAL32/alSoundfont.c | 563 +++ jni/openal-soft-android/OpenAL32/alSource.c | 3676 ++++++++++------- jni/openal-soft-android/OpenAL32/alState.c | 798 ++-- jni/openal-soft-android/OpenAL32/alThunk.c | 2 +- jni/openal-soft-android/OpenAL32/config.h | 150 - jni/openal-soft-android/README | 21 - jni/openal-soft-android/alsoftrc.sample | 198 +- .../cmake/CheckCCompilerFlag.cmake | 59 - .../cmake/FindFluidSynth.cmake | 23 + .../cmake/FindSDL_sound.cmake | 382 ++ .../{ => cmake}/toolchain.android.cmake | 102 +- jni/openal-soft-android/cmake_install.cmake | 88 - jni/openal-soft-android/config.h | 130 +- jni/openal-soft-android/config.h.in | 122 +- jni/openal-soft-android/env-vars.txt | 71 + jni/openal-soft-android/examples/allatency.c | 204 + jni/openal-soft-android/examples/alloopback.c | 244 ++ jni/openal-soft-android/examples/alreverb.c | 327 ++ jni/openal-soft-android/examples/alstream.c | 335 ++ .../examples/common/alhelpers.c | 327 ++ .../examples/common/alhelpers.h | 51 + .../examples/common/sdl_sound.c | 164 + .../examples/common/sdl_sound.h | 43 + jni/openal-soft-android/hrtf.txt | 74 + jni/openal-soft-android/include/AL/al.h | 1082 +++-- jni/openal-soft-android/include/AL/alc.h | 247 +- jni/openal-soft-android/include/AL/alext.h | 176 + .../include/AL/efx-presets.h | 402 ++ jni/openal-soft-android/include/AL/efx.h | 3 + jni/openal-soft-android/openal.pc | 11 - jni/openal-soft-android/openal.pc.in | 2 +- jni/openal-soft-android/utils/CIAIR.def | 2010 +++++++++ jni/openal-soft-android/utils/IRC_1005.def | 421 ++ jni/openal-soft-android/utils/MIT_KEMAR.def | 823 ++++ .../utils/alsoft-config/CMakeLists.txt | 29 + .../utils/alsoft-config/main.cpp | 11 + .../utils/alsoft-config/mainwindow.cpp | 586 +++ .../utils/alsoft-config/mainwindow.h | 56 + .../utils/alsoft-config/mainwindow.ui | 1397 +++++++ jni/openal-soft-android/utils/makehrtf.c | 2752 ++++++++++++ jni/openal-soft-android/utils/openal-info.c | 12 +- 164 files changed, 38848 insertions(+), 21244 deletions(-) delete mode 100644 jni/openal-soft-android/Alc/alcDedicated.c delete mode 100644 jni/openal-soft-android/Alc/alcEcho.c delete mode 100644 jni/openal-soft-android/Alc/alcModulator.c delete mode 100644 jni/openal-soft-android/Alc/alcThread.c create mode 100644 jni/openal-soft-android/Alc/atomic.h delete mode 100644 jni/openal-soft-android/Alc/backends/android.c create mode 100644 jni/openal-soft-android/Alc/backends/base.c create mode 100644 jni/openal-soft-android/Alc/backends/base.h create mode 100644 jni/openal-soft-android/Alc/backends/qsa.c create mode 100644 jni/openal-soft-android/Alc/compat.h create mode 100644 jni/openal-soft-android/Alc/effects/autowah.c create mode 100644 jni/openal-soft-android/Alc/effects/chorus.c create mode 100644 jni/openal-soft-android/Alc/effects/compressor.c create mode 100644 jni/openal-soft-android/Alc/effects/dedicated.c create mode 100644 jni/openal-soft-android/Alc/effects/distortion.c create mode 100644 jni/openal-soft-android/Alc/effects/echo.c create mode 100644 jni/openal-soft-android/Alc/effects/equalizer.c create mode 100644 jni/openal-soft-android/Alc/effects/flanger.c create mode 100644 jni/openal-soft-android/Alc/effects/modulator.c create mode 100644 jni/openal-soft-android/Alc/effects/null.c rename jni/openal-soft-android/Alc/{alcReverb.c => effects/reverb.c} (54%) create mode 100644 jni/openal-soft-android/Alc/evtqueue.h create mode 100644 jni/openal-soft-android/Alc/midi/base.c create mode 100644 jni/openal-soft-android/Alc/midi/base.h create mode 100644 jni/openal-soft-android/Alc/midi/dummy.c create mode 100644 jni/openal-soft-android/Alc/midi/fluidsynth.c create mode 100644 jni/openal-soft-android/Alc/midi/sf2load.c create mode 100644 jni/openal-soft-android/Alc/mixer_c.c create mode 100644 jni/openal-soft-android/Alc/mixer_defs.h create mode 100644 jni/openal-soft-android/Alc/mixer_inc.c create mode 100644 jni/openal-soft-android/Alc/mixer_neon.c create mode 100644 jni/openal-soft-android/Alc/mixer_sse.c create mode 100644 jni/openal-soft-android/Alc/rwlock.h create mode 100644 jni/openal-soft-android/Alc/threads.c create mode 100644 jni/openal-soft-android/Alc/uintmap.h delete mode 100644 jni/openal-soft-android/CMakeCache.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/CMakeCCompiler.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/CMakeDirectoryInformation.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/CMakeError.log delete mode 100644 jni/openal-soft-android/CMakeFiles/CMakeOutput.log delete mode 100644 jni/openal-soft-android/CMakeFiles/CMakeSystem.cmake delete mode 100755 jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.bin delete mode 100644 jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.c delete mode 100755 jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.bin delete mode 100644 jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.c delete mode 100644 jni/openal-soft-android/CMakeFiles/CompilerIdC/CMakeCCompilerId.c delete mode 100644 jni/openal-soft-android/CMakeFiles/Makefile.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/Makefile2 delete mode 100644 jni/openal-soft-android/CMakeFiles/TargetDirectories.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/cmake.check_cache delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/C.includecache delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/DependInfo.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/build.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/cmake_clean.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.internal delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/flags.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/link.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/progress.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal-info.dir/relink.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/C.includecache delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/build.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/cmake_clean.cmake delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/depend.internal delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/depend.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/flags.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/link.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/progress.make delete mode 100644 jni/openal-soft-android/CMakeFiles/openal.dir/relink.txt delete mode 100644 jni/openal-soft-android/CMakeFiles/progress.marks delete mode 100644 jni/openal-soft-android/Makefile create mode 100644 jni/openal-soft-android/OpenAL32/Include/alMidi.h delete mode 100644 jni/openal-soft-android/OpenAL32/Include/alState.h create mode 100644 jni/openal-soft-android/OpenAL32/Include/threads.h create mode 100644 jni/openal-soft-android/OpenAL32/alFontsound.c create mode 100644 jni/openal-soft-android/OpenAL32/alMidi.c create mode 100644 jni/openal-soft-android/OpenAL32/alPreset.c create mode 100644 jni/openal-soft-android/OpenAL32/alSoundfont.c delete mode 100644 jni/openal-soft-android/OpenAL32/config.h delete mode 100644 jni/openal-soft-android/cmake/CheckCCompilerFlag.cmake create mode 100644 jni/openal-soft-android/cmake/FindFluidSynth.cmake create mode 100644 jni/openal-soft-android/cmake/FindSDL_sound.cmake rename jni/openal-soft-android/{ => cmake}/toolchain.android.cmake (55%) delete mode 100644 jni/openal-soft-android/cmake_install.cmake create mode 100644 jni/openal-soft-android/env-vars.txt create mode 100644 jni/openal-soft-android/examples/allatency.c create mode 100644 jni/openal-soft-android/examples/alloopback.c create mode 100644 jni/openal-soft-android/examples/alreverb.c create mode 100644 jni/openal-soft-android/examples/alstream.c create mode 100644 jni/openal-soft-android/examples/common/alhelpers.c create mode 100644 jni/openal-soft-android/examples/common/alhelpers.h create mode 100644 jni/openal-soft-android/examples/common/sdl_sound.c create mode 100644 jni/openal-soft-android/examples/common/sdl_sound.h create mode 100644 jni/openal-soft-android/hrtf.txt create mode 100644 jni/openal-soft-android/include/AL/efx-presets.h delete mode 100644 jni/openal-soft-android/openal.pc create mode 100644 jni/openal-soft-android/utils/CIAIR.def create mode 100644 jni/openal-soft-android/utils/IRC_1005.def create mode 100644 jni/openal-soft-android/utils/MIT_KEMAR.def create mode 100644 jni/openal-soft-android/utils/alsoft-config/CMakeLists.txt create mode 100644 jni/openal-soft-android/utils/alsoft-config/main.cpp create mode 100644 jni/openal-soft-android/utils/alsoft-config/mainwindow.cpp create mode 100644 jni/openal-soft-android/utils/alsoft-config/mainwindow.h create mode 100644 jni/openal-soft-android/utils/alsoft-config/mainwindow.ui create mode 100644 jni/openal-soft-android/utils/makehrtf.c diff --git a/jni/Application.mk b/jni/Application.mk index 8233c7be..dae6fe48 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -4,4 +4,6 @@ APP_STL := gnustl_shared APP_ABI := armeabi armeabi-v7a APP_CPPFLAGS := -frtti +APP_LDFLAGS := -llog -landroid -lz -lOpenSLES + # APP_OPTIM := debug diff --git a/jni/openal-soft-android/.gitignore b/jni/openal-soft-android/.gitignore index 378eac25..b792eb2e 100644 --- a/jni/openal-soft-android/.gitignore +++ b/jni/openal-soft-android/.gitignore @@ -1 +1,6 @@ build +winbuild +win64build +include/sndio.h +include/sys +openal-soft.kdev4 diff --git a/jni/openal-soft-android/Alc/ALc.c b/jni/openal-soft-android/Alc/ALc.c index baf7638c..7d8f14cd 100644 --- a/jni/openal-soft-android/Alc/ALc.c +++ b/jni/openal-soft-android/Alc/ALc.c @@ -29,73 +29,87 @@ #include "alMain.h" #include "alSource.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alListener.h" #include "alThunk.h" #include "alSource.h" #include "alBuffer.h" #include "alAuxEffectSlot.h" #include "alError.h" +#include "alMidi.h" #include "bs2b.h" #include "alu.h" -#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +#include "backends/base.h" +#include "midi/base.h" + + +/************************************************ + * Backends + ************************************************/ +struct BackendInfo { + const char *name; + ALCbackendFactory* (*getFactory)(void); + ALCboolean (*Init)(BackendFuncs*); + void (*Deinit)(void); + void (*Probe)(enum DevProbe); + BackendFuncs Funcs; +}; + +#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } static struct BackendInfo BackendList[] = { #ifdef HAVE_PULSEAUDIO - { "pulse", alc_pulse_init, alc_pulse_deinit, alc_pulse_probe, EmptyFuncs }, + { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #endif #ifdef HAVE_ALSA - { "alsa", alc_alsa_init, alc_alsa_deinit, alc_alsa_probe, EmptyFuncs }, + { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #endif #ifdef HAVE_COREAUDIO - { "core", alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs }, + { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs }, #endif #ifdef HAVE_OSS - { "oss", alc_oss_init, alc_oss_deinit, alc_oss_probe, EmptyFuncs }, + { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #endif #ifdef HAVE_SOLARIS - { "solaris", alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs }, + { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs }, #endif #ifdef HAVE_SNDIO - { "sndio", alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs }, + { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs }, +#endif +#ifdef HAVE_QSA + { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs }, #endif #ifdef HAVE_MMDEVAPI - { "mmdevapi", alcMMDevApiInit, alcMMDevApiDeinit, alcMMDevApiProbe, EmptyFuncs }, + { "mmdevapi", NULL, alcMMDevApiInit, alcMMDevApiDeinit, alcMMDevApiProbe, EmptyFuncs }, #endif #ifdef HAVE_DSOUND - { "dsound", alcDSoundInit, alcDSoundDeinit, alcDSoundProbe, EmptyFuncs }, + { "dsound", NULL, alcDSoundInit, alcDSoundDeinit, alcDSoundProbe, EmptyFuncs }, #endif #ifdef HAVE_WINMM - { "winmm", alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs }, + { "winmm", NULL, alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs }, #endif #ifdef HAVE_PORTAUDIO - { "port", alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs }, + { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs }, #endif #ifdef HAVE_OPENSL - { "opensl", alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs }, -#endif -#ifdef HAVE_ANDROID - { "android", alc_android_init, alc_android_deinit, alc_android_probe, EmptyFuncs }, + { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs }, #endif - { "null", alc_null_init, alc_null_deinit, alc_null_probe, EmptyFuncs }, + { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs }, #ifdef HAVE_WAVE - { "wave", alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs }, + { "wave", NULL, alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs }, #endif - { NULL, NULL, NULL, NULL, EmptyFuncs } -}; -static struct BackendInfo BackendLoopback = { - "loopback", alc_loopback_init, alc_loopback_deinit, alc_loopback_probe, EmptyFuncs + { NULL, NULL, NULL, NULL, NULL, EmptyFuncs } }; #undef EmptyFuncs static struct BackendInfo PlaybackBackend; static struct BackendInfo CaptureBackend; -/////////////////////////////////////////////////////// -// STRING and EXTENSIONS +/************************************************ + * Functions, enums, and errors + ************************************************/ typedef struct ALCfunction { const ALCchar *funcName; ALCvoid *address; @@ -106,220 +120,561 @@ typedef struct ALCenums { ALCenum value; } ALCenums; - +#define DECL(x) { #x, (ALCvoid*)(x) } static const ALCfunction alcFunctions[] = { - { "alcCreateContext", (ALCvoid *) alcCreateContext }, - { "alcMakeContextCurrent", (ALCvoid *) alcMakeContextCurrent }, - { "alcProcessContext", (ALCvoid *) alcProcessContext }, - { "alcSuspendContext", (ALCvoid *) alcSuspendContext }, - { "alcDestroyContext", (ALCvoid *) alcDestroyContext }, - { "alcGetCurrentContext", (ALCvoid *) alcGetCurrentContext }, - { "alcGetContextsDevice", (ALCvoid *) alcGetContextsDevice }, - { "alcOpenDevice", (ALCvoid *) alcOpenDevice }, - { "alcCloseDevice", (ALCvoid *) alcCloseDevice }, - { "alcGetError", (ALCvoid *) alcGetError }, - { "alcIsExtensionPresent", (ALCvoid *) alcIsExtensionPresent }, - { "alcGetProcAddress", (ALCvoid *) alcGetProcAddress }, - { "alcGetEnumValue", (ALCvoid *) alcGetEnumValue }, - { "alcGetString", (ALCvoid *) alcGetString }, - { "alcGetIntegerv", (ALCvoid *) alcGetIntegerv }, - { "alcCaptureOpenDevice", (ALCvoid *) alcCaptureOpenDevice }, - { "alcCaptureCloseDevice", (ALCvoid *) alcCaptureCloseDevice }, - { "alcCaptureStart", (ALCvoid *) alcCaptureStart }, - { "alcCaptureStop", (ALCvoid *) alcCaptureStop }, - { "alcCaptureSamples", (ALCvoid *) alcCaptureSamples }, + DECL(alcCreateContext), + DECL(alcMakeContextCurrent), + DECL(alcProcessContext), + DECL(alcSuspendContext), + DECL(alcDestroyContext), + DECL(alcGetCurrentContext), + DECL(alcGetContextsDevice), + DECL(alcOpenDevice), + DECL(alcCloseDevice), + DECL(alcGetError), + DECL(alcIsExtensionPresent), + DECL(alcGetProcAddress), + DECL(alcGetEnumValue), + DECL(alcGetString), + DECL(alcGetIntegerv), + DECL(alcCaptureOpenDevice), + DECL(alcCaptureCloseDevice), + DECL(alcCaptureStart), + DECL(alcCaptureStop), + DECL(alcCaptureSamples), - { "alcSetThreadContext", (ALCvoid *) alcSetThreadContext }, - { "alcGetThreadContext", (ALCvoid *) alcGetThreadContext }, + DECL(alcSetThreadContext), + DECL(alcGetThreadContext), - { "alcLoopbackOpenDeviceSOFT", (ALCvoid *) alcLoopbackOpenDeviceSOFT}, - { "alcIsRenderFormatSupportedSOFT",(ALCvoid *) alcIsRenderFormatSupportedSOFT}, - { "alcRenderSamplesSOFT", (ALCvoid *) alcRenderSamplesSOFT }, + DECL(alcLoopbackOpenDeviceSOFT), + DECL(alcIsRenderFormatSupportedSOFT), + DECL(alcRenderSamplesSOFT), - { "alEnable", (ALCvoid *) alEnable }, - { "alDisable", (ALCvoid *) alDisable }, - { "alIsEnabled", (ALCvoid *) alIsEnabled }, - { "alGetString", (ALCvoid *) alGetString }, - { "alGetBooleanv", (ALCvoid *) alGetBooleanv }, - { "alGetIntegerv", (ALCvoid *) alGetIntegerv }, - { "alGetFloatv", (ALCvoid *) alGetFloatv }, - { "alGetDoublev", (ALCvoid *) alGetDoublev }, - { "alGetBoolean", (ALCvoid *) alGetBoolean }, - { "alGetInteger", (ALCvoid *) alGetInteger }, - { "alGetFloat", (ALCvoid *) alGetFloat }, - { "alGetDouble", (ALCvoid *) alGetDouble }, - { "alGetError", (ALCvoid *) alGetError }, - { "alIsExtensionPresent", (ALCvoid *) alIsExtensionPresent }, - { "alGetProcAddress", (ALCvoid *) alGetProcAddress }, - { "alGetEnumValue", (ALCvoid *) alGetEnumValue }, - { "alListenerf", (ALCvoid *) alListenerf }, - { "alListener3f", (ALCvoid *) alListener3f }, - { "alListenerfv", (ALCvoid *) alListenerfv }, - { "alListeneri", (ALCvoid *) alListeneri }, - { "alListener3i", (ALCvoid *) alListener3i }, - { "alListeneriv", (ALCvoid *) alListeneriv }, - { "alGetListenerf", (ALCvoid *) alGetListenerf }, - { "alGetListener3f", (ALCvoid *) alGetListener3f }, - { "alGetListenerfv", (ALCvoid *) alGetListenerfv }, - { "alGetListeneri", (ALCvoid *) alGetListeneri }, - { "alGetListener3i", (ALCvoid *) alGetListener3i }, - { "alGetListeneriv", (ALCvoid *) alGetListeneriv }, - { "alGenSources", (ALCvoid *) alGenSources }, - { "alDeleteSources", (ALCvoid *) alDeleteSources }, - { "alIsSource", (ALCvoid *) alIsSource }, - { "alSourcef", (ALCvoid *) alSourcef }, - { "alSource3f", (ALCvoid *) alSource3f }, - { "alSourcefv", (ALCvoid *) alSourcefv }, - { "alSourcei", (ALCvoid *) alSourcei }, - { "alSource3i", (ALCvoid *) alSource3i }, - { "alSourceiv", (ALCvoid *) alSourceiv }, - { "alGetSourcef", (ALCvoid *) alGetSourcef }, - { "alGetSource3f", (ALCvoid *) alGetSource3f }, - { "alGetSourcefv", (ALCvoid *) alGetSourcefv }, - { "alGetSourcei", (ALCvoid *) alGetSourcei }, - { "alGetSource3i", (ALCvoid *) alGetSource3i }, - { "alGetSourceiv", (ALCvoid *) alGetSourceiv }, - { "alSourcePlayv", (ALCvoid *) alSourcePlayv }, - { "alSourceStopv", (ALCvoid *) alSourceStopv }, - { "alSourceRewindv", (ALCvoid *) alSourceRewindv }, - { "alSourcePausev", (ALCvoid *) alSourcePausev }, - { "alSourcePlay", (ALCvoid *) alSourcePlay }, - { "alSourceStop", (ALCvoid *) alSourceStop }, - { "alSourceRewind", (ALCvoid *) alSourceRewind }, - { "alSourcePause", (ALCvoid *) alSourcePause }, - { "alSourceQueueBuffers", (ALCvoid *) alSourceQueueBuffers }, - { "alSourceUnqueueBuffers", (ALCvoid *) alSourceUnqueueBuffers }, - { "alGenBuffers", (ALCvoid *) alGenBuffers }, - { "alDeleteBuffers", (ALCvoid *) alDeleteBuffers }, - { "alIsBuffer", (ALCvoid *) alIsBuffer }, - { "alBufferData", (ALCvoid *) alBufferData }, - { "alBufferf", (ALCvoid *) alBufferf }, - { "alBuffer3f", (ALCvoid *) alBuffer3f }, - { "alBufferfv", (ALCvoid *) alBufferfv }, - { "alBufferi", (ALCvoid *) alBufferi }, - { "alBuffer3i", (ALCvoid *) alBuffer3i }, - { "alBufferiv", (ALCvoid *) alBufferiv }, - { "alGetBufferf", (ALCvoid *) alGetBufferf }, - { "alGetBuffer3f", (ALCvoid *) alGetBuffer3f }, - { "alGetBufferfv", (ALCvoid *) alGetBufferfv }, - { "alGetBufferi", (ALCvoid *) alGetBufferi }, - { "alGetBuffer3i", (ALCvoid *) alGetBuffer3i }, - { "alGetBufferiv", (ALCvoid *) alGetBufferiv }, - { "alDopplerFactor", (ALCvoid *) alDopplerFactor }, - { "alDopplerVelocity", (ALCvoid *) alDopplerVelocity }, - { "alSpeedOfSound", (ALCvoid *) alSpeedOfSound }, - { "alDistanceModel", (ALCvoid *) alDistanceModel }, + DECL(alcDevicePauseSOFT), + DECL(alcDeviceResumeSOFT), - { "alGenFilters", (ALCvoid *) alGenFilters }, - { "alDeleteFilters", (ALCvoid *) alDeleteFilters }, - { "alIsFilter", (ALCvoid *) alIsFilter }, - { "alFilteri", (ALCvoid *) alFilteri }, - { "alFilteriv", (ALCvoid *) alFilteriv }, - { "alFilterf", (ALCvoid *) alFilterf }, - { "alFilterfv", (ALCvoid *) alFilterfv }, - { "alGetFilteri", (ALCvoid *) alGetFilteri }, - { "alGetFilteriv", (ALCvoid *) alGetFilteriv }, - { "alGetFilterf", (ALCvoid *) alGetFilterf }, - { "alGetFilterfv", (ALCvoid *) alGetFilterfv }, - { "alGenEffects", (ALCvoid *) alGenEffects }, - { "alDeleteEffects", (ALCvoid *) alDeleteEffects }, - { "alIsEffect", (ALCvoid *) alIsEffect }, - { "alEffecti", (ALCvoid *) alEffecti }, - { "alEffectiv", (ALCvoid *) alEffectiv }, - { "alEffectf", (ALCvoid *) alEffectf }, - { "alEffectfv", (ALCvoid *) alEffectfv }, - { "alGetEffecti", (ALCvoid *) alGetEffecti }, - { "alGetEffectiv", (ALCvoid *) alGetEffectiv }, - { "alGetEffectf", (ALCvoid *) alGetEffectf }, - { "alGetEffectfv", (ALCvoid *) alGetEffectfv }, - { "alGenAuxiliaryEffectSlots", (ALCvoid *) alGenAuxiliaryEffectSlots}, - { "alDeleteAuxiliaryEffectSlots",(ALCvoid *) alDeleteAuxiliaryEffectSlots}, - { "alIsAuxiliaryEffectSlot", (ALCvoid *) alIsAuxiliaryEffectSlot }, - { "alAuxiliaryEffectSloti", (ALCvoid *) alAuxiliaryEffectSloti }, - { "alAuxiliaryEffectSlotiv", (ALCvoid *) alAuxiliaryEffectSlotiv }, - { "alAuxiliaryEffectSlotf", (ALCvoid *) alAuxiliaryEffectSlotf }, - { "alAuxiliaryEffectSlotfv", (ALCvoid *) alAuxiliaryEffectSlotfv }, - { "alGetAuxiliaryEffectSloti", (ALCvoid *) alGetAuxiliaryEffectSloti}, - { "alGetAuxiliaryEffectSlotiv", (ALCvoid *) alGetAuxiliaryEffectSlotiv}, - { "alGetAuxiliaryEffectSlotf", (ALCvoid *) alGetAuxiliaryEffectSlotf}, - { "alGetAuxiliaryEffectSlotfv", (ALCvoid *) alGetAuxiliaryEffectSlotfv}, + DECL(alEnable), + DECL(alDisable), + DECL(alIsEnabled), + DECL(alGetString), + DECL(alGetBooleanv), + DECL(alGetIntegerv), + DECL(alGetFloatv), + DECL(alGetDoublev), + DECL(alGetBoolean), + DECL(alGetInteger), + DECL(alGetFloat), + DECL(alGetDouble), + DECL(alGetError), + DECL(alIsExtensionPresent), + DECL(alGetProcAddress), + DECL(alGetEnumValue), + DECL(alListenerf), + DECL(alListener3f), + DECL(alListenerfv), + DECL(alListeneri), + DECL(alListener3i), + DECL(alListeneriv), + DECL(alGetListenerf), + DECL(alGetListener3f), + DECL(alGetListenerfv), + DECL(alGetListeneri), + DECL(alGetListener3i), + DECL(alGetListeneriv), + DECL(alGenSources), + DECL(alDeleteSources), + DECL(alIsSource), + DECL(alSourcef), + DECL(alSource3f), + DECL(alSourcefv), + DECL(alSourcei), + DECL(alSource3i), + DECL(alSourceiv), + DECL(alGetSourcef), + DECL(alGetSource3f), + DECL(alGetSourcefv), + DECL(alGetSourcei), + DECL(alGetSource3i), + DECL(alGetSourceiv), + DECL(alSourcePlayv), + DECL(alSourceStopv), + DECL(alSourceRewindv), + DECL(alSourcePausev), + DECL(alSourcePlay), + DECL(alSourceStop), + DECL(alSourceRewind), + DECL(alSourcePause), + DECL(alSourceQueueBuffers), + DECL(alSourceUnqueueBuffers), + DECL(alGenBuffers), + DECL(alDeleteBuffers), + DECL(alIsBuffer), + DECL(alBufferData), + DECL(alBufferf), + DECL(alBuffer3f), + DECL(alBufferfv), + DECL(alBufferi), + DECL(alBuffer3i), + DECL(alBufferiv), + DECL(alGetBufferf), + DECL(alGetBuffer3f), + DECL(alGetBufferfv), + DECL(alGetBufferi), + DECL(alGetBuffer3i), + DECL(alGetBufferiv), + DECL(alDopplerFactor), + DECL(alDopplerVelocity), + DECL(alSpeedOfSound), + DECL(alDistanceModel), - { "alBufferSubDataSOFT", (ALCvoid *) alBufferSubDataSOFT }, + DECL(alGenFilters), + DECL(alDeleteFilters), + DECL(alIsFilter), + DECL(alFilteri), + DECL(alFilteriv), + DECL(alFilterf), + DECL(alFilterfv), + DECL(alGetFilteri), + DECL(alGetFilteriv), + DECL(alGetFilterf), + DECL(alGetFilterfv), + DECL(alGenEffects), + DECL(alDeleteEffects), + DECL(alIsEffect), + DECL(alEffecti), + DECL(alEffectiv), + DECL(alEffectf), + DECL(alEffectfv), + DECL(alGetEffecti), + DECL(alGetEffectiv), + DECL(alGetEffectf), + DECL(alGetEffectfv), + DECL(alGenAuxiliaryEffectSlots), + DECL(alDeleteAuxiliaryEffectSlots), + DECL(alIsAuxiliaryEffectSlot), + DECL(alAuxiliaryEffectSloti), + DECL(alAuxiliaryEffectSlotiv), + DECL(alAuxiliaryEffectSlotf), + DECL(alAuxiliaryEffectSlotfv), + DECL(alGetAuxiliaryEffectSloti), + DECL(alGetAuxiliaryEffectSlotiv), + DECL(alGetAuxiliaryEffectSlotf), + DECL(alGetAuxiliaryEffectSlotfv), - { "alBufferSamplesSOFT", (ALCvoid *) alBufferSamplesSOFT }, - { "alBufferSubSamplesSOFT", (ALCvoid *) alBufferSubSamplesSOFT }, - { "alGetBufferSamplesSOFT", (ALCvoid *) alGetBufferSamplesSOFT }, - { "alIsBufferFormatSupportedSOFT",(ALCvoid *) alIsBufferFormatSupportedSOFT}, + DECL(alBufferSubDataSOFT), - { "alDeferUpdatesSOFT", (ALCvoid *) alDeferUpdatesSOFT }, - { "alProcessUpdatesSOFT", (ALCvoid *) alProcessUpdatesSOFT }, + DECL(alBufferSamplesSOFT), + DECL(alBufferSubSamplesSOFT), + DECL(alGetBufferSamplesSOFT), + DECL(alIsBufferFormatSupportedSOFT), - { NULL, (ALCvoid *) NULL } + DECL(alDeferUpdatesSOFT), + DECL(alProcessUpdatesSOFT), + + DECL(alSourcedSOFT), + DECL(alSource3dSOFT), + DECL(alSourcedvSOFT), + DECL(alGetSourcedSOFT), + DECL(alGetSource3dSOFT), + DECL(alGetSourcedvSOFT), + DECL(alSourcei64SOFT), + DECL(alSource3i64SOFT), + DECL(alSourcei64vSOFT), + DECL(alGetSourcei64SOFT), + DECL(alGetSource3i64SOFT), + DECL(alGetSourcei64vSOFT), + + DECL(alGenSoundfontsSOFT), + DECL(alDeleteSoundfontsSOFT), + DECL(alIsSoundfontSOFT), + DECL(alSoundfontSamplesSOFT), + DECL(alGetSoundfontSamplesSOFT), + DECL(alSoundfontMapSamplesSOFT), + DECL(alSoundfontUnmapSamplesSOFT), + DECL(alGetSoundfontivSOFT), + DECL(alSoundfontPresetsSOFT), + DECL(alGenPresetsSOFT), + DECL(alDeletePresetsSOFT), + DECL(alIsPresetSOFT), + DECL(alPresetiSOFT), + DECL(alPresetivSOFT), + DECL(alGetPresetivSOFT), + DECL(alPresetFontsoundsSOFT), + DECL(alGenFontsoundsSOFT), + DECL(alDeleteFontsoundsSOFT), + DECL(alIsFontsoundSOFT), + DECL(alFontsoundiSOFT), + DECL(alFontsound2iSOFT), + DECL(alFontsoundivSOFT), + DECL(alGetFontsoundivSOFT), + DECL(alFontsoundModulatoriSOFT), + DECL(alGetFontsoundModulatorivSOFT), + DECL(alMidiSoundfontSOFT), + DECL(alMidiSoundfontvSOFT), + DECL(alMidiEventSOFT), + DECL(alMidiSysExSOFT), + DECL(alMidiPlaySOFT), + DECL(alMidiPauseSOFT), + DECL(alMidiStopSOFT), + DECL(alMidiResetSOFT), + DECL(alMidiGainSOFT), + DECL(alGetInteger64SOFT), + DECL(alGetInteger64vSOFT), + DECL(alLoadSoundfontSOFT), + + { NULL, NULL } }; +#undef DECL +#define DECL(x) { #x, (x) } static const ALCenums enumeration[] = { - // Types - { "ALC_INVALID", ALC_INVALID }, - { "ALC_FALSE", ALC_FALSE }, - { "ALC_TRUE", ALC_TRUE }, + DECL(ALC_INVALID), + DECL(ALC_FALSE), + DECL(ALC_TRUE), - // ALC Properties - { "ALC_MAJOR_VERSION", ALC_MAJOR_VERSION }, - { "ALC_MINOR_VERSION", ALC_MINOR_VERSION }, - { "ALC_ATTRIBUTES_SIZE", ALC_ATTRIBUTES_SIZE }, - { "ALC_ALL_ATTRIBUTES", ALC_ALL_ATTRIBUTES }, - { "ALC_DEFAULT_DEVICE_SPECIFIER", ALC_DEFAULT_DEVICE_SPECIFIER }, - { "ALC_DEVICE_SPECIFIER", ALC_DEVICE_SPECIFIER }, - { "ALC_ALL_DEVICES_SPECIFIER", ALC_ALL_DEVICES_SPECIFIER }, - { "ALC_DEFAULT_ALL_DEVICES_SPECIFIER", ALC_DEFAULT_ALL_DEVICES_SPECIFIER }, - { "ALC_EXTENSIONS", ALC_EXTENSIONS }, - { "ALC_FREQUENCY", ALC_FREQUENCY }, - { "ALC_REFRESH", ALC_REFRESH }, - { "ALC_SYNC", ALC_SYNC }, - { "ALC_MONO_SOURCES", ALC_MONO_SOURCES }, - { "ALC_STEREO_SOURCES", ALC_STEREO_SOURCES }, - { "ALC_CAPTURE_DEVICE_SPECIFIER", ALC_CAPTURE_DEVICE_SPECIFIER }, - { "ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER", ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER}, - { "ALC_CAPTURE_SAMPLES", ALC_CAPTURE_SAMPLES }, - { "ALC_CONNECTED", ALC_CONNECTED }, + DECL(ALC_MAJOR_VERSION), + DECL(ALC_MINOR_VERSION), + DECL(ALC_ATTRIBUTES_SIZE), + DECL(ALC_ALL_ATTRIBUTES), + DECL(ALC_DEFAULT_DEVICE_SPECIFIER), + DECL(ALC_DEVICE_SPECIFIER), + DECL(ALC_ALL_DEVICES_SPECIFIER), + DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER), + DECL(ALC_EXTENSIONS), + DECL(ALC_FREQUENCY), + DECL(ALC_REFRESH), + DECL(ALC_SYNC), + DECL(ALC_MONO_SOURCES), + DECL(ALC_STEREO_SOURCES), + DECL(ALC_CAPTURE_DEVICE_SPECIFIER), + DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER), + DECL(ALC_CAPTURE_SAMPLES), + DECL(ALC_CONNECTED), - // EFX Properties - { "ALC_EFX_MAJOR_VERSION", ALC_EFX_MAJOR_VERSION }, - { "ALC_EFX_MINOR_VERSION", ALC_EFX_MINOR_VERSION }, - { "ALC_MAX_AUXILIARY_SENDS", ALC_MAX_AUXILIARY_SENDS }, + DECL(ALC_EFX_MAJOR_VERSION), + DECL(ALC_EFX_MINOR_VERSION), + DECL(ALC_MAX_AUXILIARY_SENDS), - // Loopback device Properties - { "ALC_FORMAT_CHANNELS_SOFT", ALC_FORMAT_CHANNELS_SOFT }, - { "ALC_FORMAT_TYPE_SOFT", ALC_FORMAT_TYPE_SOFT }, + DECL(ALC_FORMAT_CHANNELS_SOFT), + DECL(ALC_FORMAT_TYPE_SOFT), - // Buffer Channel Configurations - { "ALC_MONO", ALC_MONO }, - { "ALC_STEREO", ALC_STEREO }, - { "ALC_QUAD", ALC_QUAD }, - { "ALC_5POINT1", ALC_5POINT1 }, - { "ALC_6POINT1", ALC_6POINT1 }, - { "ALC_7POINT1", ALC_7POINT1 }, + DECL(ALC_MONO_SOFT), + DECL(ALC_STEREO_SOFT), + DECL(ALC_QUAD_SOFT), + DECL(ALC_5POINT1_SOFT), + DECL(ALC_6POINT1_SOFT), + DECL(ALC_7POINT1_SOFT), - // Buffer Sample Types - { "ALC_BYTE", ALC_BYTE }, - { "ALC_UNSIGNED_BYTE", ALC_UNSIGNED_BYTE }, - { "ALC_SHORT", ALC_SHORT }, - { "ALC_UNSIGNED_SHORT", ALC_UNSIGNED_SHORT }, - { "ALC_INT", ALC_INT }, - { "ALC_UNSIGNED_INT", ALC_UNSIGNED_INT }, - { "ALC_FLOAT", ALC_FLOAT }, + DECL(ALC_BYTE_SOFT), + DECL(ALC_UNSIGNED_BYTE_SOFT), + DECL(ALC_SHORT_SOFT), + DECL(ALC_UNSIGNED_SHORT_SOFT), + DECL(ALC_INT_SOFT), + DECL(ALC_UNSIGNED_INT_SOFT), + DECL(ALC_FLOAT_SOFT), - // ALC Error Message - { "ALC_NO_ERROR", ALC_NO_ERROR }, - { "ALC_INVALID_DEVICE", ALC_INVALID_DEVICE }, - { "ALC_INVALID_CONTEXT", ALC_INVALID_CONTEXT }, - { "ALC_INVALID_ENUM", ALC_INVALID_ENUM }, - { "ALC_INVALID_VALUE", ALC_INVALID_VALUE }, - { "ALC_OUT_OF_MEMORY", ALC_OUT_OF_MEMORY }, + DECL(ALC_NO_ERROR), + DECL(ALC_INVALID_DEVICE), + DECL(ALC_INVALID_CONTEXT), + DECL(ALC_INVALID_ENUM), + DECL(ALC_INVALID_VALUE), + DECL(ALC_OUT_OF_MEMORY), - { NULL, (ALCenum)0 } + + DECL(AL_INVALID), + DECL(AL_NONE), + DECL(AL_FALSE), + DECL(AL_TRUE), + + DECL(AL_SOURCE_RELATIVE), + DECL(AL_CONE_INNER_ANGLE), + DECL(AL_CONE_OUTER_ANGLE), + DECL(AL_PITCH), + DECL(AL_POSITION), + DECL(AL_DIRECTION), + DECL(AL_VELOCITY), + DECL(AL_LOOPING), + DECL(AL_BUFFER), + DECL(AL_GAIN), + DECL(AL_MIN_GAIN), + DECL(AL_MAX_GAIN), + DECL(AL_ORIENTATION), + DECL(AL_REFERENCE_DISTANCE), + DECL(AL_ROLLOFF_FACTOR), + DECL(AL_CONE_OUTER_GAIN), + DECL(AL_MAX_DISTANCE), + DECL(AL_SEC_OFFSET), + DECL(AL_SAMPLE_OFFSET), + DECL(AL_SAMPLE_RW_OFFSETS_SOFT), + DECL(AL_BYTE_OFFSET), + DECL(AL_BYTE_RW_OFFSETS_SOFT), + DECL(AL_SOURCE_TYPE), + DECL(AL_STATIC), + DECL(AL_STREAMING), + DECL(AL_UNDETERMINED), + DECL(AL_METERS_PER_UNIT), + DECL(AL_DIRECT_CHANNELS_SOFT), + + DECL(AL_DIRECT_FILTER), + DECL(AL_AUXILIARY_SEND_FILTER), + DECL(AL_AIR_ABSORPTION_FACTOR), + DECL(AL_ROOM_ROLLOFF_FACTOR), + DECL(AL_CONE_OUTER_GAINHF), + DECL(AL_DIRECT_FILTER_GAINHF_AUTO), + DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO), + DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO), + + DECL(AL_SOURCE_STATE), + DECL(AL_INITIAL), + DECL(AL_PLAYING), + DECL(AL_PAUSED), + DECL(AL_STOPPED), + + DECL(AL_BUFFERS_QUEUED), + DECL(AL_BUFFERS_PROCESSED), + + DECL(AL_FORMAT_MONO8), + DECL(AL_FORMAT_MONO16), + DECL(AL_FORMAT_MONO_FLOAT32), + DECL(AL_FORMAT_MONO_DOUBLE_EXT), + DECL(AL_FORMAT_STEREO8), + DECL(AL_FORMAT_STEREO16), + DECL(AL_FORMAT_STEREO_FLOAT32), + DECL(AL_FORMAT_STEREO_DOUBLE_EXT), + DECL(AL_FORMAT_MONO_IMA4), + DECL(AL_FORMAT_STEREO_IMA4), + DECL(AL_FORMAT_QUAD8_LOKI), + DECL(AL_FORMAT_QUAD16_LOKI), + DECL(AL_FORMAT_QUAD8), + DECL(AL_FORMAT_QUAD16), + DECL(AL_FORMAT_QUAD32), + DECL(AL_FORMAT_51CHN8), + DECL(AL_FORMAT_51CHN16), + DECL(AL_FORMAT_51CHN32), + DECL(AL_FORMAT_61CHN8), + DECL(AL_FORMAT_61CHN16), + DECL(AL_FORMAT_61CHN32), + DECL(AL_FORMAT_71CHN8), + DECL(AL_FORMAT_71CHN16), + DECL(AL_FORMAT_71CHN32), + DECL(AL_FORMAT_REAR8), + DECL(AL_FORMAT_REAR16), + DECL(AL_FORMAT_REAR32), + DECL(AL_FORMAT_MONO_MULAW), + DECL(AL_FORMAT_MONO_MULAW_EXT), + DECL(AL_FORMAT_STEREO_MULAW), + DECL(AL_FORMAT_STEREO_MULAW_EXT), + DECL(AL_FORMAT_QUAD_MULAW), + DECL(AL_FORMAT_51CHN_MULAW), + DECL(AL_FORMAT_61CHN_MULAW), + DECL(AL_FORMAT_71CHN_MULAW), + DECL(AL_FORMAT_REAR_MULAW), + DECL(AL_FORMAT_MONO_ALAW_EXT), + DECL(AL_FORMAT_STEREO_ALAW_EXT), + + DECL(AL_MONO8_SOFT), + DECL(AL_MONO16_SOFT), + DECL(AL_MONO32F_SOFT), + DECL(AL_STEREO8_SOFT), + DECL(AL_STEREO16_SOFT), + DECL(AL_STEREO32F_SOFT), + DECL(AL_QUAD8_SOFT), + DECL(AL_QUAD16_SOFT), + DECL(AL_QUAD32F_SOFT), + DECL(AL_REAR8_SOFT), + DECL(AL_REAR16_SOFT), + DECL(AL_REAR32F_SOFT), + DECL(AL_5POINT1_8_SOFT), + DECL(AL_5POINT1_16_SOFT), + DECL(AL_5POINT1_32F_SOFT), + DECL(AL_6POINT1_8_SOFT), + DECL(AL_6POINT1_16_SOFT), + DECL(AL_6POINT1_32F_SOFT), + DECL(AL_7POINT1_8_SOFT), + DECL(AL_7POINT1_16_SOFT), + DECL(AL_7POINT1_32F_SOFT), + + DECL(AL_MONO_SOFT), + DECL(AL_STEREO_SOFT), + DECL(AL_QUAD_SOFT), + DECL(AL_REAR_SOFT), + DECL(AL_5POINT1_SOFT), + DECL(AL_6POINT1_SOFT), + DECL(AL_7POINT1_SOFT), + + DECL(AL_BYTE_SOFT), + DECL(AL_UNSIGNED_BYTE_SOFT), + DECL(AL_SHORT_SOFT), + DECL(AL_UNSIGNED_SHORT_SOFT), + DECL(AL_INT_SOFT), + DECL(AL_UNSIGNED_INT_SOFT), + DECL(AL_FLOAT_SOFT), + DECL(AL_DOUBLE_SOFT), + DECL(AL_BYTE3_SOFT), + DECL(AL_UNSIGNED_BYTE3_SOFT), + + DECL(AL_FREQUENCY), + DECL(AL_BITS), + DECL(AL_CHANNELS), + DECL(AL_SIZE), + DECL(AL_INTERNAL_FORMAT_SOFT), + DECL(AL_BYTE_LENGTH_SOFT), + DECL(AL_SAMPLE_LENGTH_SOFT), + DECL(AL_SEC_LENGTH_SOFT), + + DECL(AL_UNUSED), + DECL(AL_PENDING), + DECL(AL_PROCESSED), + + DECL(AL_NO_ERROR), + DECL(AL_INVALID_NAME), + DECL(AL_INVALID_ENUM), + DECL(AL_INVALID_VALUE), + DECL(AL_INVALID_OPERATION), + DECL(AL_OUT_OF_MEMORY), + + DECL(AL_VENDOR), + DECL(AL_VERSION), + DECL(AL_RENDERER), + DECL(AL_EXTENSIONS), + + DECL(AL_DOPPLER_FACTOR), + DECL(AL_DOPPLER_VELOCITY), + DECL(AL_DISTANCE_MODEL), + DECL(AL_SPEED_OF_SOUND), + DECL(AL_SOURCE_DISTANCE_MODEL), + DECL(AL_DEFERRED_UPDATES_SOFT), + + DECL(AL_INVERSE_DISTANCE), + DECL(AL_INVERSE_DISTANCE_CLAMPED), + DECL(AL_LINEAR_DISTANCE), + DECL(AL_LINEAR_DISTANCE_CLAMPED), + DECL(AL_EXPONENT_DISTANCE), + DECL(AL_EXPONENT_DISTANCE_CLAMPED), + + DECL(AL_FILTER_TYPE), + DECL(AL_FILTER_NULL), + DECL(AL_FILTER_LOWPASS), +#if 0 + DECL(AL_FILTER_HIGHPASS), + DECL(AL_FILTER_BANDPASS), +#endif + + DECL(AL_LOWPASS_GAIN), + DECL(AL_LOWPASS_GAINHF), + + DECL(AL_EFFECT_TYPE), + DECL(AL_EFFECT_NULL), + DECL(AL_EFFECT_REVERB), + DECL(AL_EFFECT_EAXREVERB), + DECL(AL_EFFECT_CHORUS), + DECL(AL_EFFECT_DISTORTION), + DECL(AL_EFFECT_ECHO), + DECL(AL_EFFECT_FLANGER), +#if 0 + DECL(AL_EFFECT_FREQUENCY_SHIFTER), + DECL(AL_EFFECT_VOCAL_MORPHER), + DECL(AL_EFFECT_PITCH_SHIFTER), +#endif + DECL(AL_EFFECT_RING_MODULATOR), + DECL(AL_EFFECT_AUTOWAH), + DECL(AL_EFFECT_COMPRESSOR), + DECL(AL_EFFECT_EQUALIZER), + DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT), + DECL(AL_EFFECT_DEDICATED_DIALOGUE), + + DECL(AL_EAXREVERB_DENSITY), + DECL(AL_EAXREVERB_DIFFUSION), + DECL(AL_EAXREVERB_GAIN), + DECL(AL_EAXREVERB_GAINHF), + DECL(AL_EAXREVERB_GAINLF), + DECL(AL_EAXREVERB_DECAY_TIME), + DECL(AL_EAXREVERB_DECAY_HFRATIO), + DECL(AL_EAXREVERB_DECAY_LFRATIO), + DECL(AL_EAXREVERB_REFLECTIONS_GAIN), + DECL(AL_EAXREVERB_REFLECTIONS_DELAY), + DECL(AL_EAXREVERB_REFLECTIONS_PAN), + DECL(AL_EAXREVERB_LATE_REVERB_GAIN), + DECL(AL_EAXREVERB_LATE_REVERB_DELAY), + DECL(AL_EAXREVERB_LATE_REVERB_PAN), + DECL(AL_EAXREVERB_ECHO_TIME), + DECL(AL_EAXREVERB_ECHO_DEPTH), + DECL(AL_EAXREVERB_MODULATION_TIME), + DECL(AL_EAXREVERB_MODULATION_DEPTH), + DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF), + DECL(AL_EAXREVERB_HFREFERENCE), + DECL(AL_EAXREVERB_LFREFERENCE), + DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR), + DECL(AL_EAXREVERB_DECAY_HFLIMIT), + + DECL(AL_REVERB_DENSITY), + DECL(AL_REVERB_DIFFUSION), + DECL(AL_REVERB_GAIN), + DECL(AL_REVERB_GAINHF), + DECL(AL_REVERB_DECAY_TIME), + DECL(AL_REVERB_DECAY_HFRATIO), + DECL(AL_REVERB_REFLECTIONS_GAIN), + DECL(AL_REVERB_REFLECTIONS_DELAY), + DECL(AL_REVERB_LATE_REVERB_GAIN), + DECL(AL_REVERB_LATE_REVERB_DELAY), + DECL(AL_REVERB_AIR_ABSORPTION_GAINHF), + DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR), + DECL(AL_REVERB_DECAY_HFLIMIT), + + DECL(AL_CHORUS_WAVEFORM), + DECL(AL_CHORUS_PHASE), + DECL(AL_CHORUS_RATE), + DECL(AL_CHORUS_DEPTH), + DECL(AL_CHORUS_FEEDBACK), + DECL(AL_CHORUS_DELAY), + + DECL(AL_DISTORTION_EDGE), + DECL(AL_DISTORTION_GAIN), + DECL(AL_DISTORTION_LOWPASS_CUTOFF), + DECL(AL_DISTORTION_EQCENTER), + DECL(AL_DISTORTION_EQBANDWIDTH), + + DECL(AL_ECHO_DELAY), + DECL(AL_ECHO_LRDELAY), + DECL(AL_ECHO_DAMPING), + DECL(AL_ECHO_FEEDBACK), + DECL(AL_ECHO_SPREAD), + + DECL(AL_FLANGER_WAVEFORM), + DECL(AL_FLANGER_PHASE), + DECL(AL_FLANGER_RATE), + DECL(AL_FLANGER_DEPTH), + DECL(AL_FLANGER_FEEDBACK), + DECL(AL_FLANGER_DELAY), + + DECL(AL_RING_MODULATOR_FREQUENCY), + DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF), + DECL(AL_RING_MODULATOR_WAVEFORM), + + DECL(AL_AUTOWAH_ATTACK_TIME), + DECL(AL_AUTOWAH_PEAK_GAIN), + DECL(AL_AUTOWAH_RELEASE_TIME), + DECL(AL_AUTOWAH_RESONANCE), + + DECL(AL_COMPRESSOR_ONOFF), + + DECL(AL_EQUALIZER_LOW_GAIN), + DECL(AL_EQUALIZER_LOW_CUTOFF), + DECL(AL_EQUALIZER_MID1_GAIN), + DECL(AL_EQUALIZER_MID1_CENTER), + DECL(AL_EQUALIZER_MID1_WIDTH), + DECL(AL_EQUALIZER_MID2_GAIN), + DECL(AL_EQUALIZER_MID2_CENTER), + DECL(AL_EQUALIZER_MID2_WIDTH), + DECL(AL_EQUALIZER_HIGH_GAIN), + DECL(AL_EQUALIZER_HIGH_CUTOFF), + + DECL(AL_DEDICATED_GAIN), + + { NULL, (ALCenum)0 } }; -// Error strings +#undef DECL + static const ALCchar alcNoError[] = "No Error"; static const ALCchar alcErrInvalidDevice[] = "Invalid Device"; static const ALCchar alcErrInvalidContext[] = "Invalid Context"; @@ -327,68 +682,43 @@ static const ALCchar alcErrInvalidEnum[] = "Invalid Enum"; static const ALCchar alcErrInvalidValue[] = "Invalid Value"; static const ALCchar alcErrOutOfMemory[] = "Out of Memory"; -/* Device lists. Sizes only include the first ending null character, not the - * second */ -static ALCchar *alcDeviceList; -static size_t alcDeviceListSize; -static ALCchar *alcAllDeviceList; -static size_t alcAllDeviceListSize; + +/************************************************ + * Global variables + ************************************************/ + +/* Enumerated device names */ +static const ALCchar alcDefaultName[] = "OpenAL Soft\0"; +static ALCchar *alcAllDevicesList; static ALCchar *alcCaptureDeviceList; +/* Sizes only include the first ending null character, not the second */ +static size_t alcAllDevicesListSize; static size_t alcCaptureDeviceListSize; + /* Default is always the first in the list */ -static ALCchar *alcDefaultDeviceSpecifier; -static ALCchar *alcDefaultAllDeviceSpecifier; +static ALCchar *alcDefaultAllDevicesSpecifier; static ALCchar *alcCaptureDefaultDeviceSpecifier; - -static const ALCchar alcNoDeviceExtList[] = - "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE " - "ALC_EXT_thread_local_context ALC_SOFTX_loopback_device"; -static const ALCchar alcExtensionList[] = - "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE " - "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX " - "ALC_EXT_thread_local_context ALC_SOFTX_loopback_device"; -static const ALCint alcMajorVersion = 1; -static const ALCint alcMinorVersion = 1; - -static const ALCint alcEFXMajorVersion = 1; -static const ALCint alcEFXMinorVersion = 0; - -/////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////// -// Global Variables - -static CRITICAL_SECTION ListLock; - -/* Device List */ -static ALCdevice *volatile DeviceList = NULL; - -// Thread-local current context -static pthread_key_t LocalContext; -// Process-wide current context -static ALCcontext *GlobalContext; - -/* Device Error */ -static volatile ALCenum g_eLastNullDeviceError = ALC_NO_ERROR; - -// Default context extensions +/* Default context extensions */ static const ALchar alExtList[] = "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 " "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW " "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model " - "AL_LOKI_quadriphonic AL_SOFTX_buffer_samples AL_SOFT_buffer_sub_data " - "AL_SOFTX_deferred_updates AL_SOFT_loop_points " - "AL_SOFTX_non_virtual_channels"; + "AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data " + "AL_SOFT_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points " + "AL_SOFT_source_latency"; -// Mixing Priority Level +static volatile ALCenum LastNullDeviceError = ALC_NO_ERROR; + +/* Thread-local current context */ +static althread_key_t LocalContext; +/* Process-wide current context */ +static ALCcontext *volatile GlobalContext = NULL; + +/* Mixing thread piority level */ ALint RTPrioLevel; -// Output Log File FILE *LogFile; - -// Output Log Level #ifdef _DEBUG enum LogLevel LogLevel = LogWarning; #else @@ -399,36 +729,68 @@ enum LogLevel LogLevel = LogError; static ALCboolean TrapALCError = ALC_FALSE; /* One-time configuration init control */ -static pthread_once_t alc_config_once = PTHREAD_ONCE_INIT; +static althread_once_t alc_config_once = ALTHREAD_ONCE_INIT; -/////////////////////////////////////////////////////// +/* Default effect that applies to sources that don't have an effect on send 0 */ +static ALeffect DefaultEffect; -/////////////////////////////////////////////////////// -// ALC Related helper functions -static void ReleaseALC(void); -static void ReleaseThreadCtx(void *ptr); +/************************************************ + * ALC information + ************************************************/ +static const ALCchar alcNoDeviceExtList[] = + "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE " + "ALC_EXT_thread_local_context ALC_SOFT_loopback"; +static const ALCchar alcExtensionList[] = + "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE " + "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX " + "ALC_EXT_thread_local_context ALC_SOFTX_HRTF ALC_SOFT_loopback " + "ALC_SOFTX_midi_interface ALC_SOFTX_pause_device"; +static const ALCint alcMajorVersion = 1; +static const ALCint alcMinorVersion = 1; -static void alc_initconfig(void); -#define DO_INITCONFIG() pthread_once(&alc_config_once, alc_initconfig) +static const ALCint alcEFXMajorVersion = 1; +static const ALCint alcEFXMinorVersion = 0; + +/************************************************ + * Device lists + ************************************************/ +static ALCdevice *volatile DeviceList = NULL; + +static CRITICAL_SECTION ListLock; + +static void LockLists(void) +{ + EnterCriticalSection(&ListLock); +} +static void UnlockLists(void) +{ + LeaveCriticalSection(&ListLock); +} + +/************************************************ + * Library initialization + ************************************************/ #if defined(_WIN32) static void alc_init(void); static void alc_deinit(void); static void alc_deinit_safe(void); -#ifndef AL_LIBTYPE_STATIC UIntMap TlsDestructor; -BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) +#ifndef AL_LIBTYPE_STATIC +BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { ALsizei i; - (void)hModule; // Perform actions based on the reason for calling. switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: + /* Pin the DLL so we won't get unloaded until the process terminates */ + GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (WCHAR*)hModule, &hModule); InitUIntMap(&TlsDestructor, ~0); alc_init(); break; @@ -437,7 +799,7 @@ BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) LockUIntMapRead(&TlsDestructor); for(i = 0;i < TlsDestructor.size;i++) { - void *ptr = pthread_getspecific(TlsDestructor.array[i].key); + void *ptr = althread_getspecific(TlsDestructor.array[i].key); void (*callback)(void*) = (void(*)(void*))TlsDestructor.array[i].value; if(ptr && callback) callback(ptr); @@ -477,13 +839,17 @@ static void alc_deinit(void) __attribute__((destructor)); #else #error "No static initialization available on this platform!" #endif + #elif defined(HAVE_GCC_DESTRUCTOR) + static void alc_init(void) __attribute__((constructor)); static void alc_deinit(void) __attribute__((destructor)); + #else #error "No global initialization available on this platform!" #endif +static void ReleaseThreadCtx(void *ptr); static void alc_init(void) { const char *str; @@ -492,69 +858,21 @@ static void alc_init(void) str = getenv("__ALSOFT_HALF_ANGLE_CONES"); if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) - ConeScale = 1.0f; + ConeScale *= 0.5f; str = getenv("__ALSOFT_REVERSE_Z"); if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) - ZScale = -1.0f; + ZScale *= -1.0f; - str = getenv("__ALSOFT_TRAP_ERROR"); - if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) - { - TrapALError = AL_TRUE; - TrapALCError = AL_TRUE; - } - else - { - str = getenv("__ALSOFT_TRAP_AL_ERROR"); - if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) - TrapALError = AL_TRUE; - - str = getenv("__ALSOFT_TRAP_ALC_ERROR"); - if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) - TrapALCError = ALC_TRUE; - } - - pthread_key_create(&LocalContext, ReleaseThreadCtx); + althread_key_create(&LocalContext, ReleaseThreadCtx); InitializeCriticalSection(&ListLock); ThunkInit(); } -static void alc_deinit_safe(void) -{ - ReleaseALC(); - - FreeHrtf(); - FreeALConfig(); - - ThunkExit(); - DeleteCriticalSection(&ListLock); - pthread_key_delete(LocalContext); - - if(LogFile != stderr) - fclose(LogFile); - LogFile = NULL; -} - -static void alc_deinit(void) -{ - int i; - - ReleaseALC(); - - memset(&PlaybackBackend, 0, sizeof(PlaybackBackend)); - memset(&CaptureBackend, 0, sizeof(CaptureBackend)); - - for(i = 0;BackendList[i].Deinit;i++) - BackendList[i].Deinit(); - BackendLoopback.Deinit(); - - alc_deinit_safe(); -} - static void alc_initconfig(void) { const char *devs, *str; + ALuint capfilter; float valf; int i, n; @@ -569,14 +887,60 @@ static void alc_initconfig(void) str = getenv("ALSOFT_LOGFILE"); if(str && str[0]) { - FILE *logfile = fopen(str, "wat"); + FILE *logfile = fopen(str, "wt"); if(logfile) LogFile = logfile; else ERR("Failed to open log file '%s'\n", str); } + { + char buf[1024] = ""; + int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name); + for(i = 1;BackendList[i].name;i++) + len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name); + TRACE("Supported backends: %s\n", buf); + } ReadALConfig(); - InitHrtf(); + capfilter = 0; +#ifdef HAVE_SSE + capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2; +#endif +#ifdef HAVE_NEON + capfilter |= CPU_CAP_NEON; +#endif + if(ConfigValueStr(NULL, "disable-cpu-exts", &str)) + { + if(strcasecmp(str, "all") == 0) + capfilter = 0; + else + { + size_t len; + const char *next = str; + + do { + str = next; + while(isspace(str[0])) + str++; + next = strchr(str, ','); + + if(!str[0] || str[0] == ',') + continue; + + len = (next ? ((size_t)(next-str)) : strlen(str)); + while(len > 0 && isspace(str[len-1])) + len--; + if(len == 3 && strncasecmp(str, "sse", len) == 0) + capfilter &= ~CPU_CAP_SSE; + else if(len == 4 && strncasecmp(str, "sse2", len) == 0) + capfilter &= ~CPU_CAP_SSE2; + else if(len == 4 && strncasecmp(str, "neon", len) == 0) + capfilter &= ~CPU_CAP_NEON; + else + WARN("Invalid CPU extension \"%s\"\n", str); + } while(next++); + } + } + FillCPUCaps(capfilter); #ifdef _WIN32 RTPrioLevel = 1; @@ -585,24 +949,52 @@ static void alc_initconfig(void) #endif ConfigValueInt(NULL, "rt-prio", &RTPrioLevel); - if(ConfigValueInt(NULL, "resampler", &n)) + if(ConfigValueStr(NULL, "resampler", &str)) { - if(n < RESAMPLER_MAX && n > RESAMPLER_MIN) - DefaultResampler = n; + if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0) + DefaultResampler = PointResampler; + else if(strcasecmp(str, "linear") == 0) + DefaultResampler = LinearResampler; + else if(strcasecmp(str, "cubic") == 0) + DefaultResampler = CubicResampler; + else + { + char *end; + + n = strtol(str, &end, 0); + if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler)) + DefaultResampler = n; + else + WARN("Invalid resampler: %s\n", str); + } } - if(!TrapALCError) - TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", ALC_FALSE); + str = getenv("ALSOFT_TRAP_ERROR"); + if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) + { + TrapALError = AL_TRUE; + TrapALCError = AL_TRUE; + } + else + { + str = getenv("ALSOFT_TRAP_AL_ERROR"); + if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) + TrapALError = AL_TRUE; + TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError); - if(!TrapALError) - TrapALError = GetConfigValueBool(NULL, "trap-al-error", AL_FALSE); + str = getenv("ALSOFT_TRAP_ALC_ERROR"); + if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1)) + TrapALCError = ALC_TRUE; + TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError); + } if(ConfigValueFloat("reverb", "boost", &valf)) - ReverbBoost *= aluPow(10.0f, valf / 20.0f); + ReverbBoost *= powf(10.0f, valf / 20.0f); EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE); - if(ConfigValueStr(NULL, "drivers", &devs)) + if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) || + ConfigValueStr(NULL, "drivers", &devs)) { int n; size_t len; @@ -612,6 +1004,8 @@ static void alc_initconfig(void) i = 0; do { devs = next; + while(isspace(devs[0])) + devs++; next = strchr(devs, ','); delitem = (devs[0] == '-'); @@ -625,7 +1019,9 @@ static void alc_initconfig(void) endlist = 1; len = (next ? ((size_t)(next-devs)) : strlen(devs)); - for(n = i;BackendList[n].Init;n++) + while(len > 0 && isspace(devs[len-1])) + len--; + for(n = i;BackendList[n].name;n++) { if(len == strlen(BackendList[n].name) && strncmp(BackendList[n].name, devs, len) == 0) @@ -635,7 +1031,7 @@ static void alc_initconfig(void) do { BackendList[n] = BackendList[n+1]; ++n; - } while(BackendList[n].Init); + } while(BackendList[n].name); } else { @@ -657,14 +1053,39 @@ static void alc_initconfig(void) if(endlist) { BackendList[i].name = NULL; + BackendList[i].getFactory = NULL; BackendList[i].Init = NULL; BackendList[i].Deinit = NULL; BackendList[i].Probe = NULL; } } - for(i = 0;BackendList[i].Init && (!PlaybackBackend.name || !CaptureBackend.name);i++) + for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++) { + if(BackendList[i].getFactory) + { + ALCbackendFactory *factory = BackendList[i].getFactory(); + if(!V0(factory,init)()) + { + WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name); + continue; + } + + TRACE("Initialized backend \"%s\"\n", BackendList[i].name); + if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback)) + { + PlaybackBackend = BackendList[i]; + TRACE("Added \"%s\" for playback\n", PlaybackBackend.name); + } + if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture)) + { + CaptureBackend = BackendList[i]; + TRACE("Added \"%s\" for capture\n", CaptureBackend.name); + } + + continue; + } + if(!BackendList[i].Init(&BackendList[i].Funcs)) { WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name); @@ -683,7 +1104,10 @@ static void alc_initconfig(void) TRACE("Added \"%s\" for capture\n", CaptureBackend.name); } } - BackendLoopback.Init(&BackendLoopback.Funcs); + { + ALCbackendFactory *factory = ALCloopbackFactory_getFactory(); + V0(factory,init)(); + } if(ConfigValueStr(NULL, "excludefx", &str)) { @@ -706,20 +1130,93 @@ static void alc_initconfig(void) } } while(next++); } + + InitEffectFactoryMap(); + + InitEffect(&DefaultEffect); + str = getenv("ALSOFT_DEFAULT_REVERB"); + if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str)) + LoadReverbPreset(str, &DefaultEffect); } +#define DO_INITCONFIG() althread_once(&alc_config_once, alc_initconfig) -static void LockLists(void) +/************************************************ + * Library deinitialization + ************************************************/ +static void alc_cleanup(void) { - EnterCriticalSection(&ListLock); + ALCdevice *dev; + + free(alcAllDevicesList); alcAllDevicesList = NULL; + alcAllDevicesListSize = 0; + free(alcCaptureDeviceList); alcCaptureDeviceList = NULL; + alcCaptureDeviceListSize = 0; + + free(alcDefaultAllDevicesSpecifier); + alcDefaultAllDevicesSpecifier = NULL; + free(alcCaptureDefaultDeviceSpecifier); + alcCaptureDefaultDeviceSpecifier = NULL; + + if((dev=ExchangePtr((XchgPtr*)&DeviceList, NULL)) != NULL) + { + ALCuint num = 0; + do { + num++; + } while((dev=dev->next) != NULL); + ERR("%u device%s not closed\n", num, (num>1)?"s":""); + } + + DeinitEffectFactoryMap(); } -static void UnlockLists(void) +static void alc_deinit_safe(void) { - LeaveCriticalSection(&ListLock); + alc_cleanup(); + + FreeHrtfs(); + FreeALConfig(); + + ThunkExit(); + DeleteCriticalSection(&ListLock); + althread_key_delete(LocalContext); + + if(LogFile != stderr) + fclose(LogFile); + LogFile = NULL; +} + +static void alc_deinit(void) +{ + int i; + + alc_cleanup(); + + memset(&PlaybackBackend, 0, sizeof(PlaybackBackend)); + memset(&CaptureBackend, 0, sizeof(CaptureBackend)); + + for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++) + { + if(!BackendList[i].getFactory) + BackendList[i].Deinit(); + else + { + ALCbackendFactory *factory = BackendList[i].getFactory(); + V0(factory,deinit)(); + } + } + { + ALCbackendFactory *factory = ALCloopbackFactory_getFactory(); + V0(factory,deinit)(); + } + + alc_deinit_safe(); } +/************************************************ + * Device enumeration + ************************************************/ static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type) { DO_INITCONFIG(); @@ -729,17 +1226,31 @@ static void ProbeList(ALCchar **list, size_t *listsize, enum DevProbe type) *list = NULL; *listsize = 0; - if(type == CAPTURE_DEVICE_PROBE) - CaptureBackend.Probe(type); - else - PlaybackBackend.Probe(type); + if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory)) + { + if(!PlaybackBackend.getFactory) + PlaybackBackend.Probe(type); + else + { + ALCbackendFactory *factory = PlaybackBackend.getFactory(); + V(factory,probe)(type); + } + } + else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory)) + { + if(!CaptureBackend.getFactory) + CaptureBackend.Probe(type); + else + { + ALCbackendFactory *factory = CaptureBackend.getFactory(); + V(factory,probe)(type); + } + } UnlockLists(); } -static void ProbeDeviceList(void) -{ ProbeList(&alcDeviceList, &alcDeviceListSize, DEVICE_PROBE); } -static void ProbeAllDeviceList(void) -{ ProbeList(&alcAllDeviceList, &alcAllDeviceListSize, ALL_DEVICE_PROBE); } +static void ProbeAllDevicesList(void) +{ ProbeList(&alcAllDevicesList, &alcAllDevicesListSize, ALL_DEVICE_PROBE); } static void ProbeCaptureDeviceList(void) { ProbeList(&alcCaptureDeviceList, &alcCaptureDeviceListSize, CAPTURE_DEVICE_PROBE); } @@ -769,95 +1280,15 @@ static void AppendList(const ALCchar *name, ALCchar **List, size_t *ListSize) void Append##type##List(const ALCchar *name) \ { AppendList(name, &alc##type##List, &alc##type##ListSize); } -DECL_APPEND_LIST_FUNC(Device) -DECL_APPEND_LIST_FUNC(AllDevice) +DECL_APPEND_LIST_FUNC(AllDevices) DECL_APPEND_LIST_FUNC(CaptureDevice) #undef DECL_APPEND_LIST_FUNC -/* Sets the default channel order used by most non-WaveFormatEx-based APIs */ -void SetDefaultChannelOrder(ALCdevice *device) -{ - switch(device->FmtChans) - { - case DevFmtX51: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = BACK_LEFT; - device->DevChannels[3] = BACK_RIGHT; - device->DevChannels[4] = FRONT_CENTER; - device->DevChannels[5] = LFE; - return; - - case DevFmtX71: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = BACK_LEFT; - device->DevChannels[3] = BACK_RIGHT; - device->DevChannels[4] = FRONT_CENTER; - device->DevChannels[5] = LFE; - device->DevChannels[6] = SIDE_LEFT; - device->DevChannels[7] = SIDE_RIGHT; - return; - - /* Same as WFX order */ - case DevFmtMono: - case DevFmtStereo: - case DevFmtQuad: - case DevFmtX51Side: - case DevFmtX61: - break; - } - SetDefaultWFXChannelOrder(device); -} -/* Sets the default order used by WaveFormatEx */ -void SetDefaultWFXChannelOrder(ALCdevice *device) -{ - switch(device->FmtChans) - { - case DevFmtMono: device->DevChannels[0] = FRONT_CENTER; break; - - case DevFmtStereo: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; break; - - case DevFmtQuad: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = BACK_LEFT; - device->DevChannels[3] = BACK_RIGHT; break; - - case DevFmtX51: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = FRONT_CENTER; - device->DevChannels[3] = LFE; - device->DevChannels[4] = BACK_LEFT; - device->DevChannels[5] = BACK_RIGHT; break; - - case DevFmtX51Side: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = FRONT_CENTER; - device->DevChannels[3] = LFE; - device->DevChannels[4] = SIDE_LEFT; - device->DevChannels[5] = SIDE_RIGHT; break; - - case DevFmtX61: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = FRONT_CENTER; - device->DevChannels[3] = LFE; - device->DevChannels[4] = BACK_CENTER; - device->DevChannels[5] = SIDE_LEFT; - device->DevChannels[6] = SIDE_RIGHT; break; - - case DevFmtX71: device->DevChannels[0] = FRONT_LEFT; - device->DevChannels[1] = FRONT_RIGHT; - device->DevChannels[2] = FRONT_CENTER; - device->DevChannels[3] = LFE; - device->DevChannels[4] = BACK_LEFT; - device->DevChannels[5] = BACK_RIGHT; - device->DevChannels[6] = SIDE_LEFT; - device->DevChannels[7] = SIDE_RIGHT; break; - } -} - - +/************************************************ + * Device format information + ************************************************/ const ALCchar *DevFmtTypeString(enum DevFmtType type) { switch(type) @@ -866,6 +1297,8 @@ const ALCchar *DevFmtTypeString(enum DevFmtType type) case DevFmtUByte: return "Unsigned Byte"; case DevFmtShort: return "Signed Short"; case DevFmtUShort: return "Unsigned Short"; + case DevFmtInt: return "Signed Int"; + case DevFmtUInt: return "Unsigned Int"; case DevFmtFloat: return "Float"; } return "(unknown type)"; @@ -885,6 +1318,7 @@ const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) return "(unknown channels)"; } +extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type); ALuint BytesFromDevFmt(enum DevFmtType type) { switch(type) @@ -893,6 +1327,8 @@ ALuint BytesFromDevFmt(enum DevFmtType type) case DevFmtUByte: return sizeof(ALubyte); case DevFmtShort: return sizeof(ALshort); case DevFmtUShort: return sizeof(ALushort); + case DevFmtInt: return sizeof(ALint); + case DevFmtUInt: return sizeof(ALuint); case DevFmtFloat: return sizeof(ALfloat); } return 0; @@ -911,6 +1347,7 @@ ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) } return 0; } + static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans, enum DevFmtType *type) { @@ -945,7 +1382,7 @@ static ALboolean DecomposeDevFormat(ALenum format, enum DevFmtChannels *chans, }; ALuint i; - for(i = 0;i < sizeof(list)/sizeof(list[0]);i++) + for(i = 0;i < COUNTOF(list);i++) { if(list[i].format == format) { @@ -962,13 +1399,13 @@ static ALCboolean IsValidALCType(ALCenum type) { switch(type) { - case ALC_BYTE: - case ALC_UNSIGNED_BYTE: - case ALC_SHORT: - case ALC_UNSIGNED_SHORT: - case ALC_INT: - case ALC_UNSIGNED_INT: - case ALC_FLOAT: + case ALC_BYTE_SOFT: + case ALC_UNSIGNED_BYTE_SOFT: + case ALC_SHORT_SOFT: + case ALC_UNSIGNED_SHORT_SOFT: + case ALC_INT_SOFT: + case ALC_UNSIGNED_INT_SOFT: + case ALC_FLOAT_SOFT: return ALC_TRUE; } return ALC_FALSE; @@ -978,21 +1415,147 @@ static ALCboolean IsValidALCChannels(ALCenum channels) { switch(channels) { - case ALC_MONO: - case ALC_STEREO: - case ALC_QUAD: - case ALC_5POINT1: - case ALC_6POINT1: - case ALC_7POINT1: + case ALC_MONO_SOFT: + case ALC_STEREO_SOFT: + case ALC_QUAD_SOFT: + case ALC_5POINT1_SOFT: + case ALC_6POINT1_SOFT: + case ALC_7POINT1_SOFT: return ALC_TRUE; } return ALC_FALSE; } +/************************************************ + * Miscellaneous ALC helpers + ************************************************/ +extern inline void LockContext(ALCcontext *context); +extern inline void UnlockContext(ALCcontext *context); + +ALint64 ALCdevice_GetLatencyDefault(ALCdevice *UNUSED(device)) +{ + return 0; +} + +ALint64 ALCdevice_GetLatency(ALCdevice *device) +{ + return V0(device->Backend,getLatency)(); +} + +void ALCdevice_Lock(ALCdevice *device) +{ + V0(device->Backend,lock)(); +} + +void ALCdevice_Unlock(ALCdevice *device) +{ + V0(device->Backend,unlock)(); +} + + +/* SetDefaultWFXChannelOrder + * + * Sets the default channel order used by WaveFormatEx. + */ +void SetDefaultWFXChannelOrder(ALCdevice *device) +{ + ALuint i; + + for(i = 0;i < MaxChannels;i++) + device->ChannelOffsets[i] = INVALID_OFFSET; + + switch(device->FmtChans) + { + case DevFmtMono: device->ChannelOffsets[FrontCenter] = 0; + break; + case DevFmtStereo: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + break; + case DevFmtQuad: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[BackLeft] = 2; + device->ChannelOffsets[BackRight] = 3; + break; + case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[FrontCenter] = 2; + device->ChannelOffsets[LFE] = 3; + device->ChannelOffsets[BackLeft] = 4; + device->ChannelOffsets[BackRight] = 5; + break; + case DevFmtX51Side: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[FrontCenter] = 2; + device->ChannelOffsets[LFE] = 3; + device->ChannelOffsets[SideLeft] = 4; + device->ChannelOffsets[SideRight] = 5; + break; + case DevFmtX61: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[FrontCenter] = 2; + device->ChannelOffsets[LFE] = 3; + device->ChannelOffsets[BackCenter] = 4; + device->ChannelOffsets[SideLeft] = 5; + device->ChannelOffsets[SideRight] = 6; + break; + case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[FrontCenter] = 2; + device->ChannelOffsets[LFE] = 3; + device->ChannelOffsets[BackLeft] = 4; + device->ChannelOffsets[BackRight] = 5; + device->ChannelOffsets[SideLeft] = 6; + device->ChannelOffsets[SideRight] = 7; + break; + } +} + +/* SetDefaultChannelOrder + * + * Sets the default channel order used by most non-WaveFormatEx-based APIs. + */ +void SetDefaultChannelOrder(ALCdevice *device) +{ + ALuint i; + + for(i = 0;i < MaxChannels;i++) + device->ChannelOffsets[i] = INVALID_OFFSET; + + switch(device->FmtChans) + { + case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[BackLeft] = 2; + device->ChannelOffsets[BackRight] = 3; + device->ChannelOffsets[FrontCenter] = 4; + device->ChannelOffsets[LFE] = 5; + return; + case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0; + device->ChannelOffsets[FrontRight] = 1; + device->ChannelOffsets[BackLeft] = 2; + device->ChannelOffsets[BackRight] = 3; + device->ChannelOffsets[FrontCenter] = 4; + device->ChannelOffsets[LFE] = 5; + device->ChannelOffsets[SideLeft] = 6; + device->ChannelOffsets[SideRight] = 7; + return; + + /* Same as WFX order */ + case DevFmtMono: + case DevFmtStereo: + case DevFmtQuad: + case DevFmtX51Side: + case DevFmtX61: + break; + } + SetDefaultWFXChannelOrder(device); +} + + /* alcSetError * - * Stores the latest ALC Error + * Stores the latest ALC device error */ static void alcSetError(ALCdevice *device, ALCenum errorCode) { @@ -1010,7 +1573,7 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode) if(device) device->LastError = errorCode; else - g_eLastNullDeviceError = errorCode; + LastNullDeviceError = errorCode; } @@ -1019,76 +1582,69 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode) * Updates device parameters according to the attribute list (caller is * responsible for holding the list lock). */ -static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) +static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALCcontext *context; - int oldMode; + enum DevFmtChannels oldChans; + enum DevFmtType oldType; + ALCuint oldFreq; + FPUCtl oldMode; ALuint i; // Check for attributes - if(attrList && attrList[0]) + if(device->Type == Loopback) { + enum { + GotFreq = 1<<0, + GotChans = 1<<1, + GotType = 1<<2, + GotAll = GotFreq|GotChans|GotType + }; ALCuint freq, numMono, numStereo, numSends; enum DevFmtChannels schans; enum DevFmtType stype; - ALuint attrIdx; + ALCuint attrIdx = 0; + ALCint gotFmt = 0; - // If a context is already running on the device, stop playback so the - // device attributes can be updated - if((device->Flags&DEVICE_RUNNING)) - ALCdevice_StopPlayback(device); - device->Flags &= ~DEVICE_RUNNING; + if(!attrList) + { + WARN("Missing attributes for loopback device\n"); + return ALC_INVALID_VALUE; + } - freq = device->Frequency; - schans = device->FmtChans; - stype = device->FmtType; numMono = device->NumMonoSources; numStereo = device->NumStereoSources; numSends = device->NumAuxSends; + schans = device->FmtChans; + stype = device->FmtType; + freq = device->Frequency; - attrIdx = 0; while(attrList[attrIdx]) { - if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT && - device->IsLoopbackDevice) + if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT) { ALCint val = attrList[attrIdx + 1]; if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val)) - { - alcSetError(device, ALC_INVALID_VALUE); - return ALC_FALSE; - } + return ALC_INVALID_VALUE; schans = val; + gotFmt |= GotChans; } - if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT && - device->IsLoopbackDevice) + if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT) { ALCint val = attrList[attrIdx + 1]; if(!IsValidALCType(val) || !BytesFromDevFmt(val)) - { - alcSetError(device, ALC_INVALID_VALUE); - return ALC_FALSE; - } + return ALC_INVALID_VALUE; stype = val; + gotFmt |= GotType; } if(attrList[attrIdx] == ALC_FREQUENCY) { - if(device->IsLoopbackDevice) - { - freq = attrList[attrIdx + 1]; - if(freq < 8000) - { - alcSetError(device, ALC_INVALID_VALUE); - return ALC_FALSE; - } - } - else - { - freq = attrList[attrIdx + 1]; - device->Flags |= DEVICE_FREQUENCY_REQUEST; - } + freq = attrList[attrIdx + 1]; + if(freq < MIN_OUTPUT_RATE) + return ALC_INVALID_VALUE; + gotFmt |= GotFreq; } if(attrList[attrIdx] == ALC_STEREO_SOURCES) @@ -1103,19 +1659,29 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS) numSends = attrList[attrIdx + 1]; + if(attrList[attrIdx] == ALC_HRTF_SOFT) + { + if(attrList[attrIdx + 1] != ALC_FALSE) + device->Flags |= DEVICE_HRTF_REQUEST; + else + device->Flags &= ~DEVICE_HRTF_REQUEST; + } + attrIdx += 2; } - if(!device->IsLoopbackDevice) + if(gotFmt != GotAll) { - ConfigValueUInt(NULL, "frequency", &freq); - freq = maxu(freq, 8000); + WARN("Missing format for loopback device\n"); + return ALC_INVALID_VALUE; } + ConfigValueUInt(NULL, "sends", &numSends); numSends = minu(MAX_SENDS, numSends); - device->UpdateSize = (ALuint64)device->UpdateSize * freq / - device->Frequency; + if((device->Flags&DEVICE_RUNNING)) + V0(device->Backend,stop)(); + device->Flags &= ~DEVICE_RUNNING; device->Frequency = freq; device->FmtChans = schans; @@ -1124,41 +1690,149 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->NumStereoSources = numStereo; device->NumAuxSends = numSends; } + else if(attrList && attrList[0]) + { + ALCuint freq, numMono, numStereo, numSends; + ALCuint attrIdx = 0; + + /* If a context is already running on the device, stop playback so the + * device attributes can be updated. */ + if((device->Flags&DEVICE_RUNNING)) + V0(device->Backend,stop)(); + device->Flags &= ~DEVICE_RUNNING; + + freq = device->Frequency; + numMono = device->NumMonoSources; + numStereo = device->NumStereoSources; + numSends = device->NumAuxSends; + + while(attrList[attrIdx]) + { + if(attrList[attrIdx] == ALC_FREQUENCY) + { + freq = attrList[attrIdx + 1]; + device->Flags |= DEVICE_FREQUENCY_REQUEST; + } + + if(attrList[attrIdx] == ALC_STEREO_SOURCES) + { + numStereo = attrList[attrIdx + 1]; + if(numStereo > device->MaxNoOfSources) + numStereo = device->MaxNoOfSources; + + numMono = device->MaxNoOfSources - numStereo; + } + + if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS) + numSends = attrList[attrIdx + 1]; + + if(attrList[attrIdx] == ALC_HRTF_SOFT) + { + if(attrList[attrIdx + 1] != ALC_FALSE) + device->Flags |= DEVICE_HRTF_REQUEST; + else + device->Flags &= ~DEVICE_HRTF_REQUEST; + } + + attrIdx += 2; + } + + ConfigValueUInt(NULL, "frequency", &freq); + freq = maxu(freq, MIN_OUTPUT_RATE); + + ConfigValueUInt(NULL, "sends", &numSends); + numSends = minu(MAX_SENDS, numSends); + + device->UpdateSize = (ALuint64)device->UpdateSize * freq / + device->Frequency; + /* SSE and Neon do best with the update size being a multiple of 4 */ + if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0) + device->UpdateSize = (device->UpdateSize+3)&~3; + + device->Frequency = freq; + device->NumMonoSources = numMono; + device->NumStereoSources = numStereo; + device->NumAuxSends = numSends; + } if((device->Flags&DEVICE_RUNNING)) - return ALC_TRUE; + return ALC_NO_ERROR; - LockDevice(device); - TRACE("Format pre-setup: %s%s, %s, %uhz%s, %u update size x%d\n", + oldFreq = device->Frequency; + oldChans = device->FmtChans; + oldType = device->FmtType; + + TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n", + (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"", DevFmtChannelsString(device->FmtChans), - (device->Flags&DEVICE_CHANNELS_REQUEST)?" (requested)":"", - DevFmtTypeString(device->FmtType), device->Frequency, - (device->Flags&DEVICE_FREQUENCY_REQUEST)?" (requested)":"", + (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"", + DevFmtTypeString(device->FmtType), + (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"", + device->Frequency, device->UpdateSize, device->NumUpdates); - if(ALCdevice_ResetPlayback(device) == ALC_FALSE) + + if((device->Flags&DEVICE_HRTF_REQUEST)) { - UnlockDevice(device); - return ALC_FALSE; + enum DevFmtChannels chans; + ALCuint freq; + + FindHrtfFormat(device, &chans, &freq); + device->Frequency = freq; + device->FmtChans = chans; + device->Flags |= DEVICE_CHANNELS_REQUEST | + DEVICE_FREQUENCY_REQUEST; } - device->Flags |= DEVICE_RUNNING; - TRACE("Format post-setup: %s%s, %s, %uhz%s, %u update size x%d\n", + + if(V0(device->Backend,reset)() == ALC_FALSE) + return ALC_INVALID_DEVICE; + + if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST)) + { + ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans), + DevFmtChannelsString(device->FmtChans)); + device->Flags &= ~DEVICE_CHANNELS_REQUEST; + } + if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)) + { + ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType), + DevFmtTypeString(device->FmtType)); + device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST; + } + if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST)) + { + ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency); + device->Flags &= ~DEVICE_FREQUENCY_REQUEST; + } + + TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n", DevFmtChannelsString(device->FmtChans), - (device->Flags&DEVICE_CHANNELS_REQUEST)?" (requested)":"", DevFmtTypeString(device->FmtType), device->Frequency, - (device->Flags&DEVICE_FREQUENCY_REQUEST)?" (requested)":"", device->UpdateSize, device->NumUpdates); aluInitPanning(device); - for(i = 0;i < MAXCHANNELS;i++) + for(i = 0;i < MaxChannels;i++) { device->ClickRemoval[i] = 0.0f; device->PendingClicks[i] = 0.0f; } + V(device->Synth,update)(device); + device->Hrtf = NULL; - if(!device->IsLoopbackDevice && GetConfigValueBool(NULL, "hrtf", AL_FALSE)) + if(device->Type != Loopback && ConfigValueExists(NULL, "hrtf")) + { + if(GetConfigValueBool(NULL, "hrtf", AL_FALSE)) + device->Flags |= DEVICE_HRTF_REQUEST; + else + device->Flags &= ~DEVICE_HRTF_REQUEST; + } + if((device->Flags&DEVICE_HRTF_REQUEST)) + { device->Hrtf = GetHrtf(device); + if(!device->Hrtf) + device->Flags &= ~DEVICE_HRTF_REQUEST; + } TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled"); if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6) @@ -1179,24 +1853,20 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) TRACE("BS2B disabled\n"); } - device->Flags &= ~DEVICE_DUPLICATE_STEREO; - switch(device->FmtChans) - { - case DevFmtMono: - case DevFmtStereo: - break; - case DevFmtQuad: - case DevFmtX51: - case DevFmtX51Side: - case DevFmtX61: - case DevFmtX71: - if(GetConfigValueBool(NULL, "stereodup", AL_TRUE)) - device->Flags |= DEVICE_DUPLICATE_STEREO; - break; - } - TRACE("Stereo duplication %s\n", (device->Flags&DEVICE_DUPLICATE_STEREO)?"enabled":"disabled"); + device->Flags &= ~DEVICE_WIDE_STEREO; + if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE)) + device->Flags |= DEVICE_WIDE_STEREO; - oldMode = SetMixerFPUMode(); + if(!device->Hrtf && (device->UpdateSize&3)) + { + if((CPUCapFlags&CPU_CAP_SSE)) + WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize); + if((CPUCapFlags&CPU_CAP_NEON)) + WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize); + } + + SetMixerFPUMode(&oldMode); + ALCdevice_Lock(device); context = device->ContextList; while(context) { @@ -1208,16 +1878,15 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALeffectslot *slot = context->EffectSlotMap.array[pos].value; - if(ALeffectState_DeviceUpdate(slot->EffectState, device) == AL_FALSE) + if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); - UnlockDevice(device); - ALCdevice_StopPlayback(device); - device->Flags &= ~DEVICE_RUNNING; - return ALC_FALSE; + ALCdevice_Unlock(device); + RestoreFPUMode(&oldMode); + return ALC_INVALID_DEVICE; } slot->NeedsUpdate = AL_FALSE; - ALeffectState_Update(slot->EffectState, context, slot); + V(slot->EffectState,update)(device, slot); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -1231,8 +1900,8 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(source->Send[s].Slot) DecrementRef(&source->Send[s].Slot->ref); source->Send[s].Slot = NULL; - source->Send[s].WetGain = 1.0f; - source->Send[s].WetGainHF = 1.0f; + source->Send[s].Gain = 1.0f; + source->Send[s].GainHF = 1.0f; s++; } source->NeedsUpdate = AL_FALSE; @@ -1242,10 +1911,30 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = context->next; } - RestoreFPUMode(oldMode); - UnlockDevice(device); + if(device->DefaultSlot) + { + ALeffectslot *slot = device->DefaultSlot; - return ALC_TRUE; + if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE) + { + ALCdevice_Unlock(device); + RestoreFPUMode(&oldMode); + return ALC_INVALID_DEVICE; + } + slot->NeedsUpdate = AL_FALSE; + V(slot->EffectState,update)(device, slot); + } + ALCdevice_Unlock(device); + RestoreFPUMode(&oldMode); + + if(!(device->Flags&DEVICE_PAUSED)) + { + if(V0(device->Backend,start)() == ALC_FALSE) + return ALC_INVALID_DEVICE; + device->Flags |= DEVICE_RUNNING; + } + + return ALC_NO_ERROR; } /* FreeDevice @@ -1257,6 +1946,24 @@ static ALCvoid FreeDevice(ALCdevice *device) { TRACE("%p\n", device); + V0(device->Backend,close)(); + DELETE_OBJ(device->Backend); + device->Backend = NULL; + + DELETE_OBJ(device->Synth); + device->Synth = NULL; + + if(device->DefaultSlot) + { + ALeffectState *state = device->DefaultSlot->EffectState; + device->DefaultSlot = NULL; + DELETE_OBJ(state); + } + + if(device->DefaultSfont) + ALsoundfont_deleteSoundfont(device->DefaultSfont, device); + device->DefaultSfont = NULL; + if(device->BufferMap.size > 0) { WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size); @@ -1278,15 +1985,34 @@ static ALCvoid FreeDevice(ALCdevice *device) } ResetUIntMap(&device->FilterMap); + if(device->SfontMap.size > 0) + { + WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size); + ReleaseALSoundfonts(device); + } + ResetUIntMap(&device->SfontMap); + + if(device->PresetMap.size > 0) + { + WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size); + ReleaseALPresets(device); + } + ResetUIntMap(&device->PresetMap); + + if(device->FontsoundMap.size > 0) + { + WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size); + ReleaseALFontsounds(device); + } + ResetUIntMap(&device->FontsoundMap); + free(device->Bs2b); device->Bs2b = NULL; - free(device->szDeviceName); - device->szDeviceName = NULL; + free(device->DeviceName); + device->DeviceName = NULL; - DeleteCriticalSection(&device->Mutex); - - free(device); + al_free(device); } @@ -1328,55 +2054,53 @@ static ALCdevice *VerifyDevice(ALCdevice *device) } -ALCvoid LockDevice(ALCdevice *device) -{ - EnterCriticalSection(&device->Mutex); -} - -ALCvoid UnlockDevice(ALCdevice *device) -{ - LeaveCriticalSection(&device->Mutex); -} - - /* InitContext * - * Initializes context variables + * Initializes context fields */ -static ALvoid InitContext(ALCcontext *pContext) +static ALvoid InitContext(ALCcontext *Context) { - //Initialise listener - pContext->Listener.Gain = 1.0f; - pContext->Listener.MetersPerUnit = 1.0f; - pContext->Listener.Position[0] = 0.0f; - pContext->Listener.Position[1] = 0.0f; - pContext->Listener.Position[2] = 0.0f; - pContext->Listener.Velocity[0] = 0.0f; - pContext->Listener.Velocity[1] = 0.0f; - pContext->Listener.Velocity[2] = 0.0f; - pContext->Listener.Forward[0] = 0.0f; - pContext->Listener.Forward[1] = 0.0f; - pContext->Listener.Forward[2] = -1.0f; - pContext->Listener.Up[0] = 0.0f; - pContext->Listener.Up[1] = 1.0f; - pContext->Listener.Up[2] = 0.0f; + ALint i, j; - //Validate pContext - pContext->LastError = AL_NO_ERROR; - pContext->UpdateSources = AL_FALSE; - pContext->ActiveSourceCount = 0; - InitUIntMap(&pContext->SourceMap, pContext->Device->MaxNoOfSources); - InitUIntMap(&pContext->EffectSlotMap, pContext->Device->AuxiliaryEffectSlotMax); + //Initialise listener + Context->Listener->Gain = 1.0f; + Context->Listener->MetersPerUnit = 1.0f; + Context->Listener->Position[0] = 0.0f; + Context->Listener->Position[1] = 0.0f; + Context->Listener->Position[2] = 0.0f; + Context->Listener->Velocity[0] = 0.0f; + Context->Listener->Velocity[1] = 0.0f; + Context->Listener->Velocity[2] = 0.0f; + Context->Listener->Forward[0] = 0.0f; + Context->Listener->Forward[1] = 0.0f; + Context->Listener->Forward[2] = -1.0f; + Context->Listener->Up[0] = 0.0f; + Context->Listener->Up[1] = 1.0f; + Context->Listener->Up[2] = 0.0f; + for(i = 0;i < 4;i++) + { + for(j = 0;j < 4;j++) + Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f); + } + for(i = 0;i < 3;i++) + Context->Listener->Params.Velocity[i] = 0.0f; + + //Validate Context + Context->LastError = AL_NO_ERROR; + Context->UpdateSources = AL_FALSE; + Context->ActiveSourceCount = 0; + InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources); + InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax); //Set globals - pContext->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED; - pContext->SourceDistanceModel = AL_FALSE; - pContext->DopplerFactor = 1.0f; - pContext->DopplerVelocity = 1.0f; - pContext->flSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - pContext->DeferUpdates = AL_FALSE; + Context->DistanceModel = DefaultDistanceModel; + Context->SourceDistanceModel = AL_FALSE; + Context->DopplerFactor = 1.0f; + Context->DopplerVelocity = 1.0f; + Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; + Context->DeferUpdates = AL_FALSE; - pContext->ExtensionList = alExtList; + Context->ExtensionList = alExtList; } @@ -1391,14 +2115,14 @@ static ALCvoid FreeContext(ALCcontext *context) if(context->SourceMap.size > 0) { - ERR("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size); + WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size); ReleaseALSources(context); } ResetUIntMap(&context->SourceMap); if(context->EffectSlotMap.size > 0) { - ERR("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size); + WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size); ReleaseALAuxiliaryEffectSlots(context); } ResetUIntMap(&context->EffectSlotMap); @@ -1430,35 +2154,25 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device) { ALCcontext *volatile*tmp_ctx; - if(pthread_getspecific(LocalContext) == context) + if(althread_getspecific(LocalContext) == context) { WARN("%p released while current on thread\n", context); - pthread_setspecific(LocalContext, NULL); + althread_setspecific(LocalContext, NULL); ALCcontext_DecRef(context); } - if(CompExchangePtr((void**)&GlobalContext, context, NULL)) - { - WARN("%p released while current\n", context); + if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL)) ALCcontext_DecRef(context); - } + ALCdevice_Lock(device); tmp_ctx = &device->ContextList; while(*tmp_ctx) { - if(*tmp_ctx == context) - { - *tmp_ctx = context->next; + if(CompExchangePtr((XchgPtr*)tmp_ctx, context, context->next)) break; - } tmp_ctx = &(*tmp_ctx)->next; } - - LockDevice(device); - /* Lock the device to make sure the mixer is not using the contexts in the - * list before we go about deleting this one. There should be a more - * efficient way of doing this. */ - UnlockDevice(device); + ALCdevice_Unlock(device); ALCcontext_DecRef(context); } @@ -1515,26 +2229,16 @@ static ALCcontext *VerifyContext(ALCcontext *context) } -ALCvoid LockContext(ALCcontext *context) -{ - EnterCriticalSection(&context->Device->Mutex); -} - -ALCvoid UnlockContext(ALCcontext *context) -{ - LeaveCriticalSection(&context->Device->Mutex); -} - /* GetContextRef * - * Returns the currently active context, and adds a reference without locking - * it. + * Returns the currently active context for this thread, and adds a reference + * without locking it. */ ALCcontext *GetContextRef(void) { ALCcontext *context; - context = pthread_getspecific(LocalContext); + context = althread_getspecific(LocalContext); if(context) ALCcontext_IncRef(context); else @@ -1549,171 +2253,14 @@ ALCcontext *GetContextRef(void) return context; } -/////////////////////////////////////////////////////// +/************************************************ + * Standard ALC functions + ************************************************/ -/////////////////////////////////////////////////////// -// ALC Functions calls - - -// This should probably move to another c file but for now ... -ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize) -{ - ALCdevice *device = NULL; - ALCenum err; - - DO_INITCONFIG(); - - if(!CaptureBackend.name) - { - alcSetError(NULL, ALC_INVALID_VALUE); - return NULL; - } - - if(SampleSize <= 0) - { - alcSetError(NULL, ALC_INVALID_VALUE); - return NULL; - } - - if(deviceName && (!deviceName[0] || strcasecmp(deviceName, "openal soft") == 0 || strcasecmp(deviceName, "openal-soft") == 0)) - deviceName = NULL; - - device = calloc(1, sizeof(ALCdevice)); - if(!device) - { - alcSetError(NULL, ALC_OUT_OF_MEMORY); - return NULL; - } - - //Validate device - device->Funcs = &CaptureBackend.Funcs; - device->ref = 1; - device->Connected = ALC_TRUE; - device->IsCaptureDevice = AL_TRUE; - device->IsLoopbackDevice = AL_FALSE; - InitializeCriticalSection(&device->Mutex); - - InitUIntMap(&device->BufferMap, ~0); - InitUIntMap(&device->EffectMap, ~0); - InitUIntMap(&device->FilterMap, ~0); - - device->szDeviceName = NULL; - - device->Flags |= DEVICE_FREQUENCY_REQUEST; - device->Frequency = frequency; - - device->Flags |= DEVICE_CHANNELS_REQUEST; - if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE) - { - DeleteCriticalSection(&device->Mutex); - free(device); - alcSetError(NULL, ALC_INVALID_ENUM); - return NULL; - } - - device->UpdateSize = SampleSize; - device->NumUpdates = 1; - - LockLists(); - if((err=ALCdevice_OpenCapture(device, deviceName)) != ALC_NO_ERROR) - { - UnlockLists(); - DeleteCriticalSection(&device->Mutex); - free(device); - alcSetError(NULL, err); - return NULL; - } - UnlockLists(); - - do { - device->next = DeviceList; - } while(!CompExchangePtr((void**)&DeviceList, device->next, device)); - - TRACE("Created device %p\n", device); - return device; -} - -ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *pDevice) -{ - ALCdevice *volatile*list; - - LockLists(); - list = &DeviceList; - while(*list && *list != pDevice) - list = &(*list)->next; - - if(!*list || !(*list)->IsCaptureDevice) - { - alcSetError(*list, ALC_INVALID_DEVICE); - UnlockLists(); - return ALC_FALSE; - } - - *list = (*list)->next; - UnlockLists(); - - LockDevice(pDevice); - ALCdevice_CloseCapture(pDevice); - UnlockDevice(pDevice); - - ALCdevice_DecRef(pDevice); - - return ALC_TRUE; -} - -ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) -{ - if(!(device=VerifyDevice(device)) || !device->IsCaptureDevice) - { - alcSetError(device, ALC_INVALID_DEVICE); - if(device) ALCdevice_DecRef(device); - return; - } - LockDevice(device); - if(device->Connected) - ALCdevice_StartCapture(device); - UnlockDevice(device); - - ALCdevice_DecRef(device); -} - -ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) -{ - if(!(device=VerifyDevice(device)) || !device->IsCaptureDevice) - { - alcSetError(device, ALC_INVALID_DEVICE); - if(device) ALCdevice_DecRef(device); - return; - } - LockDevice(device); - if(device->Connected) - ALCdevice_StopCapture(device); - UnlockDevice(device); - - ALCdevice_DecRef(device); -} - -ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) -{ - ALCenum err = ALC_INVALID_DEVICE; - if((device=VerifyDevice(device)) != NULL && device->IsCaptureDevice) - { - err = ALC_INVALID_VALUE; - LockDevice(device); - if(samples >= 0 && ALCdevice_AvailableSamples(device) >= (ALCuint)samples) - err = ALCdevice_CaptureSamples(device, buffer, samples); - UnlockDevice(device); - } - if(err != ALC_NO_ERROR) - alcSetError(device, err); - if(device) ALCdevice_DecRef(device); -} - -/* - alcGetError - - Return last ALC generated error code +/* alcGetError + * + * Return last ALC generated error code for the given device */ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) { @@ -1725,7 +2272,7 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) ALCdevice_DecRef(device); } else - errorCode = ExchangeInt(&g_eLastNullDeviceError, ALC_NO_ERROR); + errorCode = ExchangeInt(&LastNullDeviceError, ALC_NO_ERROR); return errorCode; } @@ -1735,26 +2282,24 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) * * Not functional */ -ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *Context) +ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *UNUSED(context)) { - (void)Context; } /* alcProcessContext * * Not functional */ -ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *Context) +ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *UNUSED(context)) { - (void)Context; } /* alcGetString * - * Returns information about the Device, and error strings + * Returns information about the device, and error strings */ -ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *pDevice,ALCenum param) +ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param) { const ALCchar *value = NULL; @@ -1785,28 +2330,27 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *pDevice,ALCenum para break; case ALC_DEVICE_SPECIFIER: - if(VerifyDevice(pDevice)) - { - value = pDevice->szDeviceName; - ALCdevice_DecRef(pDevice); - } - else - { - ProbeDeviceList(); - value = alcDeviceList; - } + value = alcDefaultName; break; case ALC_ALL_DEVICES_SPECIFIER: - ProbeAllDeviceList(); - value = alcAllDeviceList; + if(VerifyDevice(Device)) + { + value = Device->DeviceName; + ALCdevice_DecRef(Device); + } + else + { + ProbeAllDevicesList(); + value = alcAllDevicesList; + } break; case ALC_CAPTURE_DEVICE_SPECIFIER: - if(VerifyDevice(pDevice)) + if(VerifyDevice(Device)) { - value = pDevice->szDeviceName; - ALCdevice_DecRef(pDevice); + value = Device->DeviceName; + ALCdevice_DecRef(Device); } else { @@ -1817,66 +2361,55 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *pDevice,ALCenum para /* Default devices are always first in the list */ case ALC_DEFAULT_DEVICE_SPECIFIER: - if(!alcDeviceList) - ProbeDeviceList(); - - pDevice = VerifyDevice(pDevice); - - free(alcDefaultDeviceSpecifier); - alcDefaultDeviceSpecifier = strdup(alcDeviceList ? alcDeviceList : ""); - if(!alcDefaultDeviceSpecifier) - alcSetError(pDevice, ALC_OUT_OF_MEMORY); - - value = alcDefaultDeviceSpecifier; - if(pDevice) ALCdevice_DecRef(pDevice); + value = alcDefaultName; break; case ALC_DEFAULT_ALL_DEVICES_SPECIFIER: - if(!alcAllDeviceList) - ProbeAllDeviceList(); + if(!alcAllDevicesList) + ProbeAllDevicesList(); - pDevice = VerifyDevice(pDevice); + Device = VerifyDevice(Device); - free(alcDefaultAllDeviceSpecifier); - alcDefaultAllDeviceSpecifier = strdup(alcAllDeviceList ? - alcAllDeviceList : ""); - if(!alcDefaultAllDeviceSpecifier) - alcSetError(pDevice, ALC_OUT_OF_MEMORY); + free(alcDefaultAllDevicesSpecifier); + alcDefaultAllDevicesSpecifier = strdup(alcAllDevicesList ? + alcAllDevicesList : ""); + if(!alcDefaultAllDevicesSpecifier) + alcSetError(Device, ALC_OUT_OF_MEMORY); - value = alcDefaultAllDeviceSpecifier; - if(pDevice) ALCdevice_DecRef(pDevice); + value = alcDefaultAllDevicesSpecifier; + if(Device) ALCdevice_DecRef(Device); break; case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER: if(!alcCaptureDeviceList) ProbeCaptureDeviceList(); - pDevice = VerifyDevice(pDevice); + Device = VerifyDevice(Device); free(alcCaptureDefaultDeviceSpecifier); alcCaptureDefaultDeviceSpecifier = strdup(alcCaptureDeviceList ? alcCaptureDeviceList : ""); if(!alcCaptureDefaultDeviceSpecifier) - alcSetError(pDevice, ALC_OUT_OF_MEMORY); + alcSetError(Device, ALC_OUT_OF_MEMORY); value = alcCaptureDefaultDeviceSpecifier; - if(pDevice) ALCdevice_DecRef(pDevice); + if(Device) ALCdevice_DecRef(Device); break; case ALC_EXTENSIONS: - if(!VerifyDevice(pDevice)) + if(!VerifyDevice(Device)) value = alcNoDeviceExtList; else { value = alcExtensionList; - ALCdevice_DecRef(pDevice); + ALCdevice_DecRef(Device); } break; default: - pDevice = VerifyDevice(pDevice); - alcSetError(pDevice, ALC_INVALID_ENUM); - if(pDevice) ALCdevice_DecRef(pDevice); + Device = VerifyDevice(Device); + alcSetError(Device, ALC_INVALID_ENUM); + if(Device) ALCdevice_DecRef(Device); break; } @@ -1886,7 +2419,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *pDevice,ALCenum para /* alcGetIntegerv * - * Returns information about the Device and the version of Open AL + * Returns information about the device and the version of OpenAL */ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsizei size,ALCint *data) { @@ -1928,14 +2461,14 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi break; } } - else if(device->IsCaptureDevice) + else if(device->Type == Capture) { switch(param) { case ALC_CAPTURE_SAMPLES: - LockDevice(device); - *data = ALCdevice_AvailableSamples(device); - UnlockDevice(device); + ALCdevice_Lock(device); + *data = V0(device->Backend,availableSamples)(); + ALCdevice_Unlock(device); break; case ALC_CONNECTED: @@ -1968,11 +2501,11 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi break; case ALC_ATTRIBUTES_SIZE: - *data = 13; + *data = 15; break; case ALC_ALL_ATTRIBUTES: - if(size < 13) + if(size < 15) alcSetError(device, ALC_INVALID_VALUE); else { @@ -1981,7 +2514,7 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi data[i++] = ALC_FREQUENCY; data[i++] = device->Frequency; - if(!device->IsLoopbackDevice) + if(device->Type != Loopback) { data[i++] = ALC_REFRESH; data[i++] = device->Frequency / device->UpdateSize; @@ -2007,6 +2540,9 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi data[i++] = ALC_MAX_AUXILIARY_SENDS; data[i++] = device->NumAuxSends; + data[i++] = ALC_HRTF_SOFT; + data[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE); + data[i++] = 0; } break; @@ -2016,28 +2552,28 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi break; case ALC_REFRESH: - if(device->IsLoopbackDevice) + if(device->Type == Loopback) alcSetError(device, ALC_INVALID_DEVICE); else *data = device->Frequency / device->UpdateSize; break; case ALC_SYNC: - if(device->IsLoopbackDevice) + if(device->Type == Loopback) alcSetError(device, ALC_INVALID_DEVICE); else *data = ALC_FALSE; break; case ALC_FORMAT_CHANNELS_SOFT: - if(!device->IsLoopbackDevice) + if(device->Type != Loopback) alcSetError(device, ALC_INVALID_DEVICE); else *data = device->FmtChans; break; case ALC_FORMAT_TYPE_SOFT: - if(!device->IsLoopbackDevice) + if(device->Type != Loopback) alcSetError(device, ALC_INVALID_DEVICE); else *data = device->FmtType; @@ -2059,6 +2595,10 @@ ALC_API ALCvoid ALC_APIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsi *data = device->Connected; break; + case ALC_HRTF_SOFT: + *data = (device->Hrtf ? ALC_TRUE : ALC_FALSE); + break; + default: alcSetError(device, ALC_INVALID_ENUM); break; @@ -2115,58 +2655,61 @@ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar { ALCvoid *ptr = NULL; - device = VerifyDevice(device); - if(!funcName) + { + device = VerifyDevice(device); alcSetError(device, ALC_INVALID_VALUE); + if(device) ALCdevice_DecRef(device); + } else { ALsizei i = 0; - while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName,funcName) != 0) + while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0) i++; ptr = alcFunctions[i].address; } - if(device) - ALCdevice_DecRef(device); + return ptr; } /* alcGetEnumValue * - * Get the value for a particular ALC Enumerated Value + * Get the value for a particular ALC enumeration name */ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName) { ALCenum val = 0; - device = VerifyDevice(device); - if(!enumName) + { + device = VerifyDevice(device); alcSetError(device, ALC_INVALID_VALUE); + if(device) ALCdevice_DecRef(device); + } else { ALsizei i = 0; - while(enumeration[i].enumName && strcmp(enumeration[i].enumName,enumName) != 0) + while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0) i++; val = enumeration[i].value; } - if(device) - ALCdevice_DecRef(device); + return val; } /* alcCreateContext * - * Create and attach a Context to a particular Device. + * Create and attach a context to the given device. */ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList) { ALCcontext *ALContext; + ALCenum err; LockLists(); - if(!(device=VerifyDevice(device)) || device->IsCaptureDevice || !device->Connected) + if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected) { UnlockLists(); alcSetError(device, ALC_INVALID_DEVICE); @@ -2174,22 +2717,27 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin return NULL; } - /* Reset Context Last Error code */ device->LastError = ALC_NO_ERROR; - if(UpdateDeviceParams(device, attrList) == ALC_FALSE) + if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR) { UnlockLists(); - alcSetError(device, ALC_INVALID_DEVICE); - aluHandleDisconnect(device); + alcSetError(device, err); + if(err == ALC_INVALID_DEVICE) + { + ALCdevice_Lock(device); + aluHandleDisconnect(device); + ALCdevice_Unlock(device); + } ALCdevice_DecRef(device); return NULL; } - ALContext = calloc(1, sizeof(ALCcontext)); + ALContext = calloc(1, sizeof(ALCcontext)+15+sizeof(ALlistener)); if(ALContext) { ALContext->ref = 1; + ALContext->Listener = (ALlistener*)(((ALintptrEXT)(ALContext+1)+15)&~15); ALContext->MaxActiveSources = 256; ALContext->ActiveSources = malloc(sizeof(ALContext->ActiveSources[0]) * @@ -2199,7 +2747,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin { if(!device->ContextList) { - ALCdevice_StopPlayback(device); + V0(device->Backend,stop)(); device->Flags &= ~DEVICE_RUNNING; } UnlockLists(); @@ -2216,8 +2764,9 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin ALCdevice_IncRef(device); InitContext(ALContext); - ALContext->next = device->ContextList; - device->ContextList = ALContext; + do { + ALContext->next = device->ContextList; + } while(!CompExchangePtr((XchgPtr*)&device->ContextList, ALContext->next, ALContext)); UnlockLists(); ALCdevice_DecRef(device); @@ -2228,7 +2777,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin /* alcDestroyContext * - * Remove a Context + * Remove a context from its device */ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) { @@ -2242,7 +2791,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) ReleaseContext(context, Device); if(!Device->ContextList) { - ALCdevice_StopPlayback(Device); + V0(Device->Backend,stop)(); Device->Flags &= ~DEVICE_RUNNING; } } @@ -2252,13 +2801,13 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) /* alcGetCurrentContext * - * Returns the currently active Context + * Returns the currently active context on the calling thread */ -ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid) +ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) { ALCcontext *Context; - Context = pthread_getspecific(LocalContext); + Context = althread_getspecific(LocalContext); if(!Context) Context = GlobalContext; return Context; @@ -2266,35 +2815,36 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(ALCvoid) /* alcGetThreadContext * - * Returns the currently active thread-local Context + * Returns the currently active thread-local context */ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) { ALCcontext *Context; - Context = pthread_getspecific(LocalContext); + Context = althread_getspecific(LocalContext); return Context; } /* alcMakeContextCurrent * - * Makes the given Context the active Context + * Makes the given context the active process-wide context, and removes the + * thread-local context for the calling thread. */ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) { - /* context must be a valid Context or NULL */ + /* context must be valid or NULL */ if(context && !(context=VerifyContext(context))) { alcSetError(NULL, ALC_INVALID_CONTEXT); return ALC_FALSE; } /* context's reference count is already incremented */ - context = ExchangePtr((void**)&GlobalContext, context); + context = ExchangePtr((XchgPtr*)&GlobalContext, context); if(context) ALCcontext_DecRef(context); - if((context=pthread_getspecific(LocalContext)) != NULL) + if((context=althread_getspecific(LocalContext)) != NULL) { - pthread_setspecific(LocalContext, NULL); + althread_setspecific(LocalContext, NULL); ALCcontext_DecRef(context); } @@ -2303,21 +2853,21 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) /* alcSetThreadContext * - * Makes the given Context the active Context for the current thread + * Makes the given context the active context for the current thread */ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) { ALCcontext *old; - /* context must be a valid Context or NULL */ + /* context must be valid or NULL */ if(context && !(context=VerifyContext(context))) { alcSetError(NULL, ALC_INVALID_CONTEXT); return ALC_FALSE; } /* context's reference count is already incremented */ - old = pthread_getspecific(LocalContext); - pthread_setspecific(LocalContext, context); + old = althread_getspecific(LocalContext); + althread_setspecific(LocalContext, context); if(old) ALCcontext_DecRef(old); return ALC_TRUE; @@ -2326,7 +2876,7 @@ ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) /* alcGetContextsDevice * - * Returns the Device that a particular Context is attached to + * Returns the device that a particular context is attached to */ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context) { @@ -2344,54 +2894,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context) } -static void GetFormatFromString(const char *str, enum DevFmtChannels *chans, enum DevFmtType *type) -{ - static const struct { - const char name[32]; - enum DevFmtChannels channels; - enum DevFmtType type; - } formats[] = { - { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat }, - { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat }, - { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat }, - { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat }, - { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat }, - { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat }, - - { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort }, - { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort }, - { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort }, - { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort }, - { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort }, - { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort }, - - { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte }, - { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte }, - { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte }, - { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte }, - { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte }, - { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte } - }; - size_t i; - - for(i = 0;i < sizeof(formats)/sizeof(formats[0]);i++) - { - if(strcasecmp(str, formats[i].name) == 0) - { - *chans = formats[i].channels; - *type = formats[i].type; - return; - } - } - - ERR("Unknown format: \"%s\"\n", str); - *chans = DevFmtStereo; - *type = DevFmtShort; -} - /* alcOpenDevice * - * Open the Device specified. + * Opens the named device. */ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) { @@ -2407,10 +2912,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) return NULL; } - if(deviceName && (!deviceName[0] || strcasecmp(deviceName, "openal soft") == 0 || strcasecmp(deviceName, "openal-soft") == 0)) + if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0)) deviceName = NULL; - device = calloc(1, sizeof(ALCdevice)); + device = al_calloc(16, sizeof(ALCdevice)+15+sizeof(ALeffectslot)); if(!device) { alcSetError(NULL, ALC_OUT_OF_MEMORY); @@ -2418,18 +2923,15 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } //Validate device - device->Funcs = &PlaybackBackend.Funcs; device->ref = 1; device->Connected = ALC_TRUE; - device->IsCaptureDevice = AL_FALSE; - device->IsLoopbackDevice = AL_FALSE; - InitializeCriticalSection(&device->Mutex); + device->Type = Playback; device->LastError = ALC_NO_ERROR; device->Flags = 0; device->Bs2b = NULL; device->Bs2bLevel = 0; - device->szDeviceName = NULL; + device->DeviceName = NULL; device->ContextList = NULL; @@ -2440,26 +2942,155 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) InitUIntMap(&device->BufferMap, ~0); InitUIntMap(&device->EffectMap, ~0); InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->SfontMap, ~0); + InitUIntMap(&device->PresetMap, ~0); + InitUIntMap(&device->FontsoundMap, ~0); //Set output format + device->FmtChans = DevFmtChannelsDefault; + device->FmtType = DevFmtTypeDefault; + device->Frequency = DEFAULT_OUTPUT_RATE; device->NumUpdates = 4; device->UpdateSize = 1024; - device->Frequency = DEFAULT_OUTPUT_RATE; - if(ConfigValueUInt(NULL, "frequency", &device->Frequency)) - device->Flags |= DEVICE_FREQUENCY_REQUEST; - device->Frequency = maxu(device->Frequency, 8000); + if(!PlaybackBackend.getFactory) + { + device->Funcs = &PlaybackBackend.Funcs; + device->Backend = create_backend_wrapper(device, ALCbackend_Playback); + } + else + { + ALCbackendFactory *factory = PlaybackBackend.getFactory(); + device->Backend = V(factory,createBackend)(device, ALCbackend_Playback); + } + if(!device->Backend) + { + al_free(device); + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } - fmt = "AL_FORMAT_STEREO16"; - if(ConfigValueStr(NULL, "format", &fmt)) - device->Flags |= DEVICE_CHANNELS_REQUEST; - GetFormatFromString(fmt, &device->FmtChans, &device->FmtType); + + if(ConfigValueStr(NULL, "channels", &fmt)) + { + static const struct { + const char name[16]; + enum DevFmtChannels chans; + } chanlist[] = { + { "mono", DevFmtMono }, + { "stereo", DevFmtStereo }, + { "quad", DevFmtQuad }, + { "surround51", DevFmtX51 }, + { "surround61", DevFmtX61 }, + { "surround71", DevFmtX71 }, + }; + size_t i; + + for(i = 0;i < COUNTOF(chanlist);i++) + { + if(strcasecmp(chanlist[i].name, fmt) == 0) + { + device->FmtChans = chanlist[i].chans; + device->Flags |= DEVICE_CHANNELS_REQUEST; + break; + } + } + if(i == COUNTOF(chanlist)) + ERR("Unsupported channels: %s\n", fmt); + } + if(ConfigValueStr(NULL, "sample-type", &fmt)) + { + static const struct { + const char name[16]; + enum DevFmtType type; + } typelist[] = { + { "int8", DevFmtByte }, + { "uint8", DevFmtUByte }, + { "int16", DevFmtShort }, + { "uint16", DevFmtUShort }, + { "int32", DevFmtInt }, + { "uint32", DevFmtUInt }, + { "float32", DevFmtFloat }, + }; + size_t i; + + for(i = 0;i < COUNTOF(typelist);i++) + { + if(strcasecmp(typelist[i].name, fmt) == 0) + { + device->FmtType = typelist[i].type; + device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST; + break; + } + } + if(i == COUNTOF(typelist)) + ERR("Unsupported sample-type: %s\n", fmt); + } +#define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST) + if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST && + ConfigValueStr(NULL, "format", &fmt)) + { + static const struct { + const char name[32]; + enum DevFmtChannels channels; + enum DevFmtType type; + } formats[] = { + { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat }, + { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat }, + { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat }, + { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat }, + { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat }, + { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat }, + + { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort }, + { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort }, + { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort }, + { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort }, + { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort }, + { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort }, + + { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte }, + { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte }, + { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte }, + { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte }, + { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte }, + { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte } + }; + size_t i; + + ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n"); + for(i = 0;i < COUNTOF(formats);i++) + { + if(strcasecmp(fmt, formats[i].name) == 0) + { + if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) + device->FmtChans = formats[i].channels; + if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)) + device->FmtType = formats[i].type; + device->Flags |= DEVICE_FORMAT_REQUEST; + break; + } + } + if(i == COUNTOF(formats)) + ERR("Unsupported format: %s\n", fmt); + } +#undef DEVICE_FORMAT_REQUEST + + if(ConfigValueUInt(NULL, "frequency", &device->Frequency)) + { + device->Flags |= DEVICE_FREQUENCY_REQUEST; + if(device->Frequency < MIN_OUTPUT_RATE) + ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE); + device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE); + } ConfigValueUInt(NULL, "periods", &device->NumUpdates); - if(device->NumUpdates < 2) device->NumUpdates = 4; + device->NumUpdates = clampu(device->NumUpdates, 2, 16); ConfigValueUInt(NULL, "period_size", &device->UpdateSize); - if(device->UpdateSize == 0) device->UpdateSize = 1024; + device->UpdateSize = clampu(device->UpdateSize, 64, 8192); + if((CPUCapFlags&CPU_CAP_SSE)) + device->UpdateSize = (device->UpdateSize+3)&~3; ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources); if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256; @@ -2475,41 +3106,65 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->NumStereoSources = 1; device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources; - // Find a playback device to open - LockLists(); - if((err=ALCdevice_OpenPlayback(device, deviceName)) != ALC_NO_ERROR) + device->Synth = SynthCreate(device); + if(!device->Synth) { - UnlockLists(); - DeleteCriticalSection(&device->Mutex); - free(device); + DELETE_OBJ(device->Backend); + al_free(device); + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } + + // Find a playback device to open + if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR) + { + DELETE_OBJ(device->Synth); + DELETE_OBJ(device->Backend); + al_free(device); alcSetError(NULL, err); return NULL; } - UnlockLists(); + + if(DefaultEffect.type != AL_EFFECT_NULL) + { + device->DefaultSlot = (ALeffectslot*)(((ALintptrEXT)(device+1)+15)&~15); + if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR) + { + device->DefaultSlot = NULL; + ERR("Failed to initialize the default effect slot\n"); + } + else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) + { + ALeffectState *state = device->DefaultSlot->EffectState; + device->DefaultSlot = NULL; + DELETE_OBJ(state); + ERR("Failed to initialize the default effect\n"); + } + } do { device->next = DeviceList; - } while(!CompExchangePtr((void**)&DeviceList, device->next, device)); + } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device)); - TRACE("Created device %p\n", device); + TRACE("Created device %p, \"%s\"\n", device, device->DeviceName); return device; } /* alcCloseDevice * - * Close the specified Device + * Closes the given device. */ -ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *pDevice) +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *Device) { ALCdevice *volatile*list; ALCcontext *ctx; LockLists(); list = &DeviceList; - while(*list && *list != pDevice) + while(*list && *list != Device) list = &(*list)->next; - if(!*list || (*list)->IsCaptureDevice) + if(!*list || (*list)->Type == Capture) { alcSetError(*list, ALC_INVALID_DEVICE); UnlockLists(); @@ -2519,34 +3174,47 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *pDevice) *list = (*list)->next; UnlockLists(); - if((ctx=pDevice->ContextList) != NULL) + while((ctx=Device->ContextList) != NULL) { - do { - WARN("Releasing context %p\n", ctx); - ReleaseContext(ctx, pDevice); - } while((ctx=pDevice->ContextList) != NULL); - ALCdevice_StopPlayback(pDevice); - pDevice->Flags &= ~DEVICE_RUNNING; + WARN("Releasing context %p\n", ctx); + ReleaseContext(ctx, Device); } - ALCdevice_ClosePlayback(pDevice); + if((Device->Flags&DEVICE_RUNNING)) + V0(Device->Backend,stop)(); + Device->Flags &= ~DEVICE_RUNNING; - ALCdevice_DecRef(pDevice); + ALCdevice_DecRef(Device); return ALC_TRUE; } -/* alcLoopbackOpenDeviceSOFT - * - * Open a loopback device, for manual rendering. - */ -ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void) +/************************************************ + * ALC capture functions + ************************************************/ +ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples) { - ALCdevice *device; + ALCdevice *device = NULL; + ALCenum err; DO_INITCONFIG(); - device = calloc(1, sizeof(ALCdevice)); + if(!CaptureBackend.name) + { + alcSetError(NULL, ALC_INVALID_VALUE); + return NULL; + } + + if(samples <= 0) + { + alcSetError(NULL, ALC_INVALID_VALUE); + return NULL; + } + + if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0)) + deviceName = NULL; + + device = al_calloc(16, sizeof(ALCdevice)); if(!device) { alcSetError(NULL, ALC_OUT_OF_MEMORY); @@ -2554,18 +3222,183 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void) } //Validate device - device->Funcs = &BackendLoopback.Funcs; device->ref = 1; device->Connected = ALC_TRUE; - device->IsCaptureDevice = AL_FALSE; - device->IsLoopbackDevice = AL_TRUE; - InitializeCriticalSection(&device->Mutex); + device->Type = Capture; + + InitUIntMap(&device->BufferMap, ~0); + InitUIntMap(&device->EffectMap, ~0); + InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->SfontMap, ~0); + InitUIntMap(&device->PresetMap, ~0); + InitUIntMap(&device->FontsoundMap, ~0); + + device->DeviceName = NULL; + + if(!CaptureBackend.getFactory) + { + device->Funcs = &CaptureBackend.Funcs; + device->Backend = create_backend_wrapper(device, ALCbackend_Capture); + } + else + { + ALCbackendFactory *factory = CaptureBackend.getFactory(); + device->Backend = V(factory,createBackend)(device, ALCbackend_Capture); + } + if(!device->Backend) + { + al_free(device); + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } + + device->Flags |= DEVICE_FREQUENCY_REQUEST; + device->Frequency = frequency; + + device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST; + if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE) + { + al_free(device); + alcSetError(NULL, ALC_INVALID_ENUM); + return NULL; + } + + device->UpdateSize = samples; + device->NumUpdates = 1; + + if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR) + { + al_free(device); + alcSetError(NULL, err); + return NULL; + } + + do { + device->next = DeviceList; + } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device)); + + TRACE("Created device %p, \"%s\"\n", device, device->DeviceName); + return device; +} + +ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *Device) +{ + ALCdevice *volatile*list; + + LockLists(); + list = &DeviceList; + while(*list && *list != Device) + list = &(*list)->next; + + if(!*list || (*list)->Type != Capture) + { + alcSetError(*list, ALC_INVALID_DEVICE); + UnlockLists(); + return ALC_FALSE; + } + + *list = (*list)->next; + UnlockLists(); + + ALCdevice_DecRef(Device); + + return ALC_TRUE; +} + +ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) +{ + if(!(device=VerifyDevice(device)) || device->Type != Capture) + alcSetError(device, ALC_INVALID_DEVICE); + else + { + ALCdevice_Lock(device); + if(device->Connected) + { + if(!(device->Flags&DEVICE_RUNNING)) + V0(device->Backend,start)(); + device->Flags |= DEVICE_RUNNING; + } + ALCdevice_Unlock(device); + } + + if(device) ALCdevice_DecRef(device); +} + +ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) +{ + if(!(device=VerifyDevice(device)) || device->Type != Capture) + alcSetError(device, ALC_INVALID_DEVICE); + else + { + ALCdevice_Lock(device); + if((device->Flags&DEVICE_RUNNING)) + V0(device->Backend,stop)(); + device->Flags &= ~DEVICE_RUNNING; + ALCdevice_Unlock(device); + } + + if(device) ALCdevice_DecRef(device); +} + +ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) +{ + if(!(device=VerifyDevice(device)) || device->Type != Capture) + alcSetError(device, ALC_INVALID_DEVICE); + else + { + ALCenum err = ALC_INVALID_VALUE; + + ALCdevice_Lock(device); + if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples) + err = V(device->Backend,captureSamples)(buffer, samples); + ALCdevice_Unlock(device); + + if(err != ALC_NO_ERROR) + alcSetError(device, err); + } + if(device) ALCdevice_DecRef(device); +} + + +/************************************************ + * ALC loopback functions + ************************************************/ + +/* alcLoopbackOpenDeviceSOFT + * + * Open a loopback device, for manual rendering. + */ +ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName) +{ + ALCbackendFactory *factory; + ALCdevice *device; + + DO_INITCONFIG(); + + /* Make sure the device name, if specified, is us. */ + if(deviceName && strcmp(deviceName, alcDefaultName) != 0) + { + alcSetError(NULL, ALC_INVALID_VALUE); + return NULL; + } + + device = al_calloc(16, sizeof(ALCdevice)); + if(!device) + { + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } + + //Validate device + device->ref = 1; + device->Connected = ALC_TRUE; + device->Type = Loopback; device->LastError = ALC_NO_ERROR; device->Flags = 0; device->Bs2b = NULL; device->Bs2bLevel = 0; - device->szDeviceName = NULL; + device->DeviceName = NULL; device->ContextList = NULL; @@ -2576,14 +3409,26 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void) InitUIntMap(&device->BufferMap, ~0); InitUIntMap(&device->EffectMap, ~0); InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->SfontMap, ~0); + InitUIntMap(&device->PresetMap, ~0); + InitUIntMap(&device->FontsoundMap, ~0); + + factory = ALCloopbackFactory_getFactory(); + device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback); + if(!device->Backend) + { + al_free(device); + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } //Set output format device->NumUpdates = 0; device->UpdateSize = 0; - device->Frequency = 44100; - device->FmtChans = DevFmtStereo; - device->FmtType = DevFmtShort; + device->Frequency = DEFAULT_OUTPUT_RATE; + device->FmtChans = DevFmtChannelsDefault; + device->FmtType = DevFmtTypeDefault; ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources); if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256; @@ -2594,16 +3439,23 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void) ConfigValueUInt(NULL, "sends", &device->NumAuxSends); if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS; - ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel); - device->NumStereoSources = 1; device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources; + device->Synth = SynthCreate(device); + if(!device->Synth) + { + DELETE_OBJ(device->Backend); + al_free(device); + alcSetError(NULL, ALC_OUT_OF_MEMORY); + return NULL; + } + // Open the "backend" - ALCdevice_OpenPlayback(device, "Loopback"); + V(device->Backend,open)("Loopback"); do { device->next = DeviceList; - } while(!CompExchangePtr((void**)&DeviceList, device->next, device)); + } while(!CompExchangePtr((XchgPtr*)&DeviceList, device->next, device)); TRACE("Created device %p\n", device); return device; @@ -2617,16 +3469,15 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device { ALCboolean ret = ALC_FALSE; - if(!(device=VerifyDevice(device)) || !device->IsLoopbackDevice) + if(!(device=VerifyDevice(device)) || device->Type != Loopback) alcSetError(device, ALC_INVALID_DEVICE); else if(freq <= 0) alcSetError(device, ALC_INVALID_VALUE); - else if(!IsValidALCType(type) || !IsValidALCChannels(channels)) - alcSetError(device, ALC_INVALID_ENUM); else { - if(BytesFromDevFmt(type) > 0 && ChannelsFromDevFmt(channels) > 0 && - freq >= 8000) + if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 && + IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 && + freq >= MIN_OUTPUT_RATE) ret = ALC_TRUE; } if(device) ALCdevice_DecRef(device); @@ -2639,9 +3490,9 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device * Renders some samples into a buffer, using the format last set by the * attributes given to alcCreateContext. */ -ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) +FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) { - if(!(device=VerifyDevice(device)) || !device->IsLoopbackDevice) + if(!(device=VerifyDevice(device)) || device->Type != Loopback) alcSetError(device, ALC_INVALID_DEVICE); else if(samples < 0 || (samples > 0 && buffer == NULL)) alcSetError(device, ALC_INVALID_VALUE); @@ -2651,32 +3502,57 @@ ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffe } -static void ReleaseALC(void) +/************************************************ + * ALC DSP pause/resume functions + ************************************************/ + +/* alcDevicePauseSOFT + * + * Pause the DSP to stop audio processing. + */ +ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) { - ALCdevice *dev; - - free(alcDeviceList); alcDeviceList = NULL; - alcDeviceListSize = 0; - free(alcAllDeviceList); alcAllDeviceList = NULL; - alcAllDeviceListSize = 0; - free(alcCaptureDeviceList); alcCaptureDeviceList = NULL; - alcCaptureDeviceListSize = 0; - - free(alcDefaultDeviceSpecifier); - alcDefaultDeviceSpecifier = NULL; - free(alcDefaultAllDeviceSpecifier); - alcDefaultAllDeviceSpecifier = NULL; - free(alcCaptureDefaultDeviceSpecifier); - alcCaptureDefaultDeviceSpecifier = NULL; - - if((dev=ExchangePtr((void**)&DeviceList, NULL)) != NULL) + if(!(device=VerifyDevice(device)) || device->Type != Playback) + alcSetError(device, ALC_INVALID_DEVICE); + else { - ALCuint num = 0; - do { - num++; - } while((dev=dev->next) != NULL); - ERR("%u device%s not closed\n", num, (num>1)?"s":""); + LockLists(); + if((device->Flags&DEVICE_RUNNING)) + V0(device->Backend,stop)(); + device->Flags &= ~DEVICE_RUNNING; + device->Flags |= DEVICE_PAUSED; + UnlockLists(); } + if(device) ALCdevice_DecRef(device); } -/////////////////////////////////////////////////////// +/* alcDeviceResumeSOFT + * + * Resume the DSP to restart audio processing. + */ +ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) +{ + if(!(device=VerifyDevice(device)) || device->Type != Playback) + alcSetError(device, ALC_INVALID_DEVICE); + else + { + LockLists(); + if((device->Flags&DEVICE_PAUSED)) + { + if(V0(device->Backend,start)() != ALC_FALSE) + { + device->Flags |= DEVICE_RUNNING; + device->Flags &= ~DEVICE_PAUSED; + } + else + { + alcSetError(device, ALC_INVALID_DEVICE); + ALCdevice_Lock(device); + aluHandleDisconnect(device); + ALCdevice_Unlock(device); + } + } + UnlockLists(); + } + if(device) ALCdevice_DecRef(device); +} diff --git a/jni/openal-soft-android/Alc/ALu.c b/jni/openal-soft-android/Alc/ALu.c index bc61e579..bf09450f 100644 --- a/jni/openal-soft-android/Alc/ALu.c +++ b/jni/openal-soft-android/Alc/ALu.c @@ -27,8 +27,6 @@ #include #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" #include "alSource.h" #include "alBuffer.h" #include "alListener.h" @@ -36,42 +34,139 @@ #include "alu.h" #include "bs2b.h" +#include "mixer_defs.h" + +#include "midi/base.h" + + +struct ChanMap { + enum Channel channel; + ALfloat angle; +}; /* Cone scalar */ -ALfloat ConeScale = 0.5f; +ALfloat ConeScale = 1.0f; /* Localized Z scalar for mono sources */ ALfloat ZScale = 1.0f; +extern inline ALfloat minf(ALfloat a, ALfloat b); +extern inline ALfloat maxf(ALfloat a, ALfloat b); +extern inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max); -static __inline ALvoid aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector) +extern inline ALdouble mind(ALdouble a, ALdouble b); +extern inline ALdouble maxd(ALdouble a, ALdouble b); +extern inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max); + +extern inline ALuint minu(ALuint a, ALuint b); +extern inline ALuint maxu(ALuint a, ALuint b); +extern inline ALuint clampu(ALuint val, ALuint min, ALuint max); + +extern inline ALint mini(ALint a, ALint b); +extern inline ALint maxi(ALint a, ALint b); +extern inline ALint clampi(ALint val, ALint min, ALint max); + +extern inline ALint64 mini64(ALint64 a, ALint64 b); +extern inline ALint64 maxi64(ALint64 a, ALint64 b); +extern inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max); + +extern inline ALuint64 minu64(ALuint64 a, ALuint64 b); +extern inline ALuint64 maxu64(ALuint64 a, ALuint64 b); +extern inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max); + +extern inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu); +extern inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu); + +static ResamplerFunc SelectResampler(enum Resampler Resampler, ALuint increment) +{ + if(increment == FRACTIONONE) + return Resample_copy32_C; + switch(Resampler) + { + case PointResampler: + return Resample_point32_C; + case LinearResampler: + return Resample_lerp32_C; + case CubicResampler: + return Resample_cubic32_C; + case ResamplerMax: + /* Shouldn't happen */ + break; + } + + return Resample_point32_C; +} + + +static DryMixerFunc SelectHrtfMixer(void) +{ +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + return MixDirect_Hrtf_SSE; +#endif +#ifdef HAVE_NEON + if((CPUCapFlags&CPU_CAP_NEON)) + return MixDirect_Hrtf_Neon; +#endif + + return MixDirect_Hrtf_C; +} + +static DryMixerFunc SelectDirectMixer(void) +{ +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + return MixDirect_SSE; +#endif +#ifdef HAVE_NEON + if((CPUCapFlags&CPU_CAP_NEON)) + return MixDirect_Neon; +#endif + + return MixDirect_C; +} + +static WetMixerFunc SelectSendMixer(void) +{ +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + return MixSend_SSE; +#endif +#ifdef HAVE_NEON + if((CPUCapFlags&CPU_CAP_NEON)) + return MixSend_Neon; +#endif + + return MixSend_C; +} + + +static inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector) { outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1]; outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2]; outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0]; } -static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2) +static inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2) { return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] + inVector1[2]*inVector2[2]; } -static __inline ALvoid aluNormalize(ALfloat *inVector) +static inline void aluNormalize(ALfloat *inVector) { - ALfloat length, inverse_length; - - length = aluSqrt(aluDotproduct(inVector, inVector)); - if(length != 0.0f) + ALfloat lengthsqr = aluDotproduct(inVector, inVector); + if(lengthsqr > 0.0f) { - inverse_length = 1.0f/length; - inVector[0] *= inverse_length; - inVector[1] *= inverse_length; - inVector[2] *= inverse_length; + ALfloat inv_length = 1.0f/sqrtf(lengthsqr); + inVector[0] *= inv_length; + inVector[1] *= inv_length; + inVector[2] *= inv_length; } } -static __inline ALvoid aluMatrixVector(ALfloat *vector,ALfloat w,ALfloat matrix[4][4]) +static inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat (*restrict matrix)[4]) { ALfloat temp[4] = { vector[0], vector[1], vector[2], w @@ -83,71 +178,134 @@ static __inline ALvoid aluMatrixVector(ALfloat *vector,ALfloat w,ALfloat matrix[ } +static ALvoid CalcListenerParams(ALlistener *Listener) +{ + ALfloat N[3], V[3], U[3], P[3]; + + /* AT then UP */ + N[0] = Listener->Forward[0]; + N[1] = Listener->Forward[1]; + N[2] = Listener->Forward[2]; + aluNormalize(N); + V[0] = Listener->Up[0]; + V[1] = Listener->Up[1]; + V[2] = Listener->Up[2]; + aluNormalize(V); + /* Build and normalize right-vector */ + aluCrossproduct(N, V, U); + aluNormalize(U); + + Listener->Params.Matrix[0][0] = U[0]; + Listener->Params.Matrix[0][1] = V[0]; + Listener->Params.Matrix[0][2] = -N[0]; + Listener->Params.Matrix[0][3] = 0.0f; + Listener->Params.Matrix[1][0] = U[1]; + Listener->Params.Matrix[1][1] = V[1]; + Listener->Params.Matrix[1][2] = -N[1]; + Listener->Params.Matrix[1][3] = 0.0f; + Listener->Params.Matrix[2][0] = U[2]; + Listener->Params.Matrix[2][1] = V[2]; + Listener->Params.Matrix[2][2] = -N[2]; + Listener->Params.Matrix[2][3] = 0.0f; + Listener->Params.Matrix[3][0] = 0.0f; + Listener->Params.Matrix[3][1] = 0.0f; + Listener->Params.Matrix[3][2] = 0.0f; + Listener->Params.Matrix[3][3] = 1.0f; + + P[0] = Listener->Position[0]; + P[1] = Listener->Position[1]; + P[2] = Listener->Position[2]; + aluMatrixVector(P, 1.0f, Listener->Params.Matrix); + Listener->Params.Matrix[3][0] = -P[0]; + Listener->Params.Matrix[3][1] = -P[1]; + Listener->Params.Matrix[3][2] = -P[2]; + + Listener->Params.Velocity[0] = Listener->Velocity[0]; + Listener->Params.Velocity[1] = Listener->Velocity[1]; + Listener->Params.Velocity[2] = Listener->Velocity[2]; + aluMatrixVector(Listener->Params.Velocity, 0.0f, Listener->Params.Matrix); +} + ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) { - static const ALfloat angles_Mono[1] = { 0.0f }; - static const ALfloat angles_Stereo[2] = { -30.0f, 30.0f }; - static const ALfloat angles_Rear[2] = { -150.0f, 150.0f }; - static const ALfloat angles_Quad[4] = { -45.0f, 45.0f, -135.0f, 135.0f }; - static const ALfloat angles_X51[6] = { -30.0f, 30.0f, 0.0f, 0.0f, - -110.0f, 110.0f }; - static const ALfloat angles_X61[7] = { -30.0f, 30.0f, 0.0f, 0.0f, - 180.0f, -90.0f, 90.0f }; - static const ALfloat angles_X71[8] = { -30.0f, 30.0f, 0.0f, 0.0f, - -110.0f, 110.0f, -90.0f, 90.0f }; - - static const enum Channel chans_Mono[1] = { FRONT_CENTER }; - static const enum Channel chans_Stereo[2] = { FRONT_LEFT, FRONT_RIGHT }; - static const enum Channel chans_Rear[2] = { BACK_LEFT, BACK_RIGHT }; - static const enum Channel chans_Quad[4] = { FRONT_LEFT, FRONT_RIGHT, - BACK_LEFT, BACK_RIGHT }; - static const enum Channel chans_X51[6] = { FRONT_LEFT, FRONT_RIGHT, - FRONT_CENTER, LFE, - BACK_LEFT, BACK_RIGHT }; - static const enum Channel chans_X61[7] = { FRONT_LEFT, FRONT_RIGHT, - FRONT_CENTER, LFE, BACK_CENTER, - SIDE_LEFT, SIDE_RIGHT }; - static const enum Channel chans_X71[8] = { FRONT_LEFT, FRONT_RIGHT, - FRONT_CENTER, LFE, - BACK_LEFT, BACK_RIGHT, - SIDE_LEFT, SIDE_RIGHT }; + static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } }; + static const struct ChanMap StereoMap[2] = { + { FrontLeft, DEG2RAD(-30.0f) }, + { FrontRight, DEG2RAD( 30.0f) } + }; + static const struct ChanMap StereoWideMap[2] = { + { FrontLeft, DEG2RAD(-90.0f) }, + { FrontRight, DEG2RAD( 90.0f) } + }; + static const struct ChanMap RearMap[2] = { + { BackLeft, DEG2RAD(-150.0f) }, + { BackRight, DEG2RAD( 150.0f) } + }; + static const struct ChanMap QuadMap[4] = { + { FrontLeft, DEG2RAD( -45.0f) }, + { FrontRight, DEG2RAD( 45.0f) }, + { BackLeft, DEG2RAD(-135.0f) }, + { BackRight, DEG2RAD( 135.0f) } + }; + static const struct ChanMap X51Map[6] = { + { FrontLeft, DEG2RAD( -30.0f) }, + { FrontRight, DEG2RAD( 30.0f) }, + { FrontCenter, DEG2RAD( 0.0f) }, + { LFE, 0.0f }, + { BackLeft, DEG2RAD(-110.0f) }, + { BackRight, DEG2RAD( 110.0f) } + }; + static const struct ChanMap X61Map[7] = { + { FrontLeft, DEG2RAD(-30.0f) }, + { FrontRight, DEG2RAD( 30.0f) }, + { FrontCenter, DEG2RAD( 0.0f) }, + { LFE, 0.0f }, + { BackCenter, DEG2RAD(180.0f) }, + { SideLeft, DEG2RAD(-90.0f) }, + { SideRight, DEG2RAD( 90.0f) } + }; + static const struct ChanMap X71Map[8] = { + { FrontLeft, DEG2RAD( -30.0f) }, + { FrontRight, DEG2RAD( 30.0f) }, + { FrontCenter, DEG2RAD( 0.0f) }, + { LFE, 0.0f }, + { BackLeft, DEG2RAD(-150.0f) }, + { BackRight, DEG2RAD( 150.0f) }, + { SideLeft, DEG2RAD( -90.0f) }, + { SideRight, DEG2RAD( 90.0f) } + }; ALCdevice *Device = ALContext->Device; ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume; ALbufferlistitem *BufferListItem; - enum DevFmtChannels DevChans; enum FmtChannels Channels; - ALfloat (*SrcMatrix)[MAXCHANNELS]; + ALfloat (*SrcMatrix)[MaxChannels]; ALfloat DryGain, DryGainHF; ALfloat WetGain[MAX_SENDS]; ALfloat WetGainHF[MAX_SENDS]; ALint NumSends, Frequency; - const ALfloat *SpeakerGain; - const ALfloat *angles = NULL; - const enum Channel *chans = NULL; + const struct ChanMap *chans = NULL; enum Resampler Resampler; ALint num_channels = 0; - ALboolean VirtualChannels; + ALboolean DirectChannels; + ALfloat hwidth = 0.0f; ALfloat Pitch; - ALfloat cw; - ALuint pos; ALint i, c; /* Get device properties */ - DevChans = Device->FmtChans; NumSends = Device->NumAuxSends; Frequency = Device->Frequency; /* Get listener properties */ - ListenerGain = ALContext->Listener.Gain; + ListenerGain = ALContext->Listener->Gain; /* Get source properties */ - SourceVolume = ALSource->flGain; - MinVolume = ALSource->flMinGain; - MaxVolume = ALSource->flMaxGain; - Pitch = ALSource->flPitch; + SourceVolume = ALSource->Gain; + MinVolume = ALSource->MinGain; + MaxVolume = ALSource->MaxGain; + Pitch = ALSource->Pitch; Resampler = ALSource->Resampler; - VirtualChannels = ALSource->VirtualChannels; + DirectChannels = ALSource->DirectChannels; /* Calculate the stepping value */ Channels = FmtMono; @@ -157,130 +315,125 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALbuffer *ALBuffer; if((ALBuffer=BufferListItem->buffer) != NULL) { - ALint maxstep = STACK_DATA_SIZE / ALSource->NumChannels / - ALSource->SampleSize; - maxstep -= ResamplerPadding[Resampler] + - ResamplerPrePadding[Resampler] + 1; - maxstep = mini(maxstep, INT_MAX>>FRACTIONBITS); - Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)maxstep) - ALSource->Params.Step = maxstep< 10.0f) + ALSource->Params.Step = 10<Params.Step = fastf2i(Pitch*FRACTIONONE); if(ALSource->Params.Step == 0) ALSource->Params.Step = 1; } + ALSource->Params.Resample = SelectResampler(Resampler, ALSource->Params.Step); Channels = ALBuffer->FmtChannels; break; } BufferListItem = BufferListItem->next; } - if(VirtualChannels && Device->Hrtf) - ALSource->Params.DoMix = SelectHrtfMixer((ALSource->Params.Step==FRACTIONONE) ? - POINT_RESAMPLER : Resampler); + if(!DirectChannels && Device->Hrtf) + ALSource->Params.DryMix = SelectHrtfMixer(); else - ALSource->Params.DoMix = SelectMixer((ALSource->Params.Step==FRACTIONONE) ? - POINT_RESAMPLER : Resampler); + ALSource->Params.DryMix = SelectDirectMixer(); + ALSource->Params.WetMix = SelectSendMixer(); /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ALSource->DirectGain; + DryGain *= ALSource->DirectGain * ListenerGain; DryGainHF = ALSource->DirectGainHF; for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ALSource->Send[i].WetGain; - WetGainHF[i] = ALSource->Send[i].WetGainHF; + WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; + WetGainHF[i] = ALSource->Send[i].GainHF; } - SrcMatrix = ALSource->Params.DryGains; - for(i = 0;i < MAXCHANNELS;i++) + SrcMatrix = ALSource->Params.Direct.Gains; + for(i = 0;i < MAX_INPUT_CHANNELS;i++) { - for(c = 0;c < MAXCHANNELS;c++) + for(c = 0;c < MaxChannels;c++) SrcMatrix[i][c] = 0.0f; } switch(Channels) { case FmtMono: - angles = angles_Mono; - chans = chans_Mono; + chans = MonoMap; num_channels = 1; break; - case FmtStereo: - if(VirtualChannels && (Device->Flags&DEVICE_DUPLICATE_STEREO)) - { - DryGain *= aluSqrt(2.0f/4.0f); - for(c = 0;c < 2;c++) - { - pos = aluCart2LUTpos(aluCos(F_PI/180.0f * angles_Rear[c]), - aluSin(F_PI/180.0f * angles_Rear[c])); - SpeakerGain = Device->PanningLUT[pos]; - for(i = 0;i < (ALint)Device->NumChan;i++) - { - enum Channel chan = Device->Speaker2Chan[i]; - SrcMatrix[c][chan] += DryGain * ListenerGain * - SpeakerGain[chan]; - } - } + case FmtStereo: + if(!(Device->Flags&DEVICE_WIDE_STEREO)) + { + /* HACK: Place the stereo channels at +/-90 degrees when using non- + * HRTF stereo output. This helps reduce the "monoization" caused + * by them panning towards the center. */ + if(Device->FmtChans == DevFmtStereo && !Device->Hrtf) + chans = StereoWideMap; + else + chans = StereoMap; + } + else + { + chans = StereoWideMap; + hwidth = DEG2RAD(60.0f); } - angles = angles_Stereo; - chans = chans_Stereo; num_channels = 2; break; case FmtRear: - angles = angles_Rear; - chans = chans_Rear; + chans = RearMap; num_channels = 2; break; case FmtQuad: - angles = angles_Quad; - chans = chans_Quad; + chans = QuadMap; num_channels = 4; break; case FmtX51: - angles = angles_X51; - chans = chans_X51; + chans = X51Map; num_channels = 6; break; case FmtX61: - angles = angles_X61; - chans = chans_X61; + chans = X61Map; num_channels = 7; break; case FmtX71: - angles = angles_X71; - chans = chans_X71; + chans = X71Map; num_channels = 8; break; } - if(VirtualChannels == AL_FALSE) + if(DirectChannels != AL_FALSE) { for(c = 0;c < num_channels;c++) - SrcMatrix[c][chans[c]] += DryGain * ListenerGain; + { + for(i = 0;i < (ALint)Device->NumChan;i++) + { + enum Channel chan = Device->Speaker2Chan[i]; + if(chan == chans[c].channel) + { + SrcMatrix[c][chan] = DryGain; + break; + } + } + } } else if(Device->Hrtf) { for(c = 0;c < num_channels;c++) { - if(chans[c] == LFE) + if(chans[c].channel == LFE) { /* Skip LFE */ - ALSource->Params.HrtfDelay[c][0] = 0; - ALSource->Params.HrtfDelay[c][1] = 0; + ALSource->Params.Direct.Hrtf.Params.Delay[c][0] = 0; + ALSource->Params.Direct.Hrtf.Params.Delay[c][1] = 0; for(i = 0;i < HRIR_LENGTH;i++) { - ALSource->Params.HrtfCoeffs[c][i][0] = 0.0f; - ALSource->Params.HrtfCoeffs[c][i][1] = 0.0f; + ALSource->Params.Direct.Hrtf.Params.Coeffs[c][i][0] = 0.0f; + ALSource->Params.Direct.Hrtf.Params.Coeffs[c][i][1] = 0.0f; } } else @@ -288,70 +441,84 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) /* Get the static HRIR coefficients and delays for this * channel. */ GetLerpedHrtfCoeffs(Device->Hrtf, - 0.0f, F_PI/180.0f * angles[c], - DryGain*ListenerGain, - ALSource->Params.HrtfCoeffs[c], - ALSource->Params.HrtfDelay[c]); + 0.0f, chans[c].angle, DryGain, + ALSource->Params.Direct.Hrtf.Params.Coeffs[c], + ALSource->Params.Direct.Hrtf.Params.Delay[c]); } - ALSource->HrtfCounter = 0; } + ALSource->Hrtf.Counter = 0; + ALSource->Params.Direct.Hrtf.Params.IrSize = GetHrtfIrSize(Device->Hrtf); + + ALSource->Params.Direct.Hrtf.State = &ALSource->Hrtf; } else { + DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumChan), hwidth/F_PI); for(c = 0;c < num_channels;c++) { - if(chans[c] == LFE) /* Special-case LFE */ + /* Special-case LFE */ + if(chans[c].channel == LFE) { - SrcMatrix[c][LFE] += DryGain * ListenerGain; + SrcMatrix[c][chans[c].channel] = DryGain; continue; } - pos = aluCart2LUTpos(aluCos(F_PI/180.0f * angles[c]), - aluSin(F_PI/180.0f * angles[c])); - SpeakerGain = Device->PanningLUT[pos]; - - for(i = 0;i < (ALint)Device->NumChan;i++) - { - enum Channel chan = Device->Speaker2Chan[i]; - SrcMatrix[c][chan] += DryGain * ListenerGain * - SpeakerGain[chan]; - } + ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain, + SrcMatrix[c]); } } + + ALSource->Params.Direct.OutBuffer = Device->DryBuffer; + ALSource->Params.Direct.ClickRemoval = Device->ClickRemoval; + ALSource->Params.Direct.PendingClicks = Device->PendingClicks; for(i = 0;i < NumSends;i++) { - ALSource->Params.Send[i].Slot = ALSource->Send[i].Slot; - ALSource->Params.Send[i].WetGain = WetGain[i] * ListenerGain; + ALeffectslot *Slot = ALSource->Send[i].Slot; + if(!Slot && i == 0) + Slot = Device->DefaultSlot; + if(!Slot || Slot->EffectType == AL_EFFECT_NULL) + { + ALSource->Params.Send[i].OutBuffer = NULL; + ALSource->Params.Send[i].ClickRemoval = NULL; + ALSource->Params.Send[i].PendingClicks = NULL; + } + else + { + ALSource->Params.Send[i].OutBuffer = Slot->WetBuffer; + ALSource->Params.Send[i].ClickRemoval = Slot->ClickRemoval; + ALSource->Params.Send[i].PendingClicks = Slot->PendingClicks; + } + ALSource->Params.Send[i].Gain = WetGain[i]; } - /* Update filter coefficients. Calculations based on the I3DL2 - * spec. */ - cw = aluCos(F_PI*2.0f * LOWPASSFREQREF / Frequency); - - /* We use two chained one-pole filters, so we need to take the - * square root of the squared gain, which is the same as the base - * gain. */ - ALSource->Params.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw); + { + ALfloat gain = maxf(0.01f, DryGainHF); + for(c = 0;c < num_channels;c++) + ALfilterState_setParams(&ALSource->Params.Direct.LpFilter[c], + ALfilterType_HighShelf, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); + } for(i = 0;i < NumSends;i++) { - /* We use a one-pole filter, so we need to take the squared gain */ - ALfloat a = lpCoeffCalc(WetGainHF[i]*WetGainHF[i], cw); - ALSource->Params.Send[i].iirFilter.coeff = a; + ALfloat gain = maxf(0.01f, WetGainHF[i]); + for(c = 0;c < num_channels;c++) + ALfilterState_setParams(&ALSource->Params.Send[i].LpFilter[c], + ALfilterType_HighShelf, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); } } ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) { - const ALCdevice *Device = ALContext->Device; + ALCdevice *Device = ALContext->Device; + ALfloat Velocity[3],Direction[3],Position[3],SourceToListener[3]; ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist; - ALfloat Direction[3],Position[3],SourceToListener[3]; - ALfloat Velocity[3],ListenerVel[3]; ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff; ALfloat ConeVolume,ConeHF,SourceVolume,ListenerGain; - ALfloat DopplerFactor, DopplerVelocity, SpeedOfSound; + ALfloat DopplerFactor, SpeedOfSound; ALfloat AirAbsorptionFactor; ALfloat RoomAirAbsorption[MAX_SENDS]; ALbufferlistitem *BufferListItem; - ALfloat Attenuation, EffectiveDist; + ALfloat Attenuation; ALfloat RoomAttenuation[MAX_SENDS]; ALfloat MetersPerUnit; ALfloat RoomRolloffBase; @@ -368,58 +535,60 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALfloat Pitch; ALuint Frequency; ALint NumSends; - ALfloat cw; - ALint i; + ALint i, j; DryGainHF = 1.0f; for(i = 0;i < MAX_SENDS;i++) WetGainHF[i] = 1.0f; - //Get context properties - DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor; - DopplerVelocity = ALContext->DopplerVelocity; - SpeedOfSound = ALContext->flSpeedOfSound; - NumSends = Device->NumAuxSends; - Frequency = Device->Frequency; + /* Get context/device properties */ + DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor; + SpeedOfSound = ALContext->SpeedOfSound * ALContext->DopplerVelocity; + NumSends = Device->NumAuxSends; + Frequency = Device->Frequency; - //Get listener properties - ListenerGain = ALContext->Listener.Gain; - MetersPerUnit = ALContext->Listener.MetersPerUnit; - ListenerVel[0] = ALContext->Listener.Velocity[0]; - ListenerVel[1] = ALContext->Listener.Velocity[1]; - ListenerVel[2] = ALContext->Listener.Velocity[2]; + /* Get listener properties */ + ListenerGain = ALContext->Listener->Gain; + MetersPerUnit = ALContext->Listener->MetersPerUnit; - //Get source properties - SourceVolume = ALSource->flGain; - MinVolume = ALSource->flMinGain; - MaxVolume = ALSource->flMaxGain; - Pitch = ALSource->flPitch; + /* Get source properties */ + SourceVolume = ALSource->Gain; + MinVolume = ALSource->MinGain; + MaxVolume = ALSource->MaxGain; + Pitch = ALSource->Pitch; Resampler = ALSource->Resampler; - Position[0] = ALSource->vPosition[0]; - Position[1] = ALSource->vPosition[1]; - Position[2] = ALSource->vPosition[2]; - Direction[0] = ALSource->vOrientation[0]; - Direction[1] = ALSource->vOrientation[1]; - Direction[2] = ALSource->vOrientation[2]; - Velocity[0] = ALSource->vVelocity[0]; - Velocity[1] = ALSource->vVelocity[1]; - Velocity[2] = ALSource->vVelocity[2]; - MinDist = ALSource->flRefDistance; - MaxDist = ALSource->flMaxDistance; - Rolloff = ALSource->flRollOffFactor; - InnerAngle = ALSource->flInnerAngle * ConeScale; - OuterAngle = ALSource->flOuterAngle * ConeScale; + Position[0] = ALSource->Position[0]; + Position[1] = ALSource->Position[1]; + Position[2] = ALSource->Position[2]; + Direction[0] = ALSource->Orientation[0]; + Direction[1] = ALSource->Orientation[1]; + Direction[2] = ALSource->Orientation[2]; + Velocity[0] = ALSource->Velocity[0]; + Velocity[1] = ALSource->Velocity[1]; + Velocity[2] = ALSource->Velocity[2]; + MinDist = ALSource->RefDistance; + MaxDist = ALSource->MaxDistance; + Rolloff = ALSource->RollOffFactor; + InnerAngle = ALSource->InnerAngle; + OuterAngle = ALSource->OuterAngle; AirAbsorptionFactor = ALSource->AirAbsorptionFactor; DryGainHFAuto = ALSource->DryGainHFAuto; WetGainAuto = ALSource->WetGainAuto; WetGainHFAuto = ALSource->WetGainHFAuto; RoomRolloffBase = ALSource->RoomRolloffFactor; + + ALSource->Params.Direct.OutBuffer = Device->DryBuffer; + ALSource->Params.Direct.ClickRemoval = Device->ClickRemoval; + ALSource->Params.Direct.PendingClicks = Device->PendingClicks; for(i = 0;i < NumSends;i++) { ALeffectslot *Slot = ALSource->Send[i].Slot; - if(!Slot || Slot->effect.type == AL_EFFECT_NULL) + if(!Slot && i == 0) + Slot = Device->DefaultSlot; + if(!Slot || Slot->EffectType == AL_EFFECT_NULL) { + Slot = NULL; RoomRolloff[i] = 0.0f; DecayDistance[i] = 0.0f; RoomAirAbsorption[i] = 1.0f; @@ -427,12 +596,12 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) else if(Slot->AuxSendAuto) { RoomRolloff[i] = RoomRolloffBase; - if(IsReverbEffect(Slot->effect.type)) + if(IsReverbEffect(Slot->EffectType)) { - RoomRolloff[i] += Slot->effect.Reverb.RoomRolloffFactor; - DecayDistance[i] = Slot->effect.Reverb.DecayTime * + RoomRolloff[i] += Slot->EffectProps.Reverb.RoomRolloffFactor; + DecayDistance[i] = Slot->EffectProps.Reverb.DecayTime * SPEEDOFSOUNDMETRESPERSEC; - RoomAirAbsorption[i] = Slot->effect.Reverb.AirAbsorptionGainHF; + RoomAirAbsorption[i] = Slot->EffectProps.Reverb.AirAbsorptionGainHF; } else { @@ -449,45 +618,37 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) RoomAirAbsorption[i] = AIRABSORBGAINHF; } - ALSource->Params.Send[i].Slot = Slot; + if(!Slot || Slot->EffectType == AL_EFFECT_NULL) + { + ALSource->Params.Send[i].OutBuffer = NULL; + ALSource->Params.Send[i].ClickRemoval = NULL; + ALSource->Params.Send[i].PendingClicks = NULL; + } + else + { + ALSource->Params.Send[i].OutBuffer = Slot->WetBuffer; + ALSource->Params.Send[i].ClickRemoval = Slot->ClickRemoval; + ALSource->Params.Send[i].PendingClicks = Slot->PendingClicks; + } } - //1. Translate Listener to origin (convert to head relative) - if(ALSource->bHeadRelative == AL_FALSE) + /* Transform source to listener space (convert to head relative) */ + if(ALSource->HeadRelative == AL_FALSE) { - ALfloat U[3],V[3],N[3]; - ALfloat Matrix[4][4]; - - // Build transform matrix - N[0] = ALContext->Listener.Forward[0]; // At-vector - N[1] = ALContext->Listener.Forward[1]; - N[2] = ALContext->Listener.Forward[2]; - aluNormalize(N); // Normalized At-vector - V[0] = ALContext->Listener.Up[0]; // Up-vector - V[1] = ALContext->Listener.Up[1]; - V[2] = ALContext->Listener.Up[2]; - aluNormalize(V); // Normalized Up-vector - aluCrossproduct(N, V, U); // Right-vector - aluNormalize(U); // Normalized Right-vector - Matrix[0][0] = U[0]; Matrix[0][1] = V[0]; Matrix[0][2] = -N[0]; Matrix[0][3] = 0.0f; - Matrix[1][0] = U[1]; Matrix[1][1] = V[1]; Matrix[1][2] = -N[1]; Matrix[1][3] = 0.0f; - Matrix[2][0] = U[2]; Matrix[2][1] = V[2]; Matrix[2][2] = -N[2]; Matrix[2][3] = 0.0f; - Matrix[3][0] = 0.0f; Matrix[3][1] = 0.0f; Matrix[3][2] = 0.0f; Matrix[3][3] = 1.0f; - - // Translate position - Position[0] -= ALContext->Listener.Position[0]; - Position[1] -= ALContext->Listener.Position[1]; - Position[2] -= ALContext->Listener.Position[2]; - - // Transform source position and direction into listener space + ALfloat (*restrict Matrix)[4] = ALContext->Listener->Params.Matrix; + /* Transform source vectors */ aluMatrixVector(Position, 1.0f, Matrix); aluMatrixVector(Direction, 0.0f, Matrix); - // Transform source and listener velocity into listener space aluMatrixVector(Velocity, 0.0f, Matrix); - aluMatrixVector(ListenerVel, 0.0f, Matrix); } else - ListenerVel[0] = ListenerVel[1] = ListenerVel[2] = 0.0f; + { + const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity; + /* Offset the source velocity to be relative of the listener velocity */ + Velocity[0] += ListenerVel[0]; + Velocity[1] += ListenerVel[1]; + Velocity[2] += ListenerVel[2]; + } SourceToListener[0] = -Position[0]; SourceToListener[1] = -Position[1]; @@ -495,8 +656,8 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) aluNormalize(SourceToListener); aluNormalize(Direction); - //2. Calculate distance attenuation - Distance = aluSqrt(aluDotproduct(Position, Position)); + /* Calculate distance attenuation */ + Distance = sqrtf(aluDotproduct(Position, Position)); ClampedDist = Distance; Attenuation = 1.0f; @@ -509,7 +670,7 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ClampedDist = clampf(ClampedDist, MinDist, MaxDist); if(MaxDist < MinDist) break; - //fall-through + /*fall-through*/ case InverseDistance: if(MinDist > 0.0f) { @@ -527,7 +688,7 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ClampedDist = clampf(ClampedDist, MinDist, MaxDist); if(MaxDist < MinDist) break; - //fall-through + /*fall-through*/ case LinearDistance: if(MaxDist != MinDist) { @@ -545,65 +706,64 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ClampedDist = clampf(ClampedDist, MinDist, MaxDist); if(MaxDist < MinDist) break; - //fall-through + /*fall-through*/ case ExponentDistance: if(ClampedDist > 0.0f && MinDist > 0.0f) { - Attenuation = aluPow(ClampedDist/MinDist, -Rolloff); + Attenuation = powf(ClampedDist/MinDist, -Rolloff); for(i = 0;i < NumSends;i++) - RoomAttenuation[i] = aluPow(ClampedDist/MinDist, -RoomRolloff[i]); + RoomAttenuation[i] = powf(ClampedDist/MinDist, -RoomRolloff[i]); } break; case DisableDistance: + ClampedDist = MinDist; break; } - // Source Gain + Attenuation + /* Source Gain + Attenuation */ DryGain = SourceVolume * Attenuation; for(i = 0;i < NumSends;i++) WetGain[i] = SourceVolume * RoomAttenuation[i]; - // Distance-based air absorption - EffectiveDist = 0.0f; - if(MinDist > 0.0f && Attenuation < 1.0f) - EffectiveDist = (MinDist/Attenuation - MinDist)*MetersPerUnit; - if(AirAbsorptionFactor > 0.0f && EffectiveDist > 0.0f) + /* Distance-based air absorption */ + if(AirAbsorptionFactor > 0.0f && ClampedDist > MinDist) { - DryGainHF *= aluPow(AIRABSORBGAINHF, AirAbsorptionFactor*EffectiveDist); + ALfloat meters = maxf(ClampedDist-MinDist, 0.0f) * MetersPerUnit; + DryGainHF *= powf(AIRABSORBGAINHF, AirAbsorptionFactor*meters); for(i = 0;i < NumSends;i++) - WetGainHF[i] *= aluPow(RoomAirAbsorption[i], - AirAbsorptionFactor*EffectiveDist); + WetGainHF[i] *= powf(RoomAirAbsorption[i], AirAbsorptionFactor*meters); } if(WetGainAuto) { + ALfloat ApparentDist = 1.0f/maxf(Attenuation, 0.00001f) - 1.0f; + /* Apply a decay-time transformation to the wet path, based on the * attenuation of the dry path. * - * Using the approximate (effective) source to listener distance, the + * Using the apparent distance, based on the distance attenuation, the * initial decay of the reverb effect is calculated and applied to the * wet path. */ for(i = 0;i < NumSends;i++) { if(DecayDistance[i] > 0.0f) - WetGain[i] *= aluPow(0.001f /* -60dB */, - EffectiveDist / DecayDistance[i]); + WetGain[i] *= powf(0.001f/*-60dB*/, ApparentDist/DecayDistance[i]); } } /* Calculate directional soundcones */ - Angle = aluAcos(aluDotproduct(Direction,SourceToListener)) * (180.0f/F_PI); - if(Angle >= InnerAngle && Angle <= OuterAngle) + Angle = RAD2DEG(acosf(aluDotproduct(Direction,SourceToListener)) * ConeScale) * 2.0f; + if(Angle > InnerAngle && Angle <= OuterAngle) { ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp(1.0f, ALSource->flOuterGain, scale); + ConeVolume = lerp(1.0f, ALSource->OuterGain, scale); ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale); } else if(Angle > OuterAngle) { - ConeVolume = ALSource->flOuterGain; + ConeVolume = ALSource->OuterGain; ConeHF = ALSource->OuterGainHF; } else @@ -626,41 +786,37 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) WetGainHF[i] *= ConeHF; } - // Clamp to Min/Max Gain + /* Clamp to Min/Max Gain */ DryGain = clampf(DryGain, MinVolume, MaxVolume); for(i = 0;i < NumSends;i++) WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); - // Apply filter gains and filters + /* Apply gain and frequency filters */ DryGain *= ALSource->DirectGain * ListenerGain; DryGainHF *= ALSource->DirectGainHF; for(i = 0;i < NumSends;i++) { - WetGain[i] *= ALSource->Send[i].WetGain * ListenerGain; - WetGainHF[i] *= ALSource->Send[i].WetGainHF; + WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; + WetGainHF[i] *= ALSource->Send[i].GainHF; } - // Calculate Velocity - if(DopplerFactor != 0.0f) + /* Calculate velocity-based doppler effect */ + if(DopplerFactor > 0.0f) { + const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity; ALfloat VSS, VLS; - ALfloat MaxVelocity = (SpeedOfSound*DopplerVelocity) / - DopplerFactor; - VSS = aluDotproduct(Velocity, SourceToListener); - if(VSS >= MaxVelocity) - VSS = (MaxVelocity - 1.0f); - else if(VSS <= -MaxVelocity) - VSS = -MaxVelocity + 1.0f; + if(SpeedOfSound < 1.0f) + { + DopplerFactor *= 1.0f/SpeedOfSound; + SpeedOfSound = 1.0f; + } - VLS = aluDotproduct(ListenerVel, SourceToListener); - if(VLS >= MaxVelocity) - VLS = (MaxVelocity - 1.0f); - else if(VLS <= -MaxVelocity) - VLS = -MaxVelocity + 1.0f; + VSS = aluDotproduct(Velocity, SourceToListener) * DopplerFactor; + VLS = aluDotproduct(ListenerVel, SourceToListener) * DopplerFactor; - Pitch *= ((SpeedOfSound*DopplerVelocity) - (DopplerFactor*VLS)) / - ((SpeedOfSound*DopplerVelocity) - (DopplerFactor*VSS)); + Pitch *= clampf(SpeedOfSound-VLS, 1.0f, SpeedOfSound*2.0f - 1.0f) / + clampf(SpeedOfSound-VSS, 1.0f, SpeedOfSound*2.0f - 1.0f); } BufferListItem = ALSource->queue; @@ -669,274 +825,200 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALbuffer *ALBuffer; if((ALBuffer=BufferListItem->buffer) != NULL) { - ALint maxstep = STACK_DATA_SIZE / ALSource->NumChannels / - ALSource->SampleSize; - maxstep -= ResamplerPadding[Resampler] + - ResamplerPrePadding[Resampler] + 1; - maxstep = mini(maxstep, INT_MAX>>FRACTIONBITS); - + /* Calculate fixed-point stepping value, based on the pitch, buffer + * frequency, and output frequency. */ Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)maxstep) - ALSource->Params.Step = maxstep< 10.0f) + ALSource->Params.Step = 10<Params.Step = fastf2i(Pitch*FRACTIONONE); if(ALSource->Params.Step == 0) ALSource->Params.Step = 1; } + ALSource->Params.Resample = SelectResampler(Resampler, ALSource->Params.Step); break; } BufferListItem = BufferListItem->next; } if(Device->Hrtf) - ALSource->Params.DoMix = SelectHrtfMixer((ALSource->Params.Step==FRACTIONONE) ? - POINT_RESAMPLER : Resampler); + ALSource->Params.DryMix = SelectHrtfMixer(); else - ALSource->Params.DoMix = SelectMixer((ALSource->Params.Step==FRACTIONONE) ? - POINT_RESAMPLER : Resampler); + ALSource->Params.DryMix = SelectDirectMixer(); + ALSource->Params.WetMix = SelectSendMixer(); if(Device->Hrtf) { - // Use a binaural HRTF algorithm for stereo headphone playback + /* Use a binaural HRTF algorithm for stereo headphone playback */ ALfloat delta, ev = 0.0f, az = 0.0f; - if(Distance > 0.0f) + if(Distance > FLT_EPSILON) { ALfloat invlen = 1.0f/Distance; Position[0] *= invlen; Position[1] *= invlen; Position[2] *= invlen; - // Calculate elevation and azimuth only when the source is not at - // the listener. This prevents +0 and -0 Z from producing - // inconsistent panning. - ev = aluAsin(Position[1]); - az = aluAtan2(Position[0], -Position[2]*ZScale); + /* Calculate elevation and azimuth only when the source is not at + * the listener. This prevents +0 and -0 Z from producing + * inconsistent panning. Also, clamp Y in case FP precision errors + * cause it to land outside of -1..+1. */ + ev = asinf(clampf(Position[1], -1.0f, 1.0f)); + az = atan2f(Position[0], -Position[2]*ZScale); } - // Check to see if the HRIR is already moving. - if(ALSource->HrtfMoving) + /* Check to see if the HRIR is already moving. */ + if(ALSource->Hrtf.Moving) { - // Calculate the normalized HRTF transition factor (delta). - delta = CalcHrtfDelta(ALSource->Params.HrtfGain, DryGain, - ALSource->Params.HrtfDir, Position); - // If the delta is large enough, get the moving HRIR target - // coefficients, target delays, steppping values, and counter. + /* Calculate the normalized HRTF transition factor (delta). */ + delta = CalcHrtfDelta(ALSource->Params.Direct.Hrtf.Params.Gain, DryGain, + ALSource->Params.Direct.Hrtf.Params.Dir, Position); + /* If the delta is large enough, get the moving HRIR target + * coefficients, target delays, steppping values, and counter. */ if(delta > 0.001f) { - ALSource->HrtfCounter = GetMovingHrtfCoeffs(Device->Hrtf, - ev, az, DryGain, delta, - ALSource->HrtfCounter, - ALSource->Params.HrtfCoeffs[0], - ALSource->Params.HrtfDelay[0], - ALSource->Params.HrtfCoeffStep, - ALSource->Params.HrtfDelayStep); - ALSource->Params.HrtfGain = DryGain; - ALSource->Params.HrtfDir[0] = Position[0]; - ALSource->Params.HrtfDir[1] = Position[1]; - ALSource->Params.HrtfDir[2] = Position[2]; + ALSource->Hrtf.Counter = GetMovingHrtfCoeffs(Device->Hrtf, + ev, az, DryGain, delta, + ALSource->Hrtf.Counter, + ALSource->Params.Direct.Hrtf.Params.Coeffs[0], + ALSource->Params.Direct.Hrtf.Params.Delay[0], + ALSource->Params.Direct.Hrtf.Params.CoeffStep, + ALSource->Params.Direct.Hrtf.Params.DelayStep); + ALSource->Params.Direct.Hrtf.Params.Gain = DryGain; + ALSource->Params.Direct.Hrtf.Params.Dir[0] = Position[0]; + ALSource->Params.Direct.Hrtf.Params.Dir[1] = Position[1]; + ALSource->Params.Direct.Hrtf.Params.Dir[2] = Position[2]; } } else { - // Get the initial (static) HRIR coefficients and delays. + /* Get the initial (static) HRIR coefficients and delays. */ GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, DryGain, - ALSource->Params.HrtfCoeffs[0], - ALSource->Params.HrtfDelay[0]); - ALSource->HrtfCounter = 0; - ALSource->Params.HrtfGain = DryGain; - ALSource->Params.HrtfDir[0] = Position[0]; - ALSource->Params.HrtfDir[1] = Position[1]; - ALSource->Params.HrtfDir[2] = Position[2]; + ALSource->Params.Direct.Hrtf.Params.Coeffs[0], + ALSource->Params.Direct.Hrtf.Params.Delay[0]); + ALSource->Hrtf.Counter = 0; + ALSource->Hrtf.Moving = AL_TRUE; + ALSource->Params.Direct.Hrtf.Params.Gain = DryGain; + ALSource->Params.Direct.Hrtf.Params.Dir[0] = Position[0]; + ALSource->Params.Direct.Hrtf.Params.Dir[1] = Position[1]; + ALSource->Params.Direct.Hrtf.Params.Dir[2] = Position[2]; } + ALSource->Params.Direct.Hrtf.Params.IrSize = GetHrtfIrSize(Device->Hrtf); + + ALSource->Params.Direct.Hrtf.State = &ALSource->Hrtf; } else { - // Use energy-preserving panning algorithm for multi-speaker playback - ALfloat DirGain, AmbientGain; - const ALfloat *SpeakerGain; - ALfloat length; - ALint pos; + ALfloat (*Matrix)[MaxChannels] = ALSource->Params.Direct.Gains; + ALfloat DirGain = 0.0f; + ALfloat AmbientGain; - length = maxf(Distance, MinDist); - if(length > 0.0f) + for(i = 0;i < MAX_INPUT_CHANNELS;i++) { - ALfloat invlen = 1.0f/length; + for(j = 0;j < MaxChannels;j++) + Matrix[i][j] = 0.0f; + } + + /* Normalize the length, and compute panned gains. */ + if(Distance > FLT_EPSILON) + { + ALfloat invlen = 1.0f/Distance; Position[0] *= invlen; Position[1] *= invlen; Position[2] *= invlen; + + DirGain = sqrtf(Position[0]*Position[0] + Position[2]*Position[2]); + ComputeAngleGains(Device, atan2f(Position[0], -Position[2]*ZScale), 0.0f, + DryGain*DirGain, Matrix[0]); } - pos = aluCart2LUTpos(-Position[2]*ZScale, Position[0]); - SpeakerGain = Device->PanningLUT[pos]; - - DirGain = aluSqrt(Position[0]*Position[0] + Position[2]*Position[2]); - // elevation adjustment for directional gain. this sucks, but - // has low complexity - AmbientGain = aluSqrt(1.0f/Device->NumChan); - for(i = 0;i < MAXCHANNELS;i++) - { - ALuint i2; - for(i2 = 0;i2 < MAXCHANNELS;i2++) - ALSource->Params.DryGains[i][i2] = 0.0f; - } + /* Adjustment for vertical offsets. Not the greatest, but simple + * enough. */ + AmbientGain = DryGain * sqrtf(1.0f/Device->NumChan) * (1.0f-DirGain); for(i = 0;i < (ALint)Device->NumChan;i++) { enum Channel chan = Device->Speaker2Chan[i]; - ALfloat gain = lerp(AmbientGain, SpeakerGain[chan], DirGain); - ALSource->Params.DryGains[0][chan] = DryGain * gain; + Matrix[0][chan] = maxf(Matrix[0][chan], AmbientGain); } } for(i = 0;i < NumSends;i++) - ALSource->Params.Send[i].WetGain = WetGain[i]; + ALSource->Params.Send[i].Gain = WetGain[i]; - /* Update filter coefficients. */ - cw = aluCos(F_PI*2.0f * LOWPASSFREQREF / Frequency); - ALSource->Params.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw); + { + ALfloat gain = maxf(0.01f, DryGainHF); + ALfilterState_setParams(&ALSource->Params.Direct.LpFilter[0], + ALfilterType_HighShelf, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); + } for(i = 0;i < NumSends;i++) { - ALfloat a = lpCoeffCalc(WetGainHF[i]*WetGainHF[i], cw); - ALSource->Params.Send[i].iirFilter.coeff = a; + ALfloat gain = maxf(0.01f, WetGainHF[i]); + ALfilterState_setParams(&ALSource->Params.Send[i].LpFilter[0], + ALfilterType_HighShelf, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); } } -static __inline ALfloat aluF2F(ALfloat val) -{ return val; } -static __inline ALshort aluF2S(ALfloat val) +static inline ALint aluF2I25(ALfloat val) { - if(val > 1.0f) return 32767; - if(val < -1.0f) return -32768; - return fastf2i(val*32767.0f); + /* Clamp the value between -1 and +1. This handles that with only a single branch. */ + if(fabsf(val) > 1.0f) + val = (ALfloat)((0.0f < val) - (val < 0.0f)); + /* Convert to a signed integer, between -16777215 and +16777215. */ + return fastf2i(val*16777215.0f); } -static __inline ALushort aluF2US(ALfloat val) + +static inline ALfloat aluF2F(ALfloat val) +{ return val; } +static inline ALint aluF2I(ALfloat val) +{ return aluF2I25(val)<<7; } +static inline ALuint aluF2UI(ALfloat val) +{ return aluF2I(val)+2147483648u; } +static inline ALshort aluF2S(ALfloat val) +{ return aluF2I25(val)>>9; } +static inline ALushort aluF2US(ALfloat val) { return aluF2S(val)+32768; } -static __inline ALbyte aluF2B(ALfloat val) -{ return aluF2S(val)>>8; } -static __inline ALubyte aluF2UB(ALfloat val) -{ return aluF2US(val)>>8; } +static inline ALbyte aluF2B(ALfloat val) +{ return aluF2I25(val)>>17; } +static inline ALubyte aluF2UB(ALfloat val) +{ return aluF2B(val)+128; } -#define DECL_TEMPLATE(T, N, func) \ -static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \ - ALuint SamplesToDo) \ +#define DECL_TEMPLATE(T, func) \ +static int Write_##T(ALCdevice *device, T *restrict buffer, \ + ALuint SamplesToDo) \ { \ - ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS] = device->DryBuffer; \ - const enum Channel *ChanMap = device->DevChannels; \ + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = device->DryBuffer; \ + ALuint numchans = ChannelsFromDevFmt(device->FmtChans); \ + const ALuint *offsets = device->ChannelOffsets; \ ALuint i, j; \ \ - for(i = 0;i < SamplesToDo;i++) \ + for(j = 0;j < MaxChannels;j++) \ { \ - for(j = 0;j < N;j++) \ - *(buffer++) = func(DryBuffer[i][ChanMap[j]]); \ - } \ -} - -DECL_TEMPLATE(ALfloat, 1, aluF2F) -DECL_TEMPLATE(ALfloat, 4, aluF2F) -DECL_TEMPLATE(ALfloat, 6, aluF2F) -DECL_TEMPLATE(ALfloat, 7, aluF2F) -DECL_TEMPLATE(ALfloat, 8, aluF2F) - -DECL_TEMPLATE(ALushort, 1, aluF2US) -DECL_TEMPLATE(ALushort, 4, aluF2US) -DECL_TEMPLATE(ALushort, 6, aluF2US) -DECL_TEMPLATE(ALushort, 7, aluF2US) -DECL_TEMPLATE(ALushort, 8, aluF2US) - -DECL_TEMPLATE(ALshort, 1, aluF2S) -DECL_TEMPLATE(ALshort, 4, aluF2S) -DECL_TEMPLATE(ALshort, 6, aluF2S) -DECL_TEMPLATE(ALshort, 7, aluF2S) -DECL_TEMPLATE(ALshort, 8, aluF2S) - -DECL_TEMPLATE(ALubyte, 1, aluF2UB) -DECL_TEMPLATE(ALubyte, 4, aluF2UB) -DECL_TEMPLATE(ALubyte, 6, aluF2UB) -DECL_TEMPLATE(ALubyte, 7, aluF2UB) -DECL_TEMPLATE(ALubyte, 8, aluF2UB) - -DECL_TEMPLATE(ALbyte, 1, aluF2B) -DECL_TEMPLATE(ALbyte, 4, aluF2B) -DECL_TEMPLATE(ALbyte, 6, aluF2B) -DECL_TEMPLATE(ALbyte, 7, aluF2B) -DECL_TEMPLATE(ALbyte, 8, aluF2B) - -#undef DECL_TEMPLATE - -#define DECL_TEMPLATE(T, N, func) \ -static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \ - ALuint SamplesToDo) \ -{ \ - ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS] = device->DryBuffer; \ - const enum Channel *ChanMap = device->DevChannels; \ - ALuint i, j; \ + T *restrict out; \ \ - if(device->Bs2b) \ - { \ + if(offsets[j] == INVALID_OFFSET) \ + continue; \ + \ + out = buffer + offsets[j]; \ for(i = 0;i < SamplesToDo;i++) \ - { \ - float samples[2]; \ - samples[0] = DryBuffer[i][ChanMap[0]]; \ - samples[1] = DryBuffer[i][ChanMap[1]]; \ - bs2b_cross_feed(device->Bs2b, samples); \ - *(buffer++) = func(samples[0]); \ - *(buffer++) = func(samples[1]); \ - } \ - } \ - else \ - { \ - for(i = 0;i < SamplesToDo;i++) \ - { \ - for(j = 0;j < N;j++) \ - *(buffer++) = func(DryBuffer[i][ChanMap[j]]); \ - } \ + out[i*numchans] = func(DryBuffer[j][i]); \ } \ + return SamplesToDo*numchans*sizeof(T); \ } -DECL_TEMPLATE(ALfloat, 2, aluF2F) -DECL_TEMPLATE(ALushort, 2, aluF2US) -DECL_TEMPLATE(ALshort, 2, aluF2S) -DECL_TEMPLATE(ALubyte, 2, aluF2UB) -DECL_TEMPLATE(ALbyte, 2, aluF2B) +DECL_TEMPLATE(ALfloat, aluF2F) +DECL_TEMPLATE(ALuint, aluF2UI) +DECL_TEMPLATE(ALint, aluF2I) +DECL_TEMPLATE(ALushort, aluF2US) +DECL_TEMPLATE(ALshort, aluF2S) +DECL_TEMPLATE(ALubyte, aluF2UB) +DECL_TEMPLATE(ALbyte, aluF2B) #undef DECL_TEMPLATE -#define DECL_TEMPLATE(T) \ -static void Write_##T(ALCdevice *device, T *buffer, ALuint SamplesToDo) \ -{ \ - switch(device->FmtChans) \ - { \ - case DevFmtMono: \ - Write_##T##_1(device, buffer, SamplesToDo); \ - break; \ - case DevFmtStereo: \ - Write_##T##_2(device, buffer, SamplesToDo); \ - break; \ - case DevFmtQuad: \ - Write_##T##_4(device, buffer, SamplesToDo); \ - break; \ - case DevFmtX51: \ - case DevFmtX51Side: \ - Write_##T##_6(device, buffer, SamplesToDo); \ - break; \ - case DevFmtX61: \ - Write_##T##_7(device, buffer, SamplesToDo); \ - break; \ - case DevFmtX71: \ - Write_##T##_8(device, buffer, SamplesToDo); \ - break; \ - } \ -} - -DECL_TEMPLATE(ALfloat) -DECL_TEMPLATE(ALushort) -DECL_TEMPLATE(ALshort) -DECL_TEMPLATE(ALubyte) -DECL_TEMPLATE(ALbyte) - -#undef DECL_TEMPLATE ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { @@ -944,20 +1026,20 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ALeffectslot **slot, **slot_end; ALsource **src, **src_end; ALCcontext *ctx; - int fpuState; + FPUCtl oldMode; ALuint i, c; - fpuState = SetMixerFPUMode(); + SetMixerFPUMode(&oldMode); while(size > 0) { - /* Setup variables */ SamplesToDo = minu(size, BUFFERSIZE); + for(c = 0;c < MaxChannels;c++) + memset(device->DryBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); - /* Clear mixing buffer */ - memset(device->DryBuffer, 0, SamplesToDo*MAXCHANNELS*sizeof(ALfloat)); + ALCdevice_Lock(device); + V(device->Synth,process)(SamplesToDo, device->DryBuffer); - LockDevice(device); ctx = device->ContextList; while(ctx) { @@ -967,6 +1049,10 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) if(!DeferUpdates) UpdateSources = ExchangeInt(&ctx->UpdateSources, AL_FALSE); + if(UpdateSources) + CalcListenerParams(ctx->Listener); + + /* source processing */ src = ctx->ActiveSources; src_end = src + ctx->ActiveSourceCount; while(src != src_end) @@ -991,101 +1077,154 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) slot_end = slot + ctx->ActiveEffectSlotCount; while(slot != slot_end) { - for(c = 0;c < SamplesToDo;c++) + ALfloat offset = (*slot)->ClickRemoval[0]; + if(offset < (1.0f/32768.0f)) + offset = 0.0f; + else for(i = 0;i < SamplesToDo;i++) { - (*slot)->WetBuffer[c] += (*slot)->ClickRemoval[0]; - (*slot)->ClickRemoval[0] -= (*slot)->ClickRemoval[0] * (1.0f/256.0f); + (*slot)->WetBuffer[0][i] += offset; + offset -= offset * (1.0f/256.0f); } - (*slot)->ClickRemoval[0] += (*slot)->PendingClicks[0]; + (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0]; (*slot)->PendingClicks[0] = 0.0f; if(!DeferUpdates && ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE)) - ALeffectState_Update((*slot)->EffectState, ctx, *slot); + V((*slot)->EffectState,update)(device, *slot); - ALeffectState_Process((*slot)->EffectState, SamplesToDo, - (*slot)->WetBuffer, device->DryBuffer); + V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], + device->DryBuffer); for(i = 0;i < SamplesToDo;i++) - (*slot)->WetBuffer[i] = 0.0f; + (*slot)->WetBuffer[0][i] = 0.0f; slot++; } ctx = ctx->next; } - UnlockDevice(device); - //Post processing loop + slot = &device->DefaultSlot; + if(*slot != NULL) + { + ALfloat offset = (*slot)->ClickRemoval[0]; + if(offset < (1.0f/32768.0f)) + offset = 0.0f; + else for(i = 0;i < SamplesToDo;i++) + { + (*slot)->WetBuffer[0][i] += offset; + offset -= offset * (1.0f/256.0f); + } + (*slot)->ClickRemoval[0] = offset + (*slot)->PendingClicks[0]; + (*slot)->PendingClicks[0] = 0.0f; + + if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE)) + V((*slot)->EffectState,update)(device, *slot); + + V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], + device->DryBuffer); + + for(i = 0;i < SamplesToDo;i++) + (*slot)->WetBuffer[0][i] = 0.0f; + } + ALCdevice_Unlock(device); + + /* Click-removal. Could do better; this only really handles immediate + * changes between updates where a predictive sample could be + * generated. Delays caused by effects and HRTF aren't caught. */ if(device->FmtChans == DevFmtMono) { - for(i = 0;i < SamplesToDo;i++) + ALfloat offset = device->ClickRemoval[FrontCenter]; + if(offset < (1.0f/32768.0f)) + offset = 0.0f; + else for(i = 0;i < SamplesToDo;i++) { - device->DryBuffer[i][FRONT_CENTER] += device->ClickRemoval[FRONT_CENTER]; - device->ClickRemoval[FRONT_CENTER] -= device->ClickRemoval[FRONT_CENTER] * (1.0f/256.0f); + device->DryBuffer[FrontCenter][i] += offset; + offset -= offset * (1.0f/256.0f); } - device->ClickRemoval[FRONT_CENTER] += device->PendingClicks[FRONT_CENTER]; - device->PendingClicks[FRONT_CENTER] = 0.0f; + device->ClickRemoval[FrontCenter] = offset + device->PendingClicks[FrontCenter]; + device->PendingClicks[FrontCenter] = 0.0f; } else if(device->FmtChans == DevFmtStereo) { - /* Assumes the first two channels are FRONT_LEFT and FRONT_RIGHT */ - for(i = 0;i < SamplesToDo;i++) - { - for(c = 0;c < 2;c++) - { - device->DryBuffer[i][c] += device->ClickRemoval[c]; - device->ClickRemoval[c] -= device->ClickRemoval[c] * (1.0f/256.0f); - } - } + /* Assumes the first two channels are FrontLeft and FrontRight */ for(c = 0;c < 2;c++) { - device->ClickRemoval[c] += device->PendingClicks[c]; + ALfloat offset = device->ClickRemoval[c]; + if(offset < (1.0f/32768.0f)) + offset = 0.0f; + else for(i = 0;i < SamplesToDo;i++) + { + device->DryBuffer[c][i] += offset; + offset -= offset * (1.0f/256.0f); + } + device->ClickRemoval[c] = offset + device->PendingClicks[c]; device->PendingClicks[c] = 0.0f; } + if(device->Bs2b) + { + float samples[2]; + for(i = 0;i < SamplesToDo;i++) + { + samples[0] = device->DryBuffer[FrontLeft][i]; + samples[1] = device->DryBuffer[FrontRight][i]; + bs2b_cross_feed(device->Bs2b, samples); + device->DryBuffer[FrontLeft][i] = samples[0]; + device->DryBuffer[FrontRight][i] = samples[1]; + } + } } else { - for(i = 0;i < SamplesToDo;i++) + for(c = 0;c < MaxChannels;c++) { - for(c = 0;c < MAXCHANNELS;c++) + ALfloat offset = device->ClickRemoval[c]; + if(offset < (1.0f/32768.0f)) + offset = 0.0f; + else for(i = 0;i < SamplesToDo;i++) { - device->DryBuffer[i][c] += device->ClickRemoval[c]; - device->ClickRemoval[c] -= device->ClickRemoval[c] * (1.0f/256.0f); + device->DryBuffer[c][i] += offset; + offset -= offset * (1.0f/256.0f); } - } - for(c = 0;c < MAXCHANNELS;c++) - { - device->ClickRemoval[c] += device->PendingClicks[c]; + device->ClickRemoval[c] = offset + device->PendingClicks[c]; device->PendingClicks[c] = 0.0f; } } if(buffer) { + int bytes = 0; switch(device->FmtType) { case DevFmtByte: - Write_ALbyte(device, buffer, SamplesToDo); + bytes = Write_ALbyte(device, buffer, SamplesToDo); break; case DevFmtUByte: - Write_ALubyte(device, buffer, SamplesToDo); + bytes = Write_ALubyte(device, buffer, SamplesToDo); break; case DevFmtShort: - Write_ALshort(device, buffer, SamplesToDo); + bytes = Write_ALshort(device, buffer, SamplesToDo); break; case DevFmtUShort: - Write_ALushort(device, buffer, SamplesToDo); + bytes = Write_ALushort(device, buffer, SamplesToDo); + break; + case DevFmtInt: + bytes = Write_ALint(device, buffer, SamplesToDo); + break; + case DevFmtUInt: + bytes = Write_ALuint(device, buffer, SamplesToDo); break; case DevFmtFloat: - Write_ALfloat(device, buffer, SamplesToDo); + bytes = Write_ALfloat(device, buffer, SamplesToDo); break; } + + buffer = (ALubyte*)buffer + bytes; } size -= SamplesToDo; } - RestoreFPUMode(fpuState); + RestoreFPUMode(&oldMode); } @@ -1093,7 +1232,6 @@ ALvoid aluHandleDisconnect(ALCdevice *device) { ALCcontext *Context; - LockDevice(device); device->Connected = ALC_FALSE; Context = device->ContextList; @@ -1118,5 +1256,4 @@ ALvoid aluHandleDisconnect(ALCdevice *device) Context = Context->next; } - UnlockDevice(device); } diff --git a/jni/openal-soft-android/Alc/alcConfig.c b/jni/openal-soft-android/Alc/alcConfig.c index 012c677d..98c0df32 100644 --- a/jni/openal-soft-android/Alc/alcConfig.c +++ b/jni/openal-soft-android/Alc/alcConfig.c @@ -19,7 +19,7 @@ */ #ifdef _WIN32 -#ifdef __MINGW64__ +#ifdef __MINGW32__ #define _WIN32_IE 0x501 #else #define _WIN32_IE 0x400 @@ -45,161 +45,133 @@ typedef struct ConfigEntry { } ConfigEntry; typedef struct ConfigBlock { - char *name; ConfigEntry *entries; unsigned int entryCount; } ConfigBlock; -static ConfigBlock *cfgBlocks; -static unsigned int cfgCount; +static ConfigBlock cfgBlock; static char buffer[1024]; +static char *lstrip(char *line) +{ + while(isspace(line[0])) + line++; + return line; +} + +static char *rstrip(char *line) +{ + size_t len = strlen(line); + while(len > 0 && isspace(line[len-1])) + len--; + line[len] = 0; + return line; +} + static void LoadConfigFromFile(FILE *f) { - ConfigBlock *curBlock = cfgBlocks; + char curSection[128] = ""; ConfigEntry *ent; while(fgets(buffer, sizeof(buffer), f)) { - int i = 0; + char *line, *comment; + char key[256] = ""; + char value[256] = ""; - while(isspace(buffer[i])) - i++; - if(!buffer[i] || buffer[i] == '#') + comment = strchr(buffer, '#'); + if(comment) + { + *(comment++) = 0; + comment = rstrip(lstrip(comment)); + } + + line = rstrip(lstrip(buffer)); + if(!line[0]) continue; - memmove(buffer, buffer+i, strlen(buffer+i)+1); - - if(buffer[0] == '[') + if(line[0] == '[') { - ConfigBlock *nextBlock; - unsigned int i; + char *section = line+1; + char *endsection; - i = 1; - while(buffer[i] && buffer[i] != ']') - i++; - - if(!buffer[i]) + endsection = strchr(section, ']'); + if(!endsection || section == endsection || endsection[1] != 0) { - ERR("config parse error: bad line \"%s\"\n", buffer); + ERR("config parse error: bad line \"%s\"\n", line); continue; } - buffer[i] = 0; + *endsection = 0; - do { - i++; - if(buffer[i] && !isspace(buffer[i])) - { - if(buffer[i] != '#') - WARN("config warning: extra data after block: \"%s\"\n", buffer+i); - break; - } - } while(buffer[i]); - - nextBlock = NULL; - for(i = 0;i < cfgCount;i++) + if(strcasecmp(section, "general") == 0) + curSection[0] = 0; + else { - if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0) - { - nextBlock = cfgBlocks+i; - TRACE("found block '%s'\n", nextBlock->name); - break; - } + strncpy(curSection, section, sizeof(curSection)-1); + curSection[sizeof(curSection)-1] = 0; } - if(!nextBlock) - { - nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock)); - if(!nextBlock) - { - ERR("config parse error: error reallocating config blocks\n"); - continue; - } - cfgBlocks = nextBlock; - nextBlock = cfgBlocks+cfgCount; - cfgCount++; - - nextBlock->name = strdup(buffer+1); - nextBlock->entries = NULL; - nextBlock->entryCount = 0; - - TRACE("found new block '%s'\n", nextBlock->name); - } - curBlock = nextBlock; continue; } - /* Look for the option name */ - i = 0; - while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' && - !isspace(buffer[i])) - i++; - - if(!buffer[i] || buffer[i] == '#' || i == 0) + if(sscanf(line, "%255[^=] = \"%255[^\"]\"", key, value) == 2 || + sscanf(line, "%255[^=] = '%255[^\']'", key, value) == 2 || + sscanf(line, "%255[^=] = %255[^\n]", key, value) == 2) { - ERR("config parse error: malformed option line: \"%s\"\n", buffer); - continue; - } + /* sscanf doesn't handle '' or "" as empty values, so clip it + * manually. */ + if(strcmp(value, "\"\"") == 0 || strcmp(value, "''") == 0) + value[0] = 0; + } + else if(sscanf(line, "%255[^=] %255[=]", key, value) == 2) + { + /* Special case for 'key =' */ + value[0] = 0; + } + else + { + ERR("config parse error: malformed option line: \"%s\"\n\n", line); + continue; + } + rstrip(key); - /* Seperate the option */ - if(buffer[i] != '=') - { - buffer[i++] = 0; - - while(isspace(buffer[i])) - i++; - if(buffer[i] != '=') - { - ERR("config parse error: option without a value: \"%s\"\n", buffer); - continue; - } - } - /* Find the start of the value */ - buffer[i++] = 0; - while(isspace(buffer[i])) - i++; + if(curSection[0] != 0) + { + size_t len = strlen(curSection); + memmove(&key[len+1], key, sizeof(key)-1-len); + key[len] = '/'; + memcpy(key, curSection, len); + } /* Check if we already have this option set */ - ent = curBlock->entries; - while((unsigned int)(ent-curBlock->entries) < curBlock->entryCount) + ent = cfgBlock.entries; + while((unsigned int)(ent-cfgBlock.entries) < cfgBlock.entryCount) { - if(strcasecmp(ent->key, buffer) == 0) + if(strcasecmp(ent->key, key) == 0) break; ent++; } - if((unsigned int)(ent-curBlock->entries) >= curBlock->entryCount) + if((unsigned int)(ent-cfgBlock.entries) >= cfgBlock.entryCount) { /* Allocate a new option entry */ - ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry)); + ent = realloc(cfgBlock.entries, (cfgBlock.entryCount+1)*sizeof(ConfigEntry)); if(!ent) { ERR("config parse error: error reallocating config entries\n"); continue; } - curBlock->entries = ent; - ent = curBlock->entries + curBlock->entryCount; - curBlock->entryCount++; + cfgBlock.entries = ent; + ent = cfgBlock.entries + cfgBlock.entryCount; + cfgBlock.entryCount++; - ent->key = strdup(buffer); + ent->key = strdup(key); ent->value = NULL; } - /* Look for the end of the line (Null term, new-line, or #-symbol) and - eat up the trailing whitespace */ - memmove(buffer, buffer+i, strlen(buffer+i)+1); - - i = 0; - while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n') - i++; - do { - i--; - } while(i >= 0 && isspace(buffer[i])); - buffer[++i] = 0; - free(ent->value); - ent->value = strdup(buffer); + ent->value = strdup(value); TRACE("found '%s' = '%s'\n", ent->key, ent->value); } @@ -210,15 +182,13 @@ void ReadALConfig(void) const char *str; FILE *f; - cfgBlocks = calloc(1, sizeof(ConfigBlock)); - cfgBlocks->name = strdup("general"); - cfgCount = 1; - #ifdef _WIN32 if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE) { size_t p = strlen(buffer); snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini"); + + TRACE("Loading config %s...\n", buffer); f = fopen(buffer, "rt"); if(f) { @@ -227,15 +197,75 @@ void ReadALConfig(void) } } #else - f = fopen("/etc/openal/alsoft.conf", "r"); + str = "/etc/openal/alsoft.conf"; + + TRACE("Loading config %s...\n", str); + f = fopen(str, "r"); if(f) { LoadConfigFromFile(f); fclose(f); } + + if(!(str=getenv("XDG_CONFIG_DIRS")) || str[0] == 0) + str = "/etc/xdg"; + strncpy(buffer, str, sizeof(buffer)-1); + buffer[sizeof(buffer)-1] = 0; + /* Go through the list in reverse, since "the order of base directories + * denotes their importance; the first directory listed is the most + * important". Ergo, we need to load the settings from the later dirs + * first so that the settings in the earlier dirs override them. + */ + while(1) + { + char *next = strrchr(buffer, ':'); + if(next) *(next++) = 0; + else next = buffer; + + if(next[0] != '/') + WARN("Ignoring XDG config dir: %s\n", next); + else + { + size_t len = strlen(next); + strncpy(next+len, "/alsoft.conf", buffer+sizeof(buffer)-next-len); + buffer[sizeof(buffer)-1] = 0; + + TRACE("Loading config %s...\n", next); + f = fopen(next, "r"); + if(f) + { + LoadConfigFromFile(f); + fclose(f); + } + } + if(next == buffer) + break; + } + if((str=getenv("HOME")) != NULL && *str) { snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", str); + + TRACE("Loading config %s...\n", buffer); + f = fopen(buffer, "r"); + if(f) + { + LoadConfigFromFile(f); + fclose(f); + } + } + + if((str=getenv("XDG_CONFIG_HOME")) != NULL && str[0] != 0) + snprintf(buffer, sizeof(buffer), "%s/%s", str, "alsoft.conf"); + else + { + buffer[0] = 0; + if((str=getenv("HOME")) != NULL && str[0] != 0) + snprintf(buffer, sizeof(buffer), "%s/.config/%s", str, "alsoft.conf"); + } + if(buffer[0] != 0) + { + TRACE("Loading config %s...\n", buffer); f = fopen(buffer, "r"); if(f) { @@ -244,8 +274,10 @@ void ReadALConfig(void) } } #endif + if((str=getenv("ALSOFT_CONF")) != NULL && *str) { + TRACE("Loading config %s...\n", str); f = fopen(str, "r"); if(f) { @@ -259,51 +291,42 @@ void FreeALConfig(void) { unsigned int i; - for(i = 0;i < cfgCount;i++) + for(i = 0;i < cfgBlock.entryCount;i++) { - unsigned int j; - for(j = 0;j < cfgBlocks[i].entryCount;j++) - { - free(cfgBlocks[i].entries[j].key); - free(cfgBlocks[i].entries[j].value); - } - free(cfgBlocks[i].entries); - free(cfgBlocks[i].name); + free(cfgBlock.entries[i].key); + free(cfgBlock.entries[i].value); } - free(cfgBlocks); - cfgBlocks = NULL; - cfgCount = 0; + free(cfgBlock.entries); } const char *GetConfigValue(const char *blockName, const char *keyName, const char *def) { - unsigned int i, j; + unsigned int i; + char key[256]; if(!keyName) return def; - if(!blockName) - blockName = "general"; - - for(i = 0;i < cfgCount;i++) + if(blockName && strcasecmp(blockName, "general") != 0) + snprintf(key, sizeof(key), "%s/%s", blockName, keyName); + else { - if(strcasecmp(cfgBlocks[i].name, blockName) != 0) - continue; + strncpy(key, keyName, sizeof(key)-1); + key[sizeof(key)-1] = 0; + } - for(j = 0;j < cfgBlocks[i].entryCount;j++) + for(i = 0;i < cfgBlock.entryCount;i++) + { + if(strcasecmp(cfgBlock.entries[i].key, key) == 0) { - if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0) - { - TRACE("Found %s:%s = \"%s\"\n", blockName, keyName, - cfgBlocks[i].entries[j].value); - if(cfgBlocks[i].entries[j].value[0]) - return cfgBlocks[i].entries[j].value; - return def; - } + TRACE("Found %s = \"%s\"\n", key, cfgBlock.entries[i].value); + if(cfgBlock.entries[i].value[0]) + return cfgBlock.entries[i].value; + return def; } } - TRACE("Key %s:%s not found\n", blockName, keyName); + TRACE("Key %s not found\n", key); return def; } diff --git a/jni/openal-soft-android/Alc/alcDedicated.c b/jni/openal-soft-android/Alc/alcDedicated.c deleted file mode 100644 index a371bb20..00000000 --- a/jni/openal-soft-android/Alc/alcDedicated.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2011 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALdedicatedState { - // Must be first in all effects! - ALeffectState state; - - ALfloat gains[MAXCHANNELS]; -} ALdedicatedState; - - -static ALvoid DedicatedDestroy(ALeffectState *effect) -{ - ALdedicatedState *state = (ALdedicatedState*)effect; - free(state); -} - -static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device) -{ - (void)effect; - (void)Device; - return AL_TRUE; -} - -static ALvoid DedicatedUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot) -{ - ALdedicatedState *state = (ALdedicatedState*)effect; - ALCdevice *device = Context->Device; - const ALfloat *SpeakerGain; - ALfloat Gain; - ALint pos; - ALsizei s; - - Gain = Slot->Gain * Slot->effect.Dedicated.Gain; - for(s = 0;s < MAXCHANNELS;s++) - state->gains[s] = 0.0f; - - if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE) - { - pos = aluCart2LUTpos(1.0f, 0.0f); - SpeakerGain = device->PanningLUT[pos]; - - for(s = 0;s < MAXCHANNELS;s++) - state->gains[s] = SpeakerGain[s] * Gain; - } - else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) - state->gains[LFE] = Gain; -} - -static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) -{ - ALdedicatedState *state = (ALdedicatedState*)effect; - const ALfloat *gains = state->gains; - ALuint i, s; - - for(i = 0;i < SamplesToDo;i++) - { - ALfloat sample; - - sample = SamplesIn[i]; - for(s = 0;s < MAXCHANNELS;s++) - SamplesOut[i][s] = sample * gains[s]; - } -} - -ALeffectState *DedicatedCreate(void) -{ - ALdedicatedState *state; - ALsizei s; - - state = malloc(sizeof(*state)); - if(!state) - return NULL; - - state->state.Destroy = DedicatedDestroy; - state->state.DeviceUpdate = DedicatedDeviceUpdate; - state->state.Update = DedicatedUpdate; - state->state.Process = DedicatedProcess; - - for(s = 0;s < MAXCHANNELS;s++) - state->gains[s] = 0.0f; - - return &state->state; -} diff --git a/jni/openal-soft-android/Alc/alcEcho.c b/jni/openal-soft-android/Alc/alcEcho.c deleted file mode 100644 index 9bfb19b3..00000000 --- a/jni/openal-soft-android/Alc/alcEcho.c +++ /dev/null @@ -1,191 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2009 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALechoState { - // Must be first in all effects! - ALeffectState state; - - ALfloat *SampleBuffer; - ALuint BufferLength; - - // The echo is two tap. The delay is the number of samples from before the - // current offset - struct { - ALuint delay; - } Tap[2]; - ALuint Offset; - // The LR gains for the first tap. The second tap uses the reverse - ALfloat GainL; - ALfloat GainR; - - ALfloat FeedGain; - - ALfloat Gain[MAXCHANNELS]; - - FILTER iirFilter; - ALfloat history[2]; -} ALechoState; - -static ALvoid EchoDestroy(ALeffectState *effect) -{ - ALechoState *state = (ALechoState*)effect; - if(state) - { - free(state->SampleBuffer); - state->SampleBuffer = NULL; - free(state); - } -} - -static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) -{ - ALechoState *state = (ALechoState*)effect; - ALuint maxlen, i; - - // Use the next power of 2 for the buffer length, so the tap offsets can be - // wrapped using a mask instead of a modulo - maxlen = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1; - maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1; - maxlen = NextPowerOf2(maxlen); - - if(maxlen != state->BufferLength) - { - void *temp; - - temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat)); - if(!temp) - return AL_FALSE; - state->SampleBuffer = temp; - state->BufferLength = maxlen; - } - for(i = 0;i < state->BufferLength;i++) - state->SampleBuffer[i] = 0.0f; - - return AL_TRUE; -} - -static ALvoid EchoUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot) -{ - ALechoState *state = (ALechoState*)effect; - ALCdevice *Device = Context->Device; - ALuint frequency = Device->Frequency; - ALfloat lrpan, cw, g, gain; - ALuint i; - - state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1; - state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency); - state->Tap[1].delay += state->Tap[0].delay; - - lrpan = Slot->effect.Echo.Spread*0.5f + 0.5f; - state->GainL = aluSqrt( lrpan); - state->GainR = aluSqrt(1.0f-lrpan); - - state->FeedGain = Slot->effect.Echo.Feedback; - - cw = aluCos(F_PI*2.0f * LOWPASSFREQREF / frequency); - g = 1.0f - Slot->effect.Echo.Damping; - state->iirFilter.coeff = lpCoeffCalc(g, cw); - - gain = Slot->Gain; - for(i = 0;i < MAXCHANNELS;i++) - state->Gain[i] = 0.0f; - for(i = 0;i < Device->NumChan;i++) - { - enum Channel chan = Device->Speaker2Chan[i]; - state->Gain[chan] = gain; - } -} - -static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) -{ - ALechoState *state = (ALechoState*)effect; - const ALuint mask = state->BufferLength-1; - const ALuint tap1 = state->Tap[0].delay; - const ALuint tap2 = state->Tap[1].delay; - ALuint offset = state->Offset; - ALfloat samp[2], smp; - ALuint i; - - for(i = 0;i < SamplesToDo;i++,offset++) - { - // Sample first tap - smp = state->SampleBuffer[(offset-tap1) & mask]; - samp[0] = smp * state->GainL; - samp[1] = smp * state->GainR; - // Sample second tap. Reverse LR panning - smp = state->SampleBuffer[(offset-tap2) & mask]; - samp[0] += smp * state->GainR; - samp[1] += smp * state->GainL; - - // Apply damping and feedback gain to the second tap, and mix in the - // new sample - smp = lpFilter2P(&state->iirFilter, 0, smp+SamplesIn[i]); - state->SampleBuffer[offset&mask] = smp * state->FeedGain; - - SamplesOut[i][FRONT_LEFT] += state->Gain[FRONT_LEFT] * samp[0]; - SamplesOut[i][FRONT_RIGHT] += state->Gain[FRONT_RIGHT] * samp[1]; - SamplesOut[i][SIDE_LEFT] += state->Gain[SIDE_LEFT] * samp[0]; - SamplesOut[i][SIDE_RIGHT] += state->Gain[SIDE_RIGHT] * samp[1]; - SamplesOut[i][BACK_LEFT] += state->Gain[BACK_LEFT] * samp[0]; - SamplesOut[i][BACK_RIGHT] += state->Gain[BACK_RIGHT] * samp[1]; - } - state->Offset = offset; -} - -ALeffectState *EchoCreate(void) -{ - ALechoState *state; - - state = malloc(sizeof(*state)); - if(!state) - return NULL; - - state->state.Destroy = EchoDestroy; - state->state.DeviceUpdate = EchoDeviceUpdate; - state->state.Update = EchoUpdate; - state->state.Process = EchoProcess; - - state->BufferLength = 0; - state->SampleBuffer = NULL; - - state->Tap[0].delay = 0; - state->Tap[1].delay = 0; - state->Offset = 0; - state->GainL = 0.0f; - state->GainR = 0.0f; - - state->iirFilter.coeff = 0.0f; - state->iirFilter.history[0] = 0.0f; - state->iirFilter.history[1] = 0.0f; - - return &state->state; -} diff --git a/jni/openal-soft-android/Alc/alcModulator.c b/jni/openal-soft-android/Alc/alcModulator.c deleted file mode 100644 index d955f103..00000000 --- a/jni/openal-soft-android/Alc/alcModulator.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2009 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALmodulatorState { - // Must be first in all effects! - ALeffectState state; - - enum { - SINUSOID, - SAWTOOTH, - SQUARE - } Waveform; - - ALuint index; - ALuint step; - - ALfloat Gain[MAXCHANNELS]; - - FILTER iirFilter; - ALfloat history[1]; -} ALmodulatorState; - -#define WAVEFORM_FRACBITS 16 -#define WAVEFORM_FRACONE (1<>(WAVEFORM_FRACBITS-1))&1)*2.0f - 1.0f; -} - - -static __inline ALfloat hpFilter1P(FILTER *iir, ALuint offset, ALfloat input) -{ - ALfloat *history = &iir->history[offset]; - ALfloat a = iir->coeff; - ALfloat output = input; - - output = output + (history[0]-output)*a; - history[0] = output; - - return input - output; -} - - -#define DECL_TEMPLATE(func) \ -static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ - const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) \ -{ \ - const ALuint step = state->step; \ - ALuint index = state->index; \ - ALfloat samp; \ - ALuint i; \ - \ - for(i = 0;i < SamplesToDo;i++) \ - { \ - samp = SamplesIn[i]; \ - \ - index += step; \ - index &= WAVEFORM_FRACMASK; \ - samp *= func(index); \ - \ - samp = hpFilter1P(&state->iirFilter, 0, samp); \ - \ - SamplesOut[i][FRONT_LEFT] += state->Gain[FRONT_LEFT] * samp; \ - SamplesOut[i][FRONT_RIGHT] += state->Gain[FRONT_RIGHT] * samp; \ - SamplesOut[i][FRONT_CENTER] += state->Gain[FRONT_CENTER] * samp; \ - SamplesOut[i][SIDE_LEFT] += state->Gain[SIDE_LEFT] * samp; \ - SamplesOut[i][SIDE_RIGHT] += state->Gain[SIDE_RIGHT] * samp; \ - SamplesOut[i][BACK_LEFT] += state->Gain[BACK_LEFT] * samp; \ - SamplesOut[i][BACK_RIGHT] += state->Gain[BACK_RIGHT] * samp; \ - SamplesOut[i][BACK_CENTER] += state->Gain[BACK_CENTER] * samp; \ - } \ - state->index = index; \ -} - -DECL_TEMPLATE(Sin) -DECL_TEMPLATE(Saw) -DECL_TEMPLATE(Square) - -#undef DECL_TEMPLATE - - -static ALvoid ModulatorDestroy(ALeffectState *effect) -{ - ALmodulatorState *state = (ALmodulatorState*)effect; - free(state); -} - -static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device) -{ - return AL_TRUE; - (void)effect; - (void)Device; -} - -static ALvoid ModulatorUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot) -{ - ALmodulatorState *state = (ALmodulatorState*)effect; - ALCdevice *Device = Context->Device; - ALfloat gain, cw, a = 0.0f; - ALuint index; - - if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) - state->Waveform = SINUSOID; - else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) - state->Waveform = SAWTOOTH; - else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SQUARE) - state->Waveform = SQUARE; - - state->step = fastf2u(Slot->effect.Modulator.Frequency*WAVEFORM_FRACONE / - Device->Frequency); - if(state->step == 0) state->step = 1; - - cw = aluCos(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff / - Device->Frequency); - a = (2.0f-cw) - aluSqrt(aluPow(2.0f-cw, 2.0f) - 1.0f); - state->iirFilter.coeff = a; - - gain = Slot->Gain; - for(index = 0;index < MAXCHANNELS;index++) - state->Gain[index] = 0.0f; - for(index = 0;index < Device->NumChan;index++) - { - enum Channel chan = Device->Speaker2Chan[index]; - state->Gain[chan] = gain; - } -} - -static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) -{ - ALmodulatorState *state = (ALmodulatorState*)effect; - - switch(state->Waveform) - { - case SINUSOID: - ProcessSin(state, SamplesToDo, SamplesIn, SamplesOut); - break; - - case SAWTOOTH: - ProcessSaw(state, SamplesToDo, SamplesIn, SamplesOut); - break; - - case SQUARE: - ProcessSquare(state, SamplesToDo, SamplesIn, SamplesOut); - break; - } -} - -ALeffectState *ModulatorCreate(void) -{ - ALmodulatorState *state; - - state = malloc(sizeof(*state)); - if(!state) - return NULL; - - state->state.Destroy = ModulatorDestroy; - state->state.DeviceUpdate = ModulatorDeviceUpdate; - state->state.Update = ModulatorUpdate; - state->state.Process = ModulatorProcess; - - state->index = 0; - state->step = 1; - - state->iirFilter.coeff = 0.0f; - state->iirFilter.history[0] = 0.0f; - - return &state->state; -} diff --git a/jni/openal-soft-android/Alc/alcRing.c b/jni/openal-soft-android/Alc/alcRing.c index 2d9d5069..f831860f 100644 --- a/jni/openal-soft-android/Alc/alcRing.c +++ b/jni/openal-soft-android/Alc/alcRing.c @@ -24,6 +24,7 @@ #include #include "alMain.h" +#include "compat.h" struct RingBuffer { diff --git a/jni/openal-soft-android/Alc/alcThread.c b/jni/openal-soft-android/Alc/alcThread.c deleted file mode 100644 index 582dfd8c..00000000 --- a/jni/openal-soft-android/Alc/alcThread.c +++ /dev/null @@ -1,128 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alThunk.h" - - -#ifdef _WIN32 - -typedef struct { - ALuint (*func)(ALvoid*); - ALvoid *ptr; - HANDLE thread; -} ThreadInfo; - -static DWORD CALLBACK StarterFunc(void *ptr) -{ - ThreadInfo *inf = (ThreadInfo*)ptr; - ALint ret; - - ret = inf->func(inf->ptr); - ExitThread((DWORD)ret); - - return (DWORD)ret; -} - -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr) -{ - DWORD dummy; - ThreadInfo *inf = malloc(sizeof(ThreadInfo)); - if(!inf) return 0; - - inf->func = func; - inf->ptr = ptr; - - inf->thread = CreateThread(NULL, 0, StarterFunc, inf, 0, &dummy); - if(!inf->thread) - { - free(inf); - return NULL; - } - - return inf; -} - -ALuint StopThread(ALvoid *thread) -{ - ThreadInfo *inf = thread; - DWORD ret = 0; - - WaitForSingleObject(inf->thread, INFINITE); - GetExitCodeThread(inf->thread, &ret); - CloseHandle(inf->thread); - - free(inf); - - return (ALuint)ret; -} - -#else - -#include - -typedef struct { - ALuint (*func)(ALvoid*); - ALvoid *ptr; - ALuint ret; - pthread_t thread; -} ThreadInfo; - -static void *StarterFunc(void *ptr) -{ - ThreadInfo *inf = (ThreadInfo*)ptr; - inf->ret = inf->func(inf->ptr); - return NULL; -} - -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr) -{ - ThreadInfo *inf = malloc(sizeof(ThreadInfo)); - if(!inf) return NULL; - - inf->func = func; - inf->ptr = ptr; - if(pthread_create(&inf->thread, NULL, StarterFunc, inf) != 0) - { - free(inf); - return NULL; - } - - return inf; -} - -ALuint StopThread(ALvoid *thread) -{ - ThreadInfo *inf = thread; - ALuint ret; - - pthread_join(inf->thread, NULL); - ret = inf->ret; - - free(inf); - - return ret; -} - -#endif diff --git a/jni/openal-soft-android/Alc/atomic.h b/jni/openal-soft-android/Alc/atomic.h new file mode 100644 index 00000000..1dd8f9dc --- /dev/null +++ b/jni/openal-soft-android/Alc/atomic.h @@ -0,0 +1,180 @@ +#ifndef AL_ATOMIC_H +#define AL_ATOMIC_H + + +typedef void *volatile XchgPtr; + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__QNXNTO__) +typedef unsigned int RefCount; +inline RefCount IncrementRef(volatile RefCount *ptr) +{ return __sync_add_and_fetch(ptr, 1); } +inline RefCount DecrementRef(volatile RefCount *ptr) +{ return __sync_sub_and_fetch(ptr, 1); } + +inline int ExchangeInt(volatile int *ptr, int newval) +{ + return __sync_lock_test_and_set(ptr, newval); +} +inline void *ExchangePtr(XchgPtr *ptr, void *newval) +{ + return __sync_lock_test_and_set(ptr, newval); +} +inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) +{ + return __sync_bool_compare_and_swap(ptr, oldval, newval); +} +inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval) +{ + return __sync_bool_compare_and_swap(ptr, oldval, newval); +} + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + +inline unsigned int xaddl(volatile unsigned int *dest, int incr) +{ + unsigned int ret; + __asm__ __volatile__("lock; xaddl %0,(%1)" + : "=r" (ret) + : "r" (dest), "0" (incr) + : "memory"); + return ret; +} + +typedef unsigned int RefCount; +inline RefCount IncrementRef(volatile RefCount *ptr) +{ return xaddl(ptr, 1)+1; } +inline RefCount DecrementRef(volatile RefCount *ptr) +{ return xaddl(ptr, -1)-1; } + +inline int ExchangeInt(volatile int *dest, int newval) +{ + int ret; + __asm__ __volatile__("lock; xchgl %0,(%1)" + : "=r" (ret) + : "r" (dest), "0" (newval) + : "memory"); + return ret; +} + +inline ALboolean CompExchangeInt(volatile int *dest, int oldval, int newval) +{ + int ret; + __asm__ __volatile__("lock; cmpxchgl %2,(%1)" + : "=a" (ret) + : "r" (dest), "r" (newval), "0" (oldval) + : "memory"); + return ret == oldval; +} + +inline void *ExchangePtr(XchgPtr *dest, void *newval) +{ + void *ret; + __asm__ __volatile__( +#ifdef __i386__ + "lock; xchgl %0,(%1)" +#else + "lock; xchgq %0,(%1)" +#endif + : "=r" (ret) + : "r" (dest), "0" (newval) + : "memory" + ); + return ret; +} + +inline ALboolean CompExchangePtr(XchgPtr *dest, void *oldval, void *newval) +{ + void *ret; + __asm__ __volatile__( +#ifdef __i386__ + "lock; cmpxchgl %2,(%1)" +#else + "lock; cmpxchgq %2,(%1)" +#endif + : "=a" (ret) + : "r" (dest), "r" (newval), "0" (oldval) + : "memory" + ); + return ret == oldval; +} + +#elif defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include + +typedef LONG RefCount; +inline RefCount IncrementRef(volatile RefCount *ptr) +{ return InterlockedIncrement(ptr); } +inline RefCount DecrementRef(volatile RefCount *ptr) +{ return InterlockedDecrement(ptr); } + +extern ALbyte LONG_size_does_not_match_int[(sizeof(LONG)==sizeof(int))?1:-1]; + +inline int ExchangeInt(volatile int *ptr, int newval) +{ + union { + volatile int *i; + volatile LONG *l; + } u = { ptr }; + return InterlockedExchange(u.l, newval); +} +inline void *ExchangePtr(XchgPtr *ptr, void *newval) +{ + return InterlockedExchangePointer(ptr, newval); +} +inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) +{ + union { + volatile int *i; + volatile LONG *l; + } u = { ptr }; + return InterlockedCompareExchange(u.l, newval, oldval) == oldval; +} +inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval) +{ + return InterlockedCompareExchangePointer(ptr, newval, oldval) == oldval; +} + +#elif defined(__APPLE__) + +#include + +typedef int32_t RefCount; +inline RefCount IncrementRef(volatile RefCount *ptr) +{ return OSAtomicIncrement32Barrier(ptr); } +inline RefCount DecrementRef(volatile RefCount *ptr) +{ return OSAtomicDecrement32Barrier(ptr); } + +inline int ExchangeInt(volatile int *ptr, int newval) +{ + /* Really? No regular old atomic swap? */ + int oldval; + do { + oldval = *ptr; + } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr)); + return oldval; +} +inline void *ExchangePtr(XchgPtr *ptr, void *newval) +{ + void *oldval; + do { + oldval = *ptr; + } while(!OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr)); + return oldval; +} +inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) +{ + return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); +} +inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval) +{ + return OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr); +} + +#else +#error "No atomic functions available on this platform!" +typedef ALuint RefCount; +#endif + +#endif /* AL_ATOMIC_H */ diff --git a/jni/openal-soft-android/Alc/backends/alsa.c b/jni/openal-soft-android/Alc/backends/alsa.c index b99fd147..874b31c3 100644 --- a/jni/openal-soft-android/Alc/backends/alsa.c +++ b/jni/openal-soft-android/Alc/backends/alsa.c @@ -25,6 +25,11 @@ #include #include "alMain.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" + +#include "backends/base.h" #include @@ -32,69 +37,84 @@ static const ALCchar alsaDevice[] = "ALSA Default"; -static void *alsa_handle; #ifdef HAVE_DYNLOAD -#define MAKE_FUNC(f) static typeof(f) * p##f -MAKE_FUNC(snd_strerror); -MAKE_FUNC(snd_pcm_open); -MAKE_FUNC(snd_pcm_close); -MAKE_FUNC(snd_pcm_nonblock); -MAKE_FUNC(snd_pcm_frames_to_bytes); -MAKE_FUNC(snd_pcm_bytes_to_frames); -MAKE_FUNC(snd_pcm_hw_params_malloc); -MAKE_FUNC(snd_pcm_hw_params_free); -MAKE_FUNC(snd_pcm_hw_params_any); -MAKE_FUNC(snd_pcm_hw_params_set_access); -MAKE_FUNC(snd_pcm_hw_params_set_format); -MAKE_FUNC(snd_pcm_hw_params_set_channels); -MAKE_FUNC(snd_pcm_hw_params_set_periods_near); -MAKE_FUNC(snd_pcm_hw_params_set_rate_near); -MAKE_FUNC(snd_pcm_hw_params_set_rate); -MAKE_FUNC(snd_pcm_hw_params_set_rate_resample); -MAKE_FUNC(snd_pcm_hw_params_set_buffer_time_near); -MAKE_FUNC(snd_pcm_hw_params_set_period_time_near); -MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_near); -MAKE_FUNC(snd_pcm_hw_params_set_period_size_near); -MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_min); -MAKE_FUNC(snd_pcm_hw_params_get_buffer_size); -MAKE_FUNC(snd_pcm_hw_params_get_period_size); -MAKE_FUNC(snd_pcm_hw_params_get_access); -MAKE_FUNC(snd_pcm_hw_params_get_periods); -MAKE_FUNC(snd_pcm_hw_params); -MAKE_FUNC(snd_pcm_sw_params_malloc); -MAKE_FUNC(snd_pcm_sw_params_current); -MAKE_FUNC(snd_pcm_sw_params_set_avail_min); -MAKE_FUNC(snd_pcm_sw_params); -MAKE_FUNC(snd_pcm_sw_params_free); -MAKE_FUNC(snd_pcm_prepare); -MAKE_FUNC(snd_pcm_start); -MAKE_FUNC(snd_pcm_resume); -MAKE_FUNC(snd_pcm_wait); -MAKE_FUNC(snd_pcm_state); -MAKE_FUNC(snd_pcm_avail_update); -MAKE_FUNC(snd_pcm_areas_silence); -MAKE_FUNC(snd_pcm_mmap_begin); -MAKE_FUNC(snd_pcm_mmap_commit); -MAKE_FUNC(snd_pcm_readi); -MAKE_FUNC(snd_pcm_writei); -MAKE_FUNC(snd_pcm_drain); -MAKE_FUNC(snd_pcm_recover); -MAKE_FUNC(snd_pcm_info_malloc); -MAKE_FUNC(snd_pcm_info_free); -MAKE_FUNC(snd_pcm_info_set_device); -MAKE_FUNC(snd_pcm_info_set_subdevice); -MAKE_FUNC(snd_pcm_info_set_stream); -MAKE_FUNC(snd_pcm_info_get_name); -MAKE_FUNC(snd_ctl_pcm_next_device); -MAKE_FUNC(snd_ctl_pcm_info); -MAKE_FUNC(snd_ctl_open); -MAKE_FUNC(snd_ctl_close); -MAKE_FUNC(snd_ctl_card_info_malloc); -MAKE_FUNC(snd_ctl_card_info_free); -MAKE_FUNC(snd_ctl_card_info); -MAKE_FUNC(snd_ctl_card_info_get_name); -MAKE_FUNC(snd_ctl_card_info_get_id); -MAKE_FUNC(snd_card_next); +#define ALSA_FUNCS(MAGIC) \ + MAGIC(snd_strerror); \ + MAGIC(snd_pcm_open); \ + MAGIC(snd_pcm_close); \ + MAGIC(snd_pcm_nonblock); \ + MAGIC(snd_pcm_frames_to_bytes); \ + MAGIC(snd_pcm_bytes_to_frames); \ + MAGIC(snd_pcm_hw_params_malloc); \ + MAGIC(snd_pcm_hw_params_free); \ + MAGIC(snd_pcm_hw_params_any); \ + MAGIC(snd_pcm_hw_params_current); \ + MAGIC(snd_pcm_hw_params_set_access); \ + MAGIC(snd_pcm_hw_params_set_format); \ + MAGIC(snd_pcm_hw_params_set_channels); \ + MAGIC(snd_pcm_hw_params_set_periods_near); \ + MAGIC(snd_pcm_hw_params_set_rate_near); \ + MAGIC(snd_pcm_hw_params_set_rate); \ + MAGIC(snd_pcm_hw_params_set_rate_resample); \ + MAGIC(snd_pcm_hw_params_set_buffer_time_near); \ + MAGIC(snd_pcm_hw_params_set_period_time_near); \ + MAGIC(snd_pcm_hw_params_set_buffer_size_near); \ + MAGIC(snd_pcm_hw_params_set_period_size_near); \ + MAGIC(snd_pcm_hw_params_set_buffer_size_min); \ + MAGIC(snd_pcm_hw_params_get_buffer_time_min); \ + MAGIC(snd_pcm_hw_params_get_buffer_time_max); \ + MAGIC(snd_pcm_hw_params_get_period_time_min); \ + MAGIC(snd_pcm_hw_params_get_period_time_max); \ + MAGIC(snd_pcm_hw_params_get_buffer_size); \ + MAGIC(snd_pcm_hw_params_get_period_size); \ + MAGIC(snd_pcm_hw_params_get_access); \ + MAGIC(snd_pcm_hw_params_get_periods); \ + MAGIC(snd_pcm_hw_params_test_format); \ + MAGIC(snd_pcm_hw_params_test_channels); \ + MAGIC(snd_pcm_hw_params); \ + MAGIC(snd_pcm_sw_params_malloc); \ + MAGIC(snd_pcm_sw_params_current); \ + MAGIC(snd_pcm_sw_params_set_avail_min); \ + MAGIC(snd_pcm_sw_params_set_stop_threshold); \ + MAGIC(snd_pcm_sw_params); \ + MAGIC(snd_pcm_sw_params_free); \ + MAGIC(snd_pcm_prepare); \ + MAGIC(snd_pcm_start); \ + MAGIC(snd_pcm_resume); \ + MAGIC(snd_pcm_reset); \ + MAGIC(snd_pcm_wait); \ + MAGIC(snd_pcm_delay); \ + MAGIC(snd_pcm_state); \ + MAGIC(snd_pcm_avail_update); \ + MAGIC(snd_pcm_areas_silence); \ + MAGIC(snd_pcm_mmap_begin); \ + MAGIC(snd_pcm_mmap_commit); \ + MAGIC(snd_pcm_readi); \ + MAGIC(snd_pcm_writei); \ + MAGIC(snd_pcm_drain); \ + MAGIC(snd_pcm_drop); \ + MAGIC(snd_pcm_recover); \ + MAGIC(snd_pcm_info_malloc); \ + MAGIC(snd_pcm_info_free); \ + MAGIC(snd_pcm_info_set_device); \ + MAGIC(snd_pcm_info_set_subdevice); \ + MAGIC(snd_pcm_info_set_stream); \ + MAGIC(snd_pcm_info_get_name); \ + MAGIC(snd_ctl_pcm_next_device); \ + MAGIC(snd_ctl_pcm_info); \ + MAGIC(snd_ctl_open); \ + MAGIC(snd_ctl_close); \ + MAGIC(snd_ctl_card_info_malloc); \ + MAGIC(snd_ctl_card_info_free); \ + MAGIC(snd_ctl_card_info); \ + MAGIC(snd_ctl_card_info_get_name); \ + MAGIC(snd_ctl_card_info_get_id); \ + MAGIC(snd_card_next); \ + MAGIC(snd_config_update_free_global) + +static void *alsa_handle; +#define MAKE_FUNC(f) static __typeof(f) * p##f +ALSA_FUNCS(MAKE_FUNC); #undef MAKE_FUNC #define snd_strerror psnd_strerror @@ -106,6 +126,7 @@ MAKE_FUNC(snd_card_next); #define snd_pcm_hw_params_malloc psnd_pcm_hw_params_malloc #define snd_pcm_hw_params_free psnd_pcm_hw_params_free #define snd_pcm_hw_params_any psnd_pcm_hw_params_any +#define snd_pcm_hw_params_current psnd_pcm_hw_params_current #define snd_pcm_hw_params_set_access psnd_pcm_hw_params_set_access #define snd_pcm_hw_params_set_format psnd_pcm_hw_params_set_format #define snd_pcm_hw_params_set_channels psnd_pcm_hw_params_set_channels @@ -118,20 +139,29 @@ MAKE_FUNC(snd_card_next); #define snd_pcm_hw_params_set_buffer_size_near psnd_pcm_hw_params_set_buffer_size_near #define snd_pcm_hw_params_set_period_size_near psnd_pcm_hw_params_set_period_size_near #define snd_pcm_hw_params_set_buffer_size_min psnd_pcm_hw_params_set_buffer_size_min +#define snd_pcm_hw_params_get_buffer_time_min psnd_pcm_hw_params_get_buffer_time_min +#define snd_pcm_hw_params_get_buffer_time_max psnd_pcm_hw_params_get_buffer_time_max +#define snd_pcm_hw_params_get_period_time_min psnd_pcm_hw_params_get_period_time_min +#define snd_pcm_hw_params_get_period_time_max psnd_pcm_hw_params_get_period_time_max #define snd_pcm_hw_params_get_buffer_size psnd_pcm_hw_params_get_buffer_size #define snd_pcm_hw_params_get_period_size psnd_pcm_hw_params_get_period_size #define snd_pcm_hw_params_get_access psnd_pcm_hw_params_get_access #define snd_pcm_hw_params_get_periods psnd_pcm_hw_params_get_periods +#define snd_pcm_hw_params_test_format psnd_pcm_hw_params_test_format +#define snd_pcm_hw_params_test_channels psnd_pcm_hw_params_test_channels #define snd_pcm_hw_params psnd_pcm_hw_params #define snd_pcm_sw_params_malloc psnd_pcm_sw_params_malloc #define snd_pcm_sw_params_current psnd_pcm_sw_params_current #define snd_pcm_sw_params_set_avail_min psnd_pcm_sw_params_set_avail_min +#define snd_pcm_sw_params_set_stop_threshold psnd_pcm_sw_params_set_stop_threshold #define snd_pcm_sw_params psnd_pcm_sw_params #define snd_pcm_sw_params_free psnd_pcm_sw_params_free #define snd_pcm_prepare psnd_pcm_prepare #define snd_pcm_start psnd_pcm_start #define snd_pcm_resume psnd_pcm_resume +#define snd_pcm_reset psnd_pcm_reset #define snd_pcm_wait psnd_pcm_wait +#define snd_pcm_delay psnd_pcm_delay #define snd_pcm_state psnd_pcm_state #define snd_pcm_avail_update psnd_pcm_avail_update #define snd_pcm_areas_silence psnd_pcm_areas_silence @@ -140,6 +170,7 @@ MAKE_FUNC(snd_card_next); #define snd_pcm_readi psnd_pcm_readi #define snd_pcm_writei psnd_pcm_writei #define snd_pcm_drain psnd_pcm_drain +#define snd_pcm_drop psnd_pcm_drop #define snd_pcm_recover psnd_pcm_recover #define snd_pcm_info_malloc psnd_pcm_info_malloc #define snd_pcm_info_free psnd_pcm_info_free @@ -157,112 +188,47 @@ MAKE_FUNC(snd_card_next); #define snd_ctl_card_info_get_name psnd_ctl_card_info_get_name #define snd_ctl_card_info_get_id psnd_ctl_card_info_get_id #define snd_card_next psnd_card_next +#define snd_config_update_free_global psnd_config_update_free_global #endif static ALCboolean alsa_load(void) { + ALCboolean error = ALC_FALSE; + +#ifdef HAVE_DYNLOAD if(!alsa_handle) { -#ifdef HAVE_DYNLOAD alsa_handle = LoadLib("libasound.so.2"); if(!alsa_handle) return ALC_FALSE; + error = ALC_FALSE; #define LOAD_FUNC(f) do { \ p##f = GetSymbol(alsa_handle, #f); \ if(p##f == NULL) { \ - CloseLib(alsa_handle); \ - alsa_handle = NULL; \ - return ALC_FALSE; \ + error = ALC_TRUE; \ } \ } while(0) - LOAD_FUNC(snd_strerror); - LOAD_FUNC(snd_pcm_open); - LOAD_FUNC(snd_pcm_close); - LOAD_FUNC(snd_pcm_nonblock); - LOAD_FUNC(snd_pcm_frames_to_bytes); - LOAD_FUNC(snd_pcm_bytes_to_frames); - LOAD_FUNC(snd_pcm_hw_params_malloc); - LOAD_FUNC(snd_pcm_hw_params_free); - LOAD_FUNC(snd_pcm_hw_params_any); - LOAD_FUNC(snd_pcm_hw_params_set_access); - LOAD_FUNC(snd_pcm_hw_params_set_format); - LOAD_FUNC(snd_pcm_hw_params_set_channels); - LOAD_FUNC(snd_pcm_hw_params_set_periods_near); - LOAD_FUNC(snd_pcm_hw_params_set_rate_near); - LOAD_FUNC(snd_pcm_hw_params_set_rate); - LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); - LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); - LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); - LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); - LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); - LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); - LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); - LOAD_FUNC(snd_pcm_hw_params_get_period_size); - LOAD_FUNC(snd_pcm_hw_params_get_access); - LOAD_FUNC(snd_pcm_hw_params_get_periods); - LOAD_FUNC(snd_pcm_hw_params); - LOAD_FUNC(snd_pcm_sw_params_malloc); - LOAD_FUNC(snd_pcm_sw_params_current); - LOAD_FUNC(snd_pcm_sw_params_set_avail_min); - LOAD_FUNC(snd_pcm_sw_params); - LOAD_FUNC(snd_pcm_sw_params_free); - LOAD_FUNC(snd_pcm_prepare); - LOAD_FUNC(snd_pcm_start); - LOAD_FUNC(snd_pcm_resume); - LOAD_FUNC(snd_pcm_wait); - LOAD_FUNC(snd_pcm_state); - LOAD_FUNC(snd_pcm_avail_update); - LOAD_FUNC(snd_pcm_areas_silence); - LOAD_FUNC(snd_pcm_mmap_begin); - LOAD_FUNC(snd_pcm_mmap_commit); - LOAD_FUNC(snd_pcm_readi); - LOAD_FUNC(snd_pcm_writei); - LOAD_FUNC(snd_pcm_drain); - LOAD_FUNC(snd_pcm_recover); - LOAD_FUNC(snd_pcm_info_malloc); - LOAD_FUNC(snd_pcm_info_free); - LOAD_FUNC(snd_pcm_info_set_device); - LOAD_FUNC(snd_pcm_info_set_subdevice); - LOAD_FUNC(snd_pcm_info_set_stream); - LOAD_FUNC(snd_pcm_info_get_name); - LOAD_FUNC(snd_ctl_pcm_next_device); - LOAD_FUNC(snd_ctl_pcm_info); - LOAD_FUNC(snd_ctl_open); - LOAD_FUNC(snd_ctl_close); - LOAD_FUNC(snd_ctl_card_info_malloc); - LOAD_FUNC(snd_ctl_card_info_free); - LOAD_FUNC(snd_ctl_card_info); - LOAD_FUNC(snd_ctl_card_info_get_name); - LOAD_FUNC(snd_ctl_card_info_get_id); - LOAD_FUNC(snd_card_next); + ALSA_FUNCS(LOAD_FUNC); #undef LOAD_FUNC -#else - alsa_handle = (void*)0xDEADBEEF; -#endif + + if(error) + { + CloseLib(alsa_handle); + alsa_handle = NULL; + return ALC_FALSE; + } } - return ALC_TRUE; +#endif + + return !error; } -typedef struct { - snd_pcm_t *pcmHandle; - - ALvoid *buffer; - ALsizei size; - - ALboolean doCapture; - RingBuffer *ring; - - volatile int killNow; - ALvoid *thread; -} alsa_data; - typedef struct { ALCchar *name; - char *card; - int dev; + char *device; } DevMap; static DevMap *allDevNameMap; @@ -270,50 +236,64 @@ static ALuint numDevNames; static DevMap *allCaptureDevNameMap; static ALuint numCaptureDevNames; -static const char *device_prefix; -static const char *capture_prefix; +static const char *prefix_name(snd_pcm_stream_t stream) +{ + assert(stream == SND_PCM_STREAM_PLAYBACK || stream == SND_PCM_STREAM_CAPTURE); + return (stream==SND_PCM_STREAM_PLAYBACK) ? "device-prefix" : "capture-prefix"; +} static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) { + const char *main_prefix = "plughw:"; snd_ctl_t *handle; int card, err, dev, idx; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; DevMap *DevList; - char name[1024]; snd_ctl_card_info_malloc(&info); snd_pcm_info_malloc(&pcminfo); + DevList = malloc(sizeof(DevMap) * 1); + DevList[0].name = strdup(alsaDevice); + DevList[0].device = strdup(GetConfigValue("alsa", (stream==SND_PCM_STREAM_PLAYBACK) ? + "device" : "capture", "default")); + idx = 1; + card = -1; if((err=snd_card_next(&card)) < 0) ERR("Failed to find a card: %s\n", snd_strerror(err)); - - DevList = malloc(sizeof(DevMap) * 1); - DevList[0].name = strdup("ALSA Default"); - DevList[0].card = NULL; - DevList[0].dev = 0; - idx = 1; + ConfigValueStr("alsa", prefix_name(stream), &main_prefix); while(card >= 0) { - sprintf(name, "hw:%d", card); + const char *card_prefix = main_prefix; + const char *cardname, *cardid; + char name[256]; + + snprintf(name, sizeof(name), "hw:%d", card); if((err = snd_ctl_open(&handle, name, 0)) < 0) { - ERR("control open (%i): %s\n", card, snd_strerror(err)); + ERR("control open (hw:%d): %s\n", card, snd_strerror(err)); goto next_card; } if((err = snd_ctl_card_info(handle, info)) < 0) { - ERR("control hardware info (%i): %s\n", card, snd_strerror(err)); + ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err)); snd_ctl_close(handle); goto next_card; } + cardname = snd_ctl_card_info_get_name(info); + cardid = snd_ctl_card_info_get_id(info); + + snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid); + ConfigValueStr("alsa", name, &card_prefix); + dev = -1; while(1) { - const char *cname, *dname, *cid; + const char *devname; void *temp; if(snd_ctl_pcm_next_device(handle, &dev) < 0) @@ -326,22 +306,30 @@ static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) snd_pcm_info_set_stream(pcminfo, stream); if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { if(err != -ENOENT) - ERR("control digital audio info (%i): %s\n", card, snd_strerror(err)); + ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err)); continue; } temp = realloc(DevList, sizeof(DevMap) * (idx+1)); if(temp) { + const char *device_prefix = card_prefix; + char device[128]; + DevList = temp; - cname = snd_ctl_card_info_get_name(info); - dname = snd_pcm_info_get_name(pcminfo); - cid = snd_ctl_card_info_get_id(info); + devname = snd_pcm_info_get_name(pcminfo); + + snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev); + ConfigValueStr("alsa", name, &device_prefix); + snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)", - cname, dname, cid, dev); + cardname, devname, cardid, dev); + snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d", + device_prefix, cardid, dev); + + TRACE("Got device \"%s\", \"%s\"\n", name, device); DevList[idx].name = strdup(name); - DevList[idx].card = strdup(cid); - DevList[idx].dev = dev; + DevList[idx].device = strdup(device); idx++; } } @@ -361,87 +349,141 @@ static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) } -static int xrun_recovery(snd_pcm_t *handle, int err) -{ - err = snd_pcm_recover(handle, err, 1); - if(err < 0) - ERR("recover failed: %s\n", snd_strerror(err)); - return err; -} - static int verify_state(snd_pcm_t *handle) { snd_pcm_state_t state = snd_pcm_state(handle); - if(state == SND_PCM_STATE_DISCONNECTED) - return -ENODEV; - if(state == SND_PCM_STATE_XRUN) + int err; + + switch(state) { - int err = xrun_recovery(handle, -EPIPE); - if(err < 0) return err; - } - else if(state == SND_PCM_STATE_SUSPENDED) - { - int err = xrun_recovery(handle, -ESTRPIPE); - if(err < 0) return err; + case SND_PCM_STATE_OPEN: + case SND_PCM_STATE_SETUP: + case SND_PCM_STATE_PREPARED: + case SND_PCM_STATE_RUNNING: + case SND_PCM_STATE_DRAINING: + case SND_PCM_STATE_PAUSED: + /* All Okay */ + break; + + case SND_PCM_STATE_XRUN: + if((err=snd_pcm_recover(handle, -EPIPE, 1)) < 0) + return err; + break; + case SND_PCM_STATE_SUSPENDED: + if((err=snd_pcm_recover(handle, -ESTRPIPE, 1)) < 0) + return err; + break; + case SND_PCM_STATE_DISCONNECTED: + return -ENODEV; } return state; } -static ALuint ALSAProc(ALvoid *ptr) +typedef struct ALCplaybackAlsa { + DERIVE_FROM_TYPE(ALCbackend); + + snd_pcm_t *pcmHandle; + + ALvoid *buffer; + ALsizei size; + + volatile int killNow; + althread_t thread; +} ALCplaybackAlsa; +DECLARE_ALCBACKEND_VTABLE(ALCplaybackAlsa); + +static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr); +static ALuint ALCplaybackAlsa_mixerNoMMapProc(ALvoid *ptr); + +static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device); +static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, Destruct) +static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name); +static void ALCplaybackAlsa_close(ALCplaybackAlsa *self); +static ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self); +static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self); +static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self); +static DECLARE_FORWARD2(ALCplaybackAlsa, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, unlock) + + +static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device) { - ALCdevice *pDevice = (ALCdevice*)ptr; - alsa_data *data = (alsa_data*)pDevice->ExtraData; + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCplaybackAlsa, ALCbackend, self); +} + + +static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr) +{ + ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; const snd_pcm_channel_area_t *areas = NULL; + snd_pcm_uframes_t update_size, num_updates; snd_pcm_sframes_t avail, commitres; snd_pcm_uframes_t offset, frames; char *WritePtr; int err; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); - while(!data->killNow) + update_size = device->UpdateSize; + num_updates = device->NumUpdates; + while(!self->killNow) { - int state = verify_state(data->pcmHandle); + int state = verify_state(self->pcmHandle); if(state < 0) { ERR("Invalid state detected: %s\n", snd_strerror(state)); - aluHandleDisconnect(pDevice); + ALCplaybackAlsa_lock(self); + aluHandleDisconnect(device); + ALCplaybackAlsa_unlock(self); break; } - avail = snd_pcm_avail_update(data->pcmHandle); + avail = snd_pcm_avail_update(self->pcmHandle); if(avail < 0) { ERR("available update failed: %s\n", snd_strerror(avail)); continue; } + if((snd_pcm_uframes_t)avail > update_size*(num_updates+1)) + { + WARN("available samples exceeds the buffer size\n"); + snd_pcm_reset(self->pcmHandle); + continue; + } + // make sure there's frames to process - if((snd_pcm_uframes_t)avail < pDevice->UpdateSize) + if((snd_pcm_uframes_t)avail < update_size) { if(state != SND_PCM_STATE_RUNNING) { - err = snd_pcm_start(data->pcmHandle); + err = snd_pcm_start(self->pcmHandle); if(err < 0) { ERR("start failed: %s\n", snd_strerror(err)); continue; } } - if(snd_pcm_wait(data->pcmHandle, 1000) == 0) + if(snd_pcm_wait(self->pcmHandle, 1000) == 0) ERR("Wait timeout... buffer size too low?\n"); continue; } - avail -= avail%pDevice->UpdateSize; + avail -= avail%update_size; // it is possible that contiguous areas are smaller, thus we use a loop + ALCplaybackAlsa_lock(self); while(avail > 0) { frames = avail; - err = snd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &frames); + err = snd_pcm_mmap_begin(self->pcmHandle, &areas, &offset, &frames); if(err < 0) { ERR("mmap begin error: %s\n", snd_strerror(err)); @@ -449,9 +491,9 @@ static ALuint ALSAProc(ALvoid *ptr) } WritePtr = (char*)areas->addr + (offset * areas->step / 8); - aluMixData(pDevice, WritePtr, frames); + aluMixData(device, WritePtr, frames); - commitres = snd_pcm_mmap_commit(data->pcmHandle, offset, frames); + commitres = snd_pcm_mmap_commit(self->pcmHandle, offset, frames); if(commitres < 0 || (commitres-frames) != 0) { ERR("mmap commit error: %s\n", @@ -461,37 +503,76 @@ static ALuint ALSAProc(ALvoid *ptr) avail -= frames; } + ALCplaybackAlsa_unlock(self); } return 0; } -static ALuint ALSANoMMapProc(ALvoid *ptr) +static ALuint ALCplaybackAlsa_mixerNoMMapProc(ALvoid *ptr) { - ALCdevice *pDevice = (ALCdevice*)ptr; - alsa_data *data = (alsa_data*)pDevice->ExtraData; + ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + snd_pcm_uframes_t update_size, num_updates; snd_pcm_sframes_t avail; char *WritePtr; + int err; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); - while(!data->killNow) + update_size = device->UpdateSize; + num_updates = device->NumUpdates; + while(!self->killNow) { - int state = verify_state(data->pcmHandle); + int state = verify_state(self->pcmHandle); if(state < 0) { ERR("Invalid state detected: %s\n", snd_strerror(state)); - aluHandleDisconnect(pDevice); + ALCplaybackAlsa_lock(self); + aluHandleDisconnect(device); + ALCplaybackAlsa_unlock(self); break; } - WritePtr = data->buffer; - avail = data->size / snd_pcm_frames_to_bytes(data->pcmHandle, 1); - aluMixData(pDevice, WritePtr, avail); + avail = snd_pcm_avail_update(self->pcmHandle); + if(avail < 0) + { + ERR("available update failed: %s\n", snd_strerror(avail)); + continue; + } + + if((snd_pcm_uframes_t)avail > update_size*num_updates) + { + WARN("available samples exceeds the buffer size\n"); + snd_pcm_reset(self->pcmHandle); + continue; + } + + if((snd_pcm_uframes_t)avail < update_size) + { + if(state != SND_PCM_STATE_RUNNING) + { + err = snd_pcm_start(self->pcmHandle); + if(err < 0) + { + ERR("start failed: %s\n", snd_strerror(err)); + continue; + } + } + if(snd_pcm_wait(self->pcmHandle, 1000) == 0) + ERR("Wait timeout... buffer size too low?\n"); + continue; + } + + ALCplaybackAlsa_lock(self); + WritePtr = self->buffer; + avail = snd_pcm_bytes_to_frames(self->pcmHandle, self->size); + aluMixData(device, WritePtr, avail); while(avail > 0) { - int ret = snd_pcm_writei(data->pcmHandle, WritePtr, avail); + int ret = snd_pcm_writei(self->pcmHandle, WritePtr, avail); switch (ret) { case -EAGAIN: @@ -499,42 +580,39 @@ static ALuint ALSANoMMapProc(ALvoid *ptr) case -ESTRPIPE: case -EPIPE: case -EINTR: - ret = snd_pcm_recover(data->pcmHandle, ret, 1); + ret = snd_pcm_recover(self->pcmHandle, ret, 1); if(ret < 0) avail = 0; break; default: if (ret >= 0) { - WritePtr += snd_pcm_frames_to_bytes(data->pcmHandle, ret); + WritePtr += snd_pcm_frames_to_bytes(self->pcmHandle, ret); avail -= ret; } break; } if (ret < 0) { - ret = snd_pcm_prepare(data->pcmHandle); + ret = snd_pcm_prepare(self->pcmHandle); if(ret < 0) break; } } + ALCplaybackAlsa_unlock(self); } return 0; } -static ALCenum alsa_open_playback(ALCdevice *device, const ALCchar *deviceName) + +static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name) { - const char *driver = "default"; - alsa_data *data; - char str[128]; - int i; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + const char *driver = NULL; + int err; - ConfigValueStr("alsa", "device", &driver); - - if(!deviceName) - deviceName = alsaDevice; - else if(strcmp(deviceName, alsaDevice) != 0) + if(name) { size_t idx; @@ -543,67 +621,55 @@ static ALCenum alsa_open_playback(ALCdevice *device, const ALCchar *deviceName) for(idx = 0;idx < numDevNames;idx++) { - if(allDevNameMap[idx].name && - strcmp(deviceName, allDevNameMap[idx].name) == 0) + if(strcmp(name, allDevNameMap[idx].name) == 0) { - if(idx > 0) - { - snprintf(str, sizeof(str), "%sCARD=%s,DEV=%d", device_prefix, - allDevNameMap[idx].card, allDevNameMap[idx].dev); - driver = str; - } + driver = allDevNameMap[idx].device; break; } } if(idx == numDevNames) return ALC_INVALID_VALUE; } - - data = (alsa_data*)calloc(1, sizeof(alsa_data)); - - i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if(i >= 0) + else { - i = snd_pcm_nonblock(data->pcmHandle, 0); - if(i < 0) - snd_pcm_close(data->pcmHandle); + name = alsaDevice; + driver = GetConfigValue("alsa", "device", "default"); } - if(i < 0) + + err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + if(err < 0) { - free(data); - ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(i)); + ERR("Could not open playback device '%s': %s\n", driver, snd_strerror(err)); return ALC_OUT_OF_MEMORY; } - device->szDeviceName = strdup(deviceName); - device->ExtraData = data; + /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */ + snd_config_update_free_global(); + + device->DeviceName = strdup(name); + return ALC_NO_ERROR; } -static void alsa_close_playback(ALCdevice *device) +static void ALCplaybackAlsa_close(ALCplaybackAlsa *self) { - alsa_data *data = (alsa_data*)device->ExtraData; - - snd_pcm_close(data->pcmHandle); - free(data); - device->ExtraData = NULL; + snd_pcm_close(self->pcmHandle); } -static ALCboolean alsa_reset_playback(ALCdevice *device) +static ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self) { - alsa_data *data = (alsa_data*)device->ExtraData; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; snd_pcm_uframes_t periodSizeInFrames; unsigned int periodLen, bufferLen; snd_pcm_sw_params_t *sp = NULL; - snd_pcm_hw_params_t *p = NULL; + snd_pcm_hw_params_t *hp = NULL; snd_pcm_access_t access; snd_pcm_format_t format; unsigned int periods; unsigned int rate; + const char *funcerr; int allowmmap; - char *err; - int i; - + int err; format = -1; switch(device->FmtType) @@ -620,6 +686,12 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) case DevFmtUShort: format = SND_PCM_FORMAT_U16; break; + case DevFmtInt: + format = SND_PCM_FORMAT_S32; + break; + case DevFmtUInt: + format = SND_PCM_FORMAT_U32; + break; case DevFmtFloat: format = SND_PCM_FORMAT_FLOAT; break; @@ -631,231 +703,283 @@ static ALCboolean alsa_reset_playback(ALCdevice *device) bufferLen = periodLen * periods; rate = device->Frequency; - err = NULL; - snd_pcm_hw_params_malloc(&p); - - if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) - err = "any"; + snd_pcm_hw_params_malloc(&hp); +#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error + CHECK(snd_pcm_hw_params_any(self->pcmHandle, hp)); /* set interleaved access */ - if(i >= 0 && (!allowmmap || (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0)) + if(!allowmmap || snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { - if(periods > 2) - { - periods--; - bufferLen = periodLen * periods; - } - if((i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) - err = "set access"; + /* No mmap */ + CHECK(snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED)); } - /* set format (implicitly sets sample bits) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) + /* test and set format (implicitly sets sample bits) */ + if(snd_pcm_hw_params_test_format(self->pcmHandle, hp, format) < 0) { - device->FmtType = DevFmtFloat; - if(format == SND_PCM_FORMAT_FLOAT || - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_FLOAT)) < 0) + static const struct { + snd_pcm_format_t format; + enum DevFmtType fmttype; + } formatlist[] = { + { SND_PCM_FORMAT_FLOAT, DevFmtFloat }, + { SND_PCM_FORMAT_S32, DevFmtInt }, + { SND_PCM_FORMAT_U32, DevFmtUInt }, + { SND_PCM_FORMAT_S16, DevFmtShort }, + { SND_PCM_FORMAT_U16, DevFmtUShort }, + { SND_PCM_FORMAT_S8, DevFmtByte }, + { SND_PCM_FORMAT_U8, DevFmtUByte }, + }; + size_t k; + + for(k = 0;k < COUNTOF(formatlist);k++) { - device->FmtType = DevFmtShort; - if(format == SND_PCM_FORMAT_S16 || - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_S16)) < 0) + format = formatlist[k].format; + if(snd_pcm_hw_params_test_format(self->pcmHandle, hp, format) >= 0) { - device->FmtType = DevFmtUByte; - if(format == SND_PCM_FORMAT_U8 || - (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, SND_PCM_FORMAT_U8)) < 0) - err = "set format"; + device->FmtType = formatlist[k].fmttype; + break; } } } - /* set channels (implicitly sets frame bits) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(device->FmtChans))) < 0) + CHECK(snd_pcm_hw_params_set_format(self->pcmHandle, hp, format)); + /* test and set channels (implicitly sets frame bits) */ + if(snd_pcm_hw_params_test_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans)) < 0) { - if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 2)) < 0) + static const enum DevFmtChannels channellist[] = { + DevFmtStereo, + DevFmtQuad, + DevFmtX51, + DevFmtX71, + DevFmtMono, + }; + size_t k; + + for(k = 0;k < COUNTOF(channellist);k++) { - if((i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, 1)) < 0) - err = "set channels"; - else + if(snd_pcm_hw_params_test_channels(self->pcmHandle, hp, ChannelsFromDevFmt(channellist[k])) >= 0) { - if((device->Flags&DEVICE_CHANNELS_REQUEST)) - ERR("Failed to set %s, got Mono instead\n", DevFmtChannelsString(device->FmtChans)); - device->FmtChans = DevFmtMono; + device->FmtChans = channellist[k]; + break; } } - else - { - if((device->Flags&DEVICE_CHANNELS_REQUEST)) - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(device->FmtChans)); - device->FmtChans = DevFmtStereo; - } - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } - if(i >= 0 && (i=snd_pcm_hw_params_set_rate_resample(data->pcmHandle, p, 0)) < 0) - { - ERR("Failed to disable ALSA resampler\n"); - i = 0; } + CHECK(snd_pcm_hw_params_set_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans))); /* set rate (implicitly constrains period/buffer parameters) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_rate_near(data->pcmHandle, p, &rate, NULL)) < 0) - err = "set rate near"; + if(snd_pcm_hw_params_set_rate_resample(self->pcmHandle, hp, 0) < 0) + ERR("Failed to disable ALSA resampler\n"); + CHECK(snd_pcm_hw_params_set_rate_near(self->pcmHandle, hp, &rate, NULL)); /* set buffer time (implicitly constrains period/buffer parameters) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_time_near(data->pcmHandle, p, &bufferLen, NULL)) < 0) - err = "set buffer time near"; - /* set period time in frame units (implicitly sets buffer size/bytes/time and period size/bytes) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_period_time_near(data->pcmHandle, p, &periodLen, NULL)) < 0) - err = "set period time near"; + if((err=snd_pcm_hw_params_set_buffer_time_near(self->pcmHandle, hp, &bufferLen, NULL)) < 0) + ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err)); + /* set period time (implicitly sets buffer size/bytes/time and period size/bytes) */ + if((err=snd_pcm_hw_params_set_period_time_near(self->pcmHandle, hp, &periodLen, NULL)) < 0) + ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err)); /* install and prepare hardware configuration */ - if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) - err = "set params"; - if(i >= 0 && (i=snd_pcm_hw_params_get_access(p, &access)) < 0) - err = "get access"; - if(i >= 0 && (i=snd_pcm_hw_params_get_period_size(p, &periodSizeInFrames, NULL)) < 0) - err = "get period size"; - if(i >= 0 && (i=snd_pcm_hw_params_get_periods(p, &periods, NULL)) < 0) - err = "get periods"; - if(i < 0) - { - ERR("%s failed: %s\n", err, snd_strerror(i)); - snd_pcm_hw_params_free(p); - return ALC_FALSE; - } + CHECK(snd_pcm_hw_params(self->pcmHandle, hp)); + /* retrieve configuration info */ + CHECK(snd_pcm_hw_params_get_access(hp, &access)); + CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, NULL)); + CHECK(snd_pcm_hw_params_get_periods(hp, &periods, NULL)); - snd_pcm_hw_params_free(p); - - err = NULL; + snd_pcm_hw_params_free(hp); + hp = NULL; snd_pcm_sw_params_malloc(&sp); - if((i=snd_pcm_sw_params_current(data->pcmHandle, sp)) != 0) - err = "sw current"; - if(i == 0 && (i=snd_pcm_sw_params_set_avail_min(data->pcmHandle, sp, periodSizeInFrames)) != 0) - err = "sw set avail min"; - if(i == 0 && (i=snd_pcm_sw_params(data->pcmHandle, sp)) != 0) - err = "sw set params"; - if(i != 0) - { - ERR("%s failed: %s\n", err, snd_strerror(i)); - snd_pcm_sw_params_free(sp); - return ALC_FALSE; - } - + CHECK(snd_pcm_sw_params_current(self->pcmHandle, sp)); + CHECK(snd_pcm_sw_params_set_avail_min(self->pcmHandle, sp, periodSizeInFrames)); + CHECK(snd_pcm_sw_params_set_stop_threshold(self->pcmHandle, sp, periodSizeInFrames*periods)); + CHECK(snd_pcm_sw_params(self->pcmHandle, sp)); +#undef CHECK snd_pcm_sw_params_free(sp); + sp = NULL; - if(device->Frequency != rate) - { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set %dhz, got %dhz instead\n", device->Frequency, rate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = rate; - } + device->NumUpdates = periods; + device->UpdateSize = periodSizeInFrames; + device->Frequency = rate; SetDefaultChannelOrder(device); - data->size = snd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames); + return ALC_TRUE; + +error: + ERR("%s failed: %s\n", funcerr, snd_strerror(err)); + if(hp) snd_pcm_hw_params_free(hp); + if(sp) snd_pcm_sw_params_free(sp); + return ALC_FALSE; +} + +static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + ALuint (*thread_func)(ALvoid*) = NULL; + snd_pcm_hw_params_t *hp = NULL; + snd_pcm_access_t access; + const char *funcerr; + int err; + + snd_pcm_hw_params_malloc(&hp); +#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error + CHECK(snd_pcm_hw_params_current(self->pcmHandle, hp)); + /* retrieve configuration info */ + CHECK(snd_pcm_hw_params_get_access(hp, &access)); +#undef CHECK + snd_pcm_hw_params_free(hp); + hp = NULL; + + self->size = snd_pcm_frames_to_bytes(self->pcmHandle, device->UpdateSize); if(access == SND_PCM_ACCESS_RW_INTERLEAVED) { - /* Increase periods by one, since the temp buffer counts as an extra - * period */ - periods++; - data->buffer = malloc(data->size); - if(!data->buffer) + self->buffer = malloc(self->size); + if(!self->buffer) { ERR("buffer malloc failed\n"); return ALC_FALSE; } - device->UpdateSize = periodSizeInFrames; - device->NumUpdates = periods; - data->thread = StartThread(ALSANoMMapProc, device); + thread_func = ALCplaybackAlsa_mixerNoMMapProc; } else { - i = snd_pcm_prepare(data->pcmHandle); - if(i < 0) + err = snd_pcm_prepare(self->pcmHandle); + if(err < 0) { - ERR("prepare error: %s\n", snd_strerror(i)); + ERR("snd_pcm_prepare(data->pcmHandle) failed: %s\n", snd_strerror(err)); return ALC_FALSE; } - device->UpdateSize = periodSizeInFrames; - device->NumUpdates = periods; - data->thread = StartThread(ALSAProc, device); + thread_func = ALCplaybackAlsa_mixerProc; } - if(data->thread == NULL) + if(!StartThread(&self->thread, thread_func, self)) { ERR("Could not create playback thread\n"); - free(data->buffer); - data->buffer = NULL; + free(self->buffer); + self->buffer = NULL; return ALC_FALSE; } return ALC_TRUE; + +error: + ERR("%s failed: %s\n", funcerr, snd_strerror(err)); + if(hp) snd_pcm_hw_params_free(hp); + return ALC_FALSE; } -static void alsa_stop_playback(ALCdevice *device) +static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self) { - alsa_data *data = (alsa_data*)device->ExtraData; - - if(data->thread) + if(self->thread) { - data->killNow = 1; - StopThread(data->thread); - data->thread = NULL; + self->killNow = 1; + StopThread(self->thread); + self->thread = NULL; } - data->killNow = 0; - free(data->buffer); - data->buffer = NULL; + self->killNow = 0; + free(self->buffer); + self->buffer = NULL; +} + +static ALint64 ALCplaybackAlsa_getLatency(ALCplaybackAlsa *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + snd_pcm_sframes_t delay = 0; + int err; + + if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0) + { + ERR("Failed to get pcm delay: %s\n", snd_strerror(err)); + return 0; + } + return maxi64((ALint64)delay*1000000000/device->Frequency, 0); } -static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName) +static void ALCplaybackAlsa_Delete(ALCplaybackAlsa *self) { - const char *driver = "default"; - snd_pcm_hw_params_t *p; + free(self); +} + +DEFINE_ALCBACKEND_VTABLE(ALCplaybackAlsa); + + +typedef struct ALCcaptureAlsa { + DERIVE_FROM_TYPE(ALCbackend); + + snd_pcm_t *pcmHandle; + + ALvoid *buffer; + ALsizei size; + + ALboolean doCapture; + RingBuffer *ring; + + snd_pcm_sframes_t last_avail; +} ALCcaptureAlsa; +DECLARE_ALCBACKEND_VTABLE(ALCcaptureAlsa); + +static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device); +static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, Destruct) +static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name); +static void ALCcaptureAlsa_close(ALCcaptureAlsa *self); +static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, ALCboolean, reset) +static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self); +static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self); +static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples); +static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self); +static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, unlock) + + +static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCcaptureAlsa, ALCbackend, self); +} + + +static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + const char *driver = NULL; + snd_pcm_hw_params_t *hp; snd_pcm_uframes_t bufferSizeInFrames; snd_pcm_uframes_t periodSizeInFrames; + ALboolean needring = AL_FALSE; snd_pcm_format_t format; - ALuint frameSize; - alsa_data *data; - char str[128]; - char *err; - int i; + const char *funcerr; + int err; - ConfigValueStr("alsa", "capture", &driver); - - if(!allCaptureDevNameMap) - allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); - - if(!deviceName) - deviceName = allCaptureDevNameMap[0].name; - else + if(name) { size_t idx; + if(!allCaptureDevNameMap) + allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); + for(idx = 0;idx < numCaptureDevNames;idx++) { - if(allCaptureDevNameMap[idx].name && - strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0) + if(strcmp(name, allCaptureDevNameMap[idx].name) == 0) { - if(idx > 0) - { - snprintf(str, sizeof(str), "%sCARD=%s,DEV=%d", capture_prefix, - allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev); - driver = str; - } + driver = allCaptureDevNameMap[idx].device; break; } } if(idx == numCaptureDevNames) return ALC_INVALID_VALUE; } - - data = (alsa_data*)calloc(1, sizeof(alsa_data)); - - i = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); - if(i < 0) + else { - ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(i)); - free(data); + name = alsaDevice; + driver = GetConfigValue("alsa", "capture", "default"); + } + + err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); + if(err < 0) + { + ERR("Could not open capture device '%s': %s\n", driver, snd_strerror(err)); return ALC_INVALID_VALUE; } + /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */ + snd_config_update_free_global(); + format = -1; - switch(pDevice->FmtType) + switch(device->FmtType) { case DevFmtByte: format = SND_PCM_FORMAT_S8; @@ -869,222 +993,329 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName) case DevFmtUShort: format = SND_PCM_FORMAT_U16; break; + case DevFmtInt: + format = SND_PCM_FORMAT_S32; + break; + case DevFmtUInt: + format = SND_PCM_FORMAT_U32; + break; case DevFmtFloat: format = SND_PCM_FORMAT_FLOAT; break; } - err = NULL; - bufferSizeInFrames = maxu(pDevice->UpdateSize*pDevice->NumUpdates, - 100*pDevice->Frequency/1000); - periodSizeInFrames = minu(bufferSizeInFrames, 50*pDevice->Frequency/1000); - snd_pcm_hw_params_malloc(&p); + funcerr = NULL; + bufferSizeInFrames = maxu(device->UpdateSize*device->NumUpdates, + 100*device->Frequency/1000); + periodSizeInFrames = minu(bufferSizeInFrames, 25*device->Frequency/1000); - if((i=snd_pcm_hw_params_any(data->pcmHandle, p)) < 0) - err = "any"; + snd_pcm_hw_params_malloc(&hp); +#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error + CHECK(snd_pcm_hw_params_any(self->pcmHandle, hp)); /* set interleaved access */ - if(i >= 0 && (i=snd_pcm_hw_params_set_access(data->pcmHandle, p, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) - err = "set access"; + CHECK(snd_pcm_hw_params_set_access(self->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED)); /* set format (implicitly sets sample bits) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_format(data->pcmHandle, p, format)) < 0) - err = "set format"; + CHECK(snd_pcm_hw_params_set_format(self->pcmHandle, hp, format)); /* set channels (implicitly sets frame bits) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_channels(data->pcmHandle, p, ChannelsFromDevFmt(pDevice->FmtChans))) < 0) - err = "set channels"; + CHECK(snd_pcm_hw_params_set_channels(self->pcmHandle, hp, ChannelsFromDevFmt(device->FmtChans))); /* set rate (implicitly constrains period/buffer parameters) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_rate(data->pcmHandle, p, pDevice->Frequency, 0)) < 0) - err = "set rate near"; + CHECK(snd_pcm_hw_params_set_rate(self->pcmHandle, hp, device->Frequency, 0)); /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_buffer_size_near(data->pcmHandle, p, &bufferSizeInFrames)) < 0) - err = "set buffer size near"; + if(snd_pcm_hw_params_set_buffer_size_min(self->pcmHandle, hp, &bufferSizeInFrames) < 0) + { + TRACE("Buffer too large, using intermediate ring buffer\n"); + needring = AL_TRUE; + CHECK(snd_pcm_hw_params_set_buffer_size_near(self->pcmHandle, hp, &bufferSizeInFrames)); + } /* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */ - if(i >= 0 && (i=snd_pcm_hw_params_set_period_size_near(data->pcmHandle, p, &periodSizeInFrames, NULL)) < 0) - err = "set period size near"; + CHECK(snd_pcm_hw_params_set_period_size_near(self->pcmHandle, hp, &periodSizeInFrames, NULL)); /* install and prepare hardware configuration */ - if(i >= 0 && (i=snd_pcm_hw_params(data->pcmHandle, p)) < 0) - err = "set params"; - if(i < 0) + CHECK(snd_pcm_hw_params(self->pcmHandle, hp)); + /* retrieve configuration info */ + CHECK(snd_pcm_hw_params_get_period_size(hp, &periodSizeInFrames, NULL)); +#undef CHECK + snd_pcm_hw_params_free(hp); + hp = NULL; + + if(needring) { - ERR("%s failed: %s\n", err, snd_strerror(i)); - snd_pcm_hw_params_free(p); - goto error; + self->ring = CreateRingBuffer(FrameSizeFromDevFmt(device->FmtChans, device->FmtType), + device->UpdateSize*device->NumUpdates); + if(!self->ring) + { + ERR("ring buffer create failed\n"); + goto error2; + } + + self->size = snd_pcm_frames_to_bytes(self->pcmHandle, periodSizeInFrames); + self->buffer = malloc(self->size); + if(!self->buffer) + { + ERR("buffer malloc failed\n"); + goto error2; + } } - if((i=snd_pcm_hw_params_get_period_size(p, &bufferSizeInFrames, NULL)) < 0) - { - ERR("get size failed: %s\n", snd_strerror(i)); - snd_pcm_hw_params_free(p); - goto error; - } + device->DeviceName = strdup(name); - snd_pcm_hw_params_free(p); - - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); - - data->ring = CreateRingBuffer(frameSize, pDevice->UpdateSize*pDevice->NumUpdates); - if(!data->ring) - { - ERR("ring buffer create failed\n"); - goto error; - } - - data->size = snd_pcm_frames_to_bytes(data->pcmHandle, bufferSizeInFrames); - data->buffer = malloc(data->size); - if(!data->buffer) - { - ERR("buffer malloc failed\n"); - goto error; - } - - pDevice->szDeviceName = strdup(deviceName); - - pDevice->ExtraData = data; return ALC_NO_ERROR; error: - free(data->buffer); - DestroyRingBuffer(data->ring); - snd_pcm_close(data->pcmHandle); - free(data); + ERR("%s failed: %s\n", funcerr, snd_strerror(err)); + if(hp) snd_pcm_hw_params_free(hp); + +error2: + free(self->buffer); + self->buffer = NULL; + DestroyRingBuffer(self->ring); + self->ring = NULL; + snd_pcm_close(self->pcmHandle); - pDevice->ExtraData = NULL; return ALC_INVALID_VALUE; } -static void alsa_close_capture(ALCdevice *pDevice) +static void ALCcaptureAlsa_close(ALCcaptureAlsa *self) { - alsa_data *data = (alsa_data*)pDevice->ExtraData; + snd_pcm_close(self->pcmHandle); + DestroyRingBuffer(self->ring); - snd_pcm_close(data->pcmHandle); - DestroyRingBuffer(data->ring); - - free(data->buffer); - free(data); - pDevice->ExtraData = NULL; + free(self->buffer); + self->buffer = NULL; } -static void alsa_start_capture(ALCdevice *Device) +static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self) { - alsa_data *data = (alsa_data*)Device->ExtraData; - int err; - - err = snd_pcm_start(data->pcmHandle); + int err = snd_pcm_start(self->pcmHandle); if(err < 0) { ERR("start failed: %s\n", snd_strerror(err)); - aluHandleDisconnect(Device); + aluHandleDisconnect(STATIC_CAST(ALCbackend, self)->mDevice); + return ALC_FALSE; } - else - data->doCapture = AL_TRUE; + + self->doCapture = AL_TRUE; + return ALC_TRUE; } -static void alsa_stop_capture(ALCdevice *Device) +static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self) { - alsa_data *data = (alsa_data*)Device->ExtraData; - snd_pcm_drain(data->pcmHandle); - data->doCapture = AL_FALSE; -} + ALCuint avail; + int err; -static ALCenum alsa_capture_samples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples) -{ - alsa_data *data = (alsa_data*)Device->ExtraData; - ReadRingBuffer(data->ring, Buffer, Samples); - return ALC_NO_ERROR; -} - -static ALCuint alsa_available_samples(ALCdevice *Device) -{ - alsa_data *data = (alsa_data*)Device->ExtraData; - snd_pcm_sframes_t avail; - - avail = (Device->Connected ? snd_pcm_avail_update(data->pcmHandle) : 0); - if(avail < 0) + /* OpenAL requires access to unread audio after stopping, but ALSA's + * snd_pcm_drain is unreliable and snd_pcm_drop drops it. Capture what's + * available now so it'll be available later after the drop. */ + avail = ALCcaptureAlsa_availableSamples(self); + if(!self->ring && avail > 0) { - ERR("avail update failed: %s\n", snd_strerror(avail)); + /* The ring buffer implicitly captures when checking availability. + * Direct access needs to explicitly capture it into temp storage. */ + ALsizei size; + void *ptr; - if((avail=snd_pcm_recover(data->pcmHandle, avail, 1)) >= 0) + size = snd_pcm_frames_to_bytes(self->pcmHandle, avail); + ptr = realloc(self->buffer, size); + if(ptr) { - if(data->doCapture) - avail = snd_pcm_start(data->pcmHandle); - if(avail >= 0) - avail = snd_pcm_avail_update(data->pcmHandle); - } - if(avail < 0) - { - ERR("restore error: %s\n", snd_strerror(avail)); - aluHandleDisconnect(Device); + self->buffer = ptr; + ALCcaptureAlsa_captureSamples(self, self->buffer, avail); + self->size = size; } } - while(avail > 0) + err = snd_pcm_drop(self->pcmHandle); + if(err < 0) + ERR("drop failed: %s\n", snd_strerror(err)); + self->doCapture = AL_FALSE; +} + +static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + + if(self->ring) { - snd_pcm_sframes_t amt; + ReadRingBuffer(self->ring, buffer, samples); + return ALC_NO_ERROR; + } - amt = snd_pcm_bytes_to_frames(data->pcmHandle, data->size); - if(avail < amt) amt = avail; + self->last_avail -= samples; + while(device->Connected && samples > 0) + { + snd_pcm_sframes_t amt = 0; - amt = snd_pcm_readi(data->pcmHandle, data->buffer, amt); + if(self->size > 0) + { + /* First get any data stored from the last stop */ + amt = snd_pcm_bytes_to_frames(self->pcmHandle, self->size); + if((snd_pcm_uframes_t)amt > samples) amt = samples; + + amt = snd_pcm_frames_to_bytes(self->pcmHandle, amt); + memmove(buffer, self->buffer, amt); + + if(self->size > amt) + { + memmove(self->buffer, self->buffer+amt, self->size - amt); + self->size -= amt; + } + else + { + free(self->buffer); + self->buffer = NULL; + self->size = 0; + } + amt = snd_pcm_bytes_to_frames(self->pcmHandle, amt); + } + else if(self->doCapture) + amt = snd_pcm_readi(self->pcmHandle, buffer, samples); if(amt < 0) { ERR("read error: %s\n", snd_strerror(amt)); if(amt == -EAGAIN) continue; - if((amt=snd_pcm_recover(data->pcmHandle, amt, 1)) >= 0) + if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0) { - if(data->doCapture) - amt = snd_pcm_start(data->pcmHandle); + amt = snd_pcm_start(self->pcmHandle); if(amt >= 0) - amt = snd_pcm_avail_update(data->pcmHandle); + amt = snd_pcm_avail_update(self->pcmHandle); } if(amt < 0) { ERR("restore error: %s\n", snd_strerror(amt)); - aluHandleDisconnect(Device); + aluHandleDisconnect(device); + break; + } + /* If the amount available is less than what's asked, we lost it + * during recovery. So just give silence instead. */ + if((snd_pcm_uframes_t)amt < samples) + break; + continue; + } + + buffer = (ALbyte*)buffer + amt; + samples -= amt; + } + if(samples > 0) + memset(buffer, ((device->FmtType == DevFmtUByte) ? 0x80 : 0), + snd_pcm_frames_to_bytes(self->pcmHandle, samples)); + + return ALC_NO_ERROR; +} + +static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + snd_pcm_sframes_t avail = 0; + + if(device->Connected && self->doCapture) + avail = snd_pcm_avail_update(self->pcmHandle); + if(avail < 0) + { + ERR("avail update failed: %s\n", snd_strerror(avail)); + + if((avail=snd_pcm_recover(self->pcmHandle, avail, 1)) >= 0) + { + if(self->doCapture) + avail = snd_pcm_start(self->pcmHandle); + if(avail >= 0) + avail = snd_pcm_avail_update(self->pcmHandle); + } + if(avail < 0) + { + ERR("restore error: %s\n", snd_strerror(avail)); + aluHandleDisconnect(device); + } + } + + if(!self->ring) + { + if(avail < 0) avail = 0; + avail += snd_pcm_bytes_to_frames(self->pcmHandle, self->size); + if(avail > self->last_avail) self->last_avail = avail; + return self->last_avail; + } + + while(avail > 0) + { + snd_pcm_sframes_t amt; + + amt = snd_pcm_bytes_to_frames(self->pcmHandle, self->size); + if(avail < amt) amt = avail; + + amt = snd_pcm_readi(self->pcmHandle, self->buffer, amt); + if(amt < 0) + { + ERR("read error: %s\n", snd_strerror(amt)); + + if(amt == -EAGAIN) + continue; + if((amt=snd_pcm_recover(self->pcmHandle, amt, 1)) >= 0) + { + if(self->doCapture) + amt = snd_pcm_start(self->pcmHandle); + if(amt >= 0) + amt = snd_pcm_avail_update(self->pcmHandle); + } + if(amt < 0) + { + ERR("restore error: %s\n", snd_strerror(amt)); + aluHandleDisconnect(device); break; } avail = amt; continue; } - WriteRingBuffer(data->ring, data->buffer, amt); + WriteRingBuffer(self->ring, self->buffer, amt); avail -= amt; } - return RingBufferSize(data->ring); + return RingBufferSize(self->ring); } +static ALint64 ALCcaptureAlsa_getLatency(ALCcaptureAlsa *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + snd_pcm_sframes_t delay = 0; + int err; -static const BackendFuncs alsa_funcs = { - alsa_open_playback, - alsa_close_playback, - alsa_reset_playback, - alsa_stop_playback, - alsa_open_capture, - alsa_close_capture, - alsa_start_capture, - alsa_stop_capture, - alsa_capture_samples, - alsa_available_samples -}; + if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0) + { + ERR("Failed to get pcm delay: %s\n", snd_strerror(err)); + return 0; + } + return maxi64((ALint64)delay*1000000000/device->Frequency, 0); +} -ALCboolean alc_alsa_init(BackendFuncs *func_list) +static void ALCcaptureAlsa_Delete(ALCcaptureAlsa *self) +{ + free(self); +} + +DEFINE_ALCBACKEND_VTABLE(ALCcaptureAlsa); + + + +typedef struct ALCalsaBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCalsaBackendFactory; +#define ALCALSABACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCalsaBackendFactory, ALCbackendFactory) } } + +static ALCboolean ALCalsaBackendFactory_init(ALCalsaBackendFactory* UNUSED(self)) { if(!alsa_load()) return ALC_FALSE; - device_prefix = GetConfigValue("alsa", "device-prefix", "plughw:"); - capture_prefix = GetConfigValue("alsa", "capture-prefix", "plughw:"); - *func_list = alsa_funcs; return ALC_TRUE; } -void alc_alsa_deinit(void) +static void ALCalsaBackendFactory_deinit(ALCalsaBackendFactory* UNUSED(self)) { ALuint i; for(i = 0;i < numDevNames;++i) { free(allDevNameMap[i].name); - free(allDevNameMap[i].card); + free(allDevNameMap[i].device); } free(allDevNameMap); allDevNameMap = NULL; @@ -1093,7 +1324,7 @@ void alc_alsa_deinit(void) for(i = 0;i < numCaptureDevNames;++i) { free(allCaptureDevNameMap[i].name); - free(allCaptureDevNameMap[i].card); + free(allCaptureDevNameMap[i].device); } free(allCaptureDevNameMap); allCaptureDevNameMap = NULL; @@ -1106,35 +1337,38 @@ void alc_alsa_deinit(void) #endif } -void alc_alsa_probe(enum DevProbe type) +static ALCboolean ALCalsaBackendFactory_querySupport(ALCalsaBackendFactory* UNUSED(self), ALCbackend_Type type) +{ + if(type == ALCbackend_Playback || type == ALCbackend_Capture) + return ALC_TRUE; + return ALC_FALSE; +} + +static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type) { ALuint i; switch(type) { - case DEVICE_PROBE: - AppendDeviceList(alsaDevice); - break; - case ALL_DEVICE_PROBE: for(i = 0;i < numDevNames;++i) { free(allDevNameMap[i].name); - free(allDevNameMap[i].card); + free(allDevNameMap[i].device); } free(allDevNameMap); allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); for(i = 0;i < numDevNames;++i) - AppendAllDeviceList(allDevNameMap[i].name); + AppendAllDevicesList(allDevNameMap[i].name); break; case CAPTURE_DEVICE_PROBE: for(i = 0;i < numCaptureDevNames;++i) { free(allCaptureDevNameMap[i].name); - free(allCaptureDevNameMap[i].card); + free(allCaptureDevNameMap[i].device); } free(allCaptureDevNameMap); @@ -1145,3 +1379,40 @@ void alc_alsa_probe(enum DevProbe type) break; } } + +static ALCbackend* ALCalsaBackendFactory_createBackend(ALCalsaBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + ALCplaybackAlsa *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCplaybackAlsa_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + if(type == ALCbackend_Capture) + { + ALCcaptureAlsa *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCcaptureAlsa_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} + +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCalsaBackendFactory); + + +ALCbackendFactory *ALCalsaBackendFactory_getFactory(void) +{ + static ALCalsaBackendFactory factory = ALCALSABACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} diff --git a/jni/openal-soft-android/Alc/backends/android.c b/jni/openal-soft-android/Alc/backends/android.c deleted file mode 100644 index fc501e7e..00000000 --- a/jni/openal-soft-android/Alc/backends/android.c +++ /dev/null @@ -1,270 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2010 by Chris Robinson - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" - -static const ALCchar android_device[] = "Android Legacy"; - -static JavaVM* javaVM = NULL; - -static jclass cAudioTrack = NULL; - -static jmethodID mAudioTrack; -static jmethodID mGetMinBufferSize; -static jmethodID mPlay; -static jmethodID mStop; -static jmethodID mRelease; -static jmethodID mWrite; - -__attribute__((visibility("default"))) jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - (void)reserved; - javaVM = vm; - return JNI_VERSION_1_2; -} - -static JNIEnv* GetEnv() -{ - JNIEnv* env = NULL; - if (javaVM) (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2); - return env; -} - -typedef struct -{ - pthread_t thread; - volatile int running; -} AndroidData; - -#define STREAM_MUSIC 3 -#define CHANNEL_CONFIGURATION_MONO 2 -#define CHANNEL_CONFIGURATION_STEREO 3 -#define ENCODING_PCM_8BIT 3 -#define ENCODING_PCM_16BIT 2 -#define MODE_STREAM 1 - -static void* thread_function(void* arg) -{ - ALCdevice* device = (ALCdevice*)arg; - AndroidData* data = (AndroidData*)device->ExtraData; - - JNIEnv* env; - (*javaVM)->AttachCurrentThread(javaVM, &env, NULL); - - (*env)->PushLocalFrame(env, 2); - - int sampleRateInHz = device->Frequency; - int channelConfig = ChannelsFromDevFmt(device->FmtChans) == 1 ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO; - int audioFormat = BytesFromDevFmt(device->FmtType) == 1 ? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT; - - int bufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack, - mGetMinBufferSize, sampleRateInHz, channelConfig, audioFormat); - - int bufferSizeInSamples = bufferSizeInBytes / FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - - jobject track = (*env)->NewObject(env, cAudioTrack, mAudioTrack, - STREAM_MUSIC, sampleRateInHz, channelConfig, audioFormat, device->NumUpdates * bufferSizeInBytes, MODE_STREAM); - -#ifdef HAVE_ANDROID_LOW_LATENCY - int started = 0; - size_t overallBytes = 0; -#else - (*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mPlay); -#endif - - jarray buffer = (*env)->NewByteArray(env, bufferSizeInBytes); - - while (data->running) - { - void* pBuffer = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL); - - if (pBuffer) - { - aluMixData(device, pBuffer, bufferSizeInSamples); - (*env)->ReleasePrimitiveArrayCritical(env, buffer, pBuffer, 0); - -#ifdef HAVE_ANDROID_LOW_LATENCY - if (bufferSizeInBytes >= 0) - { - if (started) - { -#endif - (*env)->CallNonvirtualIntMethod(env, track, cAudioTrack, mWrite, buffer, 0, bufferSizeInBytes); -#ifdef HAVE_ANDROID_LOW_LATENCY - } - else - { - overallBytes += (*env)->CallNonvirtualIntMethod(env, track, cAudioTrack, mWrite, buffer, 0, bufferSizeInBytes); - if (overallBytes >= (device->NumUpdates * bufferSizeInBytes)) - { - (*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mPlay); - started = 1; - } - } - } -#endif - } - else - { - AL_PRINT("Failed to get pointer to array bytes"); - } - } - - (*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mStop); - (*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mRelease); - - (*env)->PopLocalFrame(env, NULL); - - (*javaVM)->DetachCurrentThread(javaVM); - return NULL; -} - -static ALCenum android_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - JNIEnv* env = GetEnv(); - AndroidData* data; - - if (!cAudioTrack) - { - /* Cache AudioTrack class and it's method id's - * And do this only once! - */ - - cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack"); - if (!cAudioTrack) - { - AL_PRINT("android.media.AudioTrack class is not found. Are you running at least 1.5 version?"); - return ALC_INVALID_VALUE; - } - - cAudioTrack = (*env)->NewGlobalRef(env, cAudioTrack); - - mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "", "(IIIIII)V"); - mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I"); - mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V"); - mStop = (*env)->GetMethodID(env, cAudioTrack, "stop", "()V"); - mRelease = (*env)->GetMethodID(env, cAudioTrack, "release", "()V"); - mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I"); - } - - if (!deviceName) - { - deviceName = android_device; - } - else if (strcmp(deviceName, android_device) != 0) - { - return ALC_INVALID_VALUE; - } - - data = (AndroidData*)calloc(1, sizeof(*data)); - device->szDeviceName = strdup(deviceName); - device->ExtraData = data; - -#ifdef HAVE_ANDROID_LOW_LATENCY - device->Frequency = 22050; - device->NumUpdates = 1; -#endif - - return ALC_NO_ERROR; -} - -static void android_close_playback(ALCdevice *device) -{ - AndroidData* data = (AndroidData*)device->ExtraData; - if (data != NULL) - { - free(data); - device->ExtraData = NULL; - } -} - -static ALCboolean android_reset_playback(ALCdevice *device) -{ - AndroidData* data = (AndroidData*)device->ExtraData; - - device->FmtChans = ChannelsFromDevFmt(device->FmtChans) >= 2 ? DevFmtStereo : DevFmtMono; - - SetDefaultChannelOrder(device); - - data->running = 1; - pthread_create(&data->thread, NULL, thread_function, device); - - return ALC_TRUE; -} - -static void android_stop_playback(ALCdevice *device) -{ - AndroidData* data = (AndroidData*)device->ExtraData; - - if (data->running) - { - data->running = 0; - pthread_join(data->thread, NULL); - } -} - -static const BackendFuncs android_funcs = { - android_open_playback, - android_close_playback, - android_reset_playback, - android_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -ALCboolean alc_android_init(BackendFuncs *func_list) -{ - *func_list = android_funcs; - return ALC_TRUE; -} - -void alc_android_deinit(void) -{ - JNIEnv* env = GetEnv(); - - /* release cached AudioTrack class */ - (*env)->DeleteGlobalRef(env, cAudioTrack); -} - -void alc_android_probe(enum DevProbe type) -{ - switch(type) - { - case DEVICE_PROBE: - AppendDeviceList(android_device); - break; - case ALL_DEVICE_PROBE: - AppendAllDeviceList(android_device); - break; - case CAPTURE_DEVICE_PROBE: - break; - } -} diff --git a/jni/openal-soft-android/Alc/backends/base.c b/jni/openal-soft-android/Alc/backends/base.c new file mode 100644 index 00000000..fe797562 --- /dev/null +++ b/jni/openal-soft-android/Alc/backends/base.c @@ -0,0 +1,230 @@ + +#include "config.h" + +#include + +#include "alMain.h" + +#include "backends/base.h" + + +/* Base ALCbackend method implementations. */ +void ALCbackend_Construct(ALCbackend *self, ALCdevice *device) +{ + self->mDevice = device; + InitializeCriticalSection(&self->mMutex); +} + +void ALCbackend_Destruct(ALCbackend *self) +{ + DeleteCriticalSection(&self->mMutex); +} + +ALCboolean ALCbackend_reset(ALCbackend* UNUSED(self)) +{ + return ALC_FALSE; +} + +ALCenum ALCbackend_captureSamples(ALCbackend* UNUSED(self), void* UNUSED(buffer), ALCuint UNUSED(samples)) +{ + return ALC_INVALID_DEVICE; +} + +ALCuint ALCbackend_availableSamples(ALCbackend* UNUSED(self)) +{ + return 0; +} + +ALint64 ALCbackend_getLatency(ALCbackend* UNUSED(self)) +{ + return 0; +} + +void ALCbackend_lock(ALCbackend *self) +{ + EnterCriticalSection(&self->mMutex); +} + +void ALCbackend_unlock(ALCbackend *self) +{ + LeaveCriticalSection(&self->mMutex); +} + + +/* Base ALCbackendFactory method implementations. */ +void ALCbackendFactory_deinit(ALCbackendFactory* UNUSED(self)) +{ +} + + +/* Wrappers to use an old-style backend with the new interface. */ +typedef struct PlaybackWrapper { + DERIVE_FROM_TYPE(ALCbackend); +} PlaybackWrapper; + +static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device); +static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, Destruct) +static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name); +static void PlaybackWrapper_close(PlaybackWrapper *self); +static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self); +static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self); +static void PlaybackWrapper_stop(PlaybackWrapper *self); +static DECLARE_FORWARD2(PlaybackWrapper, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALCuint, availableSamples) +static ALint64 PlaybackWrapper_getLatency(PlaybackWrapper *self); +static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, lock) +static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, unlock) +static void PlaybackWrapper_Delete(PlaybackWrapper *self); +DEFINE_ALCBACKEND_VTABLE(PlaybackWrapper); + +static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(PlaybackWrapper, ALCbackend, self); +} + +static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->OpenPlayback(device, name); +} + +static void PlaybackWrapper_close(PlaybackWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + device->Funcs->ClosePlayback(device); +} + +static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->ResetPlayback(device); +} + +static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->StartPlayback(device); +} + +static void PlaybackWrapper_stop(PlaybackWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + device->Funcs->StopPlayback(device); +} + +static ALint64 PlaybackWrapper_getLatency(PlaybackWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->GetLatency(device); +} + +static void PlaybackWrapper_Delete(PlaybackWrapper *self) +{ + free(self); +} + + +typedef struct CaptureWrapper { + DERIVE_FROM_TYPE(ALCbackend); +} CaptureWrapper; + +static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device); +static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, Destruct) +static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name); +static void CaptureWrapper_close(CaptureWrapper *self); +static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ALCboolean, reset) +static ALCboolean CaptureWrapper_start(CaptureWrapper *self); +static void CaptureWrapper_stop(CaptureWrapper *self); +static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples); +static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self); +static ALint64 CaptureWrapper_getLatency(CaptureWrapper *self); +static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, lock) +static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, unlock) +static void CaptureWrapper_Delete(CaptureWrapper *self); +DEFINE_ALCBACKEND_VTABLE(CaptureWrapper); + + +static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(CaptureWrapper, ALCbackend, self); +} + +static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->OpenCapture(device, name); +} + +static void CaptureWrapper_close(CaptureWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + device->Funcs->CloseCapture(device); +} + +static ALCboolean CaptureWrapper_start(CaptureWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + device->Funcs->StartCapture(device); + return ALC_TRUE; +} + +static void CaptureWrapper_stop(CaptureWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + device->Funcs->StopCapture(device); +} + +static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->CaptureSamples(device, buffer, samples); +} + +static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->AvailableSamples(device); +} + +static ALint64 CaptureWrapper_getLatency(CaptureWrapper *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + return device->Funcs->GetLatency(device); +} + +static void CaptureWrapper_Delete(CaptureWrapper *self) +{ + free(self); +} + + +ALCbackend *create_backend_wrapper(ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + PlaybackWrapper *backend; + + backend = malloc(sizeof(*backend)); + if(!backend) return NULL; + + PlaybackWrapper_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + + if(type == ALCbackend_Capture) + { + CaptureWrapper *backend; + + backend = malloc(sizeof(*backend)); + if(!backend) return NULL; + + CaptureWrapper_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} diff --git a/jni/openal-soft-android/Alc/backends/base.h b/jni/openal-soft-android/Alc/backends/base.h new file mode 100644 index 00000000..1bbc1fb0 --- /dev/null +++ b/jni/openal-soft-android/Alc/backends/base.h @@ -0,0 +1,133 @@ +#ifndef AL_BACKENDS_BASE_H +#define AL_BACKENDS_BASE_H + +#include "alMain.h" +#include "compat.h" + + +struct ALCbackendVtable; + +typedef struct ALCbackend { + const struct ALCbackendVtable *vtbl; + + ALCdevice *mDevice; + + CRITICAL_SECTION mMutex; +} ALCbackend; + +void ALCbackend_Construct(ALCbackend *self, ALCdevice *device); +void ALCbackend_Destruct(ALCbackend *self); +ALCboolean ALCbackend_reset(ALCbackend *self); +ALCenum ALCbackend_captureSamples(ALCbackend *self, void *buffer, ALCuint samples); +ALCuint ALCbackend_availableSamples(ALCbackend *self); +ALint64 ALCbackend_getLatency(ALCbackend *self); +void ALCbackend_lock(ALCbackend *self); +void ALCbackend_unlock(ALCbackend *self); + +struct ALCbackendVtable { + void (*const Destruct)(ALCbackend*); + + ALCenum (*const open)(ALCbackend*, const ALCchar*); + void (*const close)(ALCbackend*); + + ALCboolean (*const reset)(ALCbackend*); + ALCboolean (*const start)(ALCbackend*); + void (*const stop)(ALCbackend*); + + ALCenum (*const captureSamples)(ALCbackend*, void*, ALCuint); + ALCuint (*const availableSamples)(ALCbackend*); + + ALint64 (*const getLatency)(ALCbackend*); + + void (*const lock)(ALCbackend*); + void (*const unlock)(ALCbackend*); + + void (*const Delete)(ALCbackend*); +}; + +#define DECLARE_ALCBACKEND_VTABLE(T) \ +static const struct ALCbackendVtable T##_ALCbackend_vtable + +#define DEFINE_ALCBACKEND_VTABLE(T) \ +DECLARE_THUNK(T, ALCbackend, void, Destruct) \ +DECLARE_THUNK1(T, ALCbackend, ALCenum, open, const ALCchar*) \ +DECLARE_THUNK(T, ALCbackend, void, close) \ +DECLARE_THUNK(T, ALCbackend, ALCboolean, reset) \ +DECLARE_THUNK(T, ALCbackend, ALCboolean, start) \ +DECLARE_THUNK(T, ALCbackend, void, stop) \ +DECLARE_THUNK2(T, ALCbackend, ALCenum, captureSamples, void*, ALCuint) \ +DECLARE_THUNK(T, ALCbackend, ALCuint, availableSamples) \ +DECLARE_THUNK(T, ALCbackend, ALint64, getLatency) \ +DECLARE_THUNK(T, ALCbackend, void, lock) \ +DECLARE_THUNK(T, ALCbackend, void, unlock) \ +DECLARE_THUNK(T, ALCbackend, void, Delete) \ + \ +DECLARE_ALCBACKEND_VTABLE(T) = { \ + T##_ALCbackend_Destruct, \ + \ + T##_ALCbackend_open, \ + T##_ALCbackend_close, \ + T##_ALCbackend_reset, \ + T##_ALCbackend_start, \ + T##_ALCbackend_stop, \ + T##_ALCbackend_captureSamples, \ + T##_ALCbackend_availableSamples, \ + T##_ALCbackend_getLatency, \ + T##_ALCbackend_lock, \ + T##_ALCbackend_unlock, \ + \ + T##_ALCbackend_Delete, \ +} + + +typedef enum ALCbackend_Type { + ALCbackend_Playback, + ALCbackend_Capture, + ALCbackend_Loopback +} ALCbackend_Type; + + +struct ALCbackendFactoryVtable; + +typedef struct ALCbackendFactory { + const struct ALCbackendFactoryVtable *vtbl; +} ALCbackendFactory; + +void ALCbackendFactory_deinit(ALCbackendFactory *self); + +struct ALCbackendFactoryVtable { + ALCboolean (*const init)(ALCbackendFactory *self); + void (*const deinit)(ALCbackendFactory *self); + + ALCboolean (*const querySupport)(ALCbackendFactory *self, ALCbackend_Type type); + + void (*const probe)(ALCbackendFactory *self, enum DevProbe type); + + ALCbackend* (*const createBackend)(ALCbackendFactory *self, ALCdevice *device, ALCbackend_Type type); +}; + +#define DEFINE_ALCBACKENDFACTORY_VTABLE(T) \ +DECLARE_THUNK(T, ALCbackendFactory, ALCboolean, init) \ +DECLARE_THUNK(T, ALCbackendFactory, void, deinit) \ +DECLARE_THUNK1(T, ALCbackendFactory, ALCboolean, querySupport, ALCbackend_Type) \ +DECLARE_THUNK1(T, ALCbackendFactory, void, probe, enum DevProbe) \ +DECLARE_THUNK2(T, ALCbackendFactory, ALCbackend*, createBackend, ALCdevice*, ALCbackend_Type) \ + \ +static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \ + T##_ALCbackendFactory_init, \ + T##_ALCbackendFactory_deinit, \ + T##_ALCbackendFactory_querySupport, \ + T##_ALCbackendFactory_probe, \ + T##_ALCbackendFactory_createBackend, \ +} + + +ALCbackendFactory *ALCpulseBackendFactory_getFactory(void); +ALCbackendFactory *ALCalsaBackendFactory_getFactory(void); +ALCbackendFactory *ALCossBackendFactory_getFactory(void); +ALCbackendFactory *ALCnullBackendFactory_getFactory(void); +ALCbackendFactory *ALCloopbackFactory_getFactory(void); + +ALCbackend *create_backend_wrapper(ALCdevice *device, ALCbackend_Type type); + +#endif /* AL_BACKENDS_BASE_H */ diff --git a/jni/openal-soft-android/Alc/backends/coreaudio.c b/jni/openal-soft-android/Alc/backends/coreaudio.c index 7ac43325..5c9b69c8 100644 --- a/jni/openal-soft-android/Alc/backends/coreaudio.c +++ b/jni/openal-soft-android/Alc/backends/coreaudio.c @@ -25,8 +25,7 @@ #include #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" #include #include @@ -162,17 +161,27 @@ static ALCenum ca_open_playback(ALCdevice *device, const ALCchar *deviceName) } data = calloc(1, sizeof(*data)); - device->ExtraData = data; err = OpenAComponent(comp, &data->audioUnit); if(err != noErr) { ERR("OpenAComponent failed\n"); free(data); - device->ExtraData = NULL; return ALC_INVALID_VALUE; } + /* init and start the default audio unit... */ + err = AudioUnitInitialize(data->audioUnit); + if(err != noErr) + { + ERR("AudioUnitInitialize failed\n"); + CloseComponent(data->audioUnit); + free(data); + return ALC_INVALID_VALUE; + } + + device->DeviceName = strdup(deviceName); + device->ExtraData = data; return ALC_NO_ERROR; } @@ -180,6 +189,7 @@ static void ca_close_playback(ALCdevice *device) { ca_data *data = (ca_data*)device->ExtraData; + AudioUnitUninitialize(data->audioUnit); CloseComponent(data->audioUnit); free(data); @@ -194,20 +204,9 @@ static ALCboolean ca_reset_playback(ALCdevice *device) OSStatus err; UInt32 size; - /* init and start the default audio unit... */ - err = AudioUnitInitialize(data->audioUnit); + err = AudioUnitUninitialize(data->audioUnit); if(err != noErr) - { - ERR("AudioUnitInitialize failed\n"); - return ALC_FALSE; - } - - err = AudioOutputUnitStart(data->audioUnit); - if(err != noErr) - { - ERR("AudioOutputUnitStart failed\n"); - return ALC_FALSE; - } + ERR("-- AudioUnitUninitialize failed.\n"); /* retrieve default output unit's properties (output side) */ size = sizeof(AudioStreamBasicDescription); @@ -238,10 +237,6 @@ static ALCboolean ca_reset_playback(ALCdevice *device) if(device->Frequency != streamFormat.mSampleRate) { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("CoreAudio does not support changing sample rates (wanted %dhz, got %dhz)\n", device->Frequency, streamFormat.mSampleRate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * streamFormat.mSampleRate / device->Frequency); @@ -253,62 +248,25 @@ static ALCboolean ca_reset_playback(ALCdevice *device) switch(streamFormat.mChannelsPerFrame) { case 1: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtMono) - { - ERR("Failed to set %s, got Mono instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtMono; break; case 2: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtStereo) - { - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtStereo; break; case 4: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtQuad) - { - ERR("Failed to set %s, got Quad instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtQuad; break; case 6: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtX51) - { - ERR("Failed to set %s, got 5.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtX51; break; case 7: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtX61) - { - ERR("Failed to set %s, got 6.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtX61; break; case 8: - if((device->Flags&DEVICE_CHANNELS_REQUEST) && - device->FmtChans != DevFmtX71) - { - ERR("Failed to set %s, got 7.1 Surround instead\n", DevFmtChannelsString(device->FmtChans)); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - } device->FmtChans = DevFmtX71; break; default: ERR("Unhandled channel count (%d), using Stereo\n", streamFormat.mChannelsPerFrame); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; device->FmtChans = DevFmtStereo; streamFormat.mChannelsPerFrame = 2; break; @@ -318,30 +276,41 @@ static ALCboolean ca_reset_playback(ALCdevice *device) /* use channel count and sample rate from the default output unit's current * parameters, but reset everything else */ streamFormat.mFramesPerPacket = 1; + streamFormat.mFormatFlags = 0; switch(device->FmtType) { case DevFmtUByte: device->FmtType = DevFmtByte; /* fall-through */ case DevFmtByte: + streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; streamFormat.mBitsPerChannel = 8; - streamFormat.mBytesPerPacket = streamFormat.mChannelsPerFrame; - streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame; break; case DevFmtUShort: - case DevFmtFloat: device->FmtType = DevFmtShort; /* fall-through */ case DevFmtShort: + streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; streamFormat.mBitsPerChannel = 16; - streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame; - streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame; + break; + case DevFmtUInt: + device->FmtType = DevFmtInt; + /* fall-through */ + case DevFmtInt: + streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; + streamFormat.mBitsPerChannel = 32; + break; + case DevFmtFloat: + streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat; + streamFormat.mBitsPerChannel = 32; break; } + streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame * + streamFormat.mBitsPerChannel / 8; + streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame; streamFormat.mFormatID = kAudioFormatLinearPCM; - streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | - kAudioFormatFlagsNativeEndian | - kLinearPCMFormatFlagIsPacked; + streamFormat.mFormatFlags |= kAudioFormatFlagsNativeEndian | + kLinearPCMFormatFlagIsPacked; err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(AudioStreamBasicDescription)); if(err != noErr) @@ -362,6 +331,29 @@ static ALCboolean ca_reset_playback(ALCdevice *device) return ALC_FALSE; } + /* init the default audio unit... */ + err = AudioUnitInitialize(data->audioUnit); + if(err != noErr) + { + ERR("AudioUnitInitialize failed\n"); + return ALC_FALSE; + } + + return ALC_TRUE; +} + +static ALCboolean ca_start_playback(ALCdevice *device) +{ + ca_data *data = (ca_data*)device->ExtraData; + OSStatus err; + + err = AudioOutputUnitStart(data->audioUnit); + if(err != noErr) + { + ERR("AudioOutputUnitStart failed\n"); + return ALC_FALSE; + } + return ALC_TRUE; } @@ -370,10 +362,9 @@ static void ca_stop_playback(ALCdevice *device) ca_data *data = (ca_data*)device->ExtraData; OSStatus err; - AudioOutputUnitStop(data->audioUnit); - err = AudioUnitUninitialize(data->audioUnit); + err = AudioOutputUnitStop(data->audioUnit); if(err != noErr) - ERR("-- AudioUnitUninitialize failed.\n"); + ERR("AudioOutputUnitStop failed\n"); } static ALCenum ca_open_capture(ALCdevice *device, const ALCchar *deviceName) @@ -496,12 +487,17 @@ static ALCenum ca_open_capture(ALCdevice *device, const ALCchar *deviceName) requestedFormat.mBitsPerChannel = 16; requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; break; + case DevFmtInt: + requestedFormat.mBitsPerChannel = 32; + requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; + break; case DevFmtFloat: requestedFormat.mBitsPerChannel = 32; requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked; break; case DevFmtByte: case DevFmtUShort: + case DevFmtUInt: ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType)); goto error; } @@ -673,13 +669,15 @@ static const BackendFuncs ca_funcs = { ca_open_playback, ca_close_playback, ca_reset_playback, + ca_start_playback, ca_stop_playback, ca_open_capture, ca_close_capture, ca_start_capture, ca_stop_capture, ca_capture_samples, - ca_available_samples + ca_available_samples, + ALCdevice_GetLatencyDefault }; ALCboolean alc_ca_init(BackendFuncs *func_list) @@ -696,11 +694,8 @@ void alc_ca_probe(enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - AppendDeviceList(ca_device); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(ca_device); + AppendAllDevicesList(ca_device); break; case CAPTURE_DEVICE_PROBE: AppendCaptureDeviceList(ca_device); diff --git a/jni/openal-soft-android/Alc/backends/dsound.c b/jni/openal-soft-android/Alc/backends/dsound.c index f1dd0762..6b108fba 100644 --- a/jni/openal-soft-android/Alc/backends/dsound.c +++ b/jni/openal-soft-android/Alc/backends/dsound.c @@ -33,39 +33,60 @@ #endif #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" #ifndef DSSPEAKER_5POINT1 -#define DSSPEAKER_5POINT1 6 +# define DSSPEAKER_5POINT1 0x00000006 #endif #ifndef DSSPEAKER_7POINT1 -#define DSSPEAKER_7POINT1 7 +# define DSSPEAKER_7POINT1 0x00000007 #endif +#ifndef DSSPEAKER_7POINT1_SURROUND +# define DSSPEAKER_7POINT1_SURROUND 0x00000008 +#endif +#ifndef DSSPEAKER_5POINT1_SURROUND +# define DSSPEAKER_5POINT1_SURROUND 0x00000009 +#endif + DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); -static HMODULE ds_handle; +static void *ds_handle; static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, IDirectSound **ppDS, IUnknown *pUnkOuter); static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, void *pContext); +static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID pcGuidDevice, IDirectSoundCapture **ppDSC, IUnknown *pUnkOuter); +static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, void *pContext); -#define DirectSoundCreate pDirectSoundCreate -#define DirectSoundEnumerateA pDirectSoundEnumerateA +#define DirectSoundCreate pDirectSoundCreate +#define DirectSoundEnumerateA pDirectSoundEnumerateA +#define DirectSoundCaptureCreate pDirectSoundCaptureCreate +#define DirectSoundCaptureEnumerateA pDirectSoundCaptureEnumerateA typedef struct { // DirectSound Playback Device - IDirectSound *lpDS; - IDirectSoundBuffer *DSpbuffer; - IDirectSoundBuffer *DSsbuffer; - IDirectSoundNotify *DSnotify; - HANDLE hNotifyEvent; + IDirectSound *DS; + IDirectSoundBuffer *PrimaryBuffer; + IDirectSoundBuffer *Buffer; + IDirectSoundNotify *Notifies; + HANDLE NotifyEvent; volatile int killNow; - ALvoid *thread; -} DSoundData; + althread_t thread; +} DSoundPlaybackData; + +typedef struct { + // DirectSound Capture Device + IDirectSoundCapture *DSC; + IDirectSoundCaptureBuffer *DSCbuffer; + DWORD BufferBytes; + DWORD Cursor; + RingBuffer *Ring; +} DSoundCaptureData; typedef struct { @@ -73,54 +94,51 @@ typedef struct { GUID guid; } DevMap; -static const ALCchar dsDevice[] = "DirectSound Default"; -static DevMap *DeviceList; -static ALuint NumDevices; +static DevMap *PlaybackDeviceList; +static ALuint NumPlaybackDevices; +static DevMap *CaptureDeviceList; +static ALuint NumCaptureDevices; #define MAX_UPDATES 128 static ALCboolean DSoundLoad(void) { - ALCboolean ok = ALC_TRUE; if(!ds_handle) { - ds_handle = LoadLibraryA("dsound.dll"); + ds_handle = LoadLib("dsound.dll"); if(ds_handle == NULL) { ERR("Failed to load dsound.dll\n"); return ALC_FALSE; } -#define LOAD_FUNC(x) do { \ - if((p##x = (void*)GetProcAddress(ds_handle, #x)) == NULL) { \ - ERR("Could not load %s from dsound.dll\n", #x); \ - ok = ALC_FALSE; \ +#define LOAD_FUNC(f) do { \ + p##f = GetSymbol(ds_handle, #f); \ + if(p##f == NULL) { \ + CloseLib(ds_handle); \ + ds_handle = NULL; \ + return ALC_FALSE; \ } \ } while(0) LOAD_FUNC(DirectSoundCreate); LOAD_FUNC(DirectSoundEnumerateA); + LOAD_FUNC(DirectSoundCaptureCreate); + LOAD_FUNC(DirectSoundCaptureEnumerateA); #undef LOAD_FUNC - - if(!ok) - { - FreeLibrary(ds_handle); - ds_handle = NULL; - } } - return ok; + return ALC_TRUE; } -static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data) +static BOOL CALLBACK DSoundEnumPlaybackDevices(LPGUID guid, LPCSTR desc, LPCSTR UNUSED(drvname), LPVOID UNUSED(data)) { + LPOLESTR guidstr = NULL; char str[1024]; + HRESULT hr; void *temp; int count; ALuint i; - (void)data; - (void)drvname; - if(!guid) return TRUE; @@ -132,30 +150,84 @@ static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, snprintf(str, sizeof(str), "%s #%d", desc, count+1); count++; - for(i = 0;i < NumDevices;i++) + for(i = 0;i < NumPlaybackDevices;i++) { - if(strcmp(str, DeviceList[i].name) == 0) + if(strcmp(str, PlaybackDeviceList[i].name) == 0) break; } - } while(i != NumDevices); + } while(i != NumPlaybackDevices); - temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1)); + hr = StringFromCLSID(guid, &guidstr); + if(SUCCEEDED(hr)) + { + TRACE("Got device \"%s\", GUID \"%ls\"\n", str, guidstr); + CoTaskMemFree(guidstr); + } + + temp = realloc(PlaybackDeviceList, sizeof(DevMap) * (NumPlaybackDevices+1)); if(temp) { - DeviceList = temp; - DeviceList[NumDevices].name = strdup(str); - DeviceList[NumDevices].guid = *guid; - NumDevices++; + PlaybackDeviceList = temp; + PlaybackDeviceList[NumPlaybackDevices].name = strdup(str); + PlaybackDeviceList[NumPlaybackDevices].guid = *guid; + NumPlaybackDevices++; } return TRUE; } -static ALuint DSoundProc(ALvoid *ptr) +static BOOL CALLBACK DSoundEnumCaptureDevices(LPGUID guid, LPCSTR desc, LPCSTR UNUSED(drvname), LPVOID UNUSED(data)) { - ALCdevice *pDevice = (ALCdevice*)ptr; - DSoundData *pData = (DSoundData*)pDevice->ExtraData; + LPOLESTR guidstr = NULL; + char str[1024]; + HRESULT hr; + void *temp; + int count; + ALuint i; + + if(!guid) + return TRUE; + + count = 0; + do { + if(count == 0) + snprintf(str, sizeof(str), "%s", desc); + else + snprintf(str, sizeof(str), "%s #%d", desc, count+1); + count++; + + for(i = 0;i < NumCaptureDevices;i++) + { + if(strcmp(str, CaptureDeviceList[i].name) == 0) + break; + } + } while(i != NumCaptureDevices); + + hr = StringFromCLSID(guid, &guidstr); + if(SUCCEEDED(hr)) + { + TRACE("Got device \"%s\", GUID \"%ls\"\n", str, guidstr); + CoTaskMemFree(guidstr); + } + + temp = realloc(CaptureDeviceList, sizeof(DevMap) * (NumCaptureDevices+1)); + if(temp) + { + CaptureDeviceList = temp; + CaptureDeviceList[NumCaptureDevices].name = strdup(str); + CaptureDeviceList[NumCaptureDevices].guid = *guid; + NumCaptureDevices++; + } + + return TRUE; +} + + +FORCE_ALIGN static ALuint DSoundPlaybackProc(ALvoid *ptr) +{ + ALCdevice *Device = (ALCdevice*)ptr; + DSoundPlaybackData *data = (DSoundPlaybackData*)Device->ExtraData; DSBCAPS DSBCaps; DWORD LastCursor = 0; DWORD PlayCursor; @@ -168,42 +240,47 @@ static ALuint DSoundProc(ALvoid *ptr) HRESULT err; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); memset(&DSBCaps, 0, sizeof(DSBCaps)); DSBCaps.dwSize = sizeof(DSBCaps); - err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps); + err = IDirectSoundBuffer_GetCaps(data->Buffer, &DSBCaps); if(FAILED(err)) { ERR("Failed to get buffer caps: 0x%lx\n", err); - aluHandleDisconnect(pDevice); + ALCdevice_Lock(Device); + aluHandleDisconnect(Device); + ALCdevice_Unlock(Device); return 1; } - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); - FragSize = pDevice->UpdateSize * FrameSize; + FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); + FragSize = Device->UpdateSize * FrameSize; - IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL); - while(!pData->killNow) + IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &LastCursor, NULL); + while(!data->killNow) { // Get current play cursor - IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL); + IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &PlayCursor, NULL); avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes; if(avail < FragSize) { if(!Playing) { - err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING); + err = IDirectSoundBuffer_Play(data->Buffer, 0, 0, DSBPLAY_LOOPING); if(FAILED(err)) { ERR("Failed to play buffer: 0x%lx\n", err); - aluHandleDisconnect(pDevice); + ALCdevice_Lock(Device); + aluHandleDisconnect(Device); + ALCdevice_Unlock(Device); return 1; } Playing = TRUE; } - avail = WaitForSingleObjectEx(pData->hNotifyEvent, 2000, FALSE); + avail = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE); if(avail != WAIT_OBJECT_0) ERR("WaitForSingleObjectEx error: 0x%lx\n", avail); continue; @@ -213,18 +290,18 @@ static ALuint DSoundProc(ALvoid *ptr) // Lock output buffer WriteCnt1 = 0; WriteCnt2 = 0; - err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); + err = IDirectSoundBuffer_Lock(data->Buffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); // If the buffer is lost, restore it and lock if(err == DSERR_BUFFERLOST) { WARN("Buffer lost, restoring...\n"); - err = IDirectSoundBuffer_Restore(pData->DSsbuffer); + err = IDirectSoundBuffer_Restore(data->Buffer); if(SUCCEEDED(err)) { Playing = FALSE; LastCursor = 0; - err = IDirectSoundBuffer_Lock(pData->DSsbuffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); + err = IDirectSoundBuffer_Lock(data->Buffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0); } } @@ -232,16 +309,18 @@ static ALuint DSoundProc(ALvoid *ptr) if(SUCCEEDED(err)) { // If we have an active context, mix data directly into output buffer otherwise fill with silence - aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize); - aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize); + aluMixData(Device, WritePtr1, WriteCnt1/FrameSize); + aluMixData(Device, WritePtr2, WriteCnt2/FrameSize); // Unlock output buffer only when successfully locked - IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2); + IDirectSoundBuffer_Unlock(data->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2); } else { ERR("Buffer lock error: %#lx\n", err); - aluHandleDisconnect(pDevice); + ALCdevice_Lock(Device); + aluHandleDisconnect(Device); + ALCdevice_Unlock(Device); return 1; } @@ -255,79 +334,92 @@ static ALuint DSoundProc(ALvoid *ptr) static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { - DSoundData *pData = NULL; + DSoundPlaybackData *data = NULL; LPGUID guid = NULL; HRESULT hr; - if(!deviceName) - deviceName = dsDevice; - else if(strcmp(deviceName, dsDevice) != 0) + if(!PlaybackDeviceList) + { + hr = DirectSoundEnumerateA(DSoundEnumPlaybackDevices, NULL); + if(FAILED(hr)) + ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); + } + + if(!deviceName && NumPlaybackDevices > 0) + { + deviceName = PlaybackDeviceList[0].name; + guid = &PlaybackDeviceList[0].guid; + } + else { ALuint i; - if(!DeviceList) + for(i = 0;i < NumPlaybackDevices;i++) { - hr = DirectSoundEnumerateA(DSoundEnumDevices, NULL); - if(FAILED(hr)) - ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); - } - - for(i = 0;i < NumDevices;i++) - { - if(strcmp(deviceName, DeviceList[i].name) == 0) + if(strcmp(deviceName, PlaybackDeviceList[i].name) == 0) { - guid = &DeviceList[i].guid; + guid = &PlaybackDeviceList[i].guid; break; } } - if(i == NumDevices) + if(i == NumPlaybackDevices) return ALC_INVALID_VALUE; } //Initialise requested device - pData = calloc(1, sizeof(DSoundData)); - if(!pData) + data = calloc(1, sizeof(DSoundPlaybackData)); + if(!data) return ALC_OUT_OF_MEMORY; hr = DS_OK; - pData->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if(pData->hNotifyEvent == NULL) + data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if(data->NotifyEvent == NULL) hr = E_FAIL; //DirectSound Init code if(SUCCEEDED(hr)) - hr = DirectSoundCreate(guid, &pData->lpDS, NULL); + hr = DirectSoundCreate(guid, &data->DS, NULL); if(SUCCEEDED(hr)) - hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); + hr = IDirectSound_SetCooperativeLevel(data->DS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { - if(pData->lpDS) - IDirectSound_Release(pData->lpDS); - if(pData->hNotifyEvent) - CloseHandle(pData->hNotifyEvent); - free(pData); + if(data->DS) + IDirectSound_Release(data->DS); + if(data->NotifyEvent) + CloseHandle(data->NotifyEvent); + free(data); ERR("Device init failed: 0x%08lx\n", hr); return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); - device->ExtraData = pData; + device->DeviceName = strdup(deviceName); + device->ExtraData = data; return ALC_NO_ERROR; } static void DSoundClosePlayback(ALCdevice *device) { - DSoundData *pData = device->ExtraData; + DSoundPlaybackData *data = device->ExtraData; - IDirectSound_Release(pData->lpDS); - CloseHandle(pData->hNotifyEvent); - free(pData); + if(data->Notifies) + IDirectSoundNotify_Release(data->Notifies); + data->Notifies = NULL; + if(data->Buffer) + IDirectSoundBuffer_Release(data->Buffer); + data->Buffer = NULL; + if(data->PrimaryBuffer != NULL) + IDirectSoundBuffer_Release(data->PrimaryBuffer); + data->PrimaryBuffer = NULL; + + IDirectSound_Release(data->DS); + CloseHandle(data->NotifyEvent); + free(data); device->ExtraData = NULL; } static ALCboolean DSoundResetPlayback(ALCdevice *device) { - DSoundData *pData = (DSoundData*)device->ExtraData; + DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData; DSBUFFERDESC DSBDescription; WAVEFORMATEXTENSIBLE OutputType; DWORD speakers; @@ -335,21 +427,38 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) memset(&OutputType, 0, sizeof(OutputType)); + if(data->Notifies) + IDirectSoundNotify_Release(data->Notifies); + data->Notifies = NULL; + if(data->Buffer) + IDirectSoundBuffer_Release(data->Buffer); + data->Buffer = NULL; + if(data->PrimaryBuffer != NULL) + IDirectSoundBuffer_Release(data->PrimaryBuffer); + data->PrimaryBuffer = NULL; + switch(device->FmtType) { case DevFmtByte: device->FmtType = DevFmtUByte; break; + case DevFmtFloat: + if((device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)) + break; + /* fall-through */ case DevFmtUShort: device->FmtType = DevFmtShort; break; + case DevFmtUInt: + device->FmtType = DevFmtInt; + break; case DevFmtUByte: case DevFmtShort: - case DevFmtFloat: + case DevFmtInt: break; } - hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers); + hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers); if(SUCCEEDED(hr)) { if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) @@ -361,9 +470,9 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) device->FmtChans = DevFmtStereo; else if(speakers == DSSPEAKER_QUAD) device->FmtChans = DevFmtQuad; - else if(speakers == DSSPEAKER_5POINT1) + else if(speakers == DSSPEAKER_5POINT1 || speakers == DSSPEAKER_5POINT1_SURROUND) device->FmtChans = DevFmtX51; - else if(speakers == DSSPEAKER_7POINT1) + else if(speakers == DSSPEAKER_7POINT1 || speakers == DSSPEAKER_7POINT1_SURROUND) device->FmtChans = DevFmtX71; else ERR("Unknown system speaker config: 0x%lx\n", speakers); @@ -421,6 +530,8 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) break; } +retry_open: + hr = S_OK; OutputType.Format.wFormatTag = WAVE_FORMAT_PCM; OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; @@ -439,18 +550,22 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; else OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + + if(data->PrimaryBuffer) + IDirectSoundBuffer_Release(data->PrimaryBuffer); + data->PrimaryBuffer = NULL; } else { - if(SUCCEEDED(hr)) + if(SUCCEEDED(hr) && !data->PrimaryBuffer) { memset(&DSBDescription,0,sizeof(DSBUFFERDESC)); DSBDescription.dwSize=sizeof(DSBUFFERDESC); DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER; - hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL); + hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->PrimaryBuffer, NULL); } if(SUCCEEDED(hr)) - hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format); + hr = IDirectSoundBuffer_SetFormat(data->PrimaryBuffer,&OutputType.Format); } if(SUCCEEDED(hr)) @@ -468,12 +583,17 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * OutputType.Format.nBlockAlign; DSBDescription.lpwfxFormat=&OutputType.Format; - hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL); + hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->Buffer, NULL); + if(FAILED(hr) && device->FmtType == DevFmtFloat) + { + device->FmtType = DevFmtShort; + goto retry_open; + } } if(SUCCEEDED(hr)) { - hr = IDirectSoundBuffer_QueryInterface(pData->DSsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&pData->DSnotify); + hr = IDirectSoundBuffer_QueryInterface(data->Buffer, &IID_IDirectSoundNotify, (LPVOID *)&data->Notifies); if(SUCCEEDED(hr)) { DSBPOSITIONNOTIFY notifies[MAX_UPDATES]; @@ -483,59 +603,343 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device) { notifies[i].dwOffset = i * device->UpdateSize * OutputType.Format.nBlockAlign; - notifies[i].hEventNotify = pData->hNotifyEvent; + notifies[i].hEventNotify = data->NotifyEvent; } - if(IDirectSoundNotify_SetNotificationPositions(pData->DSnotify, device->NumUpdates, notifies) != DS_OK) + if(IDirectSoundNotify_SetNotificationPositions(data->Notifies, device->NumUpdates, notifies) != DS_OK) hr = E_FAIL; } } - if(SUCCEEDED(hr)) - { - ResetEvent(pData->hNotifyEvent); - SetDefaultWFXChannelOrder(device); - pData->thread = StartThread(DSoundProc, device); - if(pData->thread == NULL) - hr = E_FAIL; - } - if(FAILED(hr)) { - if(pData->DSnotify != NULL) - IDirectSoundNotify_Release(pData->DSnotify); - pData->DSnotify = NULL; - if(pData->DSsbuffer != NULL) - IDirectSoundBuffer_Release(pData->DSsbuffer); - pData->DSsbuffer = NULL; - if(pData->DSpbuffer != NULL) - IDirectSoundBuffer_Release(pData->DSpbuffer); - pData->DSpbuffer = NULL; + if(data->Notifies != NULL) + IDirectSoundNotify_Release(data->Notifies); + data->Notifies = NULL; + if(data->Buffer != NULL) + IDirectSoundBuffer_Release(data->Buffer); + data->Buffer = NULL; + if(data->PrimaryBuffer != NULL) + IDirectSoundBuffer_Release(data->PrimaryBuffer); + data->PrimaryBuffer = NULL; return ALC_FALSE; } + ResetEvent(data->NotifyEvent); + SetDefaultWFXChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean DSoundStartPlayback(ALCdevice *device) +{ + DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData; + + if(!StartThread(&data->thread, DSoundPlaybackProc, device)) + return ALC_FALSE; + return ALC_TRUE; } static void DSoundStopPlayback(ALCdevice *device) { - DSoundData *pData = device->ExtraData; + DSoundPlaybackData *data = device->ExtraData; - if(!pData->thread) + if(!data->thread) return; - pData->killNow = 1; - StopThread(pData->thread); - pData->thread = NULL; + data->killNow = 1; + StopThread(data->thread); + data->thread = NULL; - pData->killNow = 0; + data->killNow = 0; + IDirectSoundBuffer_Stop(data->Buffer); +} - IDirectSoundNotify_Release(pData->DSnotify); - pData->DSnotify = NULL; - IDirectSoundBuffer_Release(pData->DSsbuffer); - pData->DSsbuffer = NULL; - if(pData->DSpbuffer != NULL) - IDirectSoundBuffer_Release(pData->DSpbuffer); - pData->DSpbuffer = NULL; + +static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName) +{ + DSoundCaptureData *data = NULL; + WAVEFORMATEXTENSIBLE InputType; + DSCBUFFERDESC DSCBDescription; + LPGUID guid = NULL; + HRESULT hr, hrcom; + ALuint samples; + + if(!CaptureDeviceList) + { + /* Initialize COM to prevent name truncation */ + hrcom = CoInitialize(NULL); + hr = DirectSoundCaptureEnumerateA(DSoundEnumCaptureDevices, NULL); + if(FAILED(hr)) + ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); + if(SUCCEEDED(hrcom)) + CoUninitialize(); + } + + if(!deviceName && NumCaptureDevices > 0) + { + deviceName = CaptureDeviceList[0].name; + guid = &CaptureDeviceList[0].guid; + } + else + { + ALuint i; + + for(i = 0;i < NumCaptureDevices;i++) + { + if(strcmp(deviceName, CaptureDeviceList[i].name) == 0) + { + guid = &CaptureDeviceList[i].guid; + break; + } + } + if(i == NumCaptureDevices) + return ALC_INVALID_VALUE; + } + + switch(device->FmtType) + { + case DevFmtByte: + case DevFmtUShort: + case DevFmtUInt: + WARN("%s capture samples not supported\n", DevFmtTypeString(device->FmtType)); + return ALC_INVALID_ENUM; + + case DevFmtUByte: + case DevFmtShort: + case DevFmtInt: + case DevFmtFloat: + break; + } + + //Initialise requested device + data = calloc(1, sizeof(DSoundCaptureData)); + if(!data) + return ALC_OUT_OF_MEMORY; + + hr = DS_OK; + + //DirectSoundCapture Init code + if(SUCCEEDED(hr)) + hr = DirectSoundCaptureCreate(guid, &data->DSC, NULL); + if(SUCCEEDED(hr)) + { + memset(&InputType, 0, sizeof(InputType)); + + switch(device->FmtChans) + { + case DevFmtMono: + InputType.dwChannelMask = SPEAKER_FRONT_CENTER; + break; + case DevFmtStereo: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT; + break; + case DevFmtQuad: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; + break; + case DevFmtX51: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; + break; + case DevFmtX51Side: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + case DevFmtX61: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_CENTER | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + case DevFmtX71: + InputType.dwChannelMask = SPEAKER_FRONT_LEFT | + SPEAKER_FRONT_RIGHT | + SPEAKER_FRONT_CENTER | + SPEAKER_LOW_FREQUENCY | + SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT | + SPEAKER_SIDE_LEFT | + SPEAKER_SIDE_RIGHT; + break; + } + + InputType.Format.wFormatTag = WAVE_FORMAT_PCM; + InputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans); + InputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8; + InputType.Format.nBlockAlign = InputType.Format.nChannels*InputType.Format.wBitsPerSample/8; + InputType.Format.nSamplesPerSec = device->Frequency; + InputType.Format.nAvgBytesPerSec = InputType.Format.nSamplesPerSec*InputType.Format.nBlockAlign; + InputType.Format.cbSize = 0; + + if(InputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat) + { + InputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + InputType.Samples.wValidBitsPerSample = InputType.Format.wBitsPerSample; + if(device->FmtType == DevFmtFloat) + InputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + else + InputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + } + + samples = device->UpdateSize * device->NumUpdates; + samples = maxu(samples, 100 * device->Frequency / 1000); + + memset(&DSCBDescription, 0, sizeof(DSCBUFFERDESC)); + DSCBDescription.dwSize = sizeof(DSCBUFFERDESC); + DSCBDescription.dwFlags = 0; + DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign; + DSCBDescription.lpwfxFormat = &InputType.Format; + + hr = IDirectSoundCapture_CreateCaptureBuffer(data->DSC, &DSCBDescription, &data->DSCbuffer, NULL); + } + if(SUCCEEDED(hr)) + { + data->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates); + if(data->Ring == NULL) + hr = DSERR_OUTOFMEMORY; + } + + if(FAILED(hr)) + { + ERR("Device init failed: 0x%08lx\n", hr); + + DestroyRingBuffer(data->Ring); + data->Ring = NULL; + if(data->DSCbuffer != NULL) + IDirectSoundCaptureBuffer_Release(data->DSCbuffer); + data->DSCbuffer = NULL; + if(data->DSC) + IDirectSoundCapture_Release(data->DSC); + data->DSC = NULL; + + free(data); + return ALC_INVALID_VALUE; + } + + data->BufferBytes = DSCBDescription.dwBufferBytes; + SetDefaultWFXChannelOrder(device); + + device->DeviceName = strdup(deviceName); + device->ExtraData = data; + + return ALC_NO_ERROR; +} + +static void DSoundCloseCapture(ALCdevice *device) +{ + DSoundCaptureData *data = device->ExtraData; + + DestroyRingBuffer(data->Ring); + data->Ring = NULL; + + if(data->DSCbuffer != NULL) + { + IDirectSoundCaptureBuffer_Stop(data->DSCbuffer); + IDirectSoundCaptureBuffer_Release(data->DSCbuffer); + data->DSCbuffer = NULL; + } + + IDirectSoundCapture_Release(data->DSC); + data->DSC = NULL; + + free(data); + device->ExtraData = NULL; +} + +static void DSoundStartCapture(ALCdevice *device) +{ + DSoundCaptureData *data = device->ExtraData; + HRESULT hr; + + hr = IDirectSoundCaptureBuffer_Start(data->DSCbuffer, DSCBSTART_LOOPING); + if(FAILED(hr)) + { + ERR("start failed: 0x%08lx\n", hr); + aluHandleDisconnect(device); + } +} + +static void DSoundStopCapture(ALCdevice *device) +{ + DSoundCaptureData *data = device->ExtraData; + HRESULT hr; + + hr = IDirectSoundCaptureBuffer_Stop(data->DSCbuffer); + if(FAILED(hr)) + { + ERR("stop failed: 0x%08lx\n", hr); + aluHandleDisconnect(device); + } +} + +static ALCenum DSoundCaptureSamples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples) +{ + DSoundCaptureData *data = Device->ExtraData; + ReadRingBuffer(data->Ring, pBuffer, lSamples); + return ALC_NO_ERROR; +} + +static ALCuint DSoundAvailableSamples(ALCdevice *Device) +{ + DSoundCaptureData *data = Device->ExtraData; + DWORD ReadCursor, LastCursor, BufferBytes, NumBytes; + VOID *ReadPtr1, *ReadPtr2; + DWORD ReadCnt1, ReadCnt2; + DWORD FrameSize; + HRESULT hr; + + if(!Device->Connected) + goto done; + + FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); + BufferBytes = data->BufferBytes; + LastCursor = data->Cursor; + + hr = IDirectSoundCaptureBuffer_GetCurrentPosition(data->DSCbuffer, NULL, &ReadCursor); + if(SUCCEEDED(hr)) + { + NumBytes = (ReadCursor-LastCursor + BufferBytes) % BufferBytes; + if(NumBytes == 0) + goto done; + hr = IDirectSoundCaptureBuffer_Lock(data->DSCbuffer, LastCursor, NumBytes, + &ReadPtr1, &ReadCnt1, + &ReadPtr2, &ReadCnt2, 0); + } + if(SUCCEEDED(hr)) + { + WriteRingBuffer(data->Ring, ReadPtr1, ReadCnt1/FrameSize); + if(ReadPtr2 != NULL) + WriteRingBuffer(data->Ring, ReadPtr2, ReadCnt2/FrameSize); + hr = IDirectSoundCaptureBuffer_Unlock(data->DSCbuffer, + ReadPtr1, ReadCnt1, + ReadPtr2, ReadCnt2); + data->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes; + } + + if(FAILED(hr)) + { + ERR("update failed: 0x%08lx\n", hr); + aluHandleDisconnect(Device); + } + +done: + return RingBufferSize(data->Ring); } @@ -543,13 +947,15 @@ static const BackendFuncs DSoundFuncs = { DSoundOpenPlayback, DSoundClosePlayback, DSoundResetPlayback, + DSoundStartPlayback, DSoundStopPlayback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + DSoundOpenCapture, + DSoundCloseCapture, + DSoundStartCapture, + DSoundStopCapture, + DSoundCaptureSamples, + DSoundAvailableSamples, + ALCdevice_GetLatencyDefault }; @@ -565,46 +971,66 @@ void alcDSoundDeinit(void) { ALuint i; - for(i = 0;i < NumDevices;++i) - free(DeviceList[i].name); - free(DeviceList); - DeviceList = NULL; - NumDevices = 0; + for(i = 0;i < NumPlaybackDevices;++i) + free(PlaybackDeviceList[i].name); + free(PlaybackDeviceList); + PlaybackDeviceList = NULL; + NumPlaybackDevices = 0; + + for(i = 0;i < NumCaptureDevices;++i) + free(CaptureDeviceList[i].name); + free(CaptureDeviceList); + CaptureDeviceList = NULL; + NumCaptureDevices = 0; if(ds_handle) - FreeLibrary(ds_handle); + CloseLib(ds_handle); ds_handle = NULL; } void alcDSoundProbe(enum DevProbe type) { - HRESULT hr; + HRESULT hr, hrcom; ALuint i; switch(type) { - case DEVICE_PROBE: - AppendDeviceList(dsDevice); - break; - case ALL_DEVICE_PROBE: - for(i = 0;i < NumDevices;++i) - free(DeviceList[i].name); - free(DeviceList); - DeviceList = NULL; - NumDevices = 0; + for(i = 0;i < NumPlaybackDevices;++i) + free(PlaybackDeviceList[i].name); + free(PlaybackDeviceList); + PlaybackDeviceList = NULL; + NumPlaybackDevices = 0; - hr = DirectSoundEnumerateA(DSoundEnumDevices, NULL); + hr = DirectSoundEnumerateA(DSoundEnumPlaybackDevices, NULL); if(FAILED(hr)) - ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); + ERR("Error enumerating DirectSound playback devices (%#x)!\n", (unsigned int)hr); else { - for(i = 0;i < NumDevices;i++) - AppendAllDeviceList(DeviceList[i].name); + for(i = 0;i < NumPlaybackDevices;i++) + AppendAllDevicesList(PlaybackDeviceList[i].name); } break; case CAPTURE_DEVICE_PROBE: + for(i = 0;i < NumCaptureDevices;++i) + free(CaptureDeviceList[i].name); + free(CaptureDeviceList); + CaptureDeviceList = NULL; + NumCaptureDevices = 0; + + /* Initialize COM to prevent name truncation */ + hrcom = CoInitialize(NULL); + hr = DirectSoundCaptureEnumerateA(DSoundEnumCaptureDevices, NULL); + if(FAILED(hr)) + ERR("Error enumerating DirectSound capture devices (%#x)!\n", (unsigned int)hr); + else + { + for(i = 0;i < NumCaptureDevices;i++) + AppendCaptureDeviceList(CaptureDeviceList[i].name); + } + if(SUCCEEDED(hrcom)) + CoUninitialize(); break; } } diff --git a/jni/openal-soft-android/Alc/backends/loopback.c b/jni/openal-soft-android/Alc/backends/loopback.c index 8a576361..cd5b1a1e 100644 --- a/jni/openal-soft-android/Alc/backends/loopback.c +++ b/jni/openal-soft-android/Alc/backends/loopback.c @@ -21,57 +21,120 @@ #include "config.h" #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" + +#include "backends/base.h" -static ALCenum loopback_open_playback(ALCdevice *device, const ALCchar *deviceName) +typedef struct ALCloopback { + DERIVE_FROM_TYPE(ALCbackend); +} ALCloopback; + +static void ALCloopback_Construct(ALCloopback *self, ALCdevice *device); +static DECLARE_FORWARD(ALCloopback, ALCbackend, void, Destruct) +static ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name); +static void ALCloopback_close(ALCloopback *self); +static ALCboolean ALCloopback_reset(ALCloopback *self); +static ALCboolean ALCloopback_start(ALCloopback *self); +static void ALCloopback_stop(ALCloopback *self); +static DECLARE_FORWARD2(ALCloopback, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(ALCloopback, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCloopback, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCloopback, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCloopback, ALCbackend, void, unlock) +static void ALCloopback_Delete(ALCloopback *self); +DEFINE_ALCBACKEND_VTABLE(ALCloopback); + + +static void ALCloopback_Construct(ALCloopback *self, ALCdevice *device) { - device->szDeviceName = strdup(deviceName); + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCloopback, ALCbackend, self); +} + + +static ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + + device->DeviceName = strdup(name); return ALC_NO_ERROR; } -static void loopback_close_playback(ALCdevice *device) +static void ALCloopback_close(ALCloopback* UNUSED(self)) { - (void)device; } -static ALCboolean loopback_reset_playback(ALCdevice *device) +static ALCboolean ALCloopback_reset(ALCloopback *self) { - SetDefaultWFXChannelOrder(device); + SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice); return ALC_TRUE; } -static void loopback_stop_playback(ALCdevice *device) +static ALCboolean ALCloopback_start(ALCloopback* UNUSED(self)) { - (void)device; -} - -static const BackendFuncs loopback_funcs = { - loopback_open_playback, - loopback_close_playback, - loopback_reset_playback, - loopback_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -ALCboolean alc_loopback_init(BackendFuncs *func_list) -{ - *func_list = loopback_funcs; return ALC_TRUE; } -void alc_loopback_deinit(void) +static void ALCloopback_stop(ALCloopback* UNUSED(self)) { } -void alc_loopback_probe(enum DevProbe type) + +static void ALCloopback_Delete(ALCloopback *self) { - (void)type; + free(self); +} + + +typedef struct ALCloopbackFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCloopbackFactory; +#define ALCNULLBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCloopbackFactory, ALCbackendFactory) } } + +ALCbackendFactory *ALCloopbackFactory_getFactory(void); +static ALCboolean ALCloopbackFactory_init(ALCloopbackFactory *self); +static DECLARE_FORWARD(ALCloopbackFactory, ALCbackendFactory, void, deinit) +static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory *self, ALCbackend_Type type); +static void ALCloopbackFactory_probe(ALCloopbackFactory *self, enum DevProbe type); +static ALCbackend* ALCloopbackFactory_createBackend(ALCloopbackFactory *self, ALCdevice *device, ALCbackend_Type type); +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCloopbackFactory); + + +ALCbackendFactory *ALCloopbackFactory_getFactory(void) +{ + static ALCloopbackFactory factory = ALCNULLBACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} + +static ALCboolean ALCloopbackFactory_init(ALCloopbackFactory* UNUSED(self)) +{ + return ALC_TRUE; +} + +static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory* UNUSED(self), ALCbackend_Type type) +{ + if(type == ALCbackend_Loopback) + return ALC_TRUE; + return ALC_FALSE; +} + +static void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type)) +{ +} + +static ALCbackend* ALCloopbackFactory_createBackend(ALCloopbackFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + ALCloopback *backend; + + assert(type == ALCbackend_Loopback); + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCloopback_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); } diff --git a/jni/openal-soft-android/Alc/backends/mmdevapi.c b/jni/openal-soft-android/Alc/backends/mmdevapi.c index 275a839a..fa7c54f9 100644 --- a/jni/openal-soft-android/Alc/backends/mmdevapi.c +++ b/jni/openal-soft-android/Alc/backends/mmdevapi.c @@ -28,20 +28,27 @@ #include #include #include +#include #include +#include +#include +#include #ifndef _WAVEFORMATEXTENSIBLE_ #include #include #endif #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); +DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14); + #define MONO SPEAKER_FRONT_CENTER #define STEREO (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT) #define QUAD (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT) @@ -52,18 +59,31 @@ DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0 typedef struct { + WCHAR *devid; + IMMDevice *mmdev; IAudioClient *client; - HANDLE hNotifyEvent; + IAudioRenderClient *render; + HANDLE NotifyEvent; HANDLE MsgEvent; + volatile UINT32 Padding; + volatile int killNow; - ALvoid *thread; + althread_t thread; } MMDevApiData; -static const ALCchar mmDevice[] = "WASAPI Default"; +typedef struct { + ALCchar *name; + WCHAR *devid; +} DevMap; + +static DevMap *PlaybackDeviceList; +static ALuint NumPlaybackDevices; +static DevMap *CaptureDeviceList; +static ALuint NumCaptureDevices; static HANDLE ThreadHdl; @@ -74,10 +94,14 @@ typedef struct { HRESULT result; } ThreadRequest; +#define WM_USER_First (WM_USER+0) #define WM_USER_OpenDevice (WM_USER+0) #define WM_USER_ResetDevice (WM_USER+1) -#define WM_USER_StopDevice (WM_USER+2) -#define WM_USER_CloseDevice (WM_USER+3) +#define WM_USER_StartDevice (WM_USER+2) +#define WM_USER_StopDevice (WM_USER+3) +#define WM_USER_CloseDevice (WM_USER+4) +#define WM_USER_Enumerate (WM_USER+5) +#define WM_USER_Last (WM_USER+5) static HRESULT WaitForResponse(ThreadRequest *req) { @@ -88,15 +112,120 @@ static HRESULT WaitForResponse(ThreadRequest *req) } -static ALuint MMDevApiProc(ALvoid *ptr) +static ALCchar *get_device_name(IMMDevice *device) +{ + ALCchar *name = NULL; + IPropertyStore *ps; + PROPVARIANT pvname; + HRESULT hr; + int len; + + hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps); + if(FAILED(hr)) + { + WARN("OpenPropertyStore failed: 0x%08lx\n", hr); + return calloc(1, 1); + } + + PropVariantInit(&pvname); + + hr = IPropertyStore_GetValue(ps, (const PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &pvname); + if(FAILED(hr)) + { + WARN("GetValue failed: 0x%08lx\n", hr); + name = calloc(1, 1); + } + else + { + if((len=WideCharToMultiByte(CP_ACP, 0, pvname.pwszVal, -1, NULL, 0, NULL, NULL)) > 0) + { + name = calloc(1, len); + WideCharToMultiByte(CP_ACP, 0, pvname.pwszVal, -1, name, len, NULL, NULL); + } + } + + PropVariantClear(&pvname); + IPropertyStore_Release(ps); + + return name; +} + +static void add_device(IMMDevice *device, DevMap *devmap) +{ + LPWSTR devid; + HRESULT hr; + + hr = IMMDevice_GetId(device, &devid); + if(SUCCEEDED(hr)) + { + devmap->devid = strdupW(devid); + devmap->name = get_device_name(device); + TRACE("Got device \"%s\", \"%ls\"\n", devmap->name, devmap->devid); + CoTaskMemFree(devid); + } +} + +static DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALuint *numdevs) +{ + IMMDeviceCollection *coll; + IMMDevice *defdev = NULL; + DevMap *devlist = NULL; + HRESULT hr; + UINT count; + UINT idx; + UINT i; + + hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flowdir, DEVICE_STATE_ACTIVE, &coll); + if(FAILED(hr)) + { + ERR("Failed to enumerate audio endpoints: 0x%08lx\n", hr); + return NULL; + } + + idx = count = 0; + hr = IMMDeviceCollection_GetCount(coll, &count); + if(SUCCEEDED(hr) && count > 0) + { + devlist = calloc(count, sizeof(*devlist)); + if(!devlist) + { + IMMDeviceCollection_Release(coll); + return NULL; + } + + hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flowdir, + eMultimedia, &defdev); + } + if(SUCCEEDED(hr) && defdev != NULL) + add_device(defdev, &devlist[idx++]); + + for(i = 0;i < count && idx < count;++i) + { + IMMDevice *device; + + if(FAILED(IMMDeviceCollection_Item(coll, i, &device))) + continue; + + if(device != defdev) + add_device(device, &devlist[idx++]); + + IMMDevice_Release(device); + } + + if(defdev) IMMDevice_Release(defdev); + IMMDeviceCollection_Release(coll); + + *numdevs = idx; + return devlist; +} + + +FORCE_ALIGN static ALuint MMDevApiProc(ALvoid *ptr) { ALCdevice *device = ptr; MMDevApiData *data = device->ExtraData; - union { - IAudioRenderClient *iface; - void *ptr; - } render; - UINT32 written, len; + UINT32 buffer_len, written; + ALuint update_size, len; BYTE *buffer; HRESULT hr; @@ -104,56 +233,60 @@ static ALuint MMDevApiProc(ALvoid *ptr) if(FAILED(hr)) { ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr); + ALCdevice_Lock(device); aluHandleDisconnect(device); - return 0; - } - - hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &render.ptr); - if(FAILED(hr)) - { - ERR("Failed to get AudioRenderClient service: 0x%08lx\n", hr); - aluHandleDisconnect(device); + ALCdevice_Unlock(device); return 0; } SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); + update_size = device->UpdateSize; + buffer_len = update_size * device->NumUpdates; while(!data->killNow) { hr = IAudioClient_GetCurrentPadding(data->client, &written); if(FAILED(hr)) { ERR("Failed to get padding: 0x%08lx\n", hr); + ALCdevice_Lock(device); aluHandleDisconnect(device); + ALCdevice_Unlock(device); break; } + data->Padding = written; - len = device->UpdateSize*device->NumUpdates - written; - if(len < device->UpdateSize) + len = buffer_len - written; + if(len < update_size) { DWORD res; - res = WaitForSingleObjectEx(data->hNotifyEvent, 2000, FALSE); + res = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE); if(res != WAIT_OBJECT_0) ERR("WaitForSingleObjectEx error: 0x%lx\n", res); continue; } - len -= len%device->UpdateSize; + len -= len%update_size; - hr = IAudioRenderClient_GetBuffer(render.iface, len, &buffer); + hr = IAudioRenderClient_GetBuffer(data->render, len, &buffer); if(SUCCEEDED(hr)) { + ALCdevice_Lock(device); aluMixData(device, buffer, len); - hr = IAudioRenderClient_ReleaseBuffer(render.iface, len, 0); + data->Padding = written + len; + ALCdevice_Unlock(device); + hr = IAudioRenderClient_ReleaseBuffer(data->render, len, 0); } if(FAILED(hr)) { ERR("Failed to buffer data: 0x%08lx\n", hr); + ALCdevice_Lock(device); aluHandleDisconnect(device); + ALCdevice_Unlock(device); break; } } - - IAudioRenderClient_Release(render.iface); + data->Padding = 0; CoUninitialize(); return 0; @@ -164,7 +297,7 @@ static ALCboolean MakeExtensible(WAVEFORMATEXTENSIBLE *out, const WAVEFORMATEX * { memset(out, 0, sizeof(*out)); if(in->wFormatTag == WAVE_FORMAT_EXTENSIBLE) - *out = *(WAVEFORMATEXTENSIBLE*)in; + *out = *(const WAVEFORMATEXTENSIBLE*)in; else if(in->wFormatTag == WAVE_FORMAT_PCM) { out->Format = *in; @@ -204,7 +337,7 @@ static HRESULT DoReset(ALCdevice *device) MMDevApiData *data = device->ExtraData; WAVEFORMATEXTENSIBLE OutputType; WAVEFORMATEX *wfx = NULL; - REFERENCE_TIME min_per; + REFERENCE_TIME min_per, buf_time; UINT32 buffer_len, min_len; HRESULT hr; @@ -223,6 +356,9 @@ static HRESULT DoReset(ALCdevice *device) CoTaskMemFree(wfx); wfx = NULL; + buf_time = ((REFERENCE_TIME)device->UpdateSize*device->NumUpdates*10000000 + + device->Frequency-1) / device->Frequency; + if(!(device->Flags&DEVICE_FREQUENCY_REQUEST)) device->Frequency = OutputType.Format.nSamplesPerSec; if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) @@ -294,6 +430,14 @@ static HRESULT DoReset(ALCdevice *device) OutputType.Samples.wValidBitsPerSample = 16; OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; + case DevFmtUInt: + device->FmtType = DevFmtInt; + /* fall-through */ + case DevFmtInt: + OutputType.Format.wBitsPerSample = 32; + OutputType.Samples.wValidBitsPerSample = 32; + OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + break; case DevFmtFloat: OutputType.Format.wBitsPerSample = 32; OutputType.Samples.wValidBitsPerSample = 32; @@ -329,153 +473,91 @@ static HRESULT DoReset(ALCdevice *device) CoTaskMemFree(wfx); wfx = NULL; - if(device->Frequency != OutputType.Format.nSamplesPerSec) + device->Frequency = OutputType.Format.nSamplesPerSec; + if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) + device->FmtChans = DevFmtMono; + else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) + device->FmtChans = DevFmtStereo; + else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) + device->FmtChans = DevFmtQuad; + else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) + device->FmtChans = DevFmtX51; + else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) + device->FmtChans = DevFmtX51Side; + else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) + device->FmtChans = DevFmtX61; + else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1) + device->FmtChans = DevFmtX71; + else { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set %dhz, got %ldhz instead\n", device->Frequency, OutputType.Format.nSamplesPerSec); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = OutputType.Format.nSamplesPerSec; - } - - if(!((device->FmtChans == DevFmtMono && OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) || - (device->FmtChans == DevFmtStereo && OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) || - (device->FmtChans == DevFmtQuad && OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) || - (device->FmtChans == DevFmtX51 && OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) || - (device->FmtChans == DevFmtX51Side && OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) || - (device->FmtChans == DevFmtX61 && OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) || - (device->FmtChans == DevFmtX71 && OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1))) - { - if((device->Flags&DEVICE_CHANNELS_REQUEST)) - ERR("Failed to set %s, got %d channels (0x%08lx) instead\n", DevFmtChannelsString(device->FmtChans), OutputType.Format.nChannels, OutputType.dwChannelMask); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - - if(OutputType.Format.nChannels == 1 && OutputType.dwChannelMask == MONO) - device->FmtChans = DevFmtMono; - else if(OutputType.Format.nChannels == 2 && OutputType.dwChannelMask == STEREO) - device->FmtChans = DevFmtStereo; - else if(OutputType.Format.nChannels == 4 && OutputType.dwChannelMask == QUAD) - device->FmtChans = DevFmtQuad; - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1) - device->FmtChans = DevFmtX51; - else if(OutputType.Format.nChannels == 6 && OutputType.dwChannelMask == X5DOT1SIDE) - device->FmtChans = DevFmtX51Side; - else if(OutputType.Format.nChannels == 7 && OutputType.dwChannelMask == X6DOT1) - device->FmtChans = DevFmtX61; - else if(OutputType.Format.nChannels == 8 && OutputType.dwChannelMask == X7DOT1) - device->FmtChans = DevFmtX71; - else - { - ERR("Unhandled extensible channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask); - device->FmtChans = DevFmtStereo; - OutputType.Format.nChannels = 2; - OutputType.dwChannelMask = STEREO; - } + ERR("Unhandled extensible channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask); + device->FmtChans = DevFmtStereo; + OutputType.Format.nChannels = 2; + OutputType.dwChannelMask = STEREO; } if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) { - if(OutputType.Samples.wValidBitsPerSample == 0) - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; - if(OutputType.Samples.wValidBitsPerSample != OutputType.Format.wBitsPerSample || - !((device->FmtType == DevFmtUByte && OutputType.Format.wBitsPerSample == 8) || - (device->FmtType == DevFmtShort && OutputType.Format.wBitsPerSample == 16))) + if(OutputType.Format.wBitsPerSample == 8) + device->FmtType = DevFmtUByte; + else if(OutputType.Format.wBitsPerSample == 16) + device->FmtType = DevFmtShort; + else if(OutputType.Format.wBitsPerSample == 32) + device->FmtType = DevFmtInt; + else { - ERR("Failed to set %s samples, got %d/%d-bit instead\n", DevFmtTypeString(device->FmtType), OutputType.Samples.wValidBitsPerSample, OutputType.Format.wBitsPerSample); - if(OutputType.Format.wBitsPerSample == 8) - device->FmtType = DevFmtUByte; - else if(OutputType.Format.wBitsPerSample == 16) - device->FmtType = DevFmtShort; - else - { - device->FmtType = DevFmtShort; - OutputType.Format.wBitsPerSample = 16; - } - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; + device->FmtType = DevFmtShort; + OutputType.Format.wBitsPerSample = 16; } } else if(IsEqualGUID(&OutputType.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { - if(OutputType.Samples.wValidBitsPerSample == 0) - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; - if(OutputType.Samples.wValidBitsPerSample != OutputType.Format.wBitsPerSample || - !((device->FmtType == DevFmtFloat && OutputType.Format.wBitsPerSample == 32))) - { - ERR("Failed to set %s samples, got %d/%d-bit instead\n", DevFmtTypeString(device->FmtType), OutputType.Samples.wValidBitsPerSample, OutputType.Format.wBitsPerSample); - if(OutputType.Format.wBitsPerSample != 32) - { - device->FmtType = DevFmtFloat; - OutputType.Format.wBitsPerSample = 32; - } - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; - } + device->FmtType = DevFmtFloat; + OutputType.Format.wBitsPerSample = 32; } else { ERR("Unhandled format sub-type\n"); device->FmtType = DevFmtShort; OutputType.Format.wBitsPerSample = 16; - OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; } + OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample; } SetDefaultWFXChannelOrder(device); - hr = IAudioClient_GetDevicePeriod(data->client, &min_per, NULL); - if(SUCCEEDED(hr)) - { - min_len = (min_per*device->Frequency + 10000000-1) / 10000000; - if(min_len < device->UpdateSize) - min_len *= (device->UpdateSize + min_len/2)/min_len; - - device->NumUpdates = (device->NumUpdates*device->UpdateSize + min_len/2) / - min_len; - device->NumUpdates = maxu(device->NumUpdates, 2); - device->UpdateSize = min_len; - - hr = IAudioClient_Initialize(data->client, AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - ((REFERENCE_TIME)device->UpdateSize* - device->NumUpdates*10000000 + - device->Frequency-1) / device->Frequency, - 0, &OutputType.Format, NULL); - } + hr = IAudioClient_Initialize(data->client, AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + buf_time, 0, &OutputType.Format, NULL); if(FAILED(hr)) { ERR("Failed to initialize audio client: 0x%08lx\n", hr); return hr; } - hr = IAudioClient_GetBufferSize(data->client, &buffer_len); + hr = IAudioClient_GetDevicePeriod(data->client, &min_per, NULL); + if(SUCCEEDED(hr)) + { + min_len = (UINT32)((min_per*device->Frequency + 10000000-1) / 10000000); + /* Find the nearest multiple of the period size to the update size */ + if(min_len < device->UpdateSize) + min_len *= (device->UpdateSize + min_len/2)/min_len; + hr = IAudioClient_GetBufferSize(data->client, &buffer_len); + } if(FAILED(hr)) { ERR("Failed to get audio buffer info: 0x%08lx\n", hr); return hr; } + device->UpdateSize = min_len; device->NumUpdates = buffer_len / device->UpdateSize; if(device->NumUpdates <= 1) { - device->NumUpdates = 1; ERR("Audio client returned buffer_len < period*2; expect break up\n"); - } - - ResetEvent(data->hNotifyEvent); - hr = IAudioClient_SetEventHandle(data->client, data->hNotifyEvent); - if(SUCCEEDED(hr)) - hr = IAudioClient_Start(data->client); - if(FAILED(hr)) - { - ERR("Failed to start audio client: 0x%08lx\n", hr); - return hr; - } - - data->thread = StartThread(MMDevApiProc, device); - if(!data->thread) - { - IAudioClient_Stop(data->client); - ERR("Failed to start thread\n"); - return E_FAIL; + device->NumUpdates = 2; + device->UpdateSize = buffer_len / device->NumUpdates; } return hr; @@ -489,16 +571,16 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) ALuint deviceCount = 0; MMDevApiData *data; ALCdevice *device; - HRESULT hr; + HRESULT hr, cohr; MSG msg; TRACE("Starting message thread\n"); - hr = CoInitialize(NULL); - if(FAILED(hr)) + cohr = CoInitialize(NULL); + if(FAILED(cohr)) { - WARN("Failed to initialize COM: 0x%08lx\n", hr); - req->result = hr; + WARN("Failed to initialize COM: 0x%08lx\n", cohr); + req->result = cohr; SetEvent(req->FinishedEvt); return 0; } @@ -522,7 +604,7 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) SetEvent(req->FinishedEvt); TRACE("Starting message loop\n"); - while(GetMessage(&msg, NULL, 0, 0)) + while(GetMessage(&msg, NULL, WM_USER_First, WM_USER_Last)) { TRACE("Got message %u\n", msg.message); switch(msg.message) @@ -532,28 +614,36 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) device = (ALCdevice*)msg.lParam; data = device->ExtraData; - hr = S_OK; + hr = cohr = S_OK; if(++deviceCount == 1) - hr = CoInitialize(NULL); + hr = cohr = CoInitialize(NULL); if(SUCCEEDED(hr)) hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr); if(SUCCEEDED(hr)) { Enumerator = ptr; - hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(Enumerator, eRender, eMultimedia, &data->mmdev); + if(!data->devid) + hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(Enumerator, eRender, eMultimedia, &data->mmdev); + else + hr = IMMDeviceEnumerator_GetDevice(Enumerator, data->devid, &data->mmdev); IMMDeviceEnumerator_Release(Enumerator); Enumerator = NULL; } if(SUCCEEDED(hr)) hr = IMMDevice_Activate(data->mmdev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, &ptr); if(SUCCEEDED(hr)) + { data->client = ptr; + device->DeviceName = get_device_name(data->mmdev); + } if(FAILED(hr)) { if(data->mmdev) IMMDevice_Release(data->mmdev); data->mmdev = NULL; + if(--deviceCount == 0 && SUCCEEDED(cohr)) + CoUninitialize(); } req->result = hr; @@ -568,6 +658,42 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) SetEvent(req->FinishedEvt); continue; + case WM_USER_StartDevice: + req = (ThreadRequest*)msg.wParam; + device = (ALCdevice*)msg.lParam; + data = device->ExtraData; + + ResetEvent(data->NotifyEvent); + hr = IAudioClient_SetEventHandle(data->client, data->NotifyEvent); + if(FAILED(hr)) + ERR("Failed to set event handle: 0x%08lx\n", hr); + else + { + hr = IAudioClient_Start(data->client); + if(FAILED(hr)) + ERR("Failed to start audio client: 0x%08lx\n", hr); + } + + if(SUCCEEDED(hr)) + hr = IAudioClient_GetService(data->client, &IID_IAudioRenderClient, &ptr); + if(SUCCEEDED(hr)) + { + data->render = ptr; + if(!StartThread(&data->thread, MMDevApiProc, device)) + { + if(data->render) + IAudioRenderClient_Release(data->render); + data->render = NULL; + IAudioClient_Stop(data->client); + ERR("Failed to start thread\n"); + hr = E_FAIL; + } + } + + req->result = hr; + SetEvent(req->FinishedEvt); + continue; + case WM_USER_StopDevice: req = (ThreadRequest*)msg.wParam; device = (ALCdevice*)msg.lParam; @@ -581,6 +707,8 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) data->killNow = 0; + IAudioRenderClient_Release(data->render); + data->render = NULL; IAudioClient_Stop(data->client); } @@ -606,6 +734,57 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr) SetEvent(req->FinishedEvt); continue; + case WM_USER_Enumerate: + req = (ThreadRequest*)msg.wParam; + + hr = cohr = S_OK; + if(++deviceCount == 1) + hr = cohr = CoInitialize(NULL); + if(SUCCEEDED(hr)) + hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr); + if(SUCCEEDED(hr)) + { + EDataFlow flowdir; + DevMap **devlist; + ALuint *numdevs; + ALuint i; + + Enumerator = ptr; + if(msg.lParam == CAPTURE_DEVICE_PROBE) + { + flowdir = eCapture; + devlist = &CaptureDeviceList; + numdevs = &NumCaptureDevices; + } + else + { + flowdir = eRender; + devlist = &PlaybackDeviceList; + numdevs = &NumPlaybackDevices; + } + + for(i = 0;i < *numdevs;i++) + { + free((*devlist)[i].name); + free((*devlist)[i].devid); + } + free(*devlist); + *devlist = NULL; + *numdevs = 0; + + *devlist = ProbeDevices(Enumerator, flowdir, numdevs); + + IMMDeviceEnumerator_Release(Enumerator); + Enumerator = NULL; + } + + if(--deviceCount == 0 && SUCCEEDED(cohr)) + CoUninitialize(); + + req->result = S_OK; + SetEvent(req->FinishedEvt); + continue; + default: ERR("Unexpected message: %u\n", msg.message); continue; @@ -645,11 +824,6 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName MMDevApiData *data = NULL; HRESULT hr; - if(!deviceName) - deviceName = mmDevice; - else if(strcmp(deviceName, mmDevice) != 0) - return ALC_INVALID_VALUE; - //Initialise requested device data = calloc(1, sizeof(MMDevApiData)); if(!data) @@ -657,11 +831,37 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName device->ExtraData = data; hr = S_OK; - data->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); data->MsgEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if(data->hNotifyEvent == NULL || data->MsgEvent == NULL) + if(data->NotifyEvent == NULL || data->MsgEvent == NULL) hr = E_FAIL; + if(SUCCEEDED(hr)) + { + if(deviceName) + { + ALuint i; + + if(!PlaybackDeviceList) + { + ThreadRequest req = { data->MsgEvent, 0 }; + if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, ALL_DEVICE_PROBE)) + (void)WaitForResponse(&req); + } + + hr = E_FAIL; + for(i = 0;i < NumPlaybackDevices;i++) + { + if(strcmp(deviceName, PlaybackDeviceList[i].name) == 0) + { + data->devid = strdupW(PlaybackDeviceList[i].devid); + hr = S_OK; + break; + } + } + } + } + if(SUCCEEDED(hr)) { ThreadRequest req = { data->MsgEvent, 0 }; @@ -673,13 +873,16 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName if(FAILED(hr)) { - if(data->hNotifyEvent != NULL) - CloseHandle(data->hNotifyEvent); - data->hNotifyEvent = NULL; + if(data->NotifyEvent != NULL) + CloseHandle(data->NotifyEvent); + data->NotifyEvent = NULL; if(data->MsgEvent != NULL) CloseHandle(data->MsgEvent); data->MsgEvent = NULL; + free(data->devid); + data->devid = NULL; + free(data); device->ExtraData = NULL; @@ -687,7 +890,6 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); return ALC_NO_ERROR; } @@ -702,8 +904,11 @@ static void MMDevApiClosePlayback(ALCdevice *device) CloseHandle(data->MsgEvent); data->MsgEvent = NULL; - CloseHandle(data->hNotifyEvent); - data->hNotifyEvent = NULL; + CloseHandle(data->NotifyEvent); + data->NotifyEvent = NULL; + + free(data->devid); + data->devid = NULL; free(data); device->ExtraData = NULL; @@ -721,6 +926,18 @@ static ALCboolean MMDevApiResetPlayback(ALCdevice *device) return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE; } +static ALCboolean MMDevApiStartPlayback(ALCdevice *device) +{ + MMDevApiData *data = device->ExtraData; + ThreadRequest req = { data->MsgEvent, 0 }; + HRESULT hr = E_FAIL; + + if(PostThreadMessage(ThreadID, WM_USER_StartDevice, (WPARAM)&req, (LPARAM)device)) + hr = WaitForResponse(&req); + + return SUCCEEDED(hr) ? ALC_TRUE : ALC_FALSE; +} + static void MMDevApiStopPlayback(ALCdevice *device) { MMDevApiData *data = device->ExtraData; @@ -731,17 +948,27 @@ static void MMDevApiStopPlayback(ALCdevice *device) } +static ALint64 MMDevApiGetLatency(ALCdevice *device) +{ + MMDevApiData *data = device->ExtraData; + + return (ALint64)data->Padding * 1000000000 / device->Frequency; +} + + static const BackendFuncs MMDevApiFuncs = { MMDevApiOpenPlayback, MMDevApiClosePlayback, MMDevApiResetPlayback, + MMDevApiStartPlayback, MMDevApiStopPlayback, NULL, NULL, NULL, NULL, NULL, - NULL + NULL, + MMDevApiGetLatency }; @@ -755,6 +982,26 @@ ALCboolean alcMMDevApiInit(BackendFuncs *FuncList) void alcMMDevApiDeinit(void) { + ALuint i; + + for(i = 0;i < NumPlaybackDevices;i++) + { + free(PlaybackDeviceList[i].name); + free(PlaybackDeviceList[i].devid); + } + free(PlaybackDeviceList); + PlaybackDeviceList = NULL; + NumPlaybackDevices = 0; + + for(i = 0;i < NumCaptureDevices;i++) + { + free(CaptureDeviceList[i].name); + free(CaptureDeviceList[i].devid); + } + free(CaptureDeviceList); + CaptureDeviceList = NULL; + NumCaptureDevices = 0; + if(ThreadHdl) { TRACE("Sending WM_QUIT to Thread %04lx\n", ThreadID); @@ -766,15 +1013,32 @@ void alcMMDevApiDeinit(void) void alcMMDevApiProbe(enum DevProbe type) { + ThreadRequest req = { NULL, 0 }; + HRESULT hr = E_FAIL; + switch(type) { - case DEVICE_PROBE: - AppendDeviceList(mmDevice); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(mmDevice); + req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL); + if(req.FinishedEvt == NULL) + ERR("Failed to create event: %lu\n", GetLastError()); + else if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, type)) + hr = WaitForResponse(&req); + if(SUCCEEDED(hr)) + { + ALuint i; + for(i = 0;i < NumPlaybackDevices;i++) + { + if(PlaybackDeviceList[i].name) + AppendAllDevicesList(PlaybackDeviceList[i].name); + } + } break; + case CAPTURE_DEVICE_PROBE: break; } + if(req.FinishedEvt != NULL) + CloseHandle(req.FinishedEvt); + req.FinishedEvt = NULL; } diff --git a/jni/openal-soft-android/Alc/backends/null.c b/jni/openal-soft-android/Alc/backends/null.c index 7b501b58..a7056369 100644 --- a/jni/openal-soft-android/Alc/backends/null.c +++ b/jni/openal-soft-android/Alc/backends/null.c @@ -21,144 +21,202 @@ #include "config.h" #include +#ifdef HAVE_WINDOWS_H +#include +#endif + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" + +#include "backends/base.h" -typedef struct { +typedef struct ALCnullBackend { + DERIVE_FROM_TYPE(ALCbackend); + volatile int killNow; - ALvoid *thread; -} null_data; + althread_t thread; +} ALCnullBackend; +DECLARE_ALCBACKEND_VTABLE(ALCnullBackend); +static ALuint ALCnullBackend_mixerProc(ALvoid *ptr); + +static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device); +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, Destruct) +static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name); +static void ALCnullBackend_close(ALCnullBackend *self); +static ALCboolean ALCnullBackend_reset(ALCnullBackend *self); +static ALCboolean ALCnullBackend_start(ALCnullBackend *self); +static void ALCnullBackend_stop(ALCnullBackend *self); +static DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock) static const ALCchar nullDevice[] = "No Output"; -static ALuint NullProc(ALvoid *ptr) + +static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device) { - ALCdevice *Device = (ALCdevice*)ptr; - null_data *data = (null_data*)Device->ExtraData; + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCnullBackend, ALCbackend, self); +} + + +static ALuint ALCnullBackend_mixerProc(ALvoid *ptr) +{ + ALCnullBackend *self = (ALCnullBackend*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; ALuint now, start; ALuint64 avail, done; - const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 / - Device->Frequency / 2; + + SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); done = 0; start = timeGetTime(); - while(!data->killNow && Device->Connected) + while(!self->killNow && device->Connected) { now = timeGetTime(); - avail = (ALuint64)(now-start) * Device->Frequency / 1000; + avail = (ALuint64)(now-start) * device->Frequency / 1000; if(avail < done) { - /* Timer wrapped. Add the remainder of the cycle to the available - * count and reset the number of samples done */ - avail += (ALuint64)0xFFFFFFFFu*Device->Frequency/1000 - done; + /* Timer wrapped (50 days???). Add the remainder of the cycle to + * the available count and reset the number of samples done */ + avail += (U64(1)<<32)*device->Frequency/1000 - done; done = 0; } - if(avail-done < Device->UpdateSize) + if(avail-done < device->UpdateSize) { + ALuint restTime = (ALuint)((device->UpdateSize - (avail-done)) * 1000 / + device->Frequency); Sleep(restTime); continue; } - while(avail-done >= Device->UpdateSize) - { - aluMixData(Device, NULL, Device->UpdateSize); - done += Device->UpdateSize; - } + do { + aluMixData(device, NULL, device->UpdateSize); + done += device->UpdateSize; + } while(avail-done >= device->UpdateSize); } return 0; } -static ALCenum null_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - null_data *data; - if(!deviceName) - deviceName = nullDevice; - else if(strcmp(deviceName, nullDevice) != 0) +static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name) +{ + ALCdevice *device; + + if(!name) + name = nullDevice; + else if(strcmp(name, nullDevice) != 0) return ALC_INVALID_VALUE; - data = (null_data*)calloc(1, sizeof(*data)); + device = STATIC_CAST(ALCbackend, self)->mDevice; + device->DeviceName = strdup(name); - device->szDeviceName = strdup(deviceName); - device->ExtraData = data; return ALC_NO_ERROR; } -static void null_close_playback(ALCdevice *device) +static void ALCnullBackend_close(ALCnullBackend* UNUSED(self)) { - null_data *data = (null_data*)device->ExtraData; - - free(data); - device->ExtraData = NULL; } -static ALCboolean null_reset_playback(ALCdevice *device) +static ALCboolean ALCnullBackend_reset(ALCnullBackend *self) { - null_data *data = (null_data*)device->ExtraData; - - SetDefaultWFXChannelOrder(device); - - data->thread = StartThread(NullProc, device); - if(data->thread == NULL) - return ALC_FALSE; - + SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice); return ALC_TRUE; } -static void null_stop_playback(ALCdevice *device) +static ALCboolean ALCnullBackend_start(ALCnullBackend *self) { - null_data *data = (null_data*)device->ExtraData; + if(!StartThread(&self->thread, ALCnullBackend_mixerProc, self)) + return ALC_FALSE; + return ALC_TRUE; +} - if(!data->thread) +static void ALCnullBackend_stop(ALCnullBackend *self) +{ + if(!self->thread) return; - data->killNow = 1; - StopThread(data->thread); - data->thread = NULL; + self->killNow = 1; + StopThread(self->thread); + self->thread = NULL; - data->killNow = 0; + self->killNow = 0; } -static const BackendFuncs null_funcs = { - null_open_playback, - null_close_playback, - null_reset_playback, - null_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -ALCboolean alc_null_init(BackendFuncs *func_list) +static void ALCnullBackend_Delete(ALCnullBackend *self) +{ + free(self); +} + +DEFINE_ALCBACKEND_VTABLE(ALCnullBackend); + + +typedef struct ALCnullBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCnullBackendFactory; +#define ALCNULLBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCnullBackendFactory, ALCbackendFactory) } } + +ALCbackendFactory *ALCnullBackendFactory_getFactory(void); + +static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory *self); +static DECLARE_FORWARD(ALCnullBackendFactory, ALCbackendFactory, void, deinit) +static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory *self, ALCbackend_Type type); +static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type); +static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory *self, ALCdevice *device, ALCbackend_Type type); +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCnullBackendFactory); + + +ALCbackendFactory *ALCnullBackendFactory_getFactory(void) +{ + static ALCnullBackendFactory factory = ALCNULLBACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} + + +static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory* UNUSED(self)) { - *func_list = null_funcs; return ALC_TRUE; } -void alc_null_deinit(void) +static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory* UNUSED(self), ALCbackend_Type type) { + if(type == ALCbackend_Playback) + return ALC_TRUE; + return ALC_FALSE; } -void alc_null_probe(enum DevProbe type) +static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - AppendDeviceList(nullDevice); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(nullDevice); + AppendAllDevicesList(nullDevice); break; case CAPTURE_DEVICE_PROBE: break; } } + +static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + ALCnullBackend *backend; + + assert(type == ALCbackend_Playback); + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCnullBackend_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); +} diff --git a/jni/openal-soft-android/Alc/backends/opensl.c b/jni/openal-soft-android/Alc/backends/opensl.c index 97ca2536..76cbaf1a 100644 --- a/jni/openal-soft-android/Alc/backends/opensl.c +++ b/jni/openal-soft-android/Alc/backends/opensl.c @@ -22,13 +22,13 @@ #include "config.h" #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" #include -#ifdef HAVE_ANDROID +#if 1 #include #else extern SLAPIENTRY const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE; @@ -83,6 +83,10 @@ typedef struct SLDataLocator_AndroidSimpleBufferQueue { #define SLPlayItf_SetPlayState(a,b) ((*(a))->SetPlayState((a),(b))) +/* Should start using these generic callers instead of the name-specific ones above. */ +#define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS +#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS + typedef struct { /* engine interfaces */ @@ -97,6 +101,7 @@ typedef struct { void *buffer; ALuint bufferSize; + ALuint curBuffer; ALuint frameSize; } osl_data; @@ -152,9 +157,13 @@ static const char *res_str(SLresult result) case SL_RESULT_UNKNOWN_ERROR: return "Unknown error"; case SL_RESULT_OPERATION_ABORTED: return "Operation aborted"; case SL_RESULT_CONTROL_LOST: return "Control lost"; -#ifdef HAVE_OPENSL_1_1 +#ifdef SL_RESULT_READONLY case SL_RESULT_READONLY: return "ReadOnly"; +#endif +#ifdef SL_RESULT_ENGINEOPTION_UNSUPPORTED case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported"; +#endif +#ifdef SL_RESULT_SOURCE_SINK_INCOMPATIBLE case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible"; #endif } @@ -171,12 +180,16 @@ static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *context) { ALCdevice *Device = context; osl_data *data = Device->ExtraData; + ALvoid *buf; SLresult result; - aluMixData(Device, data->buffer, data->bufferSize/data->frameSize); + buf = (ALbyte*)data->buffer + data->curBuffer*data->bufferSize; + aluMixData(Device, buf, data->bufferSize/data->frameSize); - result = (*bq)->Enqueue(bq, data->buffer, data->bufferSize); + result = (*bq)->Enqueue(bq, buf, data->bufferSize); PRINTERR(result, "bq->Enqueue"); + + data->curBuffer = (data->curBuffer+1) % Device->NumUpdates; } @@ -233,7 +246,7 @@ static ALCenum opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName return ALC_INVALID_VALUE; } - Device->szDeviceName = strdup(deviceName); + Device->DeviceName = strdup(deviceName); Device->ExtraData = data; return ALC_NO_ERROR; @@ -244,6 +257,10 @@ static void opensl_close_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + SLObjectItf_Destroy(data->outputMix); data->outputMix = NULL; @@ -259,16 +276,13 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; SLDataLocator_AndroidSimpleBufferQueue loc_bufq; - SLAndroidSimpleBufferQueueItf bufferQueue; SLDataLocator_OutputMix loc_outmix; SLDataFormat_PCM format_pcm; SLDataSource audioSrc; SLDataSink audioSnk; - SLPlayItf player; SLInterfaceID id; SLboolean req; SLresult result; - ALuint i; Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency; @@ -294,13 +308,8 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) format_pcm.bitsPerSample = BytesFromDevFmt(Device->FmtType) * 8; format_pcm.containerSize = format_pcm.bitsPerSample; format_pcm.channelMask = GetChannelMask(Device->FmtChans); -#ifdef HAVE_OPENSL_1_1 - format_pcm.endianness = SL_BYTEORDER_NATIVE; -#elif _BYTE_ORDER == _BIG_ENDIAN - format_pcm.endianness = SL_BYTEORDER_BIGENDIAN; -#else - format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; -#endif + format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : + SL_BYTEORDER_BIGENDIAN; audioSrc.pLocator = &loc_bufq; audioSrc.pFormat = &format_pcm; @@ -311,6 +320,10 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) audioSnk.pFormat = NULL; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + result = SLEngineItf_CreateAudioPlayer(data->engine, &data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req); PRINTERR(result, "engine->CreateAudioPlayer"); if(SL_RESULT_SUCCESS == result) @@ -318,11 +331,29 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) result = SLObjectItf_Realize(data->bufferQueueObject, SL_BOOLEAN_FALSE); PRINTERR(result, "bufferQueue->Realize"); } - if(SL_RESULT_SUCCESS == result) + + if(SL_RESULT_SUCCESS != result) { - result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); - PRINTERR(result, "bufferQueue->GetInterface"); + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + + return ALC_FALSE; } + + return ALC_TRUE; +} + +static ALCboolean opensl_start_playback(ALCdevice *Device) +{ + osl_data *data = Device->ExtraData; + SLAndroidSimpleBufferQueueItf bufferQueue; + SLPlayItf player; + SLresult result; + ALuint i; + + result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); + PRINTERR(result, "bufferQueue->GetInterface"); if(SL_RESULT_SUCCESS == result) { result = (*bufferQueue)->RegisterCallback(bufferQueue, opensl_callback, Device); @@ -332,7 +363,7 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) { data->frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); data->bufferSize = Device->UpdateSize * data->frameSize; - data->buffer = calloc(1, data->bufferSize); + data->buffer = calloc(Device->NumUpdates, data->bufferSize); if(!data->buffer) { result = SL_RESULT_MEMORY_FAILURE; @@ -344,10 +375,12 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) { if(SL_RESULT_SUCCESS == result) { - result = (*bufferQueue)->Enqueue(bufferQueue, data->buffer, data->bufferSize); + ALvoid *buf = (ALbyte*)data->buffer + i*data->bufferSize; + result = (*bufferQueue)->Enqueue(bufferQueue, buf, data->bufferSize); PRINTERR(result, "bufferQueue->Enqueue"); } } + data->curBuffer = 0; if(SL_RESULT_SUCCESS == result) { result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_PLAY, &player); @@ -379,10 +412,25 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) static void opensl_stop_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; + SLPlayItf player; + SLAndroidSimpleBufferQueueItf bufferQueue; + SLresult result; - if(data->bufferQueueObject != NULL) - SLObjectItf_Destroy(data->bufferQueueObject); - data->bufferQueueObject = NULL; + result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_PLAY, &player); + PRINTERR(result, "bufferQueue->GetInterface"); + if(SL_RESULT_SUCCESS == result) + { + result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED); + PRINTERR(result, "player->SetPlayState"); + } + + result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_BUFFERQUEUE, &bufferQueue); + PRINTERR(result, "bufferQueue->GetInterface"); + if(SL_RESULT_SUCCESS == result) + { + result = VCALL0(bufferQueue,Clear)(); + PRINTERR(result, "bufferQueue->Clear"); + } free(data->buffer); data->buffer = NULL; @@ -394,13 +442,15 @@ static const BackendFuncs opensl_funcs = { opensl_open_playback, opensl_close_playback, opensl_reset_playback, + opensl_start_playback, opensl_stop_playback, NULL, NULL, NULL, NULL, NULL, - NULL + NULL, + ALCdevice_GetLatencyDefault }; @@ -418,11 +468,8 @@ void alc_opensl_probe(enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - AppendDeviceList(opensl_device); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(opensl_device); + AppendAllDevicesList(opensl_device); break; case CAPTURE_DEVICE_PROBE: break; diff --git a/jni/openal-soft-android/Alc/backends/oss.c b/jni/openal-soft-android/Alc/backends/oss.c index 9206343b..c79793c2 100644 --- a/jni/openal-soft-android/Alc/backends/oss.c +++ b/jni/openal-soft-android/Alc/backends/oss.c @@ -30,9 +30,13 @@ #include #include #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" + +#include "backends/base.h" #include @@ -47,20 +51,11 @@ #define SOUND_MIXER_WRITE MIXER_WRITE #endif + static const ALCchar oss_device[] = "OSS Default"; -typedef struct { - int fd; - volatile int killNow; - ALvoid *thread; - - ALubyte *mix_data; - int data_size; - - RingBuffer *ring; - int doCapture; -} oss_data; - +static const char *oss_driver = "/dev/dsp"; +static const char *oss_capture = "/dev/dsp"; static int log2i(ALCuint x) { @@ -74,32 +69,65 @@ static int log2i(ALCuint x) } -static ALuint OSSProc(ALvoid *ptr) +typedef struct ALCplaybackOSS { + DERIVE_FROM_TYPE(ALCbackend); + + int fd; + + ALubyte *mix_data; + int data_size; + + volatile int killNow; + althread_t thread; +} ALCplaybackOSS; + +static ALuint ALCplaybackOSS_mixerProc(ALvoid *ptr); + +static void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device); +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, Destruct) +static ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name); +static void ALCplaybackOSS_close(ALCplaybackOSS *self); +static ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self); +static ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self); +static void ALCplaybackOSS_stop(ALCplaybackOSS *self); +static DECLARE_FORWARD2(ALCplaybackOSS, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALCuint, availableSamples) +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, unlock) +static void ALCplaybackOSS_Delete(ALCplaybackOSS *self); +DEFINE_ALCBACKEND_VTABLE(ALCplaybackOSS); + + +static ALuint ALCplaybackOSS_mixerProc(ALvoid *ptr) { - ALCdevice *pDevice = (ALCdevice*)ptr; - oss_data *data = (oss_data*)pDevice->ExtraData; + ALCplaybackOSS *self = (ALCplaybackOSS*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; ALint frameSize; ssize_t wrote; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); + frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - while(!data->killNow && pDevice->Connected) + while(!self->killNow && device->Connected) { - ALint len = data->data_size; - ALubyte *WritePtr = data->mix_data; + ALint len = self->data_size; + ALubyte *WritePtr = self->mix_data; - aluMixData(pDevice, WritePtr, len/frameSize); - while(len > 0 && !data->killNow) + aluMixData(device, WritePtr, len/frameSize); + while(len > 0 && !self->killNow) { - wrote = write(data->fd, WritePtr, len); + wrote = write(self->fd, WritePtr, len); if(wrote < 0) { if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) { ERR("write failed: %s\n", strerror(errno)); - aluHandleDisconnect(pDevice); + ALCplaybackOSS_lock(self); + aluHandleDisconnect(device); + ALCplaybackOSS_unlock(self); break; } @@ -115,78 +143,45 @@ static ALuint OSSProc(ALvoid *ptr) return 0; } -static ALuint OSSCaptureProc(ALvoid *ptr) + +static void ALCplaybackOSS_Construct(ALCplaybackOSS *self, ALCdevice *device) { - ALCdevice *pDevice = (ALCdevice*)ptr; - oss_data *data = (oss_data*)pDevice->ExtraData; - int frameSize; - int amt; - - SetRTPriority(); - - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); - - while(!data->killNow) - { - amt = read(data->fd, data->mix_data, data->data_size); - if(amt < 0) - { - ERR("read failed: %s\n", strerror(errno)); - aluHandleDisconnect(pDevice); - break; - } - if(amt == 0) - { - Sleep(1); - continue; - } - if(data->doCapture) - WriteRingBuffer(data->ring, data->mix_data, amt/frameSize); - } - - return 0; + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCplaybackOSS, ALCbackend, self); } -static ALCenum oss_open_playback(ALCdevice *device, const ALCchar *deviceName) +static ALCenum ALCplaybackOSS_open(ALCplaybackOSS *self, const ALCchar *name) { - char driver[64]; - oss_data *data; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1); - driver[sizeof(driver)-1] = 0; - if(!deviceName) - deviceName = oss_device; - else if(strcmp(deviceName, oss_device) != 0) + if(!name) + name = oss_device; + else if(strcmp(name, oss_device) != 0) return ALC_INVALID_VALUE; - data = (oss_data*)calloc(1, sizeof(oss_data)); - data->killNow = 0; + self->killNow = 0; - data->fd = open(driver, O_WRONLY); - if(data->fd == -1) + self->fd = open(oss_driver, O_WRONLY); + if(self->fd == -1) { - free(data); - ERR("Could not open %s: %s\n", driver, strerror(errno)); + ERR("Could not open %s: %s\n", oss_driver, strerror(errno)); return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); - device->ExtraData = data; + device->DeviceName = strdup(name); + return ALC_NO_ERROR; } -static void oss_close_playback(ALCdevice *device) +static void ALCplaybackOSS_close(ALCplaybackOSS *self) { - oss_data *data = (oss_data*)device->ExtraData; - - close(data->fd); - free(data); - device->ExtraData = NULL; + close(self->fd); + self->fd = -1; } -static ALCboolean oss_reset_playback(ALCdevice *device) +static ALCboolean ALCplaybackOSS_reset(ALCplaybackOSS *self) { - oss_data *data = (oss_data*)device->ExtraData; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; int numFragmentsLogSize; int log2FragmentSize; unsigned int periods; @@ -206,6 +201,8 @@ static ALCboolean oss_reset_playback(ALCdevice *device) ossFormat = AFMT_U8; break; case DevFmtUShort: + case DevFmtInt: + case DevFmtUInt: case DevFmtFloat: device->FmtType = DevFmtShort; /* fall-through */ @@ -235,11 +232,11 @@ static ALCboolean oss_reset_playback(ALCdevice *device) } /* Don't fail if SETFRAGMENT fails. We can handle just about anything * that's reported back via GETOSPACE */ - ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info)); + ioctl(self->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFMT, &ossFormat)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_CHANNELS, &numChannels)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_SPEED, &ossSpeed)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_GETOSPACE, &info)); if(0) { err: @@ -262,82 +259,152 @@ static ALCboolean oss_reset_playback(ALCdevice *device) return ALC_FALSE; } - if(device->Frequency != (ALuint)ossSpeed) - { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set %dhz, got %dhz instead\n", device->Frequency, ossSpeed); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = ossSpeed; - } + device->Frequency = ossSpeed; device->UpdateSize = info.fragsize / frameSize; device->NumUpdates = info.fragments + 1; - data->data_size = device->UpdateSize * frameSize; - data->mix_data = calloc(1, data->data_size); - SetDefaultChannelOrder(device); - data->thread = StartThread(OSSProc, device); - if(data->thread == NULL) + return ALC_TRUE; +} + +static ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + + self->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + self->mix_data = calloc(1, self->data_size); + + if(!StartThread(&self->thread, ALCplaybackOSS_mixerProc, self)) { - free(data->mix_data); - data->mix_data = NULL; + free(self->mix_data); + self->mix_data = NULL; return ALC_FALSE; } return ALC_TRUE; } -static void oss_stop_playback(ALCdevice *device) +static void ALCplaybackOSS_stop(ALCplaybackOSS *self) { - oss_data *data = (oss_data*)device->ExtraData; - - if(!data->thread) + if(!self->thread) return; - data->killNow = 1; - StopThread(data->thread); - data->thread = NULL; + self->killNow = 1; + StopThread(self->thread); + self->thread = NULL; - data->killNow = 0; - if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0) + self->killNow = 0; + if(ioctl(self->fd, SNDCTL_DSP_RESET) != 0) ERR("Error resetting device: %s\n", strerror(errno)); - free(data->mix_data); - data->mix_data = NULL; + free(self->mix_data); + self->mix_data = NULL; +} + +static void ALCplaybackOSS_Delete(ALCplaybackOSS *self) +{ + free(self); } -static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) +typedef struct ALCcaptureOSS { + DERIVE_FROM_TYPE(ALCbackend); + + int fd; + + ALubyte *read_data; + int data_size; + + RingBuffer *ring; + int doCapture; + + volatile int killNow; + althread_t thread; +} ALCcaptureOSS; + +static ALuint ALCcaptureOSS_recordProc(ALvoid *ptr); + +static void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device); +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, Destruct) +static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name); +static void ALCcaptureOSS_close(ALCcaptureOSS *self); +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALCboolean, reset) +static ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self); +static void ALCcaptureOSS_stop(ALCcaptureOSS *self); +static ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples); +static ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self); +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, lock) +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, unlock) +static void ALCcaptureOSS_Delete(ALCcaptureOSS *self); +DEFINE_ALCBACKEND_VTABLE(ALCcaptureOSS); + + +static ALuint ALCcaptureOSS_recordProc(ALvoid *ptr) { + ALCcaptureOSS *self = (ALCcaptureOSS*)ptr; + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; + int frameSize; + int amt; + + SetRTPriority(); + SetThreadName("alsoft-record"); + + frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + + while(!self->killNow) + { + amt = read(self->fd, self->read_data, self->data_size); + if(amt < 0) + { + ERR("read failed: %s\n", strerror(errno)); + ALCcaptureOSS_lock(self); + aluHandleDisconnect(device); + ALCcaptureOSS_unlock(self); + break; + } + if(amt == 0) + { + Sleep(1); + continue; + } + if(self->doCapture) + WriteRingBuffer(self->ring, self->read_data, amt/frameSize); + } + + return 0; +} + + +static void ALCcaptureOSS_Construct(ALCcaptureOSS *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCcaptureOSS, ALCbackend, self); +} + +static ALCenum ALCcaptureOSS_open(ALCcaptureOSS *self, const ALCchar *name) +{ + ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; int numFragmentsLogSize; int log2FragmentSize; unsigned int periods; audio_buf_info info; ALuint frameSize; int numChannels; - char driver[64]; - oss_data *data; int ossFormat; int ossSpeed; char *err; - strncpy(driver, GetConfigValue("oss", "capture", "/dev/dsp"), sizeof(driver)-1); - driver[sizeof(driver)-1] = 0; - - if(!deviceName) - deviceName = oss_device; - else if(strcmp(deviceName, oss_device) != 0) + if(!name) + name = oss_device; + else if(strcmp(name, oss_device) != 0) return ALC_INVALID_VALUE; - data = (oss_data*)calloc(1, sizeof(oss_data)); - data->killNow = 0; - - data->fd = open(driver, O_RDONLY); - if(data->fd == -1) + self->fd = open(oss_capture, O_RDONLY); + if(self->fd == -1) { - free(data); - ERR("Could not open %s: %s\n", driver, strerror(errno)); + ERR("Could not open %s: %s\n", oss_capture, strerror(errno)); return ALC_INVALID_VALUE; } @@ -353,9 +420,10 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) ossFormat = AFMT_S16_NE; break; case DevFmtUShort: + case DevFmtInt: + case DevFmtUInt: case DevFmtFloat: - free(data); - ERR("%s capture samples not supported on OSS\n", DevFmtTypeString(device->FmtType)); + ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType)); return ALC_INVALID_VALUE; } @@ -375,17 +443,17 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) err = #func; \ goto err; \ } - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed)); - CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_SETFMT, &ossFormat)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_CHANNELS, &numChannels)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_SPEED, &ossSpeed)); + CHECKERR(ioctl(self->fd, SNDCTL_DSP_GETISPACE, &info)); if(0) { err: ERR("%s failed: %s\n", err, strerror(errno)); - close(data->fd); - free(data); + close(self->fd); + self->fd = -1; return ALC_INVALID_VALUE; } #undef CHECKERR @@ -393,8 +461,8 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels) { ERR("Failed to set %s, got %d channels instead\n", DevFmtChannelsString(device->FmtChans), numChannels); - close(data->fd); - free(data); + close(self->fd); + self->fd = -1; return ALC_INVALID_VALUE; } @@ -403,122 +471,129 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName) (ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort))) { ERR("Failed to set %s samples, got OSS format %#x\n", DevFmtTypeString(device->FmtType), ossFormat); - close(data->fd); - free(data); + close(self->fd); + self->fd = -1; return ALC_INVALID_VALUE; } - data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates); - if(!data->ring) + self->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates); + if(!self->ring) { ERR("Ring buffer create failed\n"); - close(data->fd); - free(data); + close(self->fd); + self->fd = -1; return ALC_OUT_OF_MEMORY; } - data->data_size = info.fragsize; - data->mix_data = calloc(1, data->data_size); + self->data_size = info.fragsize; + self->read_data = calloc(1, self->data_size); - device->ExtraData = data; - data->thread = StartThread(OSSCaptureProc, device); - if(data->thread == NULL) + if(!StartThread(&self->thread, ALCcaptureOSS_recordProc, self)) { device->ExtraData = NULL; - free(data->mix_data); - free(data); + close(self->fd); + self->fd = -1; return ALC_OUT_OF_MEMORY; } - device->szDeviceName = strdup(deviceName); + device->DeviceName = strdup(name); + return ALC_NO_ERROR; } -static void oss_close_capture(ALCdevice *device) +static void ALCcaptureOSS_close(ALCcaptureOSS *self) { - oss_data *data = (oss_data*)device->ExtraData; - data->killNow = 1; - StopThread(data->thread); + self->killNow = 1; + StopThread(self->thread); + self->killNow = 0; - close(data->fd); + close(self->fd); + self->fd = -1; - DestroyRingBuffer(data->ring); + DestroyRingBuffer(self->ring); + self->ring = NULL; - free(data->mix_data); - free(data); - device->ExtraData = NULL; + free(self->read_data); + self->read_data = NULL; } -static void oss_start_capture(ALCdevice *pDevice) +static ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self) { - oss_data *data = (oss_data*)pDevice->ExtraData; - data->doCapture = 1; -} - -static void oss_stop_capture(ALCdevice *pDevice) -{ - oss_data *data = (oss_data*)pDevice->ExtraData; - data->doCapture = 0; -} - -static ALCenum oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples) -{ - oss_data *data = (oss_data*)pDevice->ExtraData; - ReadRingBuffer(data->ring, pBuffer, lSamples); - return ALC_NO_ERROR; -} - -static ALCuint oss_available_samples(ALCdevice *pDevice) -{ - oss_data *data = (oss_data*)pDevice->ExtraData; - return RingBufferSize(data->ring); -} - - -static const BackendFuncs oss_funcs = { - oss_open_playback, - oss_close_playback, - oss_reset_playback, - oss_stop_playback, - oss_open_capture, - oss_close_capture, - oss_start_capture, - oss_stop_capture, - oss_capture_samples, - oss_available_samples -}; - -ALCboolean alc_oss_init(BackendFuncs *func_list) -{ - *func_list = oss_funcs; + self->doCapture = 1; return ALC_TRUE; } -void alc_oss_deinit(void) +static void ALCcaptureOSS_stop(ALCcaptureOSS *self) { + self->doCapture = 0; } -void alc_oss_probe(enum DevProbe type) +static ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples) +{ + ReadRingBuffer(self->ring, buffer, samples); + return ALC_NO_ERROR; +} + +static ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self) +{ + return RingBufferSize(self->ring); +} + +void ALCcaptureOSS_Delete(ALCcaptureOSS *self) +{ + free(self); +} + + + +typedef struct ALCossBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCossBackendFactory; +#define ALCOSSBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCossBackendFactory, ALCbackendFactory) } } + +ALCbackendFactory *ALCossBackendFactory_getFactory(void); + +static ALCboolean ALCossBackendFactory_init(ALCossBackendFactory *self); +static DECLARE_FORWARD(ALCossBackendFactory, ALCbackendFactory, void, deinit) +static ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory *self, ALCbackend_Type type); +static void ALCossBackendFactory_probe(ALCossBackendFactory *self, enum DevProbe type); +static ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory *self, ALCdevice *device, ALCbackend_Type type); +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCossBackendFactory); + + +ALCbackendFactory *ALCossBackendFactory_getFactory(void) +{ + static ALCossBackendFactory factory = ALCOSSBACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} + + +ALCboolean ALCossBackendFactory_init(ALCossBackendFactory* UNUSED(self)) +{ + ConfigValueStr("oss", "device", &oss_driver); + ConfigValueStr("oss", "capture", &oss_capture); + + return ALC_TRUE; +} + +ALCboolean ALCossBackendFactory_querySupport(ALCossBackendFactory* UNUSED(self), ALCbackend_Type type) +{ + if(type == ALCbackend_Playback || type == ALCbackend_Capture) + return ALC_TRUE; + return ALC_FALSE; +} + +void ALCossBackendFactory_probe(ALCossBackendFactory* UNUSED(self), enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - { -#ifdef HAVE_STAT - struct stat buf; - if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0) -#endif - AppendDeviceList(oss_device); - } - break; - case ALL_DEVICE_PROBE: { #ifdef HAVE_STAT struct stat buf; - if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0) + if(stat(oss_driver, &buf) == 0) #endif - AppendAllDeviceList(oss_device); + AppendAllDevicesList(oss_device); } break; @@ -526,10 +601,38 @@ void alc_oss_probe(enum DevProbe type) { #ifdef HAVE_STAT struct stat buf; - if(stat(GetConfigValue("oss", "capture", "/dev/dsp"), &buf) == 0) + if(stat(oss_capture, &buf) == 0) #endif AppendCaptureDeviceList(oss_device); } break; } } + +ALCbackend* ALCossBackendFactory_createBackend(ALCossBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + ALCplaybackOSS *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCplaybackOSS_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + if(type == ALCbackend_Capture) + { + ALCcaptureOSS *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCcaptureOSS_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} diff --git a/jni/openal-soft-android/Alc/backends/portaudio.c b/jni/openal-soft-android/Alc/backends/portaudio.c index 4275ad80..162788fc 100644 --- a/jni/openal-soft-android/Alc/backends/portaudio.c +++ b/jni/openal-soft-android/Alc/backends/portaudio.c @@ -23,9 +23,10 @@ #include #include #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "compat.h" #include @@ -33,9 +34,9 @@ static const ALCchar pa_device[] = "PortAudio Default"; -static void *pa_handle; #ifdef HAVE_DYNLOAD -#define MAKE_FUNC(x) static typeof(x) * p##x +static void *pa_handle; +#define MAKE_FUNC(x) static __typeof(x) * p##x MAKE_FUNC(Pa_Initialize); MAKE_FUNC(Pa_Terminate); MAKE_FUNC(Pa_GetErrorText); @@ -60,11 +61,11 @@ MAKE_FUNC(Pa_GetStreamInfo); static ALCboolean pa_load(void) { - if(!pa_handle) - { - PaError err; + PaError err; #ifdef HAVE_DYNLOAD + if(!pa_handle) + { #ifdef _WIN32 # define PALIB "portaudio.dll" #elif defined(__APPLE__) && defined(__MACH__) @@ -98,9 +99,6 @@ static ALCboolean pa_load(void) LOAD_FUNC(Pa_GetDefaultOutputDevice); LOAD_FUNC(Pa_GetStreamInfo); #undef LOAD_FUNC -#else - pa_handle = (void*)0xDEADBEEF; -#endif if((err=Pa_Initialize()) != paNoError) { @@ -110,43 +108,43 @@ static ALCboolean pa_load(void) return ALC_FALSE; } } +#else + if((err=Pa_Initialize()) != paNoError) + { + ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err)); + return ALC_FALSE; + } +#endif return ALC_TRUE; } typedef struct { PaStream *stream; + PaStreamParameters params; ALuint update_size; RingBuffer *ring; } pa_data; -static int pa_callback(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, - const PaStreamCallbackFlags statusFlags, void *userData) +static int pa_callback(const void *UNUSED(inputBuffer), void *outputBuffer, + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo), + const PaStreamCallbackFlags UNUSED(statusFlags), void *userData) { ALCdevice *device = (ALCdevice*)userData; - (void)inputBuffer; - (void)timeInfo; - (void)statusFlags; - aluMixData(device, outputBuffer, framesPerBuffer); return 0; } -static int pa_capture_cb(const void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, - const PaStreamCallbackFlags statusFlags, void *userData) +static int pa_capture_cb(const void *inputBuffer, void *UNUSED(outputBuffer), + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo), + const PaStreamCallbackFlags UNUSED(statusFlags), void *userData) { ALCdevice *device = (ALCdevice*)userData; pa_data *data = (pa_data*)device->ExtraData; - (void)outputBuffer; - (void)timeInfo; - (void)statusFlags; - WriteRingBuffer(data->ring, inputBuffer, framesPerBuffer); return 0; } @@ -154,7 +152,6 @@ static int pa_capture_cb(const void *inputBuffer, void *outputBuffer, static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName) { - PaStreamParameters outParams; pa_data *data; PaError err; @@ -166,64 +163,56 @@ static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName) data = (pa_data*)calloc(1, sizeof(pa_data)); data->update_size = device->UpdateSize; - device->ExtraData = data; + data->params.device = -1; + if(!ConfigValueInt("port", "device", &data->params.device) || + data->params.device < 0) + data->params.device = Pa_GetDefaultOutputDevice(); + data->params.suggestedLatency = (device->UpdateSize*device->NumUpdates) / + (float)device->Frequency; + data->params.hostApiSpecificStreamInfo = NULL; - outParams.device = -1; - if(!ConfigValueInt("port", "device", &outParams.device) || outParams.device < 0) - outParams.device = Pa_GetDefaultOutputDevice(); - outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) / - (float)device->Frequency; - outParams.hostApiSpecificStreamInfo = NULL; + data->params.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2); switch(device->FmtType) { case DevFmtByte: - outParams.sampleFormat = paInt8; + data->params.sampleFormat = paInt8; break; case DevFmtUByte: - outParams.sampleFormat = paUInt8; + data->params.sampleFormat = paUInt8; break; case DevFmtUShort: - device->FmtType = DevFmtShort; /* fall-through */ case DevFmtShort: - outParams.sampleFormat = paInt16; + data->params.sampleFormat = paInt16; + break; + case DevFmtUInt: + /* fall-through */ + case DevFmtInt: + data->params.sampleFormat = paInt32; break; case DevFmtFloat: - outParams.sampleFormat = paFloat32; + data->params.sampleFormat = paFloat32; break; } - outParams.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2); - SetDefaultChannelOrder(device); - - err = Pa_OpenStream(&data->stream, NULL, &outParams, device->Frequency, +retry_open: + err = Pa_OpenStream(&data->stream, NULL, &data->params, device->Frequency, device->UpdateSize, paNoFlag, pa_callback, device); if(err != paNoError) { + if(data->params.sampleFormat == paFloat32) + { + data->params.sampleFormat = paInt16; + goto retry_open; + } ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err)); - device->ExtraData = NULL; free(data); return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); - - if((ALuint)outParams.channelCount != ChannelsFromDevFmt(device->FmtChans)) - { - if(outParams.channelCount != 1 && outParams.channelCount != 2) - { - ERR("Unhandled channel count: %u\n", outParams.channelCount); - Pa_CloseStream(data->stream); - device->ExtraData = NULL; - free(data); - return ALC_INVALID_VALUE; - } - if((device->Flags&DEVICE_CHANNELS_REQUEST)) - ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), outParams.channelCount); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - device->FmtChans = ((outParams.channelCount==1) ? DevFmtMono : DevFmtStereo); - } + device->ExtraData = data; + device->DeviceName = strdup(deviceName); return ALC_NO_ERROR; } @@ -245,18 +234,46 @@ static ALCboolean pa_reset_playback(ALCdevice *device) { pa_data *data = (pa_data*)device->ExtraData; const PaStreamInfo *streamInfo; - PaError err; streamInfo = Pa_GetStreamInfo(data->stream); - if(device->Frequency != streamInfo->sampleRate) - { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("PortAudio does not support changing sample rates (wanted %dhz, got %.1fhz)\n", device->Frequency, streamInfo->sampleRate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = streamInfo->sampleRate; - } + device->Frequency = streamInfo->sampleRate; device->UpdateSize = data->update_size; + if(data->params.sampleFormat == paInt8) + device->FmtType = DevFmtByte; + else if(data->params.sampleFormat == paUInt8) + device->FmtType = DevFmtUByte; + else if(data->params.sampleFormat == paInt16) + device->FmtType = DevFmtShort; + else if(data->params.sampleFormat == paInt32) + device->FmtType = DevFmtInt; + else if(data->params.sampleFormat == paFloat32) + device->FmtType = DevFmtFloat; + else + { + ERR("Unexpected sample format: 0x%lx\n", data->params.sampleFormat); + return ALC_FALSE; + } + + if(data->params.channelCount == 2) + device->FmtChans = DevFmtStereo; + else if(data->params.channelCount == 1) + device->FmtChans = DevFmtMono; + else + { + ERR("Unexpected channel count: %u\n", data->params.channelCount); + return ALC_FALSE; + } + SetDefaultChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean pa_start_playback(ALCdevice *device) +{ + pa_data *data = (pa_data*)device->ExtraData; + PaError err; + err = Pa_StartStream(data->stream); if(err != paNoError) { @@ -280,7 +297,6 @@ static void pa_stop_playback(ALCdevice *device) static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName) { - PaStreamParameters inParams; ALuint frame_size; pa_data *data; PaError err; @@ -299,33 +315,38 @@ static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName) if(data->ring == NULL) goto error; - inParams.device = -1; - if(!ConfigValueInt("port", "capture", &inParams.device) || inParams.device < 0) - inParams.device = Pa_GetDefaultOutputDevice(); - inParams.suggestedLatency = 0.0f; - inParams.hostApiSpecificStreamInfo = NULL; + data->params.device = -1; + if(!ConfigValueInt("port", "capture", &data->params.device) || + data->params.device < 0) + data->params.device = Pa_GetDefaultOutputDevice(); + data->params.suggestedLatency = 0.0f; + data->params.hostApiSpecificStreamInfo = NULL; switch(device->FmtType) { case DevFmtByte: - inParams.sampleFormat = paInt8; + data->params.sampleFormat = paInt8; break; case DevFmtUByte: - inParams.sampleFormat = paUInt8; + data->params.sampleFormat = paUInt8; break; case DevFmtShort: - inParams.sampleFormat = paInt16; + data->params.sampleFormat = paInt16; + break; + case DevFmtInt: + data->params.sampleFormat = paInt32; break; case DevFmtFloat: - inParams.sampleFormat = paFloat32; + data->params.sampleFormat = paFloat32; break; + case DevFmtUInt: case DevFmtUShort: - ERR("Unsigned short samples not supported\n"); + ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType)); goto error; } - inParams.channelCount = ChannelsFromDevFmt(device->FmtChans); + data->params.channelCount = ChannelsFromDevFmt(device->FmtChans); - err = Pa_OpenStream(&data->stream, &inParams, NULL, device->Frequency, + err = Pa_OpenStream(&data->stream, &data->params, NULL, device->Frequency, paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device); if(err != paNoError) { @@ -333,7 +354,7 @@ static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName) goto error; } - device->szDeviceName = strdup(deviceName); + device->DeviceName = strdup(deviceName); device->ExtraData = data; return ALC_NO_ERROR; @@ -353,6 +374,9 @@ static void pa_close_capture(ALCdevice *device) if(err != paNoError) ERR("Error closing stream: %s\n", Pa_GetErrorText(err)); + DestroyRingBuffer(data->ring); + data->ring = NULL; + free(data); device->ExtraData = NULL; } @@ -395,13 +419,15 @@ static const BackendFuncs pa_funcs = { pa_open_playback, pa_close_playback, pa_reset_playback, + pa_start_playback, pa_stop_playback, pa_open_capture, pa_close_capture, pa_start_capture, pa_stop_capture, pa_capture_samples, - pa_available_samples + pa_available_samples, + ALCdevice_GetLatencyDefault }; ALCboolean alc_pa_init(BackendFuncs *func_list) @@ -414,25 +440,24 @@ ALCboolean alc_pa_init(BackendFuncs *func_list) void alc_pa_deinit(void) { +#ifdef HAVE_DYNLOAD if(pa_handle) { Pa_Terminate(); -#ifdef HAVE_DYNLOAD CloseLib(pa_handle); -#endif pa_handle = NULL; } +#else + Pa_Terminate(); +#endif } void alc_pa_probe(enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - AppendDeviceList(pa_device); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(pa_device); + AppendAllDevicesList(pa_device); break; case CAPTURE_DEVICE_PROBE: AppendCaptureDeviceList(pa_device); diff --git a/jni/openal-soft-android/Alc/backends/pulseaudio.c b/jni/openal-soft-android/Alc/backends/pulseaudio.c index ee7a633f..e2ae52ae 100644 --- a/jni/openal-soft-android/Alc/backends/pulseaudio.c +++ b/jni/openal-soft-android/Alc/backends/pulseaudio.c @@ -21,27 +21,18 @@ #include "config.h" +#include + #include "alMain.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" + +#include "backends/base.h" #include -#if PA_API_VERSION == 11 -#define PA_STREAM_ADJUST_LATENCY 0x2000U -#define PA_STREAM_EARLY_REQUESTS 0x4000U -static __inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) -{ - return (x == PA_STREAM_CREATING || x == PA_STREAM_READY); -} -static __inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) -{ - return (x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING || - x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY); -} -#define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD -#define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD -#elif PA_API_VERSION != 12 -#error Invalid PulseAudio API version -#endif +#if PA_API_VERSION == 12 #ifndef PA_CHECK_VERSION #define PA_CHECK_VERSION(major,minor,micro) \ @@ -50,11 +41,12 @@ static __inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro))) #endif -static void *pa_handle; #ifdef HAVE_DYNLOAD -#define MAKE_FUNC(x) static typeof(x) * p##x +static void *pa_handle; +#define MAKE_FUNC(x) static __typeof(x) * p##x MAKE_FUNC(pa_context_unref); MAKE_FUNC(pa_sample_spec_valid); +MAKE_FUNC(pa_frame_size); MAKE_FUNC(pa_stream_drop); MAKE_FUNC(pa_strerror); MAKE_FUNC(pa_context_get_state); @@ -76,9 +68,11 @@ MAKE_FUNC(pa_stream_connect_record); MAKE_FUNC(pa_stream_connect_playback); MAKE_FUNC(pa_stream_readable_size); MAKE_FUNC(pa_stream_writable_size); +MAKE_FUNC(pa_stream_is_corked); MAKE_FUNC(pa_stream_cork); MAKE_FUNC(pa_stream_is_suspended); MAKE_FUNC(pa_stream_get_device_name); +MAKE_FUNC(pa_stream_get_latency); MAKE_FUNC(pa_path_get_filename); MAKE_FUNC(pa_get_binary_name); MAKE_FUNC(pa_threaded_mainloop_free); @@ -97,7 +91,7 @@ MAKE_FUNC(pa_stream_set_read_callback); MAKE_FUNC(pa_stream_set_state_callback); MAKE_FUNC(pa_stream_set_moved_callback); MAKE_FUNC(pa_stream_set_underflow_callback); -MAKE_FUNC(pa_stream_new); +MAKE_FUNC(pa_stream_new_with_proplist); MAKE_FUNC(pa_stream_disconnect); MAKE_FUNC(pa_threaded_mainloop_lock); MAKE_FUNC(pa_channel_map_init_auto); @@ -107,9 +101,13 @@ MAKE_FUNC(pa_channel_map_equal); MAKE_FUNC(pa_context_get_server_info); MAKE_FUNC(pa_context_get_sink_info_by_name); MAKE_FUNC(pa_context_get_sink_info_list); +MAKE_FUNC(pa_context_get_source_info_by_name); MAKE_FUNC(pa_context_get_source_info_list); MAKE_FUNC(pa_operation_get_state); MAKE_FUNC(pa_operation_unref); +MAKE_FUNC(pa_proplist_new); +MAKE_FUNC(pa_proplist_free); +MAKE_FUNC(pa_proplist_set); #if PA_CHECK_VERSION(0,9,15) MAKE_FUNC(pa_channel_map_superset); MAKE_FUNC(pa_stream_set_buffer_attr_callback); @@ -121,6 +119,7 @@ MAKE_FUNC(pa_stream_begin_write); #define pa_context_unref ppa_context_unref #define pa_sample_spec_valid ppa_sample_spec_valid +#define pa_frame_size ppa_frame_size #define pa_stream_drop ppa_stream_drop #define pa_strerror ppa_strerror #define pa_context_get_state ppa_context_get_state @@ -142,9 +141,11 @@ MAKE_FUNC(pa_stream_begin_write); #define pa_stream_connect_playback ppa_stream_connect_playback #define pa_stream_readable_size ppa_stream_readable_size #define pa_stream_writable_size ppa_stream_writable_size +#define pa_stream_is_corked ppa_stream_is_corked #define pa_stream_cork ppa_stream_cork #define pa_stream_is_suspended ppa_stream_is_suspended #define pa_stream_get_device_name ppa_stream_get_device_name +#define pa_stream_get_latency ppa_stream_get_latency #define pa_path_get_filename ppa_path_get_filename #define pa_get_binary_name ppa_get_binary_name #define pa_threaded_mainloop_free ppa_threaded_mainloop_free @@ -163,7 +164,7 @@ MAKE_FUNC(pa_stream_begin_write); #define pa_stream_set_state_callback ppa_stream_set_state_callback #define pa_stream_set_moved_callback ppa_stream_set_moved_callback #define pa_stream_set_underflow_callback ppa_stream_set_underflow_callback -#define pa_stream_new ppa_stream_new +#define pa_stream_new_with_proplist ppa_stream_new_with_proplist #define pa_stream_disconnect ppa_stream_disconnect #define pa_threaded_mainloop_lock ppa_threaded_mainloop_lock #define pa_channel_map_init_auto ppa_channel_map_init_auto @@ -173,9 +174,13 @@ MAKE_FUNC(pa_stream_begin_write); #define pa_context_get_server_info ppa_context_get_server_info #define pa_context_get_sink_info_by_name ppa_context_get_sink_info_by_name #define pa_context_get_sink_info_list ppa_context_get_sink_info_list +#define pa_context_get_source_info_by_name ppa_context_get_source_info_by_name #define pa_context_get_source_info_list ppa_context_get_source_info_list #define pa_operation_get_state ppa_operation_get_state #define pa_operation_unref ppa_operation_unref +#define pa_proplist_new ppa_proplist_new +#define pa_proplist_free ppa_proplist_free +#define pa_proplist_set ppa_proplist_set #if PA_CHECK_VERSION(0,9,15) #define pa_channel_map_superset ppa_channel_map_superset #define pa_stream_set_buffer_attr_callback ppa_stream_set_buffer_attr_callback @@ -186,44 +191,126 @@ MAKE_FUNC(pa_stream_begin_write); #endif +static ALCboolean pulse_load(void) +{ + ALCboolean ret = ALC_TRUE; +#ifdef HAVE_DYNLOAD + if(!pa_handle) + { +#ifdef _WIN32 +#define PALIB "libpulse-0.dll" +#elif defined(__APPLE__) && defined(__MACH__) +#define PALIB "libpulse.0.dylib" +#else +#define PALIB "libpulse.so.0" +#endif + pa_handle = LoadLib(PALIB); + if(!pa_handle) + return ALC_FALSE; + +#define LOAD_FUNC(x) do { \ + p##x = GetSymbol(pa_handle, #x); \ + if(!(p##x)) { \ + ret = ALC_FALSE; \ + } \ +} while(0) + LOAD_FUNC(pa_context_unref); + LOAD_FUNC(pa_sample_spec_valid); + LOAD_FUNC(pa_stream_drop); + LOAD_FUNC(pa_frame_size); + LOAD_FUNC(pa_strerror); + LOAD_FUNC(pa_context_get_state); + LOAD_FUNC(pa_stream_get_state); + LOAD_FUNC(pa_threaded_mainloop_signal); + LOAD_FUNC(pa_stream_peek); + LOAD_FUNC(pa_threaded_mainloop_wait); + LOAD_FUNC(pa_threaded_mainloop_unlock); + LOAD_FUNC(pa_threaded_mainloop_in_thread); + LOAD_FUNC(pa_context_new); + LOAD_FUNC(pa_threaded_mainloop_stop); + LOAD_FUNC(pa_context_disconnect); + LOAD_FUNC(pa_threaded_mainloop_start); + LOAD_FUNC(pa_threaded_mainloop_get_api); + LOAD_FUNC(pa_context_set_state_callback); + LOAD_FUNC(pa_stream_write); + LOAD_FUNC(pa_xfree); + LOAD_FUNC(pa_stream_connect_record); + LOAD_FUNC(pa_stream_connect_playback); + LOAD_FUNC(pa_stream_readable_size); + LOAD_FUNC(pa_stream_writable_size); + LOAD_FUNC(pa_stream_is_corked); + LOAD_FUNC(pa_stream_cork); + LOAD_FUNC(pa_stream_is_suspended); + LOAD_FUNC(pa_stream_get_device_name); + LOAD_FUNC(pa_stream_get_latency); + LOAD_FUNC(pa_path_get_filename); + LOAD_FUNC(pa_get_binary_name); + LOAD_FUNC(pa_threaded_mainloop_free); + LOAD_FUNC(pa_context_errno); + LOAD_FUNC(pa_xmalloc); + LOAD_FUNC(pa_stream_unref); + LOAD_FUNC(pa_threaded_mainloop_accept); + LOAD_FUNC(pa_stream_set_write_callback); + LOAD_FUNC(pa_threaded_mainloop_new); + LOAD_FUNC(pa_context_connect); + LOAD_FUNC(pa_stream_set_buffer_attr); + LOAD_FUNC(pa_stream_get_buffer_attr); + LOAD_FUNC(pa_stream_get_sample_spec); + LOAD_FUNC(pa_stream_get_time); + LOAD_FUNC(pa_stream_set_read_callback); + LOAD_FUNC(pa_stream_set_state_callback); + LOAD_FUNC(pa_stream_set_moved_callback); + LOAD_FUNC(pa_stream_set_underflow_callback); + LOAD_FUNC(pa_stream_new_with_proplist); + LOAD_FUNC(pa_stream_disconnect); + LOAD_FUNC(pa_threaded_mainloop_lock); + LOAD_FUNC(pa_channel_map_init_auto); + LOAD_FUNC(pa_channel_map_parse); + LOAD_FUNC(pa_channel_map_snprint); + LOAD_FUNC(pa_channel_map_equal); + LOAD_FUNC(pa_context_get_server_info); + LOAD_FUNC(pa_context_get_sink_info_by_name); + LOAD_FUNC(pa_context_get_sink_info_list); + LOAD_FUNC(pa_context_get_source_info_by_name); + LOAD_FUNC(pa_context_get_source_info_list); + LOAD_FUNC(pa_operation_get_state); + LOAD_FUNC(pa_operation_unref); + LOAD_FUNC(pa_proplist_new); + LOAD_FUNC(pa_proplist_free); + LOAD_FUNC(pa_proplist_set); +#undef LOAD_FUNC +#define LOAD_OPTIONAL_FUNC(x) do { \ + p##x = GetSymbol(pa_handle, #x); \ +} while(0) +#if PA_CHECK_VERSION(0,9,15) + LOAD_OPTIONAL_FUNC(pa_channel_map_superset); + LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback); +#endif +#if PA_CHECK_VERSION(0,9,16) + LOAD_OPTIONAL_FUNC(pa_stream_begin_write); +#endif +#undef LOAD_OPTIONAL_FUNC + + if(ret == ALC_FALSE) + { + CloseLib(pa_handle); + pa_handle = NULL; + } + } +#endif /* HAVE_DYNLOAD */ + return ret; +} + + +/* Global flags and properties */ +static pa_context_flags_t pulse_ctx_flags; +static pa_proplist *prop_filter; + #ifndef PATH_MAX #define PATH_MAX 4096 #endif -typedef struct { - char *device_name; - - ALCuint samples; - ALCuint frame_size; - - RingBuffer *ring; - - pa_buffer_attr attr; - pa_sample_spec spec; - - pa_threaded_mainloop *loop; - - ALvoid *thread; - volatile ALboolean killNow; - - pa_stream *stream; - pa_context *context; -} pulse_data; - -typedef struct { - char *name; - char *device_name; -} DevMap; - - -static const ALCchar pulse_device[] = "PulseAudio Default"; -static DevMap *allDevNameMap; -static ALuint numDevNames; -static DevMap *allCaptureDevNameMap; -static ALuint numCaptureDevNames; -static pa_context_flags_t pulse_ctx_flags; - - +/* PulseAudio Event Callbacks */ static void context_state_callback(pa_context *context, void *pdata) { pa_threaded_mainloop *loop = pdata; @@ -234,6 +321,33 @@ static void context_state_callback(pa_context *context, void *pdata) pa_threaded_mainloop_signal(loop, 0); } +static void stream_state_callback(pa_stream *stream, void *pdata) +{ + pa_threaded_mainloop *loop = pdata; + pa_stream_state_t state; + + state = pa_stream_get_state(stream); + if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state)) + pa_threaded_mainloop_signal(loop, 0); +} + +static void stream_success_callback(pa_stream *UNUSED(stream), int UNUSED(success), void *pdata) +{ + pa_threaded_mainloop *loop = pdata; + pa_threaded_mainloop_signal(loop, 0); +} + +static void wait_for_operation(pa_operation *op, pa_threaded_mainloop *loop) +{ + if(op) + { + while(pa_operation_get_state(op) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(loop); + pa_operation_unref(op); + } +} + + static pa_context *connect_context(pa_threaded_mainloop *loop, ALboolean silent) { const char *name = "OpenAL Soft"; @@ -282,217 +396,248 @@ static pa_context *connect_context(pa_threaded_mainloop *loop, ALboolean silent) } -static ALCboolean pulse_load(void) //{{{ +static ALCboolean pulse_open(pa_threaded_mainloop **loop, pa_context **context, + void(*state_cb)(pa_context*,void*), void *ptr) { - ALCboolean ret = ALC_FALSE; - if(!pa_handle) + if(!(*loop = pa_threaded_mainloop_new())) { - pa_threaded_mainloop *loop; - -#ifdef HAVE_DYNLOAD - -#ifdef _WIN32 -#define PALIB "libpulse-0.dll" -#elif defined(__APPLE__) && defined(__MACH__) -#define PALIB "libpulse.0.dylib" -#else -#define PALIB "libpulse.so.0" -#endif - pa_handle = LoadLib(PALIB); - if(!pa_handle) - return ALC_FALSE; - -#define LOAD_FUNC(x) do { \ - p##x = GetSymbol(pa_handle, #x); \ - if(!(p##x)) { \ - CloseLib(pa_handle); \ - pa_handle = NULL; \ - return ALC_FALSE; \ - } \ -} while(0) - LOAD_FUNC(pa_context_unref); - LOAD_FUNC(pa_sample_spec_valid); - LOAD_FUNC(pa_stream_drop); - LOAD_FUNC(pa_strerror); - LOAD_FUNC(pa_context_get_state); - LOAD_FUNC(pa_stream_get_state); - LOAD_FUNC(pa_threaded_mainloop_signal); - LOAD_FUNC(pa_stream_peek); - LOAD_FUNC(pa_threaded_mainloop_wait); - LOAD_FUNC(pa_threaded_mainloop_unlock); - LOAD_FUNC(pa_threaded_mainloop_in_thread); - LOAD_FUNC(pa_context_new); - LOAD_FUNC(pa_threaded_mainloop_stop); - LOAD_FUNC(pa_context_disconnect); - LOAD_FUNC(pa_threaded_mainloop_start); - LOAD_FUNC(pa_threaded_mainloop_get_api); - LOAD_FUNC(pa_context_set_state_callback); - LOAD_FUNC(pa_stream_write); - LOAD_FUNC(pa_xfree); - LOAD_FUNC(pa_stream_connect_record); - LOAD_FUNC(pa_stream_connect_playback); - LOAD_FUNC(pa_stream_readable_size); - LOAD_FUNC(pa_stream_writable_size); - LOAD_FUNC(pa_stream_cork); - LOAD_FUNC(pa_stream_is_suspended); - LOAD_FUNC(pa_stream_get_device_name); - LOAD_FUNC(pa_path_get_filename); - LOAD_FUNC(pa_get_binary_name); - LOAD_FUNC(pa_threaded_mainloop_free); - LOAD_FUNC(pa_context_errno); - LOAD_FUNC(pa_xmalloc); - LOAD_FUNC(pa_stream_unref); - LOAD_FUNC(pa_threaded_mainloop_accept); - LOAD_FUNC(pa_stream_set_write_callback); - LOAD_FUNC(pa_threaded_mainloop_new); - LOAD_FUNC(pa_context_connect); - LOAD_FUNC(pa_stream_set_buffer_attr); - LOAD_FUNC(pa_stream_get_buffer_attr); - LOAD_FUNC(pa_stream_get_sample_spec); - LOAD_FUNC(pa_stream_get_time); - LOAD_FUNC(pa_stream_set_read_callback); - LOAD_FUNC(pa_stream_set_state_callback); - LOAD_FUNC(pa_stream_set_moved_callback); - LOAD_FUNC(pa_stream_set_underflow_callback); - LOAD_FUNC(pa_stream_new); - LOAD_FUNC(pa_stream_disconnect); - LOAD_FUNC(pa_threaded_mainloop_lock); - LOAD_FUNC(pa_channel_map_init_auto); - LOAD_FUNC(pa_channel_map_parse); - LOAD_FUNC(pa_channel_map_snprint); - LOAD_FUNC(pa_channel_map_equal); - LOAD_FUNC(pa_context_get_server_info); - LOAD_FUNC(pa_context_get_sink_info_by_name); - LOAD_FUNC(pa_context_get_sink_info_list); - LOAD_FUNC(pa_context_get_source_info_list); - LOAD_FUNC(pa_operation_get_state); - LOAD_FUNC(pa_operation_unref); -#undef LOAD_FUNC -#define LOAD_OPTIONAL_FUNC(x) do { \ - p##x = GetSymbol(pa_handle, #x); \ -} while(0) -#if PA_CHECK_VERSION(0,9,15) - LOAD_OPTIONAL_FUNC(pa_channel_map_superset); - LOAD_OPTIONAL_FUNC(pa_stream_set_buffer_attr_callback); -#endif -#if PA_CHECK_VERSION(0,9,16) - LOAD_OPTIONAL_FUNC(pa_stream_begin_write); -#endif -#undef LOAD_OPTIONAL_FUNC - -#else /* HAVE_DYNLOAD */ - pa_handle = (void*)0xDEADBEEF; -#endif - - if((loop=pa_threaded_mainloop_new()) && - pa_threaded_mainloop_start(loop) >= 0) - { - pa_context *context; - - pa_threaded_mainloop_lock(loop); - context = connect_context(loop, AL_TRUE); - if(context) - { - ret = ALC_TRUE; - - pa_context_disconnect(context); - pa_context_unref(context); - } - pa_threaded_mainloop_unlock(loop); - pa_threaded_mainloop_stop(loop); - } - if(loop) - pa_threaded_mainloop_free(loop); - - if(!ret) - { -#ifdef HAVE_DYNLOAD - CloseLib(pa_handle); -#endif - pa_handle = NULL; - } + ERR("pa_threaded_mainloop_new() failed!\n"); + return ALC_FALSE; + } + if(pa_threaded_mainloop_start(*loop) < 0) + { + ERR("pa_threaded_mainloop_start() failed\n"); + goto error; } - return ret; -} //}}} -// PulseAudio Event Callbacks //{{{ -static void stream_state_callback(pa_stream *stream, void *pdata) //{{{ + pa_threaded_mainloop_lock(*loop); + + *context = connect_context(*loop, AL_FALSE); + if(!*context) + { + pa_threaded_mainloop_unlock(*loop); + pa_threaded_mainloop_stop(*loop); + goto error; + } + pa_context_set_state_callback(*context, state_cb, ptr); + + pa_threaded_mainloop_unlock(*loop); + return ALC_TRUE; + +error: + pa_threaded_mainloop_free(*loop); + *loop = NULL; + + return ALC_FALSE; +} + +static void pulse_close(pa_threaded_mainloop *loop, pa_context *context, + pa_stream *stream) +{ + pa_threaded_mainloop_lock(loop); + + if(stream) + { + pa_stream_set_moved_callback(stream, NULL, NULL); +#if PA_CHECK_VERSION(0,9,15) + if(pa_stream_set_buffer_attr_callback) + pa_stream_set_buffer_attr_callback(stream, NULL, NULL); +#endif + pa_stream_disconnect(stream); + pa_stream_unref(stream); + } + + pa_context_disconnect(context); + pa_context_unref(context); + + pa_threaded_mainloop_unlock(loop); + + pa_threaded_mainloop_stop(loop); + pa_threaded_mainloop_free(loop); +} + + +typedef struct { + char *name; + char *device_name; +} DevMap; + +static DevMap *allDevNameMap; +static ALuint numDevNames; +static DevMap *allCaptureDevNameMap; +static ALuint numCaptureDevNames; + + +typedef struct ALCpulsePlayback { + DERIVE_FROM_TYPE(ALCbackend); + + char *device_name; + + pa_buffer_attr attr; + pa_sample_spec spec; + + pa_threaded_mainloop *loop; + + pa_stream *stream; + pa_context *context; + + volatile ALboolean killNow; + althread_t thread; +} ALCpulsePlayback; +DECLARE_ALCBACKEND_VTABLE(ALCpulsePlayback); + +static void ALCpulsePlayback_deviceCallback(pa_context *context, const pa_sink_info *info, int eol, void *pdata); +static void ALCpulsePlayback_probeDevices(void); + +static void ALCpulsePlayback_bufferAttrCallback(pa_stream *stream, void *pdata); +static void ALCpulsePlayback_contextStateCallback(pa_context *context, void *pdata); +static void ALCpulsePlayback_streamStateCallback(pa_stream *stream, void *pdata); +static void ALCpulsePlayback_sinkInfoCallback(pa_context *context, const pa_sink_info *info, int eol, void *pdata); +static void ALCpulsePlayback_sinkNameCallback(pa_context *context, const pa_sink_info *info, int eol, void *pdata); +static void ALCpulsePlayback_streamMovedCallback(pa_stream *stream, void *pdata); +static pa_stream *ALCpulsePlayback_connectStream(const char *device_name, pa_threaded_mainloop *loop, + pa_context *context, pa_stream_flags_t flags, + pa_buffer_attr *attr, pa_sample_spec *spec, + pa_channel_map *chanmap); +static ALuint ALCpulsePlayback_mixerProc(ALvoid *ptr); + +static void ALCpulsePlayback_Construct(ALCpulsePlayback *self, ALCdevice *device); +static DECLARE_FORWARD(ALCpulsePlayback, ALCbackend, void, Destruct) +static ALCenum ALCpulsePlayback_open(ALCpulsePlayback *self, const ALCchar *name); +static void ALCpulsePlayback_close(ALCpulsePlayback *self); +static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self); +static ALCboolean ALCpulsePlayback_start(ALCpulsePlayback *self); +static void ALCpulsePlayback_stop(ALCpulsePlayback *self); +static DECLARE_FORWARD2(ALCpulsePlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) +static DECLARE_FORWARD(ALCpulsePlayback, ALCbackend, ALCuint, availableSamples) +static void ALCpulsePlayback_lock(ALCpulsePlayback *self); +static void ALCpulsePlayback_unlock(ALCpulsePlayback *self); + + +static void ALCpulsePlayback_Construct(ALCpulsePlayback *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCpulsePlayback, ALCbackend, self); +} + + +static void ALCpulsePlayback_deviceCallback(pa_context *UNUSED(context), const pa_sink_info *info, int eol, void *pdata) { pa_threaded_mainloop *loop = pdata; - pa_stream_state_t state; + void *temp; + ALuint i; - state = pa_stream_get_state(stream); - if(state == PA_STREAM_READY || !PA_STREAM_IS_GOOD(state)) + if(eol) + { pa_threaded_mainloop_signal(loop, 0); -}//}}} + return; + } -static void stream_signal_callback(pa_stream *stream, void *pdata) //{{{ + for(i = 0;i < numDevNames;i++) + { + if(strcmp(info->name, allDevNameMap[i].device_name) == 0) + return; + } + + TRACE("Got device \"%s\", \"%s\"\n", info->description, info->name); + + temp = realloc(allDevNameMap, (numDevNames+1) * sizeof(*allDevNameMap)); + if(temp) + { + allDevNameMap = temp; + allDevNameMap[numDevNames].name = strdup(info->description); + allDevNameMap[numDevNames].device_name = strdup(info->name); + numDevNames++; + } +} + +static void ALCpulsePlayback_probeDevices(void) { - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - (void)stream; + pa_threaded_mainloop *loop; - pa_threaded_mainloop_signal(data->loop, 0); -}//}}} + allDevNameMap = malloc(sizeof(DevMap) * 1); + if((loop=pa_threaded_mainloop_new()) && + pa_threaded_mainloop_start(loop) >= 0) + { + pa_context *context; -static void stream_buffer_attr_callback(pa_stream *stream, void *pdata) //{{{ + pa_threaded_mainloop_lock(loop); + context = connect_context(loop, AL_FALSE); + if(context) + { + pa_operation *o; + pa_stream_flags_t flags; + pa_sample_spec spec; + pa_stream *stream; + + flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE | + PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE; + + spec.format = PA_SAMPLE_S16NE; + spec.rate = 44100; + spec.channels = 2; + + stream = ALCpulsePlayback_connectStream(NULL, loop, context, flags, + NULL, &spec, NULL); + if(stream) + { + o = pa_context_get_sink_info_by_name(context, pa_stream_get_device_name(stream), + ALCpulsePlayback_deviceCallback, loop); + wait_for_operation(o, loop); + + pa_stream_disconnect(stream); + pa_stream_unref(stream); + stream = NULL; + } + + o = pa_context_get_sink_info_list(context, ALCpulsePlayback_deviceCallback, loop); + wait_for_operation(o, loop); + + pa_context_disconnect(context); + pa_context_unref(context); + } + pa_threaded_mainloop_unlock(loop); + pa_threaded_mainloop_stop(loop); + } + if(loop) + pa_threaded_mainloop_free(loop); +} + + +static void ALCpulsePlayback_bufferAttrCallback(pa_stream *stream, void *pdata) { - const pa_buffer_attr *attr; - (void)pdata; + ALCpulsePlayback *self = pdata; - attr = pa_stream_get_buffer_attr(stream); - WARN("PulseAudio modified buffer length: minreq=%d, tlength=%d\n", attr->minreq, attr->tlength); -}//}}} + self->attr = *pa_stream_get_buffer_attr(stream); + TRACE("minreq=%d, tlength=%d, prebuf=%d\n", self->attr.minreq, self->attr.tlength, self->attr.prebuf); +} -static void stream_device_callback(pa_stream *stream, void *pdata) //{{{ +static void ALCpulsePlayback_contextStateCallback(pa_context *context, void *pdata) { - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - - free(data->device_name); - data->device_name = strdup(pa_stream_get_device_name(stream)); -}//}}} - -static void context_state_callback2(pa_context *context, void *pdata) //{{{ -{ - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - + ALCpulsePlayback *self = pdata; if(pa_context_get_state(context) == PA_CONTEXT_FAILED) { ERR("Received context failure!\n"); - aluHandleDisconnect(Device); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); } - pa_threaded_mainloop_signal(data->loop, 0); -}//}}} + pa_threaded_mainloop_signal(self->loop, 0); +} -static void stream_state_callback2(pa_stream *stream, void *pdata) //{{{ +static void ALCpulsePlayback_streamStateCallback(pa_stream *stream, void *pdata) { - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - + ALCpulsePlayback *self = pdata; if(pa_stream_get_state(stream) == PA_STREAM_FAILED) { ERR("Received stream failure!\n"); - aluHandleDisconnect(Device); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); } - pa_threaded_mainloop_signal(data->loop, 0); -}//}}} + pa_threaded_mainloop_signal(self->loop, 0); +} -static void stream_success_callback(pa_stream *stream, int success, void *pdata) //{{{ +static void ALCpulsePlayback_sinkInfoCallback(pa_context *UNUSED(context), const pa_sink_info *info, int eol, void *pdata) { - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - (void)stream; - (void)success; - - pa_threaded_mainloop_signal(data->loop, 0); -}//}}} - -static void sink_info_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata) //{{{ -{ - ALCdevice *device = pdata; - pulse_data *data = device->ExtraData; + ALCpulsePlayback *self = pdata; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; char chanmap_str[256] = ""; const struct { const char *str; @@ -512,11 +657,10 @@ static void sink_info_callback(pa_context *context, const pa_sink_info *info, in { NULL, 0 } }; int i; - (void)context; if(eol) { - pa_threaded_mainloop_signal(data->loop, 0); + pa_threaded_mainloop_signal(self->loop, 0); return; } @@ -540,120 +684,113 @@ static void sink_info_callback(pa_context *context, const pa_sink_info *info, in pa_channel_map_snprint(chanmap_str, sizeof(chanmap_str), &info->channel_map); ERR("Failed to find format for channel map:\n %s\n", chanmap_str); -}//}}} +} -static void sink_device_callback(pa_context *context, const pa_sink_info *info, int eol, void *pdata) //{{{ +static void ALCpulsePlayback_sinkNameCallback(pa_context *UNUSED(context), const pa_sink_info *info, int eol, void *pdata) { - pa_threaded_mainloop *loop = pdata; - char str[1024]; - void *temp; - int count; - ALuint i; - - (void)context; + ALCpulsePlayback *self = pdata; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; if(eol) { - pa_threaded_mainloop_signal(loop, 0); + pa_threaded_mainloop_signal(self->loop, 0); return; } - count = 0; - do { - if(count == 0) - snprintf(str, sizeof(str), "%s", info->description); - else - snprintf(str, sizeof(str), "%s #%d", info->description, count+1); - count++; + free(device->DeviceName); + device->DeviceName = strdup(info->description); +} - for(i = 0;i < numDevNames;i++) + +static void ALCpulsePlayback_streamMovedCallback(pa_stream *stream, void *pdata) +{ + ALCpulsePlayback *self = pdata; + + free(self->device_name); + self->device_name = strdup(pa_stream_get_device_name(stream)); + + TRACE("Stream moved to %s\n", self->device_name); +} + + +static pa_stream *ALCpulsePlayback_connectStream(const char *device_name, + pa_threaded_mainloop *loop, pa_context *context, + pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec, + pa_channel_map *chanmap) +{ + pa_stream_state_t state; + pa_stream *stream; + + stream = pa_stream_new_with_proplist(context, "Playback Stream", spec, chanmap, prop_filter); + if(!stream) + { + ERR("pa_stream_new_with_proplist() failed: %s\n", pa_strerror(pa_context_errno(context))); + return NULL; + } + + pa_stream_set_state_callback(stream, stream_state_callback, loop); + + if(pa_stream_connect_playback(stream, device_name, attr, flags, NULL, NULL) < 0) + { + ERR("Stream did not connect: %s\n", pa_strerror(pa_context_errno(context))); + pa_stream_unref(stream); + return NULL; + } + + while((state=pa_stream_get_state(stream)) != PA_STREAM_READY) + { + if(!PA_STREAM_IS_GOOD(state)) { - if(strcmp(str, allDevNameMap[i].name) == 0) - break; + ERR("Stream did not get ready: %s\n", pa_strerror(pa_context_errno(context))); + pa_stream_unref(stream); + return NULL; } - } while(i != numDevNames); - temp = realloc(allDevNameMap, (numDevNames+1) * sizeof(*allDevNameMap)); - if(temp) - { - allDevNameMap = temp; - allDevNameMap[numDevNames].name = strdup(str); - allDevNameMap[numDevNames].device_name = strdup(info->name); - numDevNames++; + pa_threaded_mainloop_wait(loop); } -}//}}} + pa_stream_set_state_callback(stream, NULL, NULL); -static void source_device_callback(pa_context *context, const pa_source_info *info, int eol, void *pdata) //{{{ + return stream; +} + + +static ALuint ALCpulsePlayback_mixerProc(ALvoid *ptr) { - pa_threaded_mainloop *loop = pdata; - char str[1024]; - void *temp; - int count; - ALuint i; - - (void)context; - - if(eol) - { - pa_threaded_mainloop_signal(loop, 0); - return; - } - - count = 0; - do { - if(count == 0) - snprintf(str, sizeof(str), "%s", info->description); - else - snprintf(str, sizeof(str), "%s #%d", info->description, count+1); - count++; - - for(i = 0;i < numCaptureDevNames;i++) - { - if(strcmp(str, allCaptureDevNameMap[i].name) == 0) - break; - } - } while(i != numCaptureDevNames); - - temp = realloc(allCaptureDevNameMap, (numCaptureDevNames+1) * sizeof(*allCaptureDevNameMap)); - if(temp) - { - allCaptureDevNameMap = temp; - allCaptureDevNameMap[numCaptureDevNames].name = strdup(str); - allCaptureDevNameMap[numCaptureDevNames].device_name = strdup(info->name); - numCaptureDevNames++; - } -}//}}} -//}}} - -// PulseAudio I/O Callbacks //{{{ -static void stream_write_callback(pa_stream *stream, size_t len, void *pdata) //{{{ -{ - ALCdevice *Device = pdata; - pulse_data *data = Device->ExtraData; - (void)stream; - (void)len; - - pa_threaded_mainloop_signal(data->loop, 0); -} //}}} -//}}} - -static ALuint PulseProc(ALvoid *param) -{ - ALCdevice *Device = param; - pulse_data *data = Device->ExtraData; + ALCpulsePlayback *self = ptr; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; + ALuint buffer_size; + ALint update_size; + size_t frame_size; ssize_t len; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); - pa_threaded_mainloop_lock(data->loop); + pa_threaded_mainloop_lock(self->loop); + frame_size = pa_frame_size(&self->spec); + update_size = device->UpdateSize * frame_size; + + /* Sanitize buffer metrics, in case we actually have less than what we + * asked for. */ + buffer_size = minu(update_size*device->NumUpdates, self->attr.tlength); + update_size = minu(update_size, buffer_size/2); do { - len = (Device->Connected ? pa_stream_writable_size(data->stream) : 0); - len -= len%(Device->UpdateSize*data->frame_size); - if(len == 0) + len = pa_stream_writable_size(self->stream) - self->attr.tlength + + buffer_size; + if(len < update_size) { - pa_threaded_mainloop_wait(data->loop); + if(pa_stream_is_corked(self->stream) == 1) + { + pa_operation *o; + o = pa_stream_cork(self->stream, 0, NULL, NULL); + if(o) pa_operation_unref(o); + } + pa_threaded_mainloop_unlock(self->loop); + Sleep(1); + pa_threaded_mainloop_lock(self->loop); continue; } + len -= len%update_size; while(len > 0) { @@ -663,78 +800,412 @@ static ALuint PulseProc(ALvoid *param) #if PA_CHECK_VERSION(0,9,16) if(!pa_stream_begin_write || - pa_stream_begin_write(data->stream, &buf, &newlen) < 0) + pa_stream_begin_write(self->stream, &buf, &newlen) < 0) #endif { buf = pa_xmalloc(newlen); free_func = pa_xfree; } - pa_threaded_mainloop_unlock(data->loop); - aluMixData(Device, buf, newlen/data->frame_size); + aluMixData(device, buf, newlen/frame_size); - pa_threaded_mainloop_lock(data->loop); - pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); + pa_stream_write(self->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); len -= newlen; } - } while(Device->Connected && !data->killNow); - pa_threaded_mainloop_unlock(data->loop); + } while(!self->killNow && device->Connected); + pa_threaded_mainloop_unlock(self->loop); return 0; } -static pa_stream *connect_playback_stream(ALCdevice *device, - pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec, - pa_channel_map *chanmap) + +static ALCenum ALCpulsePlayback_open(ALCpulsePlayback *self, const ALCchar *name) { - pulse_data *data = device->ExtraData; - pa_stream_state_t state; - pa_stream *stream; + const char *pulse_name = NULL; + pa_stream_flags_t flags; + pa_sample_spec spec; + pa_operation *o; - stream = pa_stream_new(data->context, "Playback Stream", spec, chanmap); - if(!stream) + if(name) { - ERR("pa_stream_new() failed: %s\n", - pa_strerror(pa_context_errno(data->context))); - return NULL; - } + ALuint i; - pa_stream_set_state_callback(stream, stream_state_callback, data->loop); + if(!allDevNameMap) + ALCpulsePlayback_probeDevices(); - if(pa_stream_connect_playback(stream, data->device_name, attr, flags, NULL, NULL) < 0) - { - ERR("Stream did not connect: %s\n", - pa_strerror(pa_context_errno(data->context))); - pa_stream_unref(stream); - return NULL; - } - - while((state=pa_stream_get_state(stream)) != PA_STREAM_READY) - { - if(!PA_STREAM_IS_GOOD(state)) + for(i = 0;i < numDevNames;i++) { - ERR("Stream did not get ready: %s\n", - pa_strerror(pa_context_errno(data->context))); - pa_stream_unref(stream); - return NULL; + if(strcmp(name, allDevNameMap[i].name) == 0) + { + pulse_name = allDevNameMap[i].device_name; + break; + } } - - pa_threaded_mainloop_wait(data->loop); + if(i == numDevNames) + return ALC_INVALID_VALUE; } - pa_stream_set_state_callback(stream, NULL, NULL); - return stream; + if(!pulse_open(&self->loop, &self->context, ALCpulsePlayback_contextStateCallback, self)) + return ALC_INVALID_VALUE; + + pa_threaded_mainloop_lock(self->loop); + + flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE | + PA_STREAM_FIX_CHANNELS; + if(!GetConfigValueBool("pulse", "allow-moves", 0)) + flags |= PA_STREAM_DONT_MOVE; + + spec.format = PA_SAMPLE_S16NE; + spec.rate = 44100; + spec.channels = 2; + + self->stream = ALCpulsePlayback_connectStream(pulse_name, self->loop, self->context, + flags, NULL, &spec, NULL); + if(!self->stream) + { + pa_threaded_mainloop_unlock(self->loop); + pulse_close(self->loop, self->context, self->stream); + self->loop = NULL; + self->context = NULL; + return ALC_INVALID_VALUE; + } + pa_stream_set_moved_callback(self->stream, ALCpulsePlayback_streamMovedCallback, self); + + self->device_name = strdup(pa_stream_get_device_name(self->stream)); + o = pa_context_get_sink_info_by_name(self->context, self->device_name, + ALCpulsePlayback_sinkNameCallback, self); + wait_for_operation(o, self->loop); + + pa_threaded_mainloop_unlock(self->loop); + + return ALC_NO_ERROR; } -static void probe_devices(ALboolean capture) +static void ALCpulsePlayback_close(ALCpulsePlayback *self) +{ + pulse_close(self->loop, self->context, self->stream); + self->loop = NULL; + self->context = NULL; + self->stream = NULL; + + free(self->device_name); + self->device_name = NULL; +} + +static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; + pa_stream_flags_t flags = 0; + pa_channel_map chanmap; + const char *mapname; + ALuint len; + + pa_threaded_mainloop_lock(self->loop); + + if(self->stream) + { + pa_stream_set_moved_callback(self->stream, NULL, NULL); +#if PA_CHECK_VERSION(0,9,15) + if(pa_stream_set_buffer_attr_callback) + pa_stream_set_buffer_attr_callback(self->stream, NULL, NULL); +#endif + pa_stream_disconnect(self->stream); + pa_stream_unref(self->stream); + self->stream = NULL; + } + + if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) + { + pa_operation *o; + o = pa_context_get_sink_info_by_name(self->context, self->device_name, + ALCpulsePlayback_sinkInfoCallback, self); + wait_for_operation(o, self->loop); + } + if(!(device->Flags&DEVICE_FREQUENCY_REQUEST)) + flags |= PA_STREAM_FIX_RATE; + + flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE; + flags |= PA_STREAM_ADJUST_LATENCY; + flags |= PA_STREAM_START_CORKED; + if(!GetConfigValueBool("pulse", "allow-moves", 0)) + flags |= PA_STREAM_DONT_MOVE; + + switch(device->FmtType) + { + case DevFmtByte: + device->FmtType = DevFmtUByte; + /* fall-through */ + case DevFmtUByte: + self->spec.format = PA_SAMPLE_U8; + break; + case DevFmtUShort: + device->FmtType = DevFmtShort; + /* fall-through */ + case DevFmtShort: + self->spec.format = PA_SAMPLE_S16NE; + break; + case DevFmtUInt: + device->FmtType = DevFmtInt; + /* fall-through */ + case DevFmtInt: + self->spec.format = PA_SAMPLE_S32NE; + break; + case DevFmtFloat: + self->spec.format = PA_SAMPLE_FLOAT32NE; + break; + } + self->spec.rate = device->Frequency; + self->spec.channels = ChannelsFromDevFmt(device->FmtChans); + + if(pa_sample_spec_valid(&self->spec) == 0) + { + ERR("Invalid sample format\n"); + pa_threaded_mainloop_unlock(self->loop); + return ALC_FALSE; + } + + mapname = "(invalid)"; + switch(device->FmtChans) + { + case DevFmtMono: + mapname = "mono"; + break; + case DevFmtStereo: + mapname = "front-left,front-right"; + break; + case DevFmtQuad: + mapname = "front-left,front-right,rear-left,rear-right"; + break; + case DevFmtX51: + mapname = "front-left,front-right,front-center,lfe,rear-left,rear-right"; + break; + case DevFmtX51Side: + mapname = "front-left,front-right,front-center,lfe,side-left,side-right"; + break; + case DevFmtX61: + mapname = "front-left,front-right,front-center,lfe,rear-center,side-left,side-right"; + break; + case DevFmtX71: + mapname = "front-left,front-right,front-center,lfe,rear-left,rear-right,side-left,side-right"; + break; + } + if(!pa_channel_map_parse(&chanmap, mapname)) + { + ERR("Failed to build channel map for %s\n", DevFmtChannelsString(device->FmtChans)); + pa_threaded_mainloop_unlock(self->loop); + return ALC_FALSE; + } + SetDefaultWFXChannelOrder(device); + + self->attr.fragsize = -1; + self->attr.prebuf = 0; + self->attr.minreq = device->UpdateSize * pa_frame_size(&self->spec); + self->attr.tlength = self->attr.minreq * maxu(device->NumUpdates, 2); + self->attr.maxlength = -1; + + self->stream = ALCpulsePlayback_connectStream(self->device_name, self->loop, + self->context, flags, &self->attr, + &self->spec, &chanmap); + if(!self->stream) + { + pa_threaded_mainloop_unlock(self->loop); + return ALC_FALSE; + } + pa_stream_set_state_callback(self->stream, ALCpulsePlayback_streamStateCallback, self); + pa_stream_set_moved_callback(self->stream, ALCpulsePlayback_streamMovedCallback, self); + + self->spec = *(pa_stream_get_sample_spec(self->stream)); + if(device->Frequency != self->spec.rate) + { + pa_operation *o; + + /* Server updated our playback rate, so modify the buffer attribs + * accordingly. */ + device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates / device->Frequency * + self->spec.rate + 0.5); + self->attr.minreq = device->UpdateSize * pa_frame_size(&self->spec); + self->attr.tlength = self->attr.minreq * clampu(device->NumUpdates, 2, 16); + self->attr.maxlength = -1; + self->attr.prebuf = 0; + + o = pa_stream_set_buffer_attr(self->stream, &self->attr, + stream_success_callback, self->loop); + wait_for_operation(o, self->loop); + + device->Frequency = self->spec.rate; + } + +#if PA_CHECK_VERSION(0,9,15) + if(pa_stream_set_buffer_attr_callback) + pa_stream_set_buffer_attr_callback(self->stream, ALCpulsePlayback_bufferAttrCallback, self); +#endif + ALCpulsePlayback_bufferAttrCallback(self->stream, self); + + len = self->attr.minreq / pa_frame_size(&self->spec); + if((CPUCapFlags&CPU_CAP_SSE)) + len = (len+3)&~3; + device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates/len*device->UpdateSize + 0.5); + device->NumUpdates = clampu(device->NumUpdates, 2, 16); + device->UpdateSize = len; + + pa_threaded_mainloop_unlock(self->loop); + return ALC_TRUE; +} + +static ALCboolean ALCpulsePlayback_start(ALCpulsePlayback *self) +{ + if(!StartThread(&self->thread, ALCpulsePlayback_mixerProc, self)) + return ALC_FALSE; + return ALC_TRUE; +} + +static void ALCpulsePlayback_stop(ALCpulsePlayback *self) +{ + pa_operation *o; + + if(!self->stream) + return; + + self->killNow = AL_TRUE; + if(self->thread) + { + StopThread(self->thread); + self->thread = NULL; + } + self->killNow = AL_FALSE; + + pa_threaded_mainloop_lock(self->loop); + + o = pa_stream_cork(self->stream, 1, stream_success_callback, self->loop); + wait_for_operation(o, self->loop); + + pa_threaded_mainloop_unlock(self->loop); +} + + +static void ALCpulsePlayback_lock(ALCpulsePlayback *self) +{ + pa_threaded_mainloop_lock(self->loop); +} + +static void ALCpulsePlayback_unlock(ALCpulsePlayback *self) +{ + pa_threaded_mainloop_unlock(self->loop); +} + + +static ALint64 ALCpulsePlayback_getLatency(ALCpulsePlayback *self) +{ + pa_usec_t latency = 0; + int neg; + + if(pa_stream_get_latency(self->stream, &latency, &neg) != 0) + { + ERR("Failed to get stream latency!\n"); + return 0; + } + + if(neg) latency = 0; + return (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000; +} + + +static void ALCpulsePlayback_Delete(ALCpulsePlayback *self) +{ + free(self); +} + +DEFINE_ALCBACKEND_VTABLE(ALCpulsePlayback); + + +typedef struct ALCpulseCapture { + DERIVE_FROM_TYPE(ALCbackend); + + char *device_name; + + const void *cap_store; + size_t cap_len; + size_t cap_remain; + + ALCuint last_readable; + + pa_buffer_attr attr; + pa_sample_spec spec; + + pa_threaded_mainloop *loop; + + pa_stream *stream; + pa_context *context; +} ALCpulseCapture; +DECLARE_ALCBACKEND_VTABLE(ALCpulseCapture); + +static void ALCpulseCapture_deviceCallback(pa_context *context, const pa_source_info *info, int eol, void *pdata); +static void ALCpulseCapture_probeDevices(void); + +static void ALCpulseCapture_contextStateCallback(pa_context *context, void *pdata); +static void ALCpulseCapture_streamStateCallback(pa_stream *stream, void *pdata); +static void ALCpulseCapture_sourceNameCallback(pa_context *context, const pa_source_info *info, int eol, void *pdata); +static void ALCpulseCapture_streamMovedCallback(pa_stream *stream, void *pdata); +static pa_stream *ALCpulseCapture_connectStream(const char *device_name, + pa_threaded_mainloop *loop, pa_context *context, + pa_stream_flags_t flags, pa_buffer_attr *attr, + pa_sample_spec *spec, pa_channel_map *chanmap); + +static void ALCpulseCapture_Construct(ALCpulseCapture *self, ALCdevice *device); +static DECLARE_FORWARD(ALCpulseCapture, ALCbackend, void, Destruct) +static ALCenum ALCpulseCapture_open(ALCpulseCapture *self, const ALCchar *name); +static void ALCpulseCapture_close(ALCpulseCapture *self); +static DECLARE_FORWARD(ALCpulseCapture, ALCbackend, ALCboolean, reset) +static ALCboolean ALCpulseCapture_start(ALCpulseCapture *self); +static void ALCpulseCapture_stop(ALCpulseCapture *self); +static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *buffer, ALCuint samples); +static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self); +static void ALCpulseCapture_lock(ALCpulseCapture *self); +static void ALCpulseCapture_unlock(ALCpulseCapture *self); + + +static void ALCpulseCapture_Construct(ALCpulseCapture *self, ALCdevice *device) +{ + ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); + SET_VTABLE2(ALCpulseCapture, ALCbackend, self); +} + + +static void ALCpulseCapture_deviceCallback(pa_context *UNUSED(context), const pa_source_info *info, int eol, void *pdata) +{ + pa_threaded_mainloop *loop = pdata; + void *temp; + ALuint i; + + if(eol) + { + pa_threaded_mainloop_signal(loop, 0); + return; + } + + for(i = 0;i < numCaptureDevNames;i++) + { + if(strcmp(info->name, allCaptureDevNameMap[i].device_name) == 0) + return; + } + + TRACE("Got device \"%s\", \"%s\"\n", info->description, info->name); + + temp = realloc(allCaptureDevNameMap, (numCaptureDevNames+1) * sizeof(*allCaptureDevNameMap)); + if(temp) + { + allCaptureDevNameMap = temp; + allCaptureDevNameMap[numCaptureDevNames].name = strdup(info->description); + allCaptureDevNameMap[numCaptureDevNames].device_name = strdup(info->name); + numCaptureDevNames++; + } +} + +static void ALCpulseCapture_probeDevices(void) { pa_threaded_mainloop *loop; - if(capture == AL_FALSE) - allDevNameMap = malloc(sizeof(DevMap) * 1); - else - allCaptureDevNameMap = malloc(sizeof(DevMap) * 1); - + allCaptureDevNameMap = malloc(sizeof(DevMap) * 1); if((loop=pa_threaded_mainloop_new()) && pa_threaded_mainloop_start(loop) >= 0) { @@ -745,14 +1216,32 @@ static void probe_devices(ALboolean capture) if(context) { pa_operation *o; + pa_stream_flags_t flags; + pa_sample_spec spec; + pa_stream *stream; - if(capture == AL_FALSE) - o = pa_context_get_sink_info_list(context, sink_device_callback, loop); - else - o = pa_context_get_source_info_list(context, source_device_callback, loop); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(loop); - pa_operation_unref(o); + flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE | + PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE; + + spec.format = PA_SAMPLE_S16NE; + spec.rate = 44100; + spec.channels = 1; + + stream = ALCpulseCapture_connectStream(NULL, loop, context, flags, + NULL, &spec, NULL); + if(stream) + { + o = pa_context_get_source_info_by_name(context, pa_stream_get_device_name(stream), + ALCpulseCapture_deviceCallback, loop); + wait_for_operation(o, loop); + + pa_stream_disconnect(stream); + pa_stream_unref(stream); + stream = NULL; + } + + o = pa_context_get_source_info_list(context, ALCpulseCapture_deviceCallback, loop); + wait_for_operation(o, loop); pa_context_disconnect(context); pa_context_unref(context); @@ -765,352 +1254,116 @@ static void probe_devices(ALboolean capture) } -static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{ +static void ALCpulseCapture_contextStateCallback(pa_context *context, void *pdata) { - pulse_data *data = pa_xmalloc(sizeof(pulse_data)); - memset(data, 0, sizeof(*data)); - - if(!(data->loop = pa_threaded_mainloop_new())) + ALCpulseCapture *self = pdata; + if(pa_context_get_state(context) == PA_CONTEXT_FAILED) { - ERR("pa_threaded_mainloop_new() failed!\n"); - goto out; - } - if(pa_threaded_mainloop_start(data->loop) < 0) - { - ERR("pa_threaded_mainloop_start() failed\n"); - goto out; + ERR("Received context failure!\n"); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); } + pa_threaded_mainloop_signal(self->loop, 0); +} - pa_threaded_mainloop_lock(data->loop); - device->ExtraData = data; - - data->context = connect_context(data->loop, AL_FALSE); - if(!data->context) - { - pa_threaded_mainloop_unlock(data->loop); - goto out; - } - pa_context_set_state_callback(data->context, context_state_callback2, device); - - device->szDeviceName = strdup(device_name); - - pa_threaded_mainloop_unlock(data->loop); - return ALC_TRUE; - -out: - if(data->loop) - { - pa_threaded_mainloop_stop(data->loop); - pa_threaded_mainloop_free(data->loop); - } - - device->ExtraData = NULL; - pa_xfree(data); - return ALC_FALSE; -} //}}} - -static void pulse_close(ALCdevice *device) //{{{ +static void ALCpulseCapture_streamStateCallback(pa_stream *stream, void *pdata) { - pulse_data *data = device->ExtraData; - - pa_threaded_mainloop_lock(data->loop); - - if(data->stream) + ALCpulseCapture *self = pdata; + if(pa_stream_get_state(stream) == PA_STREAM_FAILED) { - pa_stream_disconnect(data->stream); - pa_stream_unref(data->stream); + ERR("Received stream failure!\n"); + aluHandleDisconnect(STATIC_CAST(ALCbackend,self)->mDevice); } + pa_threaded_mainloop_signal(self->loop, 0); +} - pa_context_disconnect(data->context); - pa_context_unref(data->context); - pa_threaded_mainloop_unlock(data->loop); - - pa_threaded_mainloop_stop(data->loop); - pa_threaded_mainloop_free(data->loop); - - DestroyRingBuffer(data->ring); - free(data->device_name); - - device->ExtraData = NULL; - pa_xfree(data); -} //}}} -//}}} - -// OpenAL {{{ -static ALCenum pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{ +static void ALCpulseCapture_sourceNameCallback(pa_context *UNUSED(context), const pa_source_info *info, int eol, void *pdata) { - char *pulse_name = NULL; - pa_sample_spec spec; - pulse_data *data; + ALCpulseCapture *self = pdata; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; - if(!allDevNameMap) - probe_devices(AL_FALSE); - - if(!device_name) - device_name = pulse_device; - else if(strcmp(device_name, pulse_device) != 0) + if(eol) { - ALuint i; - - for(i = 0;i < numDevNames;i++) - { - if(strcmp(device_name, allDevNameMap[i].name) == 0) - { - pulse_name = allDevNameMap[i].device_name; - break; - } - } - if(i == numDevNames) - return ALC_INVALID_VALUE; + pa_threaded_mainloop_signal(self->loop, 0); + return; } - if(pulse_open(device, device_name) == ALC_FALSE) - return ALC_INVALID_VALUE; + free(device->DeviceName); + device->DeviceName = strdup(info->description); +} - data = device->ExtraData; - pa_threaded_mainloop_lock(data->loop); +static void ALCpulseCapture_streamMovedCallback(pa_stream *stream, void *pdata) +{ + ALCpulseCapture *self = pdata; - spec.format = PA_SAMPLE_S16NE; - spec.rate = 44100; - spec.channels = 2; + free(self->device_name); + self->device_name = strdup(pa_stream_get_device_name(stream)); - data->device_name = pulse_name; - pa_stream *stream = connect_playback_stream(device, 0, NULL, &spec, NULL); + TRACE("Stream moved to %s\n", self->device_name); +} + + +static pa_stream *ALCpulseCapture_connectStream(const char *device_name, + pa_threaded_mainloop *loop, pa_context *context, + pa_stream_flags_t flags, pa_buffer_attr *attr, pa_sample_spec *spec, + pa_channel_map *chanmap) +{ + pa_stream_state_t state; + pa_stream *stream; + + stream = pa_stream_new_with_proplist(context, "Capture Stream", spec, chanmap, prop_filter); if(!stream) { - pa_threaded_mainloop_unlock(data->loop); - goto fail; + ERR("pa_stream_new_with_proplist() failed: %s\n", pa_strerror(pa_context_errno(context))); + return NULL; } - if(pa_stream_is_suspended(stream)) + pa_stream_set_state_callback(stream, stream_state_callback, loop); + + if(pa_stream_connect_record(stream, device_name, attr, flags) < 0) { - ERR("Device is suspended\n"); - pa_stream_disconnect(stream); + ERR("Stream did not connect: %s\n", pa_strerror(pa_context_errno(context))); pa_stream_unref(stream); - pa_threaded_mainloop_unlock(data->loop); - goto fail; + return NULL; } - data->device_name = strdup(pa_stream_get_device_name(stream)); - pa_stream_disconnect(stream); - pa_stream_unref(stream); + while((state=pa_stream_get_state(stream)) != PA_STREAM_READY) + { + if(!PA_STREAM_IS_GOOD(state)) + { + ERR("Stream did not get ready: %s\n", pa_strerror(pa_context_errno(context))); + pa_stream_unref(stream); + return NULL; + } - pa_threaded_mainloop_unlock(data->loop); + pa_threaded_mainloop_wait(loop); + } + pa_stream_set_state_callback(stream, NULL, NULL); - return ALC_NO_ERROR; + return stream; +} -fail: - pulse_close(device); - return ALC_INVALID_VALUE; -} //}}} -static void pulse_close_playback(ALCdevice *device) //{{{ +static ALCenum ALCpulseCapture_open(ALCpulseCapture *self, const ALCchar *name) { - pulse_close(device); -} //}}} - -static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{ -{ - pulse_data *data = device->ExtraData; + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; + const char *pulse_name = NULL; pa_stream_flags_t flags = 0; pa_channel_map chanmap; + pa_operation *o; + ALuint samples; - pa_threaded_mainloop_lock(data->loop); - - if(!(device->Flags&DEVICE_CHANNELS_REQUEST)) - { - pa_operation *o; - o = pa_context_get_sink_info_by_name(data->context, data->device_name, sink_info_callback, device); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(data->loop); - pa_operation_unref(o); - } - if(!(device->Flags&DEVICE_FREQUENCY_REQUEST)) - flags |= PA_STREAM_FIX_RATE; - - data->frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->attr.prebuf = -1; - data->attr.fragsize = -1; - data->attr.minreq = device->UpdateSize * data->frame_size; - data->attr.tlength = data->attr.minreq * maxu(device->NumUpdates, 2); - data->attr.maxlength = -1; - flags |= PA_STREAM_EARLY_REQUESTS; - flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE; - - switch(device->FmtType) - { - case DevFmtByte: - device->FmtType = DevFmtUByte; - /* fall-through */ - case DevFmtUByte: - data->spec.format = PA_SAMPLE_U8; - break; - case DevFmtUShort: - device->FmtType = DevFmtShort; - /* fall-through */ - case DevFmtShort: - data->spec.format = PA_SAMPLE_S16NE; - break; - case DevFmtFloat: - data->spec.format = PA_SAMPLE_FLOAT32NE; - break; - } - data->spec.rate = device->Frequency; - data->spec.channels = ChannelsFromDevFmt(device->FmtChans); - - if(pa_sample_spec_valid(&data->spec) == 0) - { - ERR("Invalid sample format\n"); - pa_threaded_mainloop_unlock(data->loop); - return ALC_FALSE; - } - - if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) - { - ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); - pa_threaded_mainloop_unlock(data->loop); - return ALC_FALSE; - } - SetDefaultWFXChannelOrder(device); - - data->stream = connect_playback_stream(device, flags, &data->attr, &data->spec, &chanmap); - if(!data->stream) - { - pa_threaded_mainloop_unlock(data->loop); - return ALC_FALSE; - } - - pa_stream_set_state_callback(data->stream, stream_state_callback2, device); - - data->spec = *(pa_stream_get_sample_spec(data->stream)); - if(device->Frequency != data->spec.rate) - { - pa_operation *o; - - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set frequency %dhz, got %dhz instead\n", device->Frequency, data->spec.rate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - - /* Server updated our playback rate, so modify the buffer attribs - * accordingly. */ - data->attr.minreq = (ALuint64)(data->attr.minreq/data->frame_size) * - data->spec.rate / device->Frequency * data->frame_size; - data->attr.tlength = data->attr.minreq * maxu(device->NumUpdates, 2); - - o = pa_stream_set_buffer_attr(data->stream, &data->attr, - stream_success_callback, device); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(data->loop); - pa_operation_unref(o); - - device->Frequency = data->spec.rate; - } - -#if PA_CHECK_VERSION(0,9,15) - if(pa_stream_set_buffer_attr_callback) - pa_stream_set_buffer_attr_callback(data->stream, stream_buffer_attr_callback, device); -#endif - pa_stream_set_moved_callback(data->stream, stream_device_callback, device); - pa_stream_set_write_callback(data->stream, stream_write_callback, device); - pa_stream_set_underflow_callback(data->stream, stream_signal_callback, device); - - data->attr = *(pa_stream_get_buffer_attr(data->stream)); - device->UpdateSize = data->attr.minreq / data->frame_size; - device->NumUpdates = (data->attr.tlength/data->frame_size) / device->UpdateSize; - if(device->NumUpdates <= 1) - { - pa_operation *o; - - ERR("PulseAudio returned minreq=%d, tlength=%d; expect lag or break up\n", data->attr.minreq, data->attr.tlength); - - /* Server gave a comparatively large minreq, so modify the tlength. */ - device->NumUpdates = 2; - data->attr.tlength = data->attr.minreq * device->NumUpdates; - - o = pa_stream_set_buffer_attr(data->stream, &data->attr, - stream_success_callback, device); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(data->loop); - pa_operation_unref(o); - } - - data->thread = StartThread(PulseProc, device); - if(!data->thread) - { -#if PA_CHECK_VERSION(0,9,15) - if(pa_stream_set_buffer_attr_callback) - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); -#endif - pa_stream_set_moved_callback(data->stream, NULL, NULL); - pa_stream_set_write_callback(data->stream, NULL, NULL); - pa_stream_set_underflow_callback(data->stream, NULL, NULL); - pa_stream_disconnect(data->stream); - pa_stream_unref(data->stream); - data->stream = NULL; - - pa_threaded_mainloop_unlock(data->loop); - return ALC_FALSE; - } - - pa_threaded_mainloop_unlock(data->loop); - return ALC_TRUE; -} //}}} - -static void pulse_stop_playback(ALCdevice *device) //{{{ -{ - pulse_data *data = device->ExtraData; - - if(!data->stream) - return; - - data->killNow = AL_TRUE; - if(data->thread) - { - pa_threaded_mainloop_signal(data->loop, 0); - StopThread(data->thread); - data->thread = NULL; - } - data->killNow = AL_FALSE; - - pa_threaded_mainloop_lock(data->loop); - -#if PA_CHECK_VERSION(0,9,15) - if(pa_stream_set_buffer_attr_callback) - pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL); -#endif - pa_stream_set_moved_callback(data->stream, NULL, NULL); - pa_stream_set_write_callback(data->stream, NULL, NULL); - pa_stream_set_underflow_callback(data->stream, NULL, NULL); - pa_stream_disconnect(data->stream); - pa_stream_unref(data->stream); - data->stream = NULL; - - pa_threaded_mainloop_unlock(data->loop); -} //}}} - - -static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name) //{{{ -{ - char *pulse_name = NULL; - pulse_data *data; - pa_stream_flags_t flags = 0; - pa_stream_state_t state; - pa_channel_map chanmap; - - if(!allCaptureDevNameMap) - probe_devices(AL_TRUE); - - if(!device_name) - device_name = pulse_device; - else if(strcmp(device_name, pulse_device) != 0) + if(name) { ALuint i; + if(!allCaptureDevNameMap) + ALCpulseCapture_probeDevices(); + for(i = 0;i < numCaptureDevNames;i++) { - if(strcmp(device_name, allCaptureDevNameMap[i].name) == 0) + if(strcmp(name, allCaptureDevNameMap[i].name) == 0) { pulse_name = allCaptureDevNameMap[i].device_name; break; @@ -1120,213 +1373,280 @@ static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name) return ALC_INVALID_VALUE; } - if(pulse_open(device, device_name) == ALC_FALSE) + if(!pulse_open(&self->loop, &self->context, ALCpulseCapture_contextStateCallback, self)) return ALC_INVALID_VALUE; - data = device->ExtraData; - pa_threaded_mainloop_lock(data->loop); + pa_threaded_mainloop_lock(self->loop); - data->samples = device->UpdateSize * device->NumUpdates; - data->frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->samples = maxu(data->samples, 100 * device->Frequency / 1000); - - if(!(data->ring = CreateRingBuffer(data->frame_size, data->samples))) - { - pa_threaded_mainloop_unlock(data->loop); - goto fail; - } - - data->attr.minreq = -1; - data->attr.prebuf = -1; - data->attr.maxlength = data->samples * data->frame_size; - data->attr.tlength = -1; - data->attr.fragsize = minu(data->samples, 50*device->Frequency/1000) * - data->frame_size; - - data->spec.rate = device->Frequency; - data->spec.channels = ChannelsFromDevFmt(device->FmtChans); + self->spec.rate = device->Frequency; + self->spec.channels = ChannelsFromDevFmt(device->FmtChans); switch(device->FmtType) { case DevFmtUByte: - data->spec.format = PA_SAMPLE_U8; + self->spec.format = PA_SAMPLE_U8; break; case DevFmtShort: - data->spec.format = PA_SAMPLE_S16NE; + self->spec.format = PA_SAMPLE_S16NE; + break; + case DevFmtInt: + self->spec.format = PA_SAMPLE_S32NE; break; case DevFmtFloat: - data->spec.format = PA_SAMPLE_FLOAT32NE; + self->spec.format = PA_SAMPLE_FLOAT32NE; break; case DevFmtByte: case DevFmtUShort: - ERR("Capture format type %#x capture not supported on PulseAudio\n", device->FmtType); - pa_threaded_mainloop_unlock(data->loop); + case DevFmtUInt: + ERR("%s capture samples not supported\n", DevFmtTypeString(device->FmtType)); + pa_threaded_mainloop_unlock(self->loop); goto fail; } - if(pa_sample_spec_valid(&data->spec) == 0) + if(pa_sample_spec_valid(&self->spec) == 0) { ERR("Invalid sample format\n"); - pa_threaded_mainloop_unlock(data->loop); + pa_threaded_mainloop_unlock(self->loop); goto fail; } - if(!pa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX)) + if(!pa_channel_map_init_auto(&chanmap, self->spec.channels, PA_CHANNEL_MAP_WAVEEX)) { - ERR("Couldn't build map for channel count (%d)!\n", data->spec.channels); - pa_threaded_mainloop_unlock(data->loop); + ERR("Couldn't build map for channel count (%d)!\n", self->spec.channels); + pa_threaded_mainloop_unlock(self->loop); goto fail; } - data->stream = pa_stream_new(data->context, "Capture Stream", &data->spec, &chanmap); - if(!data->stream) - { - ERR("pa_stream_new() failed: %s\n", - pa_strerror(pa_context_errno(data->context))); + samples = device->UpdateSize * device->NumUpdates; + samples = maxu(samples, 100 * device->Frequency / 1000); - pa_threaded_mainloop_unlock(data->loop); - goto fail; - } - - pa_stream_set_state_callback(data->stream, stream_state_callback, data->loop); + self->attr.minreq = -1; + self->attr.prebuf = -1; + self->attr.maxlength = samples * pa_frame_size(&self->spec); + self->attr.tlength = -1; + self->attr.fragsize = minu(samples, 50*device->Frequency/1000) * + pa_frame_size(&self->spec); flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY; - if(pa_stream_connect_record(data->stream, pulse_name, &data->attr, flags) < 0) + if(!GetConfigValueBool("pulse", "allow-moves", 0)) + flags |= PA_STREAM_DONT_MOVE; + + self->stream = ALCpulseCapture_connectStream(pulse_name, self->loop, self->context, + flags, &self->attr, &self->spec, + &chanmap); + if(!self->stream) { - ERR("Stream did not connect: %s\n", - pa_strerror(pa_context_errno(data->context))); - - pa_stream_unref(data->stream); - data->stream = NULL; - - pa_threaded_mainloop_unlock(data->loop); + pa_threaded_mainloop_unlock(self->loop); goto fail; } + pa_stream_set_moved_callback(self->stream, ALCpulseCapture_streamMovedCallback, self); + pa_stream_set_state_callback(self->stream, ALCpulseCapture_streamStateCallback, self); - while((state=pa_stream_get_state(data->stream)) != PA_STREAM_READY) - { - if(!PA_STREAM_IS_GOOD(state)) - { - ERR("Stream did not get ready: %s\n", - pa_strerror(pa_context_errno(data->context))); + self->device_name = strdup(pa_stream_get_device_name(self->stream)); + o = pa_context_get_source_info_by_name(self->context, self->device_name, + ALCpulseCapture_sourceNameCallback, self); + wait_for_operation(o, self->loop); - pa_stream_unref(data->stream); - data->stream = NULL; - - pa_threaded_mainloop_unlock(data->loop); - goto fail; - } - - pa_threaded_mainloop_wait(data->loop); - } - pa_stream_set_state_callback(data->stream, stream_state_callback2, device); - - pa_threaded_mainloop_unlock(data->loop); + pa_threaded_mainloop_unlock(self->loop); return ALC_NO_ERROR; fail: - pulse_close(device); + pulse_close(self->loop, self->context, self->stream); + self->loop = NULL; + self->context = NULL; + self->stream = NULL; + return ALC_INVALID_VALUE; -} //}}} +} -static void pulse_close_capture(ALCdevice *device) //{{{ +static void ALCpulseCapture_close(ALCpulseCapture *self) { - pulse_close(device); -} //}}} + pulse_close(self->loop, self->context, self->stream); + self->loop = NULL; + self->context = NULL; + self->stream = NULL; -static void pulse_start_capture(ALCdevice *device) //{{{ + free(self->device_name); + self->device_name = NULL; +} + +static ALCboolean ALCpulseCapture_start(ALCpulseCapture *self) { - pulse_data *data = device->ExtraData; pa_operation *o; - - pa_threaded_mainloop_lock(data->loop); - o = pa_stream_cork(data->stream, 0, stream_success_callback, device); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(data->loop); - pa_operation_unref(o); - pa_threaded_mainloop_unlock(data->loop); -} //}}} - -static void pulse_stop_capture(ALCdevice *device) //{{{ -{ - pulse_data *data = device->ExtraData; - pa_operation *o; - - pa_threaded_mainloop_lock(data->loop); - o = pa_stream_cork(data->stream, 1, stream_success_callback, device); - while(pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(data->loop); - pa_operation_unref(o); - pa_threaded_mainloop_unlock(data->loop); -} //}}} - -static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{ -{ - pulse_data *data = device->ExtraData; - ReadRingBuffer(data->ring, buffer, samples); - return ALC_NO_ERROR; -} //}}} - -static ALCuint pulse_available_samples(ALCdevice *device) //{{{ -{ - pulse_data *data = device->ExtraData; - size_t samples; - - pa_threaded_mainloop_lock(data->loop); - /* Capture is done in fragment-sized chunks, so we loop until we get all - * that's available */ - samples = (device->Connected ? pa_stream_readable_size(data->stream) : 0); - while(samples > 0) - { - const void *buf; - size_t length; - - if(pa_stream_peek(data->stream, &buf, &length) < 0) - { - ERR("pa_stream_peek() failed: %s\n", - pa_strerror(pa_context_errno(data->context))); - break; - } - - WriteRingBuffer(data->ring, buf, length/data->frame_size); - samples -= length; - - pa_stream_drop(data->stream); - } - pa_threaded_mainloop_unlock(data->loop); - - return RingBufferSize(data->ring); -} //}}} - - -static const BackendFuncs pulse_funcs = { //{{{ - pulse_open_playback, - pulse_close_playback, - pulse_reset_playback, - pulse_stop_playback, - pulse_open_capture, - pulse_close_capture, - pulse_start_capture, - pulse_stop_capture, - pulse_capture_samples, - pulse_available_samples -}; //}}} - -ALCboolean alc_pulse_init(BackendFuncs *func_list) //{{{ -{ - if(!pulse_load()) - return ALC_FALSE; - - *func_list = pulse_funcs; - - pulse_ctx_flags = 0; - if(!GetConfigValueBool("pulse", "spawn-server", 0)) - pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN; + o = pa_stream_cork(self->stream, 0, stream_success_callback, self->loop); + wait_for_operation(o, self->loop); return ALC_TRUE; -} //}}} +} -void alc_pulse_deinit(void) //{{{ +static void ALCpulseCapture_stop(ALCpulseCapture *self) +{ + pa_operation *o; + o = pa_stream_cork(self->stream, 1, stream_success_callback, self->loop); + wait_for_operation(o, self->loop); +} + +static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *buffer, ALCuint samples) +{ + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; + ALCuint todo = samples * pa_frame_size(&self->spec); + + /* Capture is done in fragment-sized chunks, so we loop until we get all + * that's available */ + self->last_readable -= todo; + while(todo > 0) + { + size_t rem = todo; + + if(self->cap_len == 0) + { + pa_stream_state_t state; + + state = pa_stream_get_state(self->stream); + if(!PA_STREAM_IS_GOOD(state)) + { + aluHandleDisconnect(device); + break; + } + if(pa_stream_peek(self->stream, &self->cap_store, &self->cap_len) < 0) + { + ERR("pa_stream_peek() failed: %s\n", + pa_strerror(pa_context_errno(self->context))); + aluHandleDisconnect(device); + break; + } + self->cap_remain = self->cap_len; + } + if(rem > self->cap_remain) + rem = self->cap_remain; + + memcpy(buffer, self->cap_store, rem); + + buffer = (ALbyte*)buffer + rem; + todo -= rem; + + self->cap_store = (ALbyte*)self->cap_store + rem; + self->cap_remain -= rem; + if(self->cap_remain == 0) + { + pa_stream_drop(self->stream); + self->cap_len = 0; + } + } + if(todo > 0) + memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo); + + return ALC_NO_ERROR; +} + +static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self) +{ + ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; + size_t readable = self->cap_remain; + + if(device->Connected) + { + ssize_t got = pa_stream_readable_size(self->stream); + if(got < 0) + { + ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got)); + aluHandleDisconnect(device); + } + else if((size_t)got > self->cap_len) + readable += got - self->cap_len; + } + + if(self->last_readable < readable) + self->last_readable = readable; + return self->last_readable / pa_frame_size(&self->spec); +} + + +static void ALCpulseCapture_lock(ALCpulseCapture *self) +{ + pa_threaded_mainloop_lock(self->loop); +} + +static void ALCpulseCapture_unlock(ALCpulseCapture *self) +{ + pa_threaded_mainloop_unlock(self->loop); +} + + +static ALint64 ALCpulseCapture_getLatency(ALCpulseCapture *self) +{ + pa_usec_t latency = 0; + int neg; + + if(pa_stream_get_latency(self->stream, &latency, &neg) != 0) + { + ERR("Failed to get stream latency!\n"); + return 0; + } + + if(neg) latency = 0; + return (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000; +} + + +static void ALCpulseCapture_Delete(ALCpulseCapture *self) +{ + free(self); +} + +DEFINE_ALCBACKEND_VTABLE(ALCpulseCapture); + + +typedef struct ALCpulseBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCpulseBackendFactory; +#define ALCPULSEBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCpulseBackendFactory, ALCbackendFactory) } } + +static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory* UNUSED(self)) +{ + ALCboolean ret = ALC_FALSE; + + if(pulse_load()) + { + pa_threaded_mainloop *loop; + + pulse_ctx_flags = 0; + if(!GetConfigValueBool("pulse", "spawn-server", 1)) + pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN; + + if((loop=pa_threaded_mainloop_new()) && + pa_threaded_mainloop_start(loop) >= 0) + { + pa_context *context; + + pa_threaded_mainloop_lock(loop); + context = connect_context(loop, AL_TRUE); + if(context) + { + ret = ALC_TRUE; + + /* Some libraries (Phonon, Qt) set some pulseaudio properties + * through environment variables, which causes all streams in + * the process to inherit them. This attempts to filter those + * properties out by setting them to 0-length data. */ + prop_filter = pa_proplist_new(); + pa_proplist_set(prop_filter, PA_PROP_MEDIA_ROLE, NULL, 0); + pa_proplist_set(prop_filter, "phonon.streamid", NULL, 0); + + pa_context_disconnect(context); + pa_context_unref(context); + } + pa_threaded_mainloop_unlock(loop); + pa_threaded_mainloop_stop(loop); + } + if(loop) + pa_threaded_mainloop_free(loop); + } + + return ret; +} + +static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory* UNUSED(self)) { ALuint i; @@ -1348,42 +1668,26 @@ void alc_pulse_deinit(void) //{{{ allCaptureDevNameMap = NULL; numCaptureDevNames = 0; -#ifdef HAVE_DYNLOAD - if(pa_handle) - CloseLib(pa_handle); - pa_handle = NULL; -#endif -} //}}} + if(prop_filter) + pa_proplist_free(prop_filter); + prop_filter = NULL; -void alc_pulse_probe(enum DevProbe type) //{{{ + /* PulseAudio doesn't like being CloseLib'd sometimes */ +} + +static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UNUSED(self), ALCbackend_Type type) +{ + if(type == ALCbackend_Playback || type == ALCbackend_Capture) + return ALC_TRUE; + return ALC_FALSE; +} + +static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe type) { - pa_threaded_mainloop *loop; ALuint i; switch(type) { - case DEVICE_PROBE: - if((loop=pa_threaded_mainloop_new()) && - pa_threaded_mainloop_start(loop) >= 0) - { - pa_context *context; - - pa_threaded_mainloop_lock(loop); - context = connect_context(loop, AL_FALSE); - if(context) - { - AppendDeviceList(pulse_device); - - pa_context_disconnect(context); - pa_context_unref(context); - } - pa_threaded_mainloop_unlock(loop); - pa_threaded_mainloop_stop(loop); - } - if(loop) - pa_threaded_mainloop_free(loop); - break; - case ALL_DEVICE_PROBE: for(i = 0;i < numDevNames;++i) { @@ -1394,10 +1698,10 @@ void alc_pulse_probe(enum DevProbe type) //{{{ allDevNameMap = NULL; numDevNames = 0; - probe_devices(AL_FALSE); + ALCpulsePlayback_probeDevices(); for(i = 0;i < numDevNames;i++) - AppendAllDeviceList(allDevNameMap[i].name); + AppendAllDevicesList(allDevNameMap[i].name); break; case CAPTURE_DEVICE_PROBE: @@ -1410,11 +1714,83 @@ void alc_pulse_probe(enum DevProbe type) //{{{ allCaptureDevNameMap = NULL; numCaptureDevNames = 0; - probe_devices(AL_TRUE); + ALCpulseCapture_probeDevices(); for(i = 0;i < numCaptureDevNames;i++) AppendCaptureDeviceList(allCaptureDevNameMap[i].name); break; } -} //}}} -//}}} +} + +static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type) +{ + if(type == ALCbackend_Playback) + { + ALCpulsePlayback *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCpulsePlayback_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + if(type == ALCbackend_Capture) + { + ALCpulseCapture *backend; + + backend = calloc(1, sizeof(*backend)); + if(!backend) return NULL; + + ALCpulseCapture_Construct(backend, device); + + return STATIC_CAST(ALCbackend, backend); + } + + return NULL; +} + +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCpulseBackendFactory); + + +#else /* PA_API_VERSION == 12 */ + +#warning "Unsupported API version, backend will be unavailable!" + +typedef struct ALCpulseBackendFactory { + DERIVE_FROM_TYPE(ALCbackendFactory); +} ALCpulseBackendFactory; +#define ALCPULSEBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCpulseBackendFactory, ALCbackendFactory) } } + +static ALCboolean ALCpulseBackendFactory_init(ALCpulseBackendFactory* UNUSED(self)) +{ + return ALC_FALSE; +} + +static void ALCpulseBackendFactory_deinit(ALCpulseBackendFactory* UNUSED(self)) +{ +} + +static ALCboolean ALCpulseBackendFactory_querySupport(ALCpulseBackendFactory* UNUSED(self), ALCbackend_Type UNUSED(type)) +{ + return ALC_FALSE; +} + +static void ALCpulseBackendFactory_probe(ALCpulseBackendFactory* UNUSED(self), enum DevProbe UNUSED(type)) +{ +} + +static ALCbackend* ALCpulseBackendFactory_createBackend(ALCpulseBackendFactory* UNUSED(self), ALCdevice* UNUSED(device), ALCbackend_Type UNUSED(type)) +{ + return NULL; +} + +DEFINE_ALCBACKENDFACTORY_VTABLE(ALCpulseBackendFactory); + +#endif /* PA_API_VERSION == 12 */ + +ALCbackendFactory *ALCpulseBackendFactory_getFactory(void) +{ + static ALCpulseBackendFactory factory = ALCPULSEBACKENDFACTORY_INITIALIZER; + return STATIC_CAST(ALCbackendFactory, &factory); +} diff --git a/jni/openal-soft-android/Alc/backends/qsa.c b/jni/openal-soft-android/Alc/backends/qsa.c new file mode 100644 index 00000000..c9762f85 --- /dev/null +++ b/jni/openal-soft-android/Alc/backends/qsa.c @@ -0,0 +1,1169 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2011-2013 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alMain.h" +#include "alu.h" +#include "threads.h" + + +typedef struct +{ + snd_pcm_t* pcmHandle; + int audio_fd; + + snd_pcm_channel_setup_t csetup; + snd_pcm_channel_params_t cparams; + + ALvoid* buffer; + ALsizei size; + + volatile int killNow; + althread_t thread; +} qsa_data; + +typedef struct +{ + ALCchar* name; + int card; + int dev; +} DevMap; + +static const ALCchar qsaDevice[]="QSA Default"; +static DevMap* allDevNameMap; +static ALuint numDevNames; +static DevMap* allCaptureDevNameMap; +static ALuint numCaptureDevNames; + +static const struct +{ + int32_t format; +} formatlist[]= +{ + {SND_PCM_SFMT_FLOAT_LE}, + {SND_PCM_SFMT_S32_LE}, + {SND_PCM_SFMT_U32_LE}, + {SND_PCM_SFMT_S16_LE}, + {SND_PCM_SFMT_U16_LE}, + {SND_PCM_SFMT_S8}, + {SND_PCM_SFMT_U8}, + {0}, +}; + +static const struct +{ + int32_t rate; +} ratelist[]= +{ + {192000}, + {176400}, + {96000}, + {88200}, + {48000}, + {44100}, + {32000}, + {24000}, + {22050}, + {16000}, + {12000}, + {11025}, + {8000}, + {0}, +}; + +static const struct +{ + int32_t channels; +} channellist[]= +{ + {8}, + {7}, + {6}, + {4}, + {2}, + {1}, + {0}, +}; + +static DevMap* deviceList(int type, ALuint* count) +{ + snd_ctl_t* handle; + snd_pcm_info_t pcminfo; + int max_cards, card, err, dev, num_devices, idx; + DevMap* dev_list; + char name[1024]; + struct snd_ctl_hw_info info; + void* temp; + + idx=0; + num_devices=0; + max_cards=snd_cards(); + + if (max_cards<=0) + { + return 0; + } + + dev_list=malloc(sizeof(DevMap)*1); + dev_list[0].name=strdup(qsaDevice); + num_devices=1; + + for (card=0; cardExtraData; + char* write_ptr; + int avail; + snd_pcm_channel_status_t status; + struct sched_param param; + fd_set wfds; + int selectret; + struct timeval timeout; + + SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); + + /* Increase default 10 priority to 11 to avoid jerky sound */ + SchedGet(0, 0, ¶m); + param.sched_priority=param.sched_curpriority+1; + SchedSet(0, 0, SCHED_NOCHANGE, ¶m); + + ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + + while (!data->killNow) + { + ALint len=data->size; + write_ptr=data->buffer; + + avail=len/frame_size; + aluMixData(device, write_ptr, avail); + + while (len>0 && !data->killNow) + { + FD_ZERO(&wfds); + FD_SET(data->audio_fd, &wfds); + timeout.tv_sec=2; + timeout.tv_usec=0; + + /* Select also works like time slice to OS */ + selectret=select(data->audio_fd+1, NULL, &wfds, NULL, &timeout); + switch (selectret) + { + case -1: + aluHandleDisconnect(device); + return 1; + case 0: + break; + default: + if (FD_ISSET(data->audio_fd, &wfds)) + { + break; + } + break; + } + + int wrote=snd_pcm_plugin_write(data->pcmHandle, write_ptr, len); + + if (wrote<=0) + { + if ((errno==EAGAIN) || (errno==EWOULDBLOCK)) + { + continue; + } + + memset(&status, 0, sizeof (status)); + status.channel=SND_PCM_CHANNEL_PLAYBACK; + + snd_pcm_plugin_status(data->pcmHandle, &status); + + /* we need to reinitialize the sound channel if we've underrun the buffer */ + if ((status.status==SND_PCM_STATUS_UNDERRUN) || + (status.status==SND_PCM_STATUS_READY)) + { + if ((snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK))<0) + { + aluHandleDisconnect(device); + break; + } + } + } + else + { + write_ptr+=wrote; + len-=wrote; + } + } + } + + return 0; +} + +/************/ +/* Playback */ +/************/ + +static ALCenum qsa_open_playback(ALCdevice* device, const ALCchar* deviceName) +{ + qsa_data* data; + char driver[64]; + int status; + int card, dev; + + strncpy(driver, GetConfigValue("qsa", "device", qsaDevice), sizeof(driver)-1); + driver[sizeof(driver)-1]=0; + + data=(qsa_data*)calloc(1, sizeof(qsa_data)); + if (data==NULL) + { + return ALC_OUT_OF_MEMORY; + } + + if (!deviceName) + { + deviceName=driver; + } + + if (strcmp(deviceName, qsaDevice)==0) + { + if (!deviceName) + { + deviceName=qsaDevice; + } + + status=snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK); + } + else + { + size_t idx; + + if (!allDevNameMap) + { + allDevNameMap=deviceList(SND_PCM_CHANNEL_PLAYBACK, &numDevNames); + } + + for (idx=0; idx0) + { + break; + } + } + } + if (idx==numDevNames) + { + free(data); + return ALC_INVALID_DEVICE; + } + + status=snd_pcm_open(&data->pcmHandle, allDevNameMap[idx].card, allDevNameMap[idx].dev, SND_PCM_OPEN_PLAYBACK); + } + + if (status<0) + { + free(data); + return ALC_INVALID_DEVICE; + } + + data->audio_fd=snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK); + if (data->audio_fd<0) + { + free(data); + return ALC_INVALID_DEVICE; + } + + device->DeviceName=strdup(deviceName); + device->ExtraData=data; + + return ALC_NO_ERROR; +} + +static void qsa_close_playback(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + + if (data->buffer!=NULL) + { + free(data->buffer); + data->buffer=NULL; + } + + snd_pcm_close(data->pcmHandle); + free(data); + + device->ExtraData=NULL; +} + +static ALCboolean qsa_reset_playback(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + int32_t format=-1; + + switch(device->FmtType) + { + case DevFmtByte: + format=SND_PCM_SFMT_S8; + break; + case DevFmtUByte: + format=SND_PCM_SFMT_U8; + break; + case DevFmtShort: + format=SND_PCM_SFMT_S16_LE; + break; + case DevFmtUShort: + format=SND_PCM_SFMT_U16_LE; + break; + case DevFmtInt: + format=SND_PCM_SFMT_S32_LE; + break; + case DevFmtUInt: + format=SND_PCM_SFMT_U32_LE; + break; + case DevFmtFloat: + format=SND_PCM_SFMT_FLOAT_LE; + break; + } + + /* we actually don't want to block on writes */ + snd_pcm_nonblock_mode(data->pcmHandle, 1); + /* Disable mmap to control data transfer to the audio device */ + snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_MMAP); + snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_BUFFER_PARTIAL_BLOCKS); + + // configure a sound channel + memset(&data->cparams, 0, sizeof(data->cparams)); + data->cparams.channel=SND_PCM_CHANNEL_PLAYBACK; + data->cparams.mode=SND_PCM_MODE_BLOCK; + data->cparams.start_mode=SND_PCM_START_FULL; + data->cparams.stop_mode=SND_PCM_STOP_STOP; + + data->cparams.buf.block.frag_size=device->UpdateSize* + ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType); + data->cparams.buf.block.frags_max=device->NumUpdates; + data->cparams.buf.block.frags_min=device->NumUpdates; + + data->cparams.format.interleave=1; + data->cparams.format.rate=device->Frequency; + data->cparams.format.voices=ChannelsFromDevFmt(device->FmtChans); + data->cparams.format.format=format; + + if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) + { + int original_rate=data->cparams.format.rate; + int original_voices=data->cparams.format.voices; + int original_format=data->cparams.format.format; + int it; + int jt; + + for (it=0; it<1; it++) + { + /* Check for second pass */ + if (it==1) + { + original_rate=ratelist[0].rate; + original_voices=channellist[0].channels; + original_format=formatlist[0].format; + } + + do { + /* At first downgrade sample format */ + jt=0; + do { + if (formatlist[jt].format==data->cparams.format.format) + { + data->cparams.format.format=formatlist[jt+1].format; + break; + } + if (formatlist[jt].format==0) + { + data->cparams.format.format=0; + break; + } + jt++; + } while(1); + + if (data->cparams.format.format==0) + { + data->cparams.format.format=original_format; + + /* At secod downgrade sample rate */ + jt=0; + do { + if (ratelist[jt].rate==data->cparams.format.rate) + { + data->cparams.format.rate=ratelist[jt+1].rate; + break; + } + if (ratelist[jt].rate==0) + { + data->cparams.format.rate=0; + break; + } + jt++; + } while(1); + + if (data->cparams.format.rate==0) + { + data->cparams.format.rate=original_rate; + data->cparams.format.format=original_format; + + /* At third downgrade channels number */ + jt=0; + do { + if(channellist[jt].channels==data->cparams.format.voices) + { + data->cparams.format.voices=channellist[jt+1].channels; + break; + } + if (channellist[jt].channels==0) + { + data->cparams.format.voices=0; + break; + } + jt++; + } while(1); + } + + if (data->cparams.format.voices==0) + { + break; + } + } + + data->cparams.buf.block.frag_size=device->UpdateSize* + data->cparams.format.voices* + snd_pcm_format_width(data->cparams.format.format)/8; + data->cparams.buf.block.frags_max=device->NumUpdates; + data->cparams.buf.block.frags_min=device->NumUpdates; + if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) + { + continue; + } + else + { + break; + } + } while(1); + + if (data->cparams.format.voices!=0) + { + break; + } + } + + if (data->cparams.format.voices==0) + { + return ALC_FALSE; + } + } + + if ((snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK))<0) + { + return ALC_FALSE; + } + + memset(&data->csetup, 0, sizeof(data->csetup)); + data->csetup.channel=SND_PCM_CHANNEL_PLAYBACK; + if (snd_pcm_plugin_setup(data->pcmHandle, &data->csetup)<0) + { + return ALC_FALSE; + } + + /* now fill back to the our AL device */ + device->Frequency=data->cparams.format.rate; + + switch (data->cparams.format.voices) + { + case 1: + device->FmtChans=DevFmtMono; + break; + case 2: + device->FmtChans=DevFmtStereo; + break; + case 4: + device->FmtChans=DevFmtQuad; + break; + case 6: + device->FmtChans=DevFmtX51; + break; + case 7: + device->FmtChans=DevFmtX61; + break; + case 8: + device->FmtChans=DevFmtX71; + break; + default: + device->FmtChans=DevFmtMono; + break; + } + + switch (data->cparams.format.format) + { + case SND_PCM_SFMT_S8: + device->FmtType=DevFmtByte; + break; + case SND_PCM_SFMT_U8: + device->FmtType=DevFmtUByte; + break; + case SND_PCM_SFMT_S16_LE: + device->FmtType=DevFmtShort; + break; + case SND_PCM_SFMT_U16_LE: + device->FmtType=DevFmtUShort; + break; + case SND_PCM_SFMT_S32_LE: + device->FmtType=DevFmtInt; + break; + case SND_PCM_SFMT_U32_LE: + device->FmtType=DevFmtUInt; + break; + case SND_PCM_SFMT_FLOAT_LE: + device->FmtType=DevFmtFloat; + break; + default: + device->FmtType=DevFmtShort; + break; + } + + SetDefaultChannelOrder(device); + + device->UpdateSize=data->csetup.buf.block.frag_size/ + (ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType)); + device->NumUpdates=data->csetup.buf.block.frags; + + data->size=data->csetup.buf.block.frag_size; + data->buffer=malloc(data->size); + if (!data->buffer) + { + return ALC_FALSE; + } + + return ALC_TRUE; +} + +static ALCboolean qsa_start_playback(ALCdevice* device) +{ + qsa_data *data = (qsa_data*)device->ExtraData; + + if(!StartThread(&data->thread, qsa_proc_playback, device)) + return ALC_FALSE; + + return ALC_TRUE; +} + +static void qsa_stop_playback(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + + if (data->thread) + { + data->killNow=1; + StopThread(data->thread); + data->thread=NULL; + } + data->killNow=0; +} + +/***********/ +/* Capture */ +/***********/ + +static ALCenum qsa_open_capture(ALCdevice* device, const ALCchar* deviceName) +{ + qsa_data* data; + int format=-1; + char driver[64]; + int card, dev; + int status; + + strncpy(driver, GetConfigValue("qsa", "capture", qsaDevice), sizeof(driver)-1); + driver[sizeof(driver)-1]=0; + + data=(qsa_data*)calloc(1, sizeof(qsa_data)); + if (data==NULL) + { + return ALC_OUT_OF_MEMORY; + } + + if (!deviceName) + { + deviceName=driver; + } + + if (strcmp(deviceName, qsaDevice)==0) + { + if (!deviceName) + { + deviceName=qsaDevice; + } + + status=snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_CAPTURE); + } + else + { + size_t idx; + + if (!allCaptureDevNameMap) + { + allCaptureDevNameMap=deviceList(SND_PCM_CHANNEL_CAPTURE, &numDevNames); + } + + for (idx=0; idx0) + { + break; + } + } + } + if (idx==numDevNames) + { + free(data); + return ALC_INVALID_DEVICE; + } + + status=snd_pcm_open(&data->pcmHandle, allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev, SND_PCM_OPEN_CAPTURE); + } + + if (status<0) + { + free(data); + return ALC_INVALID_DEVICE; + } + + data->audio_fd=snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE); + if (data->audio_fd<0) + { + free(data); + return ALC_INVALID_DEVICE; + } + + device->DeviceName=strdup(deviceName); + device->ExtraData=data; + + switch (device->FmtType) + { + case DevFmtByte: + format=SND_PCM_SFMT_S8; + break; + case DevFmtUByte: + format=SND_PCM_SFMT_U8; + break; + case DevFmtShort: + format=SND_PCM_SFMT_S16_LE; + break; + case DevFmtUShort: + format=SND_PCM_SFMT_U16_LE; + break; + case DevFmtInt: + format=SND_PCM_SFMT_S32_LE; + break; + case DevFmtUInt: + format=SND_PCM_SFMT_U32_LE; + break; + case DevFmtFloat: + format=SND_PCM_SFMT_FLOAT_LE; + break; + } + + /* we actually don't want to block on reads */ + snd_pcm_nonblock_mode(data->pcmHandle, 1); + /* Disable mmap to control data transfer to the audio device */ + snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_MMAP); + + /* configure a sound channel */ + memset(&data->cparams, 0, sizeof(data->cparams)); + data->cparams.mode=SND_PCM_MODE_BLOCK; + data->cparams.channel=SND_PCM_CHANNEL_CAPTURE; + data->cparams.start_mode=SND_PCM_START_GO; + data->cparams.stop_mode=SND_PCM_STOP_STOP; + + data->cparams.buf.block.frag_size=device->UpdateSize* + ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType); + data->cparams.buf.block.frags_max=device->NumUpdates; + data->cparams.buf.block.frags_min=device->NumUpdates; + + data->cparams.format.interleave=1; + data->cparams.format.rate=device->Frequency; + data->cparams.format.voices=ChannelsFromDevFmt(device->FmtChans); + data->cparams.format.format=format; + + if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) + { + int original_rate=data->cparams.format.rate; + int original_voices=data->cparams.format.voices; + int original_format=data->cparams.format.format; + int it; + int jt; + + for (it=0; it<1; it++) + { + /* Check for second pass */ + if (it==1) + { + original_rate=ratelist[0].rate; + original_voices=channellist[0].channels; + original_format=formatlist[0].format; + } + + do { + /* At first downgrade sample format */ + jt=0; + do { + if (formatlist[jt].format==data->cparams.format.format) + { + data->cparams.format.format=formatlist[jt+1].format; + break; + } + if (formatlist[jt].format==0) + { + data->cparams.format.format=0; + break; + } + jt++; + } while(1); + + if (data->cparams.format.format==0) + { + data->cparams.format.format=original_format; + + /* At secod downgrade sample rate */ + jt=0; + do { + if (ratelist[jt].rate==data->cparams.format.rate) + { + data->cparams.format.rate=ratelist[jt+1].rate; + break; + } + if (ratelist[jt].rate==0) + { + data->cparams.format.rate=0; + break; + } + jt++; + } while(1); + + if (data->cparams.format.rate==0) + { + data->cparams.format.rate=original_rate; + data->cparams.format.format=original_format; + + /* At third downgrade channels number */ + jt=0; + do { + if(channellist[jt].channels==data->cparams.format.voices) + { + data->cparams.format.voices=channellist[jt+1].channels; + break; + } + if (channellist[jt].channels==0) + { + data->cparams.format.voices=0; + break; + } + jt++; + } while(1); + } + + if (data->cparams.format.voices==0) + { + break; + } + } + + data->cparams.buf.block.frag_size=device->UpdateSize* + data->cparams.format.voices* + snd_pcm_format_width(data->cparams.format.format)/8; + data->cparams.buf.block.frags_max=device->NumUpdates; + data->cparams.buf.block.frags_min=device->NumUpdates; + if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) + { + continue; + } + else + { + break; + } + } while(1); + + if (data->cparams.format.voices!=0) + { + break; + } + } + + if (data->cparams.format.voices==0) + { + return ALC_INVALID_VALUE; + } + } + + /* now fill back to the our AL device */ + device->Frequency=data->cparams.format.rate; + + switch (data->cparams.format.voices) + { + case 1: + device->FmtChans=DevFmtMono; + break; + case 2: + device->FmtChans=DevFmtStereo; + break; + case 4: + device->FmtChans=DevFmtQuad; + break; + case 6: + device->FmtChans=DevFmtX51; + break; + case 7: + device->FmtChans=DevFmtX61; + break; + case 8: + device->FmtChans=DevFmtX71; + break; + default: + device->FmtChans=DevFmtMono; + break; + } + + switch (data->cparams.format.format) + { + case SND_PCM_SFMT_S8: + device->FmtType=DevFmtByte; + break; + case SND_PCM_SFMT_U8: + device->FmtType=DevFmtUByte; + break; + case SND_PCM_SFMT_S16_LE: + device->FmtType=DevFmtShort; + break; + case SND_PCM_SFMT_U16_LE: + device->FmtType=DevFmtUShort; + break; + case SND_PCM_SFMT_S32_LE: + device->FmtType=DevFmtInt; + break; + case SND_PCM_SFMT_U32_LE: + device->FmtType=DevFmtUInt; + break; + case SND_PCM_SFMT_FLOAT_LE: + device->FmtType=DevFmtFloat; + break; + default: + device->FmtType=DevFmtShort; + break; + } + + return ALC_NO_ERROR; +} + +static void qsa_close_capture(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + + if (data->pcmHandle!=NULL) + { + snd_pcm_close(data->pcmHandle); + } + free(data); + device->ExtraData=NULL; +} + +static void qsa_start_capture(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + int rstatus; + + if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0) + { + ERR("capture prepare failed: %s\n", snd_strerror(rstatus)); + return; + } + + memset(&data->csetup, 0, sizeof(data->csetup)); + data->csetup.channel=SND_PCM_CHANNEL_CAPTURE; + if ((rstatus=snd_pcm_plugin_setup(data->pcmHandle, &data->csetup))<0) + { + ERR("capture setup failed: %s\n", snd_strerror(rstatus)); + return; + } + + snd_pcm_capture_go(data->pcmHandle); + + device->UpdateSize=data->csetup.buf.block.frag_size/ + (ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType)); + device->NumUpdates=data->csetup.buf.block.frags; +} + +static void qsa_stop_capture(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + + snd_pcm_capture_flush(data->pcmHandle); +} + +static ALCuint qsa_available_samples(ALCdevice* device) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + snd_pcm_channel_status_t status; + ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + ALint free_size; + int rstatus; + + memset(&status, 0, sizeof (status)); + status.channel=SND_PCM_CHANNEL_CAPTURE; + snd_pcm_plugin_status(data->pcmHandle, &status); + if ((status.status==SND_PCM_STATUS_OVERRUN) || + (status.status==SND_PCM_STATUS_READY)) + { + if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0) + { + ERR("capture prepare failed: %s\n", snd_strerror(rstatus)); + aluHandleDisconnect(device); + return 0; + } + + snd_pcm_capture_go(data->pcmHandle); + return 0; + } + + free_size=data->csetup.buf.block.frag_size*data->csetup.buf.block.frags; + free_size-=status.free; + + return free_size/frame_size; +} + +static ALCenum qsa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) +{ + qsa_data* data=(qsa_data*)device->ExtraData; + char* read_ptr; + snd_pcm_channel_status_t status; + fd_set rfds; + int selectret; + struct timeval timeout; + int bytes_read; + ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + ALint len=samples*frame_size; + int rstatus; + + read_ptr=buffer; + + while (len>0) + { + FD_ZERO(&rfds); + FD_SET(data->audio_fd, &rfds); + timeout.tv_sec=2; + timeout.tv_usec=0; + + /* Select also works like time slice to OS */ + bytes_read=0; + selectret=select(data->audio_fd+1, &rfds, NULL, NULL, &timeout); + switch (selectret) + { + case -1: + aluHandleDisconnect(device); + return ALC_INVALID_DEVICE; + case 0: + break; + default: + if (FD_ISSET(data->audio_fd, &rfds)) + { + bytes_read=snd_pcm_plugin_read(data->pcmHandle, read_ptr, len); + break; + } + break; + } + + if (bytes_read<=0) + { + if ((errno==EAGAIN) || (errno==EWOULDBLOCK)) + { + continue; + } + + memset(&status, 0, sizeof (status)); + status.channel=SND_PCM_CHANNEL_CAPTURE; + snd_pcm_plugin_status(data->pcmHandle, &status); + + /* we need to reinitialize the sound channel if we've overrun the buffer */ + if ((status.status==SND_PCM_STATUS_OVERRUN) || + (status.status==SND_PCM_STATUS_READY)) + { + if ((rstatus=snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE))<0) + { + ERR("capture prepare failed: %s\n", snd_strerror(rstatus)); + aluHandleDisconnect(device); + return ALC_INVALID_DEVICE; + } + snd_pcm_capture_go(data->pcmHandle); + } + } + else + { + read_ptr+=bytes_read; + len-=bytes_read; + } + } + + return ALC_NO_ERROR; +} + +static ALint64 qsa_get_latency(ALCdevice* device) +{ + ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + + return (ALint64)(device->UpdateSize*device->NumUpdates/frame_size)* + 1000000000/device->Frequency; +} + +BackendFuncs qsa_funcs= +{ + qsa_open_playback, + qsa_close_playback, + qsa_reset_playback, + qsa_start_playback, + qsa_stop_playback, + qsa_open_capture, + qsa_close_capture, + qsa_start_capture, + qsa_stop_capture, + qsa_capture_samples, + qsa_available_samples, + qsa_get_latency, +}; + +ALCboolean alc_qsa_init(BackendFuncs* func_list) +{ + *func_list=qsa_funcs; + + return ALC_TRUE; +} + +void alc_qsa_deinit(void) +{ + ALuint i; + + for (i=0; i #include #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" #include @@ -33,86 +34,8 @@ static const ALCchar sndio_device[] = "SndIO Default"; -static void *sndio_handle; -#ifdef HAVE_DYNLOAD -#define MAKE_FUNC(x) static typeof(x) * p##x -MAKE_FUNC(sio_initpar); -MAKE_FUNC(sio_open); -MAKE_FUNC(sio_close); -MAKE_FUNC(sio_setpar); -MAKE_FUNC(sio_getpar); -MAKE_FUNC(sio_getcap); -MAKE_FUNC(sio_onmove); -MAKE_FUNC(sio_write); -MAKE_FUNC(sio_read); -MAKE_FUNC(sio_start); -MAKE_FUNC(sio_stop); -MAKE_FUNC(sio_nfds); -MAKE_FUNC(sio_pollfd); -MAKE_FUNC(sio_revents); -MAKE_FUNC(sio_eof); -MAKE_FUNC(sio_setvol); -MAKE_FUNC(sio_onvol); - -#define sio_initpar psio_initpar -#define sio_open psio_open -#define sio_close psio_close -#define sio_setpar psio_setpar -#define sio_getpar psio_getpar -#define sio_getcap psio_getcap -#define sio_onmove psio_onmove -#define sio_write psio_write -#define sio_read psio_read -#define sio_start psio_start -#define sio_stop psio_stop -#define sio_nfds psio_nfds -#define sio_pollfd psio_pollfd -#define sio_revents psio_revents -#define sio_eof psio_eof -#define sio_setvol psio_setvol -#define sio_onvol psio_onvol -#endif - - static ALCboolean sndio_load(void) { - if(!sndio_handle) - { -#ifdef HAVE_DYNLOAD - sndio_handle = LoadLib("libsndio.so"); - if(!sndio_handle) - return ALC_FALSE; - -#define LOAD_FUNC(f) do { \ - p##f = GetSymbol(sndio_handle, #f); \ - if(p##f == NULL) { \ - CloseLib(sndio_handle); \ - sndio_handle = NULL; \ - return ALC_FALSE; \ - } \ -} while(0) - LOAD_FUNC(sio_initpar); - LOAD_FUNC(sio_open); - LOAD_FUNC(sio_close); - LOAD_FUNC(sio_setpar); - LOAD_FUNC(sio_getpar); - LOAD_FUNC(sio_getcap); - LOAD_FUNC(sio_onmove); - LOAD_FUNC(sio_write); - LOAD_FUNC(sio_read); - LOAD_FUNC(sio_start); - LOAD_FUNC(sio_stop); - LOAD_FUNC(sio_nfds); - LOAD_FUNC(sio_pollfd); - LOAD_FUNC(sio_revents); - LOAD_FUNC(sio_eof); - LOAD_FUNC(sio_setvol); - LOAD_FUNC(sio_onvol); -#undef LOAD_FUNC -#else - sndio_handle = (void*)0xDEADBEEF; -#endif - } return ALC_TRUE; } @@ -124,7 +47,7 @@ typedef struct { ALsizei data_size; volatile int killNow; - ALvoid *thread; + althread_t thread; } sndio_data; @@ -136,6 +59,7 @@ static ALuint sndio_proc(ALvoid *ptr) size_t wrote; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); @@ -151,7 +75,9 @@ static ALuint sndio_proc(ALvoid *ptr) if(wrote == 0) { ERR("sio_write failed\n"); + ALCdevice_Lock(device); aluHandleDisconnect(device); + ALCdevice_Unlock(device); break; } @@ -185,7 +111,7 @@ static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar *deviceName) return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); + device->DeviceName = strdup(deviceName); device->ExtraData = data; return ALC_NO_ERROR; @@ -208,7 +134,6 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) sio_initpar(&par); par.rate = device->Frequency; - par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1); switch(device->FmtType) @@ -222,8 +147,6 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) par.sig = 0; break; case DevFmtFloat: - device->FmtType = DevFmtShort; - /* fall-through */ case DevFmtShort: par.bits = 16; par.sig = 1; @@ -232,6 +155,14 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) par.bits = 16; par.sig = 0; break; + case DevFmtInt: + par.bits = 32; + par.sig = 1; + break; + case DevFmtUInt: + par.bits = 32; + par.sig = 0; + break; } par.le = SIO_LE_NATIVE; @@ -239,40 +170,21 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) par.appbufsz = device->UpdateSize * (device->NumUpdates-1); if(!par.appbufsz) par.appbufsz = device->UpdateSize; - if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par)) { ERR("Failed to set device parameters\n"); return ALC_FALSE; } - if(par.rate != device->Frequency) - { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set frequency %uhz, got %uhz instead\n", device->Frequency, par.rate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = par.rate; - } - - if(par.pchan != ChannelsFromDevFmt(device->FmtChans)) - { - if(par.pchan != 1 && par.pchan != 2) - { - ERR("Unhandled channel count: %u\n", par.pchan); - return ALC_FALSE; - } - if((device->Flags&DEVICE_CHANNELS_REQUEST)) - ERR("Failed to set %s, got %u channels instead\n", DevFmtChannelsString(device->FmtChans), par.pchan); - device->Flags &= ~DEVICE_CHANNELS_REQUEST; - device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); - } - if(par.bits != par.bps*8) { ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8); return ALC_FALSE; } + device->Frequency = par.rate; + device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); + if(par.bits == 8 && par.sig == 1) device->FmtType = DevFmtByte; else if(par.bits == 8 && par.sig == 0) @@ -281,18 +193,27 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) device->FmtType = DevFmtShort; else if(par.bits == 16 && par.sig == 0) device->FmtType = DevFmtUShort; + else if(par.bits == 32 && par.sig == 1) + device->FmtType = DevFmtInt; + else if(par.bits == 32 && par.sig == 0) + device->FmtType = DevFmtUInt; else { ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits); return ALC_FALSE; } - device->UpdateSize = par.round; device->NumUpdates = (par.bufsz/par.round) + 1; SetDefaultChannelOrder(device); + return ALC_TRUE; +} + +static ALCboolean sndio_start_playback(ALCdevice *device) +{ + sndio_data *data = device->ExtraData; if(!sio_start(data->sndHandle)) { @@ -300,11 +221,10 @@ static ALCboolean sndio_reset_playback(ALCdevice *device) return ALC_FALSE; } - data->data_size = device->UpdateSize * par.bps * par.pchan; + data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->mix_data = calloc(1, data->data_size); - data->thread = StartThread(sndio_proc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, sndio_proc, device)) { sio_stop(data->sndHandle); free(data->mix_data); @@ -339,13 +259,15 @@ static const BackendFuncs sndio_funcs = { sndio_open_playback, sndio_close_playback, sndio_reset_playback, + sndio_start_playback, sndio_stop_playback, NULL, NULL, NULL, NULL, NULL, - NULL + NULL, + ALCdevice_GetLatencyDefault }; ALCboolean alc_sndio_init(BackendFuncs *func_list) @@ -358,22 +280,14 @@ ALCboolean alc_sndio_init(BackendFuncs *func_list) void alc_sndio_deinit(void) { -#ifdef HAVE_DYNLOAD - if(sndio_handle) - CloseLib(sndio_handle); - sndio_handle = NULL; -#endif } void alc_sndio_probe(enum DevProbe type) { switch(type) { - case DEVICE_PROBE: - AppendDeviceList(sndio_device); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(sndio_device); + AppendAllDevicesList(sndio_device); break; case CAPTURE_DEVICE_PROBE: break; diff --git a/jni/openal-soft-android/Alc/backends/solaris.c b/jni/openal-soft-android/Alc/backends/solaris.c index 1ac1f9fb..700131c8 100644 --- a/jni/openal-soft-android/Alc/backends/solaris.c +++ b/jni/openal-soft-android/Alc/backends/solaris.c @@ -30,42 +30,48 @@ #include #include #include + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" #include static const ALCchar solaris_device[] = "Solaris Default"; +static const char *solaris_driver = "/dev/audio"; + typedef struct { int fd; - volatile int killNow; - ALvoid *thread; ALubyte *mix_data; int data_size; + + volatile int killNow; + althread_t thread; } solaris_data; static ALuint SolarisProc(ALvoid *ptr) { - ALCdevice *pDevice = (ALCdevice*)ptr; - solaris_data *data = (solaris_data*)pDevice->ExtraData; + ALCdevice *Device = (ALCdevice*)ptr; + solaris_data *data = (solaris_data*)Device->ExtraData; ALint frameSize; int wrote; SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); + frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); - while(!data->killNow && pDevice->Connected) + while(!data->killNow && Device->Connected) { ALint len = data->data_size; ALubyte *WritePtr = data->mix_data; - aluMixData(pDevice, WritePtr, len/frameSize); + aluMixData(Device, WritePtr, len/frameSize); while(len > 0 && !data->killNow) { wrote = write(data->fd, WritePtr, len); @@ -74,7 +80,9 @@ static ALuint SolarisProc(ALvoid *ptr) if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) { ERR("write failed: %s\n", strerror(errno)); - aluHandleDisconnect(pDevice); + ALCdevice_Lock(Device); + aluHandleDisconnect(Device); + ALCdevice_Unlock(Device); break; } @@ -93,12 +101,8 @@ static ALuint SolarisProc(ALvoid *ptr) static ALCenum solaris_open_playback(ALCdevice *device, const ALCchar *deviceName) { - char driver[64]; solaris_data *data; - strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1); - driver[sizeof(driver)-1] = 0; - if(!deviceName) deviceName = solaris_device; else if(strcmp(deviceName, solaris_device) != 0) @@ -107,15 +111,15 @@ static ALCenum solaris_open_playback(ALCdevice *device, const ALCchar *deviceNam data = (solaris_data*)calloc(1, sizeof(solaris_data)); data->killNow = 0; - data->fd = open(driver, O_WRONLY); + data->fd = open(solaris_driver, O_WRONLY); if(data->fd == -1) { free(data); - ERR("Could not open %s: %s\n", driver, strerror(errno)); + ERR("Could not open %s: %s\n", solaris_driver, strerror(errno)); return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); + device->DeviceName = strdup(deviceName); device->ExtraData = data; return ALC_NO_ERROR; } @@ -156,6 +160,8 @@ static ALCboolean solaris_reset_playback(ALCdevice *device) info.play.encoding = AUDIO_ENCODING_LINEAR8; break; case DevFmtUShort: + case DevFmtInt: + case DevFmtUInt: case DevFmtFloat: device->FmtType = DevFmtShort; /* fall-through */ @@ -180,34 +186,32 @@ static ALCboolean solaris_reset_playback(ALCdevice *device) return ALC_FALSE; } - if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && - device->FmtType == DevFmtByte) || - (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && - device->FmtType == DevFmtUByte) || - (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && - device->FmtType == DevFmtShort))) + if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && device->FmtType == DevFmtUByte) || + (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtByte) || + (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtShort) || + (info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtInt))) { - ERR("Could not set %#x sample type, got %d (%#x)\n", - device->FmtType, info.play.precision, info.play.encoding); + ERR("Could not set %s samples, got %d (0x%x)\n", DevFmtTypeString(device->FmtType), + info.play.precision, info.play.encoding); return ALC_FALSE; } - if(device->Frequency != info.play.sample_rate) - { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("Failed to set requested frequency %dhz, got %dhz instead\n", device->Frequency, info.play.sample_rate); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = info.play.sample_rate; - } + device->Frequency = info.play.sample_rate; device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1; - data->data_size = device->UpdateSize * frameSize; - data->mix_data = calloc(1, data->data_size); - SetDefaultChannelOrder(device); - data->thread = StartThread(SolarisProc, device); - if(data->thread == NULL) + return ALC_TRUE; +} + +static ALCboolean solaris_start_playback(ALCdevice *device) +{ + solaris_data *data = (solaris_data*)device->ExtraData; + + data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + data->mix_data = calloc(1, data->data_size); + + if(!StartThread(&data->thread, SolarisProc, device)) { free(data->mix_data); data->mix_data = NULL; @@ -241,17 +245,21 @@ static const BackendFuncs solaris_funcs = { solaris_open_playback, solaris_close_playback, solaris_reset_playback, + solaris_start_playback, solaris_stop_playback, NULL, NULL, NULL, NULL, NULL, - NULL + NULL, + ALCdevice_GetLatencyDefault }; ALCboolean alc_solaris_init(BackendFuncs *func_list) { + ConfigValueStr("solaris", "device", &solaris_driver); + *func_list = solaris_funcs; return ALC_TRUE; } @@ -262,20 +270,18 @@ void alc_solaris_deinit(void) void alc_solaris_probe(enum DevProbe type) { -#ifdef HAVE_STAT - struct stat buf; - if(stat(GetConfigValue("solaris", "device", "/dev/audio"), &buf) != 0) - return; -#endif - switch(type) { - case DEVICE_PROBE: - AppendDeviceList(solaris_device); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(solaris_device); - break; + { +#ifdef HAVE_STAT + struct stat buf; + if(stat(solaris_driver, &buf) == 0) +#endif + AppendAllDevicesList(solaris_device); + } + break; + case CAPTURE_DEVICE_PROBE: break; } diff --git a/jni/openal-soft-android/Alc/backends/wave.c b/jni/openal-soft-android/Alc/backends/wave.c index ae0ef2be..2fafc4b9 100644 --- a/jni/openal-soft-android/Alc/backends/wave.c +++ b/jni/openal-soft-android/Alc/backends/wave.c @@ -23,9 +23,15 @@ #include #include #include +#include +#ifdef HAVE_WINDOWS_H +#include +#endif + #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" +#include "compat.h" typedef struct { @@ -36,7 +42,7 @@ typedef struct { ALuint size; volatile int killNow; - ALvoid *thread; + althread_t thread; } wave_data; @@ -81,50 +87,47 @@ static void fwrite32le(ALuint val, FILE *f) static ALuint WaveProc(ALvoid *ptr) { - ALCdevice *pDevice = (ALCdevice*)ptr; - wave_data *data = (wave_data*)pDevice->ExtraData; + ALCdevice *Device = (ALCdevice*)ptr; + wave_data *data = (wave_data*)Device->ExtraData; ALuint frameSize; ALuint now, start; ALuint64 avail, done; size_t fs; - union { - short s; - char b[sizeof(short)]; - } uSB; - const ALuint restTime = (ALuint64)pDevice->UpdateSize * 1000 / - pDevice->Frequency / 2; + const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 / + Device->Frequency / 2; - uSB.s = 1; - frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); + SetThreadName(MIXER_THREAD_NAME); + + frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); done = 0; start = timeGetTime(); - while(!data->killNow && pDevice->Connected) + while(!data->killNow && Device->Connected) { now = timeGetTime(); - avail = (ALuint64)(now-start) * pDevice->Frequency / 1000; + avail = (ALuint64)(now-start) * Device->Frequency / 1000; if(avail < done) { - /* Timer wrapped. Add the remainder of the cycle to the available - * count and reset the number of samples done */ - avail += (ALuint64)0xFFFFFFFFu*pDevice->Frequency/1000 - done; + /* Timer wrapped (50 days???). Add the remainder of the cycle to + * the available count and reset the number of samples done */ + avail += ((ALuint64)1<<32)*Device->Frequency/1000 - done; done = 0; } - if(avail-done < pDevice->UpdateSize) + if(avail-done < Device->UpdateSize) { Sleep(restTime); continue; } - while(avail-done >= pDevice->UpdateSize) + while(avail-done >= Device->UpdateSize) { - aluMixData(pDevice, data->buffer, pDevice->UpdateSize); - done += pDevice->UpdateSize; + aluMixData(Device, data->buffer, Device->UpdateSize); + done += Device->UpdateSize; - if(uSB.b[0] != 1) + if(!IS_LITTLE_ENDIAN) { - ALuint bytesize = BytesFromDevFmt(pDevice->FmtType); + ALuint bytesize = BytesFromDevFmt(Device->FmtType); ALubyte *bytes = data->buffer; ALuint i; @@ -145,12 +148,17 @@ static ALuint WaveProc(ALvoid *ptr) } } else - fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize, + { + fs = fwrite(data->buffer, frameSize, Device->UpdateSize, data->f); + (void)fs; + } if(ferror(data->f)) { ERR("Error writing to file\n"); - aluHandleDisconnect(pDevice); + ALCdevice_Lock(Device); + aluHandleDisconnect(Device); + ALCdevice_Unlock(Device); break; } } @@ -183,7 +191,7 @@ static ALCenum wave_open_playback(ALCdevice *device, const ALCchar *deviceName) return ALC_INVALID_VALUE; } - device->szDeviceName = strdup(deviceName); + device->DeviceName = strdup(deviceName); device->ExtraData = data; return ALC_NO_ERROR; } @@ -214,8 +222,12 @@ static ALCboolean wave_reset_playback(ALCdevice *device) case DevFmtUShort: device->FmtType = DevFmtShort; break; + case DevFmtUInt: + device->FmtType = DevFmtInt; + break; case DevFmtUByte: case DevFmtShort: + case DevFmtInt: case DevFmtFloat: break; } @@ -250,6 +262,7 @@ static ALCboolean wave_reset_playback(ALCdevice *device) fwrite32le(channel_masks[channels], data->f); // 16 byte GUID, sub-type format val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f); + (void)val; fprintf(data->f, "data"); fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close @@ -259,10 +272,18 @@ static ALCboolean wave_reset_playback(ALCdevice *device) ERR("Error writing header: %s\n", strerror(errno)); return ALC_FALSE; } - data->DataStart = ftell(data->f); - data->size = device->UpdateSize * channels * bits / 8; + SetDefaultWFXChannelOrder(device); + + return ALC_TRUE; +} + +static ALCboolean wave_start_playback(ALCdevice *device) +{ + wave_data *data = (wave_data*)device->ExtraData; + + data->size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); data->buffer = malloc(data->size); if(!data->buffer) { @@ -270,10 +291,7 @@ static ALCboolean wave_reset_playback(ALCdevice *device) return ALC_FALSE; } - SetDefaultWFXChannelOrder(device); - - data->thread = StartThread(WaveProc, device); - if(data->thread == NULL) + if(!StartThread(&data->thread, WaveProc, device)) { free(data->buffer); data->buffer = NULL; @@ -317,13 +335,15 @@ static const BackendFuncs wave_funcs = { wave_open_playback, wave_close_playback, wave_reset_playback, + wave_start_playback, wave_stop_playback, NULL, NULL, NULL, NULL, NULL, - NULL + NULL, + ALCdevice_GetLatencyDefault }; ALCboolean alc_wave_init(BackendFuncs *func_list) @@ -343,11 +363,8 @@ void alc_wave_probe(enum DevProbe type) switch(type) { - case DEVICE_PROBE: - AppendDeviceList(waveDevice); - break; case ALL_DEVICE_PROBE: - AppendAllDeviceList(waveDevice); + AppendAllDevicesList(waveDevice); break; case CAPTURE_DEVICE_PROBE: break; diff --git a/jni/openal-soft-android/Alc/backends/winmm.c b/jni/openal-soft-android/Alc/backends/winmm.c index 1af5105b..7082a874 100644 --- a/jni/openal-soft-android/Alc/backends/winmm.c +++ b/jni/openal-soft-android/Alc/backends/winmm.c @@ -28,32 +28,34 @@ #include #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" +#include "threads.h" + +#ifndef WAVE_FORMAT_IEEE_FLOAT +#define WAVE_FORMAT_IEEE_FLOAT 0x0003 +#endif typedef struct { // MMSYSTEM Device - volatile ALboolean bWaveShutdown; - HANDLE hWaveThreadEvent; - HANDLE hWaveThread; - DWORD ulWaveThreadID; - LONG lWaveBuffersCommitted; + volatile ALboolean killNow; + HANDLE WaveThreadEvent; + HANDLE WaveThread; + DWORD WaveThreadID; + volatile LONG WaveBuffersCommitted; WAVEHDR WaveBuffer[4]; union { HWAVEIN In; HWAVEOUT Out; - } hWaveHandle; + } WaveHandle; - ALuint Frequency; + WAVEFORMATEX Format; - RingBuffer *pRing; + RingBuffer *Ring; } WinMMData; -static const ALCchar woDefault[] = "WaveOut Default"; - static ALCchar **PlaybackDeviceList; static ALuint NumPlaybackDevices; static ALCchar **CaptureDeviceList; @@ -145,33 +147,16 @@ static void ProbeCaptureDevices(void) Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and returns to the application (for more data) */ -static void CALLBACK WaveOutProc(HWAVEOUT hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) +static void CALLBACK WaveOutProc(HWAVEOUT UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) { - ALCdevice *pDevice = (ALCdevice*)dwInstance; - WinMMData *pData = pDevice->ExtraData; + ALCdevice *Device = (ALCdevice*)instance; + WinMMData *data = Device->ExtraData; - (void)hDevice; - (void)dwParam2; - - if(uMsg != WOM_DONE) + if(msg != WOM_DONE) return; - // Decrement number of buffers in use - InterlockedDecrement(&pData->lWaveBuffersCommitted); - - if(pData->bWaveShutdown == AL_FALSE) - { - // Notify Wave Processor Thread that a Wave Header has returned - PostThreadMessage(pData->ulWaveThreadID, uMsg, 0, dwParam1); - } - else - { - if(pData->lWaveBuffersCommitted == 0) - { - // Post 'Quit' Message to WaveOut Processor Thread - PostThreadMessage(pData->ulWaveThreadID, WM_QUIT, 0, 0); - } - } + InterlockedDecrement(&data->WaveBuffersCommitted); + PostThreadMessage(data->WaveThreadID, msg, 0, param1); } /* @@ -180,38 +165,44 @@ static void CALLBACK WaveOutProc(HWAVEOUT hDevice,UINT uMsg,DWORD_PTR dwInstance Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its audio data. */ -static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter) +FORCE_ALIGN static DWORD WINAPI PlaybackThreadProc(LPVOID param) { - ALCdevice *pDevice = (ALCdevice*)lpParameter; - WinMMData *pData = pDevice->ExtraData; - LPWAVEHDR pWaveHdr; + ALCdevice *Device = (ALCdevice*)param; + WinMMData *data = Device->ExtraData; + LPWAVEHDR WaveHdr; ALuint FrameSize; MSG msg; - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); + FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); SetRTPriority(); + SetThreadName(MIXER_THREAD_NAME); while(GetMessage(&msg, NULL, 0, 0)) { - if(msg.message != WOM_DONE || pData->bWaveShutdown) + if(msg.message != WOM_DONE) continue; - pWaveHdr = ((LPWAVEHDR)msg.lParam); + if(data->killNow) + { + if(data->WaveBuffersCommitted == 0) + break; + continue; + } - aluMixData(pDevice, pWaveHdr->lpData, pWaveHdr->dwBufferLength/FrameSize); + WaveHdr = ((LPWAVEHDR)msg.lParam); + aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength/FrameSize); // Send buffer back to play more data - waveOutWrite(pData->hWaveHandle.Out, pWaveHdr, sizeof(WAVEHDR)); - InterlockedIncrement(&pData->lWaveBuffersCommitted); + waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR)); + InterlockedIncrement(&data->WaveBuffersCommitted); } // Signal Wave Thread completed event - if(pData->hWaveThreadEvent) - SetEvent(pData->hWaveThreadEvent); + if(data->WaveThreadEvent) + SetEvent(data->WaveThreadEvent); ExitThread(0); - return 0; } @@ -221,33 +212,16 @@ static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter) Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and returns to the application (with more data) */ -static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2) +static void CALLBACK WaveInProc(HWAVEIN UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) { - ALCdevice *pDevice = (ALCdevice*)dwInstance; - WinMMData *pData = pDevice->ExtraData; + ALCdevice *Device = (ALCdevice*)instance; + WinMMData *data = Device->ExtraData; - (void)hDevice; - (void)dwParam2; - - if(uMsg != WIM_DATA) + if(msg != WIM_DATA) return; - // Decrement number of buffers in use - InterlockedDecrement(&pData->lWaveBuffersCommitted); - - if(pData->bWaveShutdown == AL_FALSE) - { - // Notify Wave Processor Thread that a Wave Header has returned - PostThreadMessage(pData->ulWaveThreadID,uMsg,0,dwParam1); - } - else - { - if(pData->lWaveBuffersCommitted == 0) - { - // Post 'Quit' Message to WaveIn Processor Thread - PostThreadMessage(pData->ulWaveThreadID,WM_QUIT,0,0); - } - } + InterlockedDecrement(&data->WaveBuffersCommitted); + PostThreadMessage(data->WaveThreadID, msg, 0, param1); } /* @@ -256,196 +230,223 @@ static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,D Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new audio data. */ -static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter) +static DWORD WINAPI CaptureThreadProc(LPVOID param) { - ALCdevice *pDevice = (ALCdevice*)lpParameter; - WinMMData *pData = pDevice->ExtraData; - LPWAVEHDR pWaveHdr; + ALCdevice *Device = (ALCdevice*)param; + WinMMData *data = Device->ExtraData; + LPWAVEHDR WaveHdr; ALuint FrameSize; MSG msg; - FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); + FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); + SetThreadName("alsoft-record"); while(GetMessage(&msg, NULL, 0, 0)) { - if(msg.message != WIM_DATA || pData->bWaveShutdown) + if(msg.message != WIM_DATA) continue; + /* Don't wait for other buffers to finish before quitting. We're + * closing so we don't need them. */ + if(data->killNow) + break; - pWaveHdr = ((LPWAVEHDR)msg.lParam); - - WriteRingBuffer(pData->pRing, (ALubyte*)pWaveHdr->lpData, - pWaveHdr->dwBytesRecorded/FrameSize); + WaveHdr = ((LPWAVEHDR)msg.lParam); + WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, WaveHdr->dwBytesRecorded/FrameSize); // Send buffer back to capture more data - waveInAddBuffer(pData->hWaveHandle.In,pWaveHdr,sizeof(WAVEHDR)); - InterlockedIncrement(&pData->lWaveBuffersCommitted); + waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR)); + InterlockedIncrement(&data->WaveBuffersCommitted); } // Signal Wave Thread completed event - if(pData->hWaveThreadEvent) - SetEvent(pData->hWaveThreadEvent); + if(data->WaveThreadEvent) + SetEvent(data->WaveThreadEvent); ExitThread(0); - return 0; } -static ALCenum WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName) +static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName) { - WAVEFORMATEX wfexFormat; - WinMMData *pData = NULL; - UINT lDeviceID = 0; + WinMMData *data = NULL; + UINT DeviceID = 0; MMRESULT res; ALuint i = 0; + if(!PlaybackDeviceList) + ProbePlaybackDevices(); + // Find the Device ID matching the deviceName if valid - if(!deviceName || strcmp(deviceName, woDefault) == 0) - lDeviceID = WAVE_MAPPER; + for(i = 0;i < NumPlaybackDevices;i++) + { + if(PlaybackDeviceList[i] && + (!deviceName || strcmp(deviceName, PlaybackDeviceList[i]) == 0)) + { + DeviceID = i; + break; + } + } + if(i == NumPlaybackDevices) + return ALC_INVALID_VALUE; + + data = calloc(1, sizeof(*data)); + if(!data) + return ALC_OUT_OF_MEMORY; + Device->ExtraData = data; + +retry_open: + memset(&data->Format, 0, sizeof(WAVEFORMATEX)); + if(Device->FmtType == DevFmtFloat) + { + data->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + data->Format.wBitsPerSample = 32; + } else { - if(!PlaybackDeviceList) - ProbePlaybackDevices(); + data->Format.wFormatTag = WAVE_FORMAT_PCM; + if(Device->FmtType == DevFmtUByte || Device->FmtType == DevFmtByte) + data->Format.wBitsPerSample = 8; + else + data->Format.wBitsPerSample = 16; + } + data->Format.nChannels = ((Device->FmtChans == DevFmtMono) ? 1 : 2); + data->Format.nBlockAlign = data->Format.wBitsPerSample * + data->Format.nChannels / 8; + data->Format.nSamplesPerSec = Device->Frequency; + data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec * + data->Format.nBlockAlign; + data->Format.cbSize = 0; - for(i = 0;i < NumPlaybackDevices;i++) + if((res=waveOutOpen(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) + { + if(Device->FmtType == DevFmtFloat) { - if(PlaybackDeviceList[i] && - strcmp(deviceName, PlaybackDeviceList[i]) == 0) - { - lDeviceID = i; - break; - } + Device->FmtType = DevFmtShort; + goto retry_open; } - if(i == NumPlaybackDevices) - return ALC_INVALID_VALUE; - } - - pData = calloc(1, sizeof(*pData)); - if(!pData) - return ALC_OUT_OF_MEMORY; - pDevice->ExtraData = pData; - - if(pDevice->FmtChans != DevFmtMono) - { - if((pDevice->Flags&DEVICE_CHANNELS_REQUEST) && - pDevice->FmtChans != DevFmtStereo) - { - ERR("Failed to set %s, got Stereo instead\n", DevFmtChannelsString(pDevice->FmtChans)); - pDevice->Flags &= ~DEVICE_CHANNELS_REQUEST; - } - pDevice->FmtChans = DevFmtStereo; - } - switch(pDevice->FmtType) - { - case DevFmtByte: - pDevice->FmtType = DevFmtUByte; - break; - case DevFmtUShort: - case DevFmtFloat: - pDevice->FmtType = DevFmtShort; - break; - case DevFmtUByte: - case DevFmtShort: - break; - } - - memset(&wfexFormat, 0, sizeof(WAVEFORMATEX)); - wfexFormat.wFormatTag = WAVE_FORMAT_PCM; - wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); - wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; - wfexFormat.nBlockAlign = wfexFormat.wBitsPerSample * - wfexFormat.nChannels / 8; - wfexFormat.nSamplesPerSec = pDevice->Frequency; - wfexFormat.nAvgBytesPerSec = wfexFormat.nSamplesPerSec * - wfexFormat.nBlockAlign; - wfexFormat.cbSize = 0; - - if((res=waveOutOpen(&pData->hWaveHandle.Out, lDeviceID, &wfexFormat, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) - { ERR("waveOutOpen failed: %u\n", res); goto failure; } - pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if(pData->hWaveThreadEvent == NULL) + data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if(data->WaveThreadEvent == NULL) { ERR("CreateEvent failed: %lu\n", GetLastError()); goto failure; } - pData->Frequency = pDevice->Frequency; - - pDevice->szDeviceName = strdup((lDeviceID==WAVE_MAPPER) ? woDefault : - PlaybackDeviceList[lDeviceID]); + Device->DeviceName = strdup(PlaybackDeviceList[DeviceID]); return ALC_NO_ERROR; failure: - if(pData->hWaveThreadEvent) - CloseHandle(pData->hWaveThreadEvent); + if(data->WaveThreadEvent) + CloseHandle(data->WaveThreadEvent); - if(pData->hWaveHandle.Out) - waveOutClose(pData->hWaveHandle.Out); + if(data->WaveHandle.Out) + waveOutClose(data->WaveHandle.Out); - free(pData); - pDevice->ExtraData = NULL; + free(data); + Device->ExtraData = NULL; return ALC_INVALID_VALUE; } static void WinMMClosePlayback(ALCdevice *device) { - WinMMData *pData = (WinMMData*)device->ExtraData; + WinMMData *data = (WinMMData*)device->ExtraData; // Close the Wave device - CloseHandle(pData->hWaveThreadEvent); - pData->hWaveThreadEvent = 0; + CloseHandle(data->WaveThreadEvent); + data->WaveThreadEvent = 0; - waveOutClose(pData->hWaveHandle.Out); - pData->hWaveHandle.Out = 0; + waveOutClose(data->WaveHandle.Out); + data->WaveHandle.Out = 0; - free(pData); + free(data); device->ExtraData = NULL; } static ALCboolean WinMMResetPlayback(ALCdevice *device) { - WinMMData *pData = (WinMMData*)device->ExtraData; - ALbyte *BufferData; - ALint lBufferSize; - ALuint i; - - pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &pData->ulWaveThreadID); - if(pData->hWaveThread == NULL) - return ALC_FALSE; + WinMMData *data = (WinMMData*)device->ExtraData; device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * - pData->Frequency / device->Frequency); - if(device->Frequency != pData->Frequency) + data->Format.nSamplesPerSec / + device->Frequency); + device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4; + device->NumUpdates = 4; + device->Frequency = data->Format.nSamplesPerSec; + + if(data->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { - if((device->Flags&DEVICE_FREQUENCY_REQUEST)) - ERR("WinMM does not support changing sample rates (wanted %dhz, got %dhz)\n", device->Frequency, pData->Frequency); - device->Flags &= ~DEVICE_FREQUENCY_REQUEST; - device->Frequency = pData->Frequency; + if(data->Format.wBitsPerSample == 32) + device->FmtType = DevFmtFloat; + else + { + ERR("Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample); + return ALC_FALSE; + } + } + else if(data->Format.wFormatTag == WAVE_FORMAT_PCM) + { + if(data->Format.wBitsPerSample == 16) + device->FmtType = DevFmtShort; + else if(data->Format.wBitsPerSample == 8) + device->FmtType = DevFmtUByte; + else + { + ERR("Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample); + return ALC_FALSE; + } + } + else + { + ERR("Unhandled format tag: 0x%04x\n", data->Format.wFormatTag); + return ALC_FALSE; } + if(data->Format.nChannels == 2) + device->FmtChans = DevFmtStereo; + else if(data->Format.nChannels == 1) + device->FmtChans = DevFmtMono; + else + { + ERR("Unhandled channel count: %d\n", data->Format.nChannels); + return ALC_FALSE; + } SetDefaultWFXChannelOrder(device); - pData->lWaveBuffersCommitted = 0; + return ALC_TRUE; +} + +static ALCboolean WinMMStartPlayback(ALCdevice *device) +{ + WinMMData *data = (WinMMData*)device->ExtraData; + ALbyte *BufferData; + ALint BufferSize; + ALuint i; + + data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &data->WaveThreadID); + if(data->WaveThread == NULL) + return ALC_FALSE; + + data->WaveBuffersCommitted = 0; // Create 4 Buffers - lBufferSize = device->UpdateSize*device->NumUpdates / 4; - lBufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType); + BufferSize = device->UpdateSize*device->NumUpdates / 4; + BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - BufferData = calloc(4, lBufferSize); + BufferData = calloc(4, BufferSize); for(i = 0;i < 4;i++) { - memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); - pData->WaveBuffer[i].dwBufferLength = lBufferSize; - pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : - (pData->WaveBuffer[i-1].lpData + - pData->WaveBuffer[i-1].dwBufferLength)); - waveOutPrepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - waveOutWrite(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - InterlockedIncrement(&pData->lWaveBuffersCommitted); + memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR)); + data->WaveBuffer[i].dwBufferLength = BufferSize; + data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : + (data->WaveBuffer[i-1].lpData + + data->WaveBuffer[i-1].dwBufferLength)); + waveOutPrepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR)); + waveOutWrite(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR)); + InterlockedIncrement(&data->WaveBuffersCommitted); } return ALC_TRUE; @@ -453,43 +454,42 @@ static ALCboolean WinMMResetPlayback(ALCdevice *device) static void WinMMStopPlayback(ALCdevice *device) { - WinMMData *pData = (WinMMData*)device->ExtraData; + WinMMData *data = (WinMMData*)device->ExtraData; void *buffer = NULL; int i; - if(pData->hWaveThread == NULL) + if(data->WaveThread == NULL) return; // Set flag to stop processing headers - pData->bWaveShutdown = AL_TRUE; + data->killNow = AL_TRUE; // Wait for signal that Wave Thread has been destroyed - WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE); + WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE); - CloseHandle(pData->hWaveThread); - pData->hWaveThread = 0; + CloseHandle(data->WaveThread); + data->WaveThread = 0; - pData->bWaveShutdown = AL_FALSE; + data->killNow = AL_FALSE; // Release the wave buffers for(i = 0;i < 4;i++) { - waveOutUnprepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - if(i == 0) buffer = pData->WaveBuffer[i].lpData; - pData->WaveBuffer[i].lpData = NULL; + waveOutUnprepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR)); + if(i == 0) buffer = data->WaveBuffer[i].lpData; + data->WaveBuffer[i].lpData = NULL; } free(buffer); } -static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName) +static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName) { - WAVEFORMATEX wfexCaptureFormat; ALbyte *BufferData = NULL; - DWORD ulCapturedDataSize; - WinMMData *pData = NULL; - UINT lDeviceID = 0; - ALint lBufferSize; + DWORD CapturedDataSize; + WinMMData *data = NULL; + UINT DeviceID = 0; + ALint BufferSize; MMRESULT res; ALuint i; @@ -497,196 +497,207 @@ static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName) ProbeCaptureDevices(); // Find the Device ID matching the deviceName if valid - if(deviceName) + for(i = 0;i < NumCaptureDevices;i++) { - for(i = 0;i < NumCaptureDevices;i++) + if(CaptureDeviceList[i] && + (!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0)) { - if(CaptureDeviceList[i] && - strcmp(deviceName, CaptureDeviceList[i]) == 0) - { - lDeviceID = i; - break; - } - } - } - else - { - for(i = 0;i < NumCaptureDevices;i++) - { - if(CaptureDeviceList[i]) - { - lDeviceID = i; - break; - } + DeviceID = i; + break; } } if(i == NumCaptureDevices) return ALC_INVALID_VALUE; - pData = calloc(1, sizeof(*pData)); - if(!pData) + switch(Device->FmtChans) + { + case DevFmtMono: + case DevFmtStereo: + break; + + case DevFmtQuad: + case DevFmtX51: + case DevFmtX51Side: + case DevFmtX61: + case DevFmtX71: + return ALC_INVALID_ENUM; + } + + switch(Device->FmtType) + { + case DevFmtUByte: + case DevFmtShort: + case DevFmtInt: + case DevFmtFloat: + break; + + case DevFmtByte: + case DevFmtUShort: + case DevFmtUInt: + return ALC_INVALID_ENUM; + } + + data = calloc(1, sizeof(*data)); + if(!data) return ALC_OUT_OF_MEMORY; - pDevice->ExtraData = pData; + Device->ExtraData = data; - if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) || - (pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort)) - goto failure; + memset(&data->Format, 0, sizeof(WAVEFORMATEX)); + data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ? + WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM); + data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans); + data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8; + data->Format.nBlockAlign = data->Format.wBitsPerSample * + data->Format.nChannels / 8; + data->Format.nSamplesPerSec = Device->Frequency; + data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec * + data->Format.nBlockAlign; + data->Format.cbSize = 0; - memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX)); - wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM; - wfexCaptureFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans); - wfexCaptureFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8; - wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample * - wfexCaptureFormat.nChannels / 8; - wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency; - wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec * - wfexCaptureFormat.nBlockAlign; - wfexCaptureFormat.cbSize = 0; - - if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) + if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) { ERR("waveInOpen failed: %u\n", res); goto failure; } - pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if(pData->hWaveThreadEvent == NULL) + data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if(data->WaveThreadEvent == NULL) { ERR("CreateEvent failed: %lu\n", GetLastError()); goto failure; } - pData->Frequency = pDevice->Frequency; - // Allocate circular memory buffer for the captured audio - ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates; + CapturedDataSize = Device->UpdateSize*Device->NumUpdates; // Make sure circular buffer is at least 100ms in size - if(ulCapturedDataSize < (wfexCaptureFormat.nSamplesPerSec / 10)) - ulCapturedDataSize = wfexCaptureFormat.nSamplesPerSec / 10; + if(CapturedDataSize < (data->Format.nSamplesPerSec / 10)) + CapturedDataSize = data->Format.nSamplesPerSec / 10; - pData->pRing = CreateRingBuffer(wfexCaptureFormat.nBlockAlign, ulCapturedDataSize); - if(!pData->pRing) + data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize); + if(!data->Ring) goto failure; - pData->lWaveBuffersCommitted = 0; + data->WaveBuffersCommitted = 0; // Create 4 Buffers of 50ms each - lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20; - lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign); + BufferSize = data->Format.nAvgBytesPerSec / 20; + BufferSize -= (BufferSize % data->Format.nBlockAlign); - BufferData = calloc(4, lBufferSize); + BufferData = calloc(4, BufferSize); if(!BufferData) goto failure; for(i = 0;i < 4;i++) { - memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); - pData->WaveBuffer[i].dwBufferLength = lBufferSize; - pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : - (pData->WaveBuffer[i-1].lpData + - pData->WaveBuffer[i-1].dwBufferLength)); - pData->WaveBuffer[i].dwFlags = 0; - pData->WaveBuffer[i].dwLoops = 0; - waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - InterlockedIncrement(&pData->lWaveBuffersCommitted); + memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR)); + data->WaveBuffer[i].dwBufferLength = BufferSize; + data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : + (data->WaveBuffer[i-1].lpData + + data->WaveBuffer[i-1].dwBufferLength)); + data->WaveBuffer[i].dwFlags = 0; + data->WaveBuffer[i].dwLoops = 0; + waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); + waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); + InterlockedIncrement(&data->WaveBuffersCommitted); } - pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID); - if (pData->hWaveThread == NULL) + data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)Device, 0, &data->WaveThreadID); + if (data->WaveThread == NULL) goto failure; - pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]); + Device->DeviceName = strdup(CaptureDeviceList[DeviceID]); return ALC_NO_ERROR; failure: - if(pData->hWaveThread) - CloseHandle(pData->hWaveThread); + if(data->WaveThread) + CloseHandle(data->WaveThread); if(BufferData) { for(i = 0;i < 4;i++) - waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); + waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); free(BufferData); } - if(pData->pRing) - DestroyRingBuffer(pData->pRing); + if(data->Ring) + DestroyRingBuffer(data->Ring); - if(pData->hWaveThreadEvent) - CloseHandle(pData->hWaveThreadEvent); + if(data->WaveThreadEvent) + CloseHandle(data->WaveThreadEvent); - if(pData->hWaveHandle.In) - waveInClose(pData->hWaveHandle.In); + if(data->WaveHandle.In) + waveInClose(data->WaveHandle.In); - free(pData); - pDevice->ExtraData = NULL; + free(data); + Device->ExtraData = NULL; return ALC_INVALID_VALUE; } -static void WinMMCloseCapture(ALCdevice *pDevice) +static void WinMMCloseCapture(ALCdevice *Device) { - WinMMData *pData = (WinMMData*)pDevice->ExtraData; + WinMMData *data = (WinMMData*)Device->ExtraData; void *buffer = NULL; int i; - // Call waveOutReset to shutdown wave device - pData->bWaveShutdown = AL_TRUE; - waveInReset(pData->hWaveHandle.In); + /* Tell the processing thread to quit and wait for it to do so. */ + data->killNow = AL_TRUE; + PostThreadMessage(data->WaveThreadID, WM_QUIT, 0, 0); - // Wait for signal that Wave Thread has been destroyed - WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE); + WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE); - CloseHandle(pData->hWaveThread); - pData->hWaveThread = 0; + /* Make sure capture is stopped and all pending buffers are flushed. */ + waveInReset(data->WaveHandle.In); + + CloseHandle(data->WaveThread); + data->WaveThread = 0; // Release the wave buffers for(i = 0;i < 4;i++) { - waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR)); - if(i == 0) buffer = pData->WaveBuffer[i].lpData; - pData->WaveBuffer[i].lpData = NULL; + waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); + if(i == 0) buffer = data->WaveBuffer[i].lpData; + data->WaveBuffer[i].lpData = NULL; } free(buffer); - DestroyRingBuffer(pData->pRing); - pData->pRing = NULL; + DestroyRingBuffer(data->Ring); + data->Ring = NULL; // Close the Wave device - CloseHandle(pData->hWaveThreadEvent); - pData->hWaveThreadEvent = 0; + CloseHandle(data->WaveThreadEvent); + data->WaveThreadEvent = 0; - waveInClose(pData->hWaveHandle.In); - pData->hWaveHandle.In = 0; + waveInClose(data->WaveHandle.In); + data->WaveHandle.In = 0; - free(pData); - pDevice->ExtraData = NULL; + free(data); + Device->ExtraData = NULL; } -static void WinMMStartCapture(ALCdevice *pDevice) +static void WinMMStartCapture(ALCdevice *Device) { - WinMMData *pData = (WinMMData*)pDevice->ExtraData; - waveInStart(pData->hWaveHandle.In); + WinMMData *data = (WinMMData*)Device->ExtraData; + waveInStart(data->WaveHandle.In); } -static void WinMMStopCapture(ALCdevice *pDevice) +static void WinMMStopCapture(ALCdevice *Device) { - WinMMData *pData = (WinMMData*)pDevice->ExtraData; - waveInStop(pData->hWaveHandle.In); + WinMMData *data = (WinMMData*)Device->ExtraData; + waveInStop(data->WaveHandle.In); } -static ALCenum WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples) +static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples) { - WinMMData *pData = (WinMMData*)pDevice->ExtraData; - ReadRingBuffer(pData->pRing, pBuffer, lSamples); + WinMMData *data = (WinMMData*)Device->ExtraData; + ReadRingBuffer(data->Ring, Buffer, Samples); return ALC_NO_ERROR; } -static ALCuint WinMMAvailableSamples(ALCdevice *pDevice) +static ALCuint WinMMAvailableSamples(ALCdevice *Device) { - WinMMData *pData = (WinMMData*)pDevice->ExtraData; - return RingBufferSize(pData->pRing); + WinMMData *data = (WinMMData*)Device->ExtraData; + return RingBufferSize(data->Ring); } @@ -694,13 +705,15 @@ static const BackendFuncs WinMMFuncs = { WinMMOpenPlayback, WinMMClosePlayback, WinMMResetPlayback, + WinMMStartPlayback, WinMMStopPlayback, WinMMOpenCapture, WinMMCloseCapture, WinMMStartCapture, WinMMStopCapture, WinMMCaptureSamples, - WinMMAvailableSamples + WinMMAvailableSamples, + ALCdevice_GetLatencyDefault }; ALCboolean alcWinMMInit(BackendFuncs *FuncList) @@ -711,18 +724,18 @@ ALCboolean alcWinMMInit(BackendFuncs *FuncList) void alcWinMMDeinit() { - ALuint lLoop; + ALuint i; - for(lLoop = 0;lLoop < NumPlaybackDevices;lLoop++) - free(PlaybackDeviceList[lLoop]); + for(i = 0;i < NumPlaybackDevices;i++) + free(PlaybackDeviceList[i]); free(PlaybackDeviceList); PlaybackDeviceList = NULL; NumPlaybackDevices = 0; - for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++) - free(CaptureDeviceList[lLoop]); + for(i = 0;i < NumCaptureDevices;i++) + free(CaptureDeviceList[i]); free(CaptureDeviceList); CaptureDeviceList = NULL; @@ -735,20 +748,12 @@ void alcWinMMProbe(enum DevProbe type) switch(type) { - case DEVICE_PROBE: - ProbePlaybackDevices(); - if(NumPlaybackDevices > 0) - AppendDeviceList(woDefault); - break; - case ALL_DEVICE_PROBE: ProbePlaybackDevices(); - if(NumPlaybackDevices > 0) - AppendAllDeviceList(woDefault); for(i = 0;i < NumPlaybackDevices;i++) { if(PlaybackDeviceList[i]) - AppendAllDeviceList(PlaybackDeviceList[i]); + AppendAllDevicesList(PlaybackDeviceList[i]); } break; diff --git a/jni/openal-soft-android/Alc/bs2b.c b/jni/openal-soft-android/Alc/bs2b.c index 4cad23f5..0319f948 100644 --- a/jni/openal-soft-android/Alc/bs2b.c +++ b/jni/openal-soft-android/Alc/bs2b.c @@ -24,6 +24,7 @@ #include "config.h" #include +#include #include "bs2b.h" @@ -147,26 +148,9 @@ int bs2b_get_srate(struct bs2b *bs2b) void bs2b_clear(struct bs2b *bs2b) { - int loopv = sizeof(bs2b->last_sample); - - while (loopv) - { - ((char *)&bs2b->last_sample)[--loopv] = 0; - } + memset(&bs2b->last_sample, 0, sizeof(bs2b->last_sample)); } /* bs2b_clear */ -int bs2b_is_clear(struct bs2b *bs2b) -{ - int loopv = sizeof(bs2b->last_sample); - - while (loopv) - { - if (((char *)&bs2b->last_sample)[--loopv] != 0) - return 0; - } - return 1; -} /* bs2b_is_clear */ - void bs2b_cross_feed(struct bs2b *bs2b, float *sample) { /* Lowpass filter */ diff --git a/jni/openal-soft-android/Alc/compat.h b/jni/openal-soft-android/Alc/compat.h new file mode 100644 index 00000000..dbbcce28 --- /dev/null +++ b/jni/openal-soft-android/Alc/compat.h @@ -0,0 +1,65 @@ +#ifndef AL_COMPAT_H +#define AL_COMPAT_H + +#include "AL/al.h" + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include + +typedef DWORD althread_key_t; +int althread_key_create(althread_key_t *key, void (*callback)(void*)); +int althread_key_delete(althread_key_t key); +void *althread_getspecific(althread_key_t key); +int althread_setspecific(althread_key_t key, void *val); + +typedef LONG althread_once_t; +#define ALTHREAD_ONCE_INIT 0 +void althread_once(althread_once_t *once, void (*callback)(void)); + +inline int alsched_yield(void) +{ SwitchToThread(); return 0; } + +WCHAR *strdupW(const WCHAR *str); + +#define HAVE_DYNLOAD 1 + +#else + +#include + +typedef pthread_mutex_t CRITICAL_SECTION; +void InitializeCriticalSection(CRITICAL_SECTION *cs); +void DeleteCriticalSection(CRITICAL_SECTION *cs); +void EnterCriticalSection(CRITICAL_SECTION *cs); +void LeaveCriticalSection(CRITICAL_SECTION *cs); + +ALuint timeGetTime(void); +void Sleep(ALuint t); + +#define althread_key_t pthread_key_t +#define althread_key_create pthread_key_create +#define althread_key_delete pthread_key_delete +#define althread_getspecific pthread_getspecific +#define althread_setspecific pthread_setspecific + +#define althread_once_t pthread_once_t +#define ALTHREAD_ONCE_INIT PTHREAD_ONCE_INIT +#define althread_once pthread_once + +#define alsched_yield sched_yield + +#if defined(HAVE_DLFCN_H) +#define HAVE_DYNLOAD 1 +#endif + +#endif + +#ifdef HAVE_DYNLOAD +void *LoadLib(const char *name); +void CloseLib(void *handle); +void *GetSymbol(void *handle, const char *name); +#endif + +#endif /* AL_COMPAT_H */ diff --git a/jni/openal-soft-android/Alc/effects/autowah.c b/jni/openal-soft-android/Alc/effects/autowah.c new file mode 100644 index 00000000..9a45e233 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/autowah.c @@ -0,0 +1,275 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Anis A. Hireche, Nasca Octavian Paul + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include + +#include "config.h" +#include "alu.h" +#include "alFilter.h" +#include "alError.h" +#include "alMain.h" +#include "alAuxEffectSlot.h" + + +/* Auto-wah is simply a low-pass filter with a cutoff frequency that shifts up + * or down depending on the input signal, and a resonant peak at the cutoff. + * + * Currently, we assume a cutoff frequency range of 500hz (no amplitude) to + * 3khz (peak gain). Peak gain is assumed to be in normalized scale. + */ + +typedef struct ALautowahState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALfloat AttackRate; + ALfloat ReleaseRate; + ALfloat Resonance; + ALfloat PeakGain; + ALfloat GainCtrl; + ALfloat Frequency; + + /* Samples processing */ + ALfilterState LowPass; +} ALautowahState; + +static ALvoid ALautowahState_Destruct(ALautowahState *UNUSED(state)) +{ +} + +static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device) +{ + state->Frequency = device->Frequency; + return AL_TRUE; +} + +static ALvoid ALautowahState_update(ALautowahState *state, ALCdevice *device, const ALeffectslot *slot) +{ + ALfloat attackTime, releaseTime; + ALfloat gain; + + attackTime = slot->EffectProps.Autowah.AttackTime * state->Frequency; + releaseTime = slot->EffectProps.Autowah.ReleaseTime * state->Frequency; + + state->AttackRate = 1.0f / attackTime; + state->ReleaseRate = 1.0f / releaseTime; + state->PeakGain = slot->EffectProps.Autowah.PeakGain; + state->Resonance = slot->EffectProps.Autowah.Resonance; + + gain = sqrtf(1.0f / device->NumChan) * slot->Gain; + SetGains(device, gain, state->Gain); +} + +static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]) +{ + ALuint it, kt; + ALuint base; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + ALfloat gain = state->GainCtrl; + + for(it = 0;it < td;it++) + { + ALfloat smp = SamplesIn[it+base]; + ALfloat alpha, w0; + ALfloat amplitude; + ALfloat cutoff; + + /* Similar to compressor, we get the current amplitude of the + * incoming signal, and attack or release to reach it. */ + amplitude = fabs(smp); + if(amplitude > gain) + gain = minf(gain+state->AttackRate, amplitude); + else if(amplitude < gain) + gain = maxf(gain-state->ReleaseRate, amplitude); + gain = maxf(gain, GAIN_SILENCE_THRESHOLD); + + /* FIXME: What range does the filter cover? */ + cutoff = lerp(1000.0f, (ALfloat)LOWPASSFREQREF, minf(gain/state->PeakGain, 1.0f)); + + /* The code below is like calling ALfilterState_setParams with + * ALfilterType_LowPass. However, instead of passing a bandwidth, + * we use the resonance property for Q. This also inlines the call. + */ + w0 = F_2PI * cutoff / state->Frequency; + + /* FIXME: Resonance controls the resonant peak, or Q. How? Not sure + * that Q = resonance*0.1. */ + alpha = sinf(w0) / (2.0f * state->Resonance*0.1f); + state->LowPass.b[0] = (1.0f - cosf(w0)) / 2.0f; + state->LowPass.b[1] = 1.0f - cosf(w0); + state->LowPass.b[2] = (1.0f - cosf(w0)) / 2.0f; + state->LowPass.a[0] = 1.0f + alpha; + state->LowPass.a[1] = -2.0f * cosf(w0); + state->LowPass.a[2] = 1.0f - alpha; + + state->LowPass.b[2] /= state->LowPass.a[0]; + state->LowPass.b[1] /= state->LowPass.a[0]; + state->LowPass.b[0] /= state->LowPass.a[0]; + state->LowPass.a[2] /= state->LowPass.a[0]; + state->LowPass.a[1] /= state->LowPass.a[0]; + state->LowPass.a[0] /= state->LowPass.a[0]; + + temps[it] = ALfilterState_processSingle(&state->LowPass, smp); + } + state->GainCtrl = gain; + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > GAIN_SILENCE_THRESHOLD)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static void ALautowahState_Delete(ALautowahState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALautowahState); + + +typedef struct ALautowahStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALautowahStateFactory; + +static ALeffectState *ALautowahStateFactory_create(ALautowahStateFactory *UNUSED(factory)) +{ + ALautowahState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALautowahState, ALeffectState, state); + + state->AttackRate = 0.0f; + state->ReleaseRate = 0.0f; + state->Resonance = 0.0f; + state->PeakGain = 1.0f; + state->GainCtrl = 1.0f; + + ALfilterState_clear(&state->LowPass); + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALautowahStateFactory); + +ALeffectStateFactory *ALautowahStateFactory_getFactory(void) +{ + static ALautowahStateFactory AutowahFactory = { { GET_VTABLE2(ALautowahStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &AutowahFactory); +} + + +void ALautowah_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALautowah_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALautowah_setParami(effect, context, param, vals[0]); +} +void ALautowah_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_AUTOWAH_ATTACK_TIME: + if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Autowah.AttackTime = val; + break; + + case AL_AUTOWAH_RELEASE_TIME: + if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Autowah.ReleaseTime = val; + break; + + case AL_AUTOWAH_RESONANCE: + if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Autowah.Resonance = val; + break; + + case AL_AUTOWAH_PEAK_GAIN: + if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Autowah.PeakGain = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALautowah_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALautowah_setParamf(effect, context, param, vals[0]); +} + +void ALautowah_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALautowah_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALautowah_getParami(effect, context, param, vals); +} +void ALautowah_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_AUTOWAH_ATTACK_TIME: + *val = props->Autowah.AttackTime; + break; + + case AL_AUTOWAH_RELEASE_TIME: + *val = props->Autowah.ReleaseTime; + break; + + case AL_AUTOWAH_RESONANCE: + *val = props->Autowah.Resonance; + break; + + case AL_AUTOWAH_PEAK_GAIN: + *val = props->Autowah.PeakGain; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALautowah_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALautowah_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALautowah); diff --git a/jni/openal-soft-android/Alc/effects/chorus.c b/jni/openal-soft-android/Alc/effects/chorus.c new file mode 100644 index 00000000..4945faf2 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/chorus.c @@ -0,0 +1,381 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALchorusState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBuffer[2]; + ALuint BufferLength; + ALuint offset; + ALuint lfo_range; + ALfloat lfo_scale; + ALint lfo_disp; + + /* Gains for left and right sides */ + ALfloat Gain[2][MaxChannels]; + + /* effect parameters */ + ALint waveform; + ALint delay; + ALfloat depth; + ALfloat feedback; +} ALchorusState; + +static ALvoid ALchorusState_Destruct(ALchorusState *state) +{ + free(state->SampleBuffer[0]); + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; +} + +static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device) +{ + ALuint maxlen; + ALuint it; + + maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 3.0f * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2); + if(!temp) return AL_FALSE; + state->SampleBuffer[0] = temp; + state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen; + + state->BufferLength = maxlen; + } + + for(it = 0;it < state->BufferLength;it++) + { + state->SampleBuffer[0][it] = 0.0f; + state->SampleBuffer[1][it] = 0.0f; + } + + return AL_TRUE; +} + +static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat frequency = (ALfloat)Device->Frequency; + ALfloat rate; + ALint phase; + + state->waveform = Slot->EffectProps.Chorus.Waveform; + state->depth = Slot->EffectProps.Chorus.Depth; + state->feedback = Slot->EffectProps.Chorus.Feedback; + state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency); + + /* Gains for left and right sides */ + ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); + ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + + phase = Slot->EffectProps.Chorus.Phase; + rate = Slot->EffectProps.Chorus.Rate; + if(!(rate > 0.0f)) + { + state->lfo_scale = 0.0f; + state->lfo_range = 1; + state->lfo_disp = 0; + } + else + { + /* Calculate LFO coefficient */ + state->lfo_range = fastf2u(frequency/rate + 0.5f); + switch(state->waveform) + { + case AL_CHORUS_WAVEFORM_TRIANGLE: + state->lfo_scale = 4.0f / state->lfo_range; + break; + case AL_CHORUS_WAVEFORM_SINUSOID: + state->lfo_scale = F_2PI / state->lfo_range; + break; + } + + /* Calculate lfo phase displacement */ + state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f)); + } +} + +static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset, const ALchorusState *state) +{ + ALfloat lfo_value; + + lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + offset += state->lfo_disp; + lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset, const ALchorusState *state) +{ + ALfloat lfo_value; + + lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + offset += state->lfo_disp; + lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +#define DECL_TEMPLATE(Func) \ +static void Process##Func(ALchorusState *state, const ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, ALfloat (*restrict out)[2]) \ +{ \ + const ALuint bufmask = state->BufferLength-1; \ + ALfloat *restrict leftbuf = state->SampleBuffer[0]; \ + ALfloat *restrict rightbuf = state->SampleBuffer[1]; \ + ALuint offset = state->offset; \ + const ALfloat feedback = state->feedback; \ + ALuint it; \ + \ + for(it = 0;it < SamplesToDo;it++) \ + { \ + ALint delay_left, delay_right; \ + Func(&delay_left, &delay_right, offset, state); \ + \ + out[it][0] = leftbuf[(offset-delay_left)&bufmask]; \ + leftbuf[offset&bufmask] = (out[it][0]+SamplesIn[it]) * feedback; \ + \ + out[it][1] = rightbuf[(offset-delay_right)&bufmask]; \ + rightbuf[offset&bufmask] = (out[it][1]+SamplesIn[it]) * feedback; \ + \ + offset++; \ + } \ + state->offset = offset; \ +} + +DECL_TEMPLATE(Triangle) +DECL_TEMPLATE(Sinusoid) + +#undef DECL_TEMPLATE + +static ALvoid ALchorusState_process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + ALuint it, kt; + ALuint base; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64][2]; + ALuint td = minu(SamplesToDo-base, 64); + + if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) + ProcessTriangle(state, td, SamplesIn+base, temps); + else if(state->waveform == AL_CHORUS_WAVEFORM_SINUSOID) + ProcessSinusoid(state, td, SamplesIn+base, temps); + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[0][kt]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(it = 0;it < td;it++) + SamplesOut[kt][it+base] += temps[it][0] * gain; + } + + gain = state->Gain[1][kt]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(it = 0;it < td;it++) + SamplesOut[kt][it+base] += temps[it][1] * gain; + } + } + + base += td; + } +} + +static void ALchorusState_Delete(ALchorusState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); + + +typedef struct ALchorusStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALchorusStateFactory; + +static ALeffectState *ALchorusStateFactory_create(ALchorusStateFactory *UNUSED(factory)) +{ + ALchorusState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALchorusState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; + state->offset = 0; + state->lfo_range = 1; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory); + + +ALeffectStateFactory *ALchorusStateFactory_getFactory(void) +{ + static ALchorusStateFactory ChorusFactory = { { GET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); +} + + +void ALchorus_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_CHORUS_WAVEFORM: + if(!(val >= AL_CHORUS_MIN_WAVEFORM && val <= AL_CHORUS_MAX_WAVEFORM)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Waveform = val; + break; + + case AL_CHORUS_PHASE: + if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Phase = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALchorus_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALchorus_setParami(effect, context, param, vals[0]); +} +void ALchorus_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_CHORUS_RATE: + if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Rate = val; + break; + + case AL_CHORUS_DEPTH: + if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Depth = val; + break; + + case AL_CHORUS_FEEDBACK: + if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Feedback = val; + break; + + case AL_CHORUS_DELAY: + if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Chorus.Delay = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALchorus_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALchorus_setParamf(effect, context, param, vals[0]); +} + +void ALchorus_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_CHORUS_WAVEFORM: + *val = props->Chorus.Waveform; + break; + + case AL_CHORUS_PHASE: + *val = props->Chorus.Phase; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALchorus_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALchorus_getParami(effect, context, param, vals); +} +void ALchorus_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_CHORUS_RATE: + *val = props->Chorus.Rate; + break; + + case AL_CHORUS_DEPTH: + *val = props->Chorus.Depth; + break; + + case AL_CHORUS_FEEDBACK: + *val = props->Chorus.Feedback; + break; + + case AL_CHORUS_DELAY: + *val = props->Chorus.Delay; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALchorus_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALchorus_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALchorus); diff --git a/jni/openal-soft-android/Alc/effects/compressor.c b/jni/openal-soft-android/Alc/effects/compressor.c new file mode 100644 index 00000000..14c0ed10 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/compressor.c @@ -0,0 +1,223 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Anis A. Hireche + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include + +#include "config.h" +#include "alError.h" +#include "alMain.h" +#include "alAuxEffectSlot.h" +#include "alu.h" + + +typedef struct ALcompressorState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALboolean Enabled; + ALfloat AttackRate; + ALfloat ReleaseRate; + ALfloat GainCtrl; +} ALcompressorState; + +static ALvoid ALcompressorState_Destruct(ALcompressorState *UNUSED(state)) +{ +} + +static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdevice *device) +{ + const ALfloat attackTime = device->Frequency * 0.2f; /* 200ms Attack */ + const ALfloat releaseTime = device->Frequency * 0.4f; /* 400ms Release */ + + state->AttackRate = 1.0f / attackTime; + state->ReleaseRate = 1.0f / releaseTime; + + return AL_TRUE; +} + +static ALvoid ALcompressorState_update(ALcompressorState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat gain; + + state->Enabled = Slot->EffectProps.Compressor.OnOff; + + gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; + SetGains(Device, gain, state->Gain); +} + +static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]) +{ + ALuint it, kt; + ALuint base; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + + if(state->Enabled) + { + ALfloat output, smp, amplitude; + ALfloat gain = state->GainCtrl; + + for(it = 0;it < td;it++) + { + smp = SamplesIn[it+base]; + + amplitude = fabs(smp); + if(amplitude > gain) + gain = minf(gain+state->AttackRate, amplitude); + else if(amplitude < gain) + gain = maxf(gain-state->ReleaseRate, amplitude); + output = 1.0 / clampf(gain, 0.5f, 2.0f); + + temps[it] = smp * output; + } + + state->GainCtrl = gain; + } + else + { + ALfloat output, smp, amplitude; + ALfloat gain = state->GainCtrl; + + for(it = 0;it < td;it++) + { + smp = SamplesIn[it+base]; + + amplitude = 1.0f; + if(amplitude > gain) + gain = minf(gain+state->AttackRate, amplitude); + else if(amplitude < gain) + gain = maxf(gain-state->ReleaseRate, amplitude); + output = 1.0f / clampf(gain, 0.5f, 2.0f); + + temps[it] = smp * output; + } + + state->GainCtrl = gain; + } + + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > GAIN_SILENCE_THRESHOLD)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static void ALcompressorState_Delete(ALcompressorState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALcompressorState); + + +typedef struct ALcompressorStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALcompressorStateFactory; + +static ALeffectState *ALcompressorStateFactory_create(ALcompressorStateFactory *UNUSED(factory)) +{ + ALcompressorState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALcompressorState, ALeffectState, state); + + state->Enabled = AL_TRUE; + state->AttackRate = 0.0f; + state->ReleaseRate = 0.0f; + state->GainCtrl = 1.0f; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALcompressorStateFactory); + +ALeffectStateFactory *ALcompressorStateFactory_getFactory(void) +{ + static ALcompressorStateFactory CompressorFactory = { { GET_VTABLE2(ALcompressorStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &CompressorFactory); +} + + +void ALcompressor_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_COMPRESSOR_ONOFF: + if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Compressor.OnOff = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALcompressor_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALcompressor_setParami(effect, context, param, vals[0]); +} +void ALcompressor_setParamf(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALcompressor_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALcompressor_setParamf(effect, context, param, vals[0]); +} + +void ALcompressor_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_COMPRESSOR_ONOFF: + *val = props->Compressor.OnOff; + break; + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALcompressor_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALcompressor_getParami(effect, context, param, vals); +} +void ALcompressor_getParamf(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALcompressor_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALcompressor_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALcompressor); diff --git a/jni/openal-soft-android/Alc/effects/dedicated.c b/jni/openal-soft-android/Alc/effects/dedicated.c new file mode 100644 index 00000000..fe57c7d8 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/dedicated.c @@ -0,0 +1,167 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2011 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALdedicatedState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat gains[MaxChannels]; +} ALdedicatedState; + + +static ALvoid ALdedicatedState_Destruct(ALdedicatedState *UNUSED(state)) +{ +} + +static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *UNUSED(state), ALCdevice *UNUSED(device)) +{ + return AL_TRUE; +} + +static ALvoid ALdedicatedState_update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot) +{ + ALfloat Gain; + ALsizei s; + + Gain = Slot->Gain * Slot->EffectProps.Dedicated.Gain; + if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE) + ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains); + else if(Slot->EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + { + for(s = 0;s < MaxChannels;s++) + state->gains[s] = 0.0f; + state->gains[LFE] = Gain; + } +} + +static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALfloat *gains = state->gains; + ALuint i, c; + + for(c = 0;c < MaxChannels;c++) + { + if(!(gains[c] > GAIN_SILENCE_THRESHOLD)) + continue; + + for(i = 0;i < SamplesToDo;i++) + SamplesOut[c][i] = SamplesIn[i] * gains[c]; + } +} + +static void ALdedicatedState_Delete(ALdedicatedState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); + + +typedef struct ALdedicatedStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdedicatedStateFactory; + +ALeffectState *ALdedicatedStateFactory_create(ALdedicatedStateFactory *UNUSED(factory)) +{ + ALdedicatedState *state; + ALsizei s; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALdedicatedState, ALeffectState, state); + + for(s = 0;s < MaxChannels;s++) + state->gains[s] = 0.0f; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory); + + +ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) +{ + static ALdedicatedStateFactory DedicatedFactory = { { GET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); +} + + +void ALdedicated_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALdedicated_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALdedicated_setParami(effect, context, param, vals[0]); +} +void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_DEDICATED_GAIN: + if(!(val >= 0.0f && isfinite(val))) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Dedicated.Gain = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALdedicated_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALdedicated_setParamf(effect, context, param, vals[0]); +} + +void ALdedicated_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALdedicated_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALdedicated_getParami(effect, context, param, vals); +} +void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_DEDICATED_GAIN: + *val = props->Dedicated.Gain; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALdedicated_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALdedicated_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALdedicated); diff --git a/jni/openal-soft-android/Alc/effects/distortion.c b/jni/openal-soft-android/Alc/effects/distortion.c new file mode 100644 index 00000000..e39a8197 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/distortion.c @@ -0,0 +1,300 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALdistortionState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALfilterState lowpass; + ALfilterState bandpass; + ALfloat attenuation; + ALfloat edge_coeff; +} ALdistortionState; + +static ALvoid ALdistortionState_Destruct(ALdistortionState *UNUSED(state)) +{ +} + +static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *UNUSED(state), ALCdevice *UNUSED(device)) +{ + return AL_TRUE; +} + +static ALvoid ALdistortionState_update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat frequency = (ALfloat)Device->Frequency; + ALfloat bandwidth; + ALfloat cutoff; + ALfloat edge; + ALfloat gain; + + /* Store distorted signal attenuation settings */ + state->attenuation = Slot->EffectProps.Distortion.Gain; + + /* Store waveshaper edge settings */ + edge = sinf(Slot->EffectProps.Distortion.Edge * (F_PI_2)); + edge = minf(edge, 0.99f); + state->edge_coeff = 2.0f * edge / (1.0f-edge); + + /* Lowpass filter */ + cutoff = Slot->EffectProps.Distortion.LowpassCutoff; + /* Bandwidth value is constant in octaves */ + bandwidth = (cutoff / 2.0f) / (cutoff * 0.67f); + ALfilterState_setParams(&state->lowpass, ALfilterType_LowPass, 1.0f, + cutoff / (frequency*4.0f), bandwidth); + + /* Bandpass filter */ + cutoff = Slot->EffectProps.Distortion.EQCenter; + /* Convert bandwidth in Hz to octaves */ + bandwidth = Slot->EffectProps.Distortion.EQBandwidth / (cutoff * 0.67f); + ALfilterState_setParams(&state->bandpass, ALfilterType_BandPass, 1.0f, + cutoff / (frequency*4.0f), bandwidth); + + gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; + SetGains(Device, gain, state->Gain); +} + +static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALfloat fc = state->edge_coeff; + float oversample_buffer[64][4]; + ALuint base; + ALuint it; + ALuint ot; + ALuint kt; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + + /* Perform 4x oversampling to avoid aliasing. */ + /* Oversampling greatly improves distortion */ + /* quality and allows to implement lowpass and */ + /* bandpass filters using high frequencies, at */ + /* which classic IIR filters became unstable. */ + + /* Fill oversample buffer using zero stuffing */ + for(it = 0;it < td;it++) + { + oversample_buffer[it][0] = SamplesIn[it+base]; + oversample_buffer[it][1] = 0.0f; + oversample_buffer[it][2] = 0.0f; + oversample_buffer[it][3] = 0.0f; + } + + /* First step, do lowpass filtering of original signal, */ + /* additionally perform buffer interpolation and lowpass */ + /* cutoff for oversampling (which is fortunately first */ + /* step of distortion). So combine three operations into */ + /* the one. */ + for(it = 0;it < td;it++) + { + for(ot = 0;ot < 4;ot++) + { + ALfloat smp; + smp = ALfilterState_processSingle(&state->lowpass, oversample_buffer[it][ot]); + + /* Restore signal power by multiplying sample by amount of oversampling */ + oversample_buffer[it][ot] = smp * 4.0f; + } + } + + for(it = 0;it < td;it++) + { + /* Second step, do distortion using waveshaper function */ + /* to emulate signal processing during tube overdriving. */ + /* Three steps of waveshaping are intended to modify */ + /* waveform without boost/clipping/attenuation process. */ + for(ot = 0;ot < 4;ot++) + { + ALfloat smp = oversample_buffer[it][ot]; + + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + + /* Third step, do bandpass filtering of distorted signal */ + smp = ALfilterState_processSingle(&state->bandpass, smp); + oversample_buffer[it][ot] = smp; + } + + /* Fourth step, final, do attenuation and perform decimation, */ + /* store only one sample out of 4. */ + temps[it] = oversample_buffer[it][0] * state->attenuation; + } + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > GAIN_SILENCE_THRESHOLD)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static void ALdistortionState_Delete(ALdistortionState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); + + +typedef struct ALdistortionStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdistortionStateFactory; + +static ALeffectState *ALdistortionStateFactory_create(ALdistortionStateFactory *UNUSED(factory)) +{ + ALdistortionState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALdistortionState, ALeffectState, state); + + ALfilterState_clear(&state->lowpass); + ALfilterState_clear(&state->bandpass); + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory); + + +ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) +{ + static ALdistortionStateFactory DistortionFactory = { { GET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); +} + + +void ALdistortion_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALdistortion_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALdistortion_setParami(effect, context, param, vals[0]); +} +void ALdistortion_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_DISTORTION_EDGE: + if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Distortion.Edge = val; + break; + + case AL_DISTORTION_GAIN: + if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Distortion.Gain = val; + break; + + case AL_DISTORTION_LOWPASS_CUTOFF: + if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Distortion.LowpassCutoff = val; + break; + + case AL_DISTORTION_EQCENTER: + if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Distortion.EQCenter = val; + break; + + case AL_DISTORTION_EQBANDWIDTH: + if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Distortion.EQBandwidth = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALdistortion_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALdistortion_setParamf(effect, context, param, vals[0]); +} + +void ALdistortion_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALdistortion_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALdistortion_getParami(effect, context, param, vals); +} +void ALdistortion_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_DISTORTION_EDGE: + *val = props->Distortion.Edge; + break; + + case AL_DISTORTION_GAIN: + *val = props->Distortion.Gain; + break; + + case AL_DISTORTION_LOWPASS_CUTOFF: + *val = props->Distortion.LowpassCutoff; + break; + + case AL_DISTORTION_EQCENTER: + *val = props->Distortion.EQCenter; + break; + + case AL_DISTORTION_EQBANDWIDTH: + *val = props->Distortion.EQBandwidth; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALdistortion_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALdistortion_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALdistortion); diff --git a/jni/openal-soft-android/Alc/effects/echo.c b/jni/openal-soft-android/Alc/effects/echo.c new file mode 100644 index 00000000..7471c3dd --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/echo.c @@ -0,0 +1,296 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2009 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALechoState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBuffer; + ALuint BufferLength; + + // The echo is two tap. The delay is the number of samples from before the + // current offset + struct { + ALuint delay; + } Tap[2]; + ALuint Offset; + /* The panning gains for the two taps */ + ALfloat Gain[2][MaxChannels]; + + ALfloat FeedGain; + + ALfilterState Filter; +} ALechoState; + +static ALvoid ALechoState_Destruct(ALechoState *state) +{ + free(state->SampleBuffer); + state->SampleBuffer = NULL; +} + +static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device) +{ + ALuint maxlen, i; + + // Use the next power of 2 for the buffer length, so the tap offsets can be + // wrapped using a mask instead of a modulo + maxlen = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1; + maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat)); + if(!temp) return AL_FALSE; + state->SampleBuffer = temp; + state->BufferLength = maxlen; + } + for(i = 0;i < state->BufferLength;i++) + state->SampleBuffer[i] = 0.0f; + + return AL_TRUE; +} + +static ALvoid ALechoState_update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALuint frequency = Device->Frequency; + ALfloat lrpan, gain; + ALfloat dirGain; + + state->Tap[0].delay = fastf2u(Slot->EffectProps.Echo.Delay * frequency) + 1; + state->Tap[1].delay = fastf2u(Slot->EffectProps.Echo.LRDelay * frequency); + state->Tap[1].delay += state->Tap[0].delay; + + lrpan = Slot->EffectProps.Echo.Spread; + + state->FeedGain = Slot->EffectProps.Echo.Feedback; + + ALfilterState_setParams(&state->Filter, ALfilterType_HighShelf, + 1.0f - Slot->EffectProps.Echo.Damping, + (ALfloat)LOWPASSFREQREF/frequency, 0.0f); + + gain = Slot->Gain; + dirGain = fabsf(lrpan); + + /* First tap panning */ + ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]); + + /* Second tap panning */ + ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); +} + +static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALuint mask = state->BufferLength-1; + const ALuint tap1 = state->Tap[0].delay; + const ALuint tap2 = state->Tap[1].delay; + ALuint offset = state->Offset; + ALfloat smp; + ALuint base; + ALuint i, k; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64][2]; + ALuint td = minu(SamplesToDo-base, 64); + + for(i = 0;i < td;i++) + { + /* First tap */ + temps[i][0] = state->SampleBuffer[(offset-tap1) & mask]; + /* Second tap */ + temps[i][1] = state->SampleBuffer[(offset-tap2) & mask]; + + // Apply damping and feedback gain to the second tap, and mix in the + // new sample + smp = ALfilterState_processSingle(&state->Filter, temps[i][1]+SamplesIn[i+base]); + state->SampleBuffer[offset&mask] = smp * state->FeedGain; + offset++; + } + + for(k = 0;k < MaxChannels;k++) + { + ALfloat gain = state->Gain[0][k]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][0] * gain; + } + + gain = state->Gain[1][k]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][1] * gain; + } + } + + base += td; + } + + state->Offset = offset; +} + +static void ALechoState_Delete(ALechoState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); + + +typedef struct ALechoStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALechoStateFactory; + +ALeffectState *ALechoStateFactory_create(ALechoStateFactory *UNUSED(factory)) +{ + ALechoState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALechoState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer = NULL; + + state->Tap[0].delay = 0; + state->Tap[1].delay = 0; + state->Offset = 0; + + ALfilterState_clear(&state->Filter); + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory); + +ALeffectStateFactory *ALechoStateFactory_getFactory(void) +{ + static ALechoStateFactory EchoFactory = { { GET_VTABLE2(ALechoStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &EchoFactory); +} + + +void ALecho_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALecho_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALecho_setParami(effect, context, param, vals[0]); +} +void ALecho_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_ECHO_DELAY: + if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Echo.Delay = val; + break; + + case AL_ECHO_LRDELAY: + if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Echo.LRDelay = val; + break; + + case AL_ECHO_DAMPING: + if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Echo.Damping = val; + break; + + case AL_ECHO_FEEDBACK: + if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Echo.Feedback = val; + break; + + case AL_ECHO_SPREAD: + if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Echo.Spread = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALecho_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALecho_setParamf(effect, context, param, vals[0]); +} + +void ALecho_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALecho_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALecho_getParami(effect, context, param, vals); +} +void ALecho_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_ECHO_DELAY: + *val = props->Echo.Delay; + break; + + case AL_ECHO_LRDELAY: + *val = props->Echo.LRDelay; + break; + + case AL_ECHO_DAMPING: + *val = props->Echo.Damping; + break; + + case AL_ECHO_FEEDBACK: + *val = props->Echo.Feedback; + break; + + case AL_ECHO_SPREAD: + *val = props->Echo.Spread; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALecho_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALecho_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALecho); diff --git a/jni/openal-soft-android/Alc/effects/equalizer.c b/jni/openal-soft-android/Alc/effects/equalizer.c new file mode 100644 index 00000000..d5bd2caf --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/equalizer.c @@ -0,0 +1,337 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +/* The document "Effects Extension Guide.pdf" says that low and high * + * frequencies are cutoff frequencies. This is not fully correct, they * + * are corner frequencies for low and high shelf filters. If they were * + * just cutoff frequencies, there would be no need in cutoff frequency * + * gains, which are present. Documentation for "Creative Proteus X2" * + * software describes 4-band equalizer functionality in a much better * + * way. This equalizer seems to be a predecessor of OpenAL 4-band * + * equalizer. With low and high shelf filters we are able to cutoff * + * frequencies below and/or above corner frequencies using attenuation * + * gains (below 1.0) and amplify all low and/or high frequencies using * + * gains above 1.0. * + * * + * Low-shelf Low Mid Band High Mid Band High-shelf * + * corner center center corner * + * frequency frequency frequency frequency * + * 50Hz..800Hz 200Hz..3000Hz 1000Hz..8000Hz 4000Hz..16000Hz * + * * + * | | | | * + * | | | | * + * B -----+ /--+--\ /--+--\ +----- * + * O |\ | | | | | | /| * + * O | \ - | - - | - / | * + * S + | \ | | | | | | / | * + * T | | | | | | | | | | * + * ---------+---------------+------------------+---------------+-------- * + * C | | | | | | | | | | * + * U - | / | | | | | | \ | * + * T | / - | - - | - \ | * + * O |/ | | | | | | \| * + * F -----+ \--+--/ \--+--/ +----- * + * F | | | | * + * | | | | * + * * + * Gains vary from 0.126 up to 7.943, which means from -18dB attenuation * + * up to +18dB amplification. Band width varies from 0.01 up to 1.0 in * + * octaves for two mid bands. * + * * + * Implementation is based on the "Cookbook formulae for audio EQ biquad * + * filter coefficients" by Robert Bristow-Johnson * + * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ + +typedef struct ALequalizerState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALfilterState filter[4]; +} ALequalizerState; + +static ALvoid ALequalizerState_Destruct(ALequalizerState *UNUSED(state)) +{ +} + +static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *UNUSED(state), ALCdevice *UNUSED(device)) +{ + return AL_TRUE; +} + +static ALvoid ALequalizerState_update(ALequalizerState *state, ALCdevice *device, const ALeffectslot *slot) +{ + ALfloat frequency = (ALfloat)device->Frequency; + ALfloat gain = sqrtf(1.0f / device->NumChan) * slot->Gain; + + SetGains(device, gain, state->Gain); + + /* Calculate coefficients for the each type of filter */ + ALfilterState_setParams(&state->filter[0], ALfilterType_LowShelf, + sqrtf(slot->EffectProps.Equalizer.LowGain), + slot->EffectProps.Equalizer.LowCutoff/frequency, + 0.0f); + + ALfilterState_setParams(&state->filter[1], ALfilterType_Peaking, + sqrtf(slot->EffectProps.Equalizer.Mid1Gain), + slot->EffectProps.Equalizer.Mid1Center/frequency, + slot->EffectProps.Equalizer.Mid1Width); + + ALfilterState_setParams(&state->filter[2], ALfilterType_Peaking, + sqrtf(slot->EffectProps.Equalizer.Mid2Gain), + slot->EffectProps.Equalizer.Mid2Center/frequency, + slot->EffectProps.Equalizer.Mid2Width); + + ALfilterState_setParams(&state->filter[3], ALfilterType_HighShelf, + sqrtf(slot->EffectProps.Equalizer.HighGain), + slot->EffectProps.Equalizer.HighCutoff/frequency, + 0.0f); +} + +static ALvoid ALequalizerState_process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + ALuint base; + ALuint it; + ALuint kt; + ALuint ft; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + + for(it = 0;it < td;it++) + { + ALfloat smp = SamplesIn[base+it]; + + for(ft = 0;ft < 4;ft++) + smp = ALfilterState_processSingle(&state->filter[ft], smp); + + temps[it] = smp; + } + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > GAIN_SILENCE_THRESHOLD)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static void ALequalizerState_Delete(ALequalizerState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); + + +typedef struct ALequalizerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALequalizerStateFactory; + +ALeffectState *ALequalizerStateFactory_create(ALequalizerStateFactory *UNUSED(factory)) +{ + ALequalizerState *state; + int it; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALequalizerState, ALeffectState, state); + + /* Initialize sample history only on filter creation to avoid */ + /* sound clicks if filter settings were changed in runtime. */ + for(it = 0; it < 4; it++) + ALfilterState_clear(&state->filter[it]); + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory); + +ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) +{ + static ALequalizerStateFactory EqualizerFactory = { { GET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); +} + + +void ALequalizer_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALequalizer_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALequalizer_setParami(effect, context, param, vals[0]); +} +void ALequalizer_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EQUALIZER_LOW_GAIN: + if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.LowGain = val; + break; + + case AL_EQUALIZER_LOW_CUTOFF: + if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.LowCutoff = val; + break; + + case AL_EQUALIZER_MID1_GAIN: + if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid1Gain = val; + break; + + case AL_EQUALIZER_MID1_CENTER: + if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid1Center = val; + break; + + case AL_EQUALIZER_MID1_WIDTH: + if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid1Width = val; + break; + + case AL_EQUALIZER_MID2_GAIN: + if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid2Gain = val; + break; + + case AL_EQUALIZER_MID2_CENTER: + if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid2Center = val; + break; + + case AL_EQUALIZER_MID2_WIDTH: + if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.Mid2Width = val; + break; + + case AL_EQUALIZER_HIGH_GAIN: + if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.HighGain = val; + break; + + case AL_EQUALIZER_HIGH_CUTOFF: + if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Equalizer.HighCutoff = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALequalizer_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALequalizer_setParamf(effect, context, param, vals[0]); +} + +void ALequalizer_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +void ALequalizer_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALequalizer_getParami(effect, context, param, vals); +} +void ALequalizer_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EQUALIZER_LOW_GAIN: + *val = props->Equalizer.LowGain; + break; + + case AL_EQUALIZER_LOW_CUTOFF: + *val = props->Equalizer.LowCutoff; + break; + + case AL_EQUALIZER_MID1_GAIN: + *val = props->Equalizer.Mid1Gain; + break; + + case AL_EQUALIZER_MID1_CENTER: + *val = props->Equalizer.Mid1Center; + break; + + case AL_EQUALIZER_MID1_WIDTH: + *val = props->Equalizer.Mid1Width; + break; + + case AL_EQUALIZER_MID2_GAIN: + *val = props->Equalizer.Mid2Gain; + break; + + case AL_EQUALIZER_MID2_CENTER: + *val = props->Equalizer.Mid2Center; + break; + + case AL_EQUALIZER_MID2_WIDTH: + *val = props->Equalizer.Mid2Width; + break; + + case AL_EQUALIZER_HIGH_GAIN: + *val = props->Equalizer.HighGain; + break; + + case AL_EQUALIZER_HIGH_CUTOFF: + *val = props->Equalizer.HighCutoff; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALequalizer_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALequalizer_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALequalizer); diff --git a/jni/openal-soft-android/Alc/effects/flanger.c b/jni/openal-soft-android/Alc/effects/flanger.c new file mode 100644 index 00000000..a94cd365 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/flanger.c @@ -0,0 +1,380 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALflangerState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBuffer[2]; + ALuint BufferLength; + ALuint offset; + ALuint lfo_range; + ALfloat lfo_scale; + ALint lfo_disp; + + /* Gains for left and right sides */ + ALfloat Gain[2][MaxChannels]; + + /* effect parameters */ + ALint waveform; + ALint delay; + ALfloat depth; + ALfloat feedback; +} ALflangerState; + +static ALvoid ALflangerState_Destruct(ALflangerState *state) +{ + free(state->SampleBuffer[0]); + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; +} + +static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *Device) +{ + ALuint maxlen; + ALuint it; + + maxlen = fastf2u(AL_FLANGER_MAX_DELAY * 3.0f * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2); + if(!temp) return AL_FALSE; + state->SampleBuffer[0] = temp; + state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen; + + state->BufferLength = maxlen; + } + + for(it = 0;it < state->BufferLength;it++) + { + state->SampleBuffer[0][it] = 0.0f; + state->SampleBuffer[1][it] = 0.0f; + } + + return AL_TRUE; +} + +static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat frequency = (ALfloat)Device->Frequency; + ALfloat rate; + ALint phase; + + state->waveform = Slot->EffectProps.Flanger.Waveform; + state->depth = Slot->EffectProps.Flanger.Depth; + state->feedback = Slot->EffectProps.Flanger.Feedback; + state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency); + + /* Gains for left and right sides */ + ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); + ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + + phase = Slot->EffectProps.Flanger.Phase; + rate = Slot->EffectProps.Flanger.Rate; + if(!(rate > 0.0f)) + { + state->lfo_scale = 0.0f; + state->lfo_range = 1; + state->lfo_disp = 0; + } + else + { + /* Calculate LFO coefficient */ + state->lfo_range = fastf2u(frequency/rate + 0.5f); + switch(state->waveform) + { + case AL_FLANGER_WAVEFORM_TRIANGLE: + state->lfo_scale = 4.0f / state->lfo_range; + break; + case AL_FLANGER_WAVEFORM_SINUSOID: + state->lfo_scale = F_2PI / state->lfo_range; + break; + } + + /* Calculate lfo phase displacement */ + state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f)); + } +} + +static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset, const ALflangerState *state) +{ + ALfloat lfo_value; + + lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + offset += state->lfo_disp; + lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset, const ALflangerState *state) +{ + ALfloat lfo_value; + + lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + offset += state->lfo_disp; + lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +#define DECL_TEMPLATE(Func) \ +static void Process##Func(ALflangerState *state, const ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, ALfloat (*restrict out)[2]) \ +{ \ + const ALuint bufmask = state->BufferLength-1; \ + ALfloat *restrict leftbuf = state->SampleBuffer[0]; \ + ALfloat *restrict rightbuf = state->SampleBuffer[1]; \ + ALuint offset = state->offset; \ + const ALfloat feedback = state->feedback; \ + ALuint it; \ + \ + for(it = 0;it < SamplesToDo;it++) \ + { \ + ALint delay_left, delay_right; \ + Func(&delay_left, &delay_right, offset, state); \ + \ + out[it][0] = leftbuf[(offset-delay_left)&bufmask]; \ + leftbuf[offset&bufmask] = (out[it][0]+SamplesIn[it]) * feedback; \ + \ + out[it][1] = rightbuf[(offset-delay_right)&bufmask]; \ + rightbuf[offset&bufmask] = (out[it][1]+SamplesIn[it]) * feedback; \ + \ + offset++; \ + } \ + state->offset = offset; \ +} + +DECL_TEMPLATE(Triangle) +DECL_TEMPLATE(Sinusoid) + +#undef DECL_TEMPLATE + +static ALvoid ALflangerState_process(ALflangerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + ALuint it, kt; + ALuint base; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64][2]; + ALuint td = minu(SamplesToDo-base, 64); + + if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) + ProcessTriangle(state, td, SamplesIn+base, temps); + else if(state->waveform == AL_FLANGER_WAVEFORM_SINUSOID) + ProcessSinusoid(state, td, SamplesIn+base, temps); + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[0][kt]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(it = 0;it < td;it++) + SamplesOut[kt][it+base] += temps[it][0] * gain; + } + + gain = state->Gain[1][kt]; + if(gain > GAIN_SILENCE_THRESHOLD) + { + for(it = 0;it < td;it++) + SamplesOut[kt][it+base] += temps[it][1] * gain; + } + } + + base += td; + } +} + +static void ALflangerState_Delete(ALflangerState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); + + +typedef struct ALflangerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALflangerStateFactory; + +ALeffectState *ALflangerStateFactory_create(ALflangerStateFactory *UNUSED(factory)) +{ + ALflangerState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALflangerState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; + state->offset = 0; + state->lfo_range = 1; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory); + +ALeffectStateFactory *ALflangerStateFactory_getFactory(void) +{ + static ALflangerStateFactory FlangerFactory = { { GET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); +} + + +void ALflanger_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FLANGER_WAVEFORM: + if(!(val >= AL_FLANGER_MIN_WAVEFORM && val <= AL_FLANGER_MAX_WAVEFORM)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Waveform = val; + break; + + case AL_FLANGER_PHASE: + if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Phase = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALflanger_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALflanger_setParami(effect, context, param, vals[0]); +} +void ALflanger_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FLANGER_RATE: + if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Rate = val; + break; + + case AL_FLANGER_DEPTH: + if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Depth = val; + break; + + case AL_FLANGER_FEEDBACK: + if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Feedback = val; + break; + + case AL_FLANGER_DELAY: + if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Flanger.Delay = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALflanger_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALflanger_setParamf(effect, context, param, vals[0]); +} + +void ALflanger_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FLANGER_WAVEFORM: + *val = props->Flanger.Waveform; + break; + + case AL_FLANGER_PHASE: + *val = props->Flanger.Phase; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALflanger_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALflanger_getParami(effect, context, param, vals); +} +void ALflanger_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FLANGER_RATE: + *val = props->Flanger.Rate; + break; + + case AL_FLANGER_DEPTH: + *val = props->Flanger.Depth; + break; + + case AL_FLANGER_FEEDBACK: + *val = props->Flanger.Feedback; + break; + + case AL_FLANGER_DELAY: + *val = props->Flanger.Delay; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALflanger_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALflanger_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALflanger); diff --git a/jni/openal-soft-android/Alc/effects/modulator.c b/jni/openal-soft-android/Alc/effects/modulator.c new file mode 100644 index 00000000..17ca7e17 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/modulator.c @@ -0,0 +1,306 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2009 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALmodulatorState { + DERIVE_FROM_TYPE(ALeffectState); + + enum { + SINUSOID, + SAWTOOTH, + SQUARE + } Waveform; + + ALuint index; + ALuint step; + + ALfloat Gain[MaxChannels]; + + ALfilterState Filter; +} ALmodulatorState; + +#define WAVEFORM_FRACBITS 24 +#define WAVEFORM_FRACONE (1<> (WAVEFORM_FRACBITS - 1)) & 1); +} + +#define DECL_TEMPLATE(func) \ +static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALuint step = state->step; \ + ALuint index = state->index; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + ALuint i, k; \ + \ + for(i = 0;i < td;i++) \ + { \ + ALfloat samp; \ + samp = SamplesIn[base+i]; \ + samp = ALfilterState_processSingle(&state->Filter, samp); \ + \ + index += step; \ + index &= WAVEFORM_FRACMASK; \ + temps[i] = samp * func(index); \ + } \ + \ + for(k = 0;k < MaxChannels;k++) \ + { \ + ALfloat gain = state->Gain[k]; \ + if(!(gain > GAIN_SILENCE_THRESHOLD)) \ + continue; \ + \ + for(i = 0;i < td;i++) \ + SamplesOut[k][base+i] += gain * temps[i]; \ + } \ + \ + base += td; \ + } \ + state->index = index; \ +} + +DECL_TEMPLATE(Sin) +DECL_TEMPLATE(Saw) +DECL_TEMPLATE(Square) + +#undef DECL_TEMPLATE + + +static ALvoid ALmodulatorState_Destruct(ALmodulatorState *UNUSED(state)) +{ +} + +static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *UNUSED(state), ALCdevice *UNUSED(device)) +{ + return AL_TRUE; +} + +static ALvoid ALmodulatorState_update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat gain, cw, a; + + if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) + state->Waveform = SINUSOID; + else if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) + state->Waveform = SAWTOOTH; + else if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE) + state->Waveform = SQUARE; + + state->step = fastf2u(Slot->EffectProps.Modulator.Frequency*WAVEFORM_FRACONE / + Device->Frequency); + if(state->step == 0) state->step = 1; + + /* Custom filter coeffs, which match the old version instead of a low-shelf. */ + cw = cosf(F_2PI * Slot->EffectProps.Modulator.HighPassCutoff / Device->Frequency); + a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f); + + state->Filter.b[0] = a; + state->Filter.b[1] = -a; + state->Filter.b[2] = 0.0f; + state->Filter.a[0] = 1.0f; + state->Filter.a[1] = -a; + state->Filter.a[2] = 0.0f; + + gain = sqrtf(1.0f/Device->NumChan) * Slot->Gain; + SetGains(Device, gain, state->Gain); +} + +static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + switch(state->Waveform) + { + case SINUSOID: + ProcessSin(state, SamplesToDo, SamplesIn, SamplesOut); + break; + + case SAWTOOTH: + ProcessSaw(state, SamplesToDo, SamplesIn, SamplesOut); + break; + + case SQUARE: + ProcessSquare(state, SamplesToDo, SamplesIn, SamplesOut); + break; + } +} + +static void ALmodulatorState_Delete(ALmodulatorState *state) +{ + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); + + +typedef struct ALmodulatorStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALmodulatorStateFactory; + +static ALeffectState *ALmodulatorStateFactory_create(ALmodulatorStateFactory *UNUSED(factory)) +{ + ALmodulatorState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALmodulatorState, ALeffectState, state); + + state->index = 0; + state->step = 1; + + ALfilterState_clear(&state->Filter); + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory); + +ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void) +{ + static ALmodulatorStateFactory ModulatorFactory = { { GET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); +} + + +void ALmodulator_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Modulator.Frequency = val; + break; + + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Modulator.HighPassCutoff = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALmodulator_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALmodulator_setParamf(effect, context, param, vals[0]); +} +void ALmodulator_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + ALmodulator_setParamf(effect, context, param, (ALfloat)val); + break; + + case AL_RING_MODULATOR_WAVEFORM: + if(!(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Modulator.Waveform = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALmodulator_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALmodulator_setParami(effect, context, param, vals[0]); +} + +void ALmodulator_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = (ALint)props->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = (ALint)props->Modulator.HighPassCutoff; + break; + case AL_RING_MODULATOR_WAVEFORM: + *val = props->Modulator.Waveform; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALmodulator_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALmodulator_getParami(effect, context, param, vals); +} +void ALmodulator_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = props->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = props->Modulator.HighPassCutoff; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALmodulator_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALmodulator_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALmodulator); diff --git a/jni/openal-soft-android/Alc/effects/null.c b/jni/openal-soft-android/Alc/effects/null.c new file mode 100644 index 00000000..816a2525 --- /dev/null +++ b/jni/openal-soft-android/Alc/effects/null.c @@ -0,0 +1,155 @@ +#include "config.h" + +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "alMain.h" +#include "alAuxEffectSlot.h" +#include "alError.h" + + +typedef struct ALnullState { + DERIVE_FROM_TYPE(ALeffectState); +} ALnullState; + + +/* This destructs (not free!) the effect state. It's called only when the + * effect slot is no longer used. + */ +static ALvoid ALnullState_Destruct(ALnullState* UNUSED(state)) +{ +} + +/* This updates the device-dependant effect state. This is called on + * initialization and any time the device parameters (eg. playback frequency, + * format) have been changed. + */ +static ALboolean ALnullState_deviceUpdate(ALnullState* UNUSED(state), ALCdevice* UNUSED(device)) +{ + return AL_TRUE; +} + +/* This updates the effect state. This is called any time the effect is + * (re)loaded into a slot. + */ +static ALvoid ALnullState_update(ALnullState* UNUSED(state), ALCdevice* UNUSED(device), const ALeffectslot* UNUSED(slot)) +{ +} + +/* This processes the effect state, for the given number of samples from the + * input to the output buffer. The result should be added to the output buffer, + * not replace it. + */ +static ALvoid ALnullState_process(ALnullState* UNUSED(state), ALuint UNUSED(samplesToDo), const ALfloat *restrict UNUSED(samplesIn), ALfloat (*restrict samplesOut)[BUFFERSIZE]) +{ + /* NOTE: Couldn't use the UNUSED macro on samplesOut due to the way GCC's + * __attribute__ declaration interacts with the parenthesis. */ + (void)samplesOut; +} + +/* This frees the memory used by the object, after it has been destructed. */ +static void ALnullState_Delete(ALnullState *state) +{ + free(state); +} + +/* Define the forwards and the ALeffectState vtable for this type. */ +DEFINE_ALEFFECTSTATE_VTABLE(ALnullState); + + +typedef struct ALnullStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALnullStateFactory; + +/* Creates ALeffectState objects of the appropriate type. */ +ALeffectState *ALnullStateFactory_create(ALnullStateFactory *UNUSED(factory)) +{ + ALnullState *state; + + state = calloc(1, sizeof(*state)); + if(!state) return NULL; + /* Set vtables for inherited types. */ + SET_VTABLE2(ALnullState, ALeffectState, state); + + return STATIC_CAST(ALeffectState, state); +} + +/* Define the ALeffectStateFactory vtable for this type. */ +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALnullStateFactory); + +ALeffectStateFactory *ALnullStateFactory_getFactory(void) +{ + static ALnullStateFactory NullFactory = { { GET_VTABLE2(ALnullStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &NullFactory); +} + + +void ALnull_setParami(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_setParamiv(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, const ALint* UNUSED(vals)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_setParamf(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_setParamfv(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, const ALfloat* UNUSED(vals)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +void ALnull_getParami(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(val)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_getParamiv(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(vals)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_getParamf(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(val)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALnull_getParamfv(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(vals)) +{ + switch(param) + { + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +DEFINE_ALEFFECT_VTABLE(ALnull); diff --git a/jni/openal-soft-android/Alc/alcReverb.c b/jni/openal-soft-android/Alc/effects/reverb.c similarity index 54% rename from jni/openal-soft-android/Alc/alcReverb.c rename to jni/openal-soft-android/Alc/effects/reverb.c index f194d7ab..75ec76e3 100644 --- a/jni/openal-soft-android/Alc/alcReverb.c +++ b/jni/openal-soft-android/Alc/effects/reverb.c @@ -24,13 +24,13 @@ #include #include -#include "AL/al.h" -#include "AL/alc.h" #include "alMain.h" +#include "alu.h" #include "alAuxEffectSlot.h" #include "alEffect.h" +#include "alFilter.h" #include "alError.h" -#include "alu.h" + typedef struct DelayLine { @@ -40,18 +40,19 @@ typedef struct DelayLine ALfloat *Line; } DelayLine; -typedef struct ALverbState { - // Must be first in all effects! - ALeffectState state; +typedef struct ALreverbState { + DERIVE_FROM_TYPE(ALeffectState); + + ALboolean IsEax; // All delay lines are allocated as a single buffer to reduce memory // fragmentation and management code. ALfloat *SampleBuffer; ALuint TotalSamples; - // Master effect low-pass filter (2 chained 1-pole filters). - FILTER LpFilter; - ALfloat LpHistory[2]; + // Master effect filters + ALfilterState LpFilter; + ALfilterState HpFilter; // EAX only struct { // Modulator delay line. @@ -85,7 +86,7 @@ typedef struct ALverbState { // The gain for each output channel based on 3D panning (only for the // EAX path). - ALfloat PanGain[MAXCHANNELS]; + ALfloat PanGain[MaxChannels]; } Early; // Decorrelator delay line. @@ -124,7 +125,7 @@ typedef struct ALverbState { // The gain for each output channel based on 3D panning (only for the // EAX path). - ALfloat PanGain[MAXCHANNELS]; + ALfloat PanGain[MaxChannels]; } Late; struct { @@ -157,7 +158,11 @@ typedef struct ALverbState { // The gain for each output channel (non-EAX path only; aliased from // Late.PanGain) ALfloat *Gain; -} ALverbState; + + /* Temporary storage used when processing, before deinterlacing. */ + ALfloat ReverbSamples[BUFFERSIZE][4]; + ALfloat EarlySamples[BUFFERSIZE][4]; +} ALreverbState; /* This is a user config option for modifying the overall output of the reverb * effect. @@ -219,24 +224,24 @@ static const ALfloat LATE_LINE_MULTIPLIER = 4.0f; // Basic delay line input/output routines. -static __inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset) +static inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset) { return Delay->Line[offset&Delay->Mask]; } -static __inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in) +static inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in) { Delay->Line[offset&Delay->Mask] = in; } // Attenuated delay line output routine. -static __inline ALfloat AttenuatedDelayLineOut(DelayLine *Delay, ALuint offset, ALfloat coeff) +static inline ALfloat AttenuatedDelayLineOut(DelayLine *Delay, ALuint offset, ALfloat coeff) { return coeff * Delay->Line[offset&Delay->Mask]; } // Basic attenuated all-pass input/output routine. -static __inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint inOffset, ALfloat in, ALfloat feedCoeff, ALfloat coeff) +static inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint inOffset, ALfloat in, ALfloat feedCoeff, ALfloat coeff) { ALfloat out, feed; @@ -252,7 +257,7 @@ static __inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint // Given an input sample, this function produces modulation for the late // reverb. -static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in) +static inline ALfloat EAXModulation(ALreverbState *State, ALfloat in) { ALfloat sinus, frac; ALuint offset; @@ -261,7 +266,7 @@ static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in) // Calculate the sinus rythm (dependent on modulation time and the // sampling rate). The center of the sinus is moved to reduce the delay // of the effect when the time or depth are low. - sinus = 1.0f - aluCos(F_PI*2.0f * State->Mod.Index / State->Mod.Range); + sinus = 1.0f - cosf(F_2PI * State->Mod.Index / State->Mod.Range); // The depth determines the range over which to read the input samples // from, so it must be filtered to reduce the distortion caused by even @@ -289,7 +294,7 @@ static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in) } // Delay line output routine for early reflections. -static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index) +static inline ALfloat EarlyDelayLineOut(ALreverbState *State, ALuint index) { return AttenuatedDelayLineOut(&State->Early.Delay[index], State->Offset - State->Early.Offset[index], @@ -298,7 +303,7 @@ static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index) // Given an input sample, this function produces four-channel output for the // early reflections. -static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *out) +static inline ALvoid EarlyReflection(ALreverbState *State, ALfloat in, ALfloat *restrict out) { ALfloat d[4], v, f[4]; @@ -343,7 +348,7 @@ static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat * } // All-pass input/output routine for late reverb. -static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALfloat in) +static inline ALfloat LateAllPassInOut(ALreverbState *State, ALuint index, ALfloat in) { return AllpassInOut(&State->Late.ApDelay[index], State->Offset - State->Late.ApOffset[index], @@ -352,7 +357,7 @@ static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALflo } // Delay line output routine for late reverb. -static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index) +static inline ALfloat LateDelayLineOut(ALreverbState *State, ALuint index) { return AttenuatedDelayLineOut(&State->Late.Delay[index], State->Offset - State->Late.Offset[index], @@ -360,7 +365,7 @@ static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index) } // Low-pass filter input/output routine for late reverb. -static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALfloat in) +static inline ALfloat LateLowPassInOut(ALreverbState *State, ALuint index, ALfloat in) { in = lerp(in, State->Late.LpSample[index], State->Late.LpCoeff[index]); State->Late.LpSample[index] = in; @@ -369,7 +374,7 @@ static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALflo // Given four decorrelated input samples, this function produces four-channel // output for the late reverb. -static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out) +static inline ALvoid LateReverb(ALreverbState *State, const ALfloat *restrict in, ALfloat *restrict out) { ALfloat d[4], f[4]; @@ -440,7 +445,7 @@ static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out) // Given an input sample, this function mixes echo into the four-channel late // reverb. -static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late) +static inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *restrict late) { ALfloat out, feed; @@ -474,19 +479,19 @@ static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late) // Perform the non-EAX reverb pass on a given input sample, resulting in // four-channel output. -static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late) +static inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *restrict out) { - ALfloat feed, taps[4]; + ALfloat feed, late[4], taps[4]; - // Low-pass filter the incoming sample. - in = lpFilter2P(&State->LpFilter, 0, in); + // Filter the incoming sample. + in = ALfilterState_processSingle(&State->LpFilter, in); // Feed the initial delay line. DelayLineIn(&State->Delay, State->Offset, in); // Calculate the early reflection from the first delay tap. in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]); - EarlyReflection(State, in, early); + EarlyReflection(State, in, out); // Feed the decorrelator from the energy-attenuated output of the second // delay tap. @@ -501,18 +506,25 @@ static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]); LateReverb(State, taps, late); + // Mix early reflections and late reverb. + out[0] += late[0]; + out[1] += late[1]; + out[2] += late[2]; + out[3] += late[3]; + // Step all delays forward one sample. State->Offset++; } // Perform the EAX reverb pass on a given input sample, resulting in four- // channel output. -static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late) +static inline ALvoid EAXVerbPass(ALreverbState *State, ALfloat in, ALfloat *restrict early, ALfloat *restrict late) { ALfloat feed, taps[4]; // Low-pass filter the incoming sample. - in = lpFilter2P(&State->LpFilter, 0, in); + in = ALfilterState_processSingle(&State->LpFilter, in); + in = ALfilterState_processSingle(&State->HpFilter, in); // Perform any modulation on the input. in = EAXModulation(State, in); @@ -544,85 +556,66 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *earl State->Offset++; } -// This processes the reverb state, given the input samples and an output -// buffer. -static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) +static ALvoid ALreverbState_processStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { - ALverbState *State = (ALverbState*)effect; - ALuint index; - ALfloat early[4], late[4], out[4]; - const ALfloat *panGain = State->Gain; + ALfloat (*restrict out)[4] = State->ReverbSamples; + ALuint index, c; + /* Process reverb for these samples. */ for(index = 0;index < SamplesToDo;index++) + VerbPass(State, SamplesIn[index], out[index]); + + for(c = 0;c < MaxChannels;c++) { - // Process reverb for this sample. - VerbPass(State, SamplesIn[index], early, late); + ALfloat gain = State->Gain[c]; + if(!(gain > GAIN_SILENCE_THRESHOLD)) + continue; - // Mix early reflections and late reverb. - out[0] = (early[0] + late[0]); - out[1] = (early[1] + late[1]); - out[2] = (early[2] + late[2]); - out[3] = (early[3] + late[3]); - - // Output the results. - SamplesOut[index][FRONT_LEFT] += panGain[FRONT_LEFT] * out[0]; - SamplesOut[index][FRONT_RIGHT] += panGain[FRONT_RIGHT] * out[1]; - SamplesOut[index][FRONT_CENTER] += panGain[FRONT_CENTER] * out[3]; - SamplesOut[index][SIDE_LEFT] += panGain[SIDE_LEFT] * out[0]; - SamplesOut[index][SIDE_RIGHT] += panGain[SIDE_RIGHT] * out[1]; - SamplesOut[index][BACK_LEFT] += panGain[BACK_LEFT] * out[0]; - SamplesOut[index][BACK_RIGHT] += panGain[BACK_RIGHT] * out[1]; - SamplesOut[index][BACK_CENTER] += panGain[BACK_CENTER] * out[2]; + for(index = 0;index < SamplesToDo;index++) + SamplesOut[c][index] += gain * out[index][c&3]; } } -// This processes the EAX reverb state, given the input samples and an output -// buffer. -static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) +static ALvoid ALreverbState_processEax(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { - ALverbState *State = (ALverbState*)effect; - ALuint index; - ALfloat early[4], late[4]; + ALfloat (*restrict early)[4] = State->EarlySamples; + ALfloat (*restrict late)[4] = State->ReverbSamples; + ALuint index, c; + /* Process reverb for these samples. */ for(index = 0;index < SamplesToDo;index++) - { - // Process reverb for this sample. - EAXVerbPass(State, SamplesIn[index], early, late); + EAXVerbPass(State, SamplesIn[index], early[index], late[index]); - // Unfortunately, while the number and configuration of gains for - // panning adjust according to MAXCHANNELS, the output from the - // reverb engine is not so scalable. - SamplesOut[index][FRONT_LEFT] += - (State->Early.PanGain[FRONT_LEFT]*early[0] + - State->Late.PanGain[FRONT_LEFT]*late[0]); - SamplesOut[index][FRONT_RIGHT] += - (State->Early.PanGain[FRONT_RIGHT]*early[1] + - State->Late.PanGain[FRONT_RIGHT]*late[1]); - SamplesOut[index][FRONT_CENTER] += - (State->Early.PanGain[FRONT_CENTER]*early[3] + - State->Late.PanGain[FRONT_CENTER]*late[3]); - SamplesOut[index][SIDE_LEFT] += - (State->Early.PanGain[SIDE_LEFT]*early[0] + - State->Late.PanGain[SIDE_LEFT]*late[0]); - SamplesOut[index][SIDE_RIGHT] += - (State->Early.PanGain[SIDE_RIGHT]*early[1] + - State->Late.PanGain[SIDE_RIGHT]*late[1]); - SamplesOut[index][BACK_LEFT] += - (State->Early.PanGain[BACK_LEFT]*early[0] + - State->Late.PanGain[BACK_LEFT]*late[0]); - SamplesOut[index][BACK_RIGHT] += - (State->Early.PanGain[BACK_RIGHT]*early[1] + - State->Late.PanGain[BACK_RIGHT]*late[1]); - SamplesOut[index][BACK_CENTER] += - (State->Early.PanGain[BACK_CENTER]*early[2] + - State->Late.PanGain[BACK_CENTER]*late[2]); + for(c = 0;c < MaxChannels;c++) + { + ALfloat earlyGain, lateGain; + + earlyGain = State->Early.PanGain[c]; + if(earlyGain > GAIN_SILENCE_THRESHOLD) + { + for(index = 0;index < SamplesToDo;index++) + SamplesOut[c][index] += earlyGain*early[index][c&3]; + } + lateGain = State->Late.PanGain[c]; + if(lateGain > GAIN_SILENCE_THRESHOLD) + { + for(index = 0;index < SamplesToDo;index++) + SamplesOut[c][index] += lateGain*late[index][c&3]; + } } } +static ALvoid ALreverbState_process(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + if(State->IsEax) + ALreverbState_processEax(State, SamplesToDo, SamplesIn, SamplesOut); + else + ALreverbState_processStandard(State, SamplesToDo, SamplesIn, SamplesOut); +} // Given the allocated sample buffer, this function updates each delay line // offset. -static __inline ALvoid RealizeLineOffset(ALfloat * sampleBuffer, DelayLine *Delay) +static inline ALvoid RealizeLineOffset(ALfloat *sampleBuffer, DelayLine *Delay) { Delay->Line = &sampleBuffer[(ALintptrEXT)Delay->Line]; } @@ -646,7 +639,7 @@ static ALuint CalcLineLength(ALfloat length, ALintptrEXT offset, ALuint frequenc * for all lines given the sample rate (frequency). If an allocation failure * occurs, it returns AL_FALSE. */ -static ALboolean AllocLines(ALuint frequency, ALverbState *State) +static ALboolean AllocLines(ALuint frequency, ALreverbState *State) { ALuint totalSamples, index; ALfloat length; @@ -734,12 +727,8 @@ static ALboolean AllocLines(ALuint frequency, ALverbState *State) return AL_TRUE; } -// This updates the device-dependant EAX reverb state. This is called on -// initialization and any time the device parameters (eg. playback frequency, -// format) have been changed. -static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device) { - ALverbState *State = (ALverbState*)effect; ALuint frequency = Device->Frequency, index; // Allocate the delay lines. @@ -750,8 +739,8 @@ static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) // is calculated given the current sample rate. This ensures that the // resulting filter response over time is consistent across all sample // rates. - State->Mod.Coeff = aluPow(MODULATION_FILTER_COEFF, - MODULATION_FILTER_CONST / frequency); + State->Mod.Coeff = powf(MODULATION_FILTER_COEFF, + MODULATION_FILTER_CONST / frequency); // The early reflection and late all-pass filter line lengths are static, // so their offsets only need to be calculated once. @@ -772,28 +761,21 @@ static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) // Calculate a decay coefficient given the length of each cycle and the time // until the decay reaches -60 dB. -static __inline ALfloat CalcDecayCoeff(ALfloat length, ALfloat decayTime) +static inline ALfloat CalcDecayCoeff(ALfloat length, ALfloat decayTime) { - return aluPow(0.001f/*-60 dB*/, length/decayTime); + return powf(0.001f/*-60 dB*/, length/decayTime); } // Calculate a decay length from a coefficient and the time until the decay // reaches -60 dB. -static __inline ALfloat CalcDecayLength(ALfloat coeff, ALfloat decayTime) +static inline ALfloat CalcDecayLength(ALfloat coeff, ALfloat decayTime) { - return aluLog10(coeff) * decayTime / aluLog10(0.001f)/*-60 dB*/; -} - -// Calculate the high frequency parameter for the I3DL2 coefficient -// calculation. -static __inline ALfloat CalcI3DL2HFreq(ALfloat hfRef, ALuint frequency) -{ - return aluCos(F_PI*2.0f * hfRef / frequency); + return log10f(coeff) * decayTime / log10f(0.001f)/*-60 dB*/; } // Calculate an attenuation to be applied to the input of any echo models to // compensate for modal density and decay time. -static __inline ALfloat CalcDensityGain(ALfloat a) +static inline ALfloat CalcDensityGain(ALfloat a) { /* The energy of a signal can be obtained by finding the area under the * squared signal. This takes the form of Sum(x_n^2), where x is the @@ -808,22 +790,22 @@ static __inline ALfloat CalcDensityGain(ALfloat a) * calculated by inverting the square root of this approximation, * yielding: 1 / sqrt(1 / (1 - a^2)), simplified to: sqrt(1 - a^2). */ - return aluSqrt(1.0f - (a * a)); + return sqrtf(1.0f - (a * a)); } // Calculate the mixing matrix coefficients given a diffusion factor. -static __inline ALvoid CalcMatrixCoeffs(ALfloat diffusion, ALfloat *x, ALfloat *y) +static inline ALvoid CalcMatrixCoeffs(ALfloat diffusion, ALfloat *x, ALfloat *y) { ALfloat n, t; // The matrix is of order 4, so n is sqrt (4 - 1). - n = aluSqrt(3.0f); - t = diffusion * aluAtan(n); + n = sqrtf(3.0f); + t = diffusion * atanf(n); // Calculate the first mixing matrix coefficient. - *x = aluCos(t); + *x = cosf(t); // Calculate the second mixing matrix coefficient. - *y = aluSin(t) / n; + *y = sinf(t) / n; } // Calculate the limited HF ratio for use with the late reverb low-pass @@ -847,7 +829,7 @@ static ALfloat CalcLimitedHfRatio(ALfloat hfRatio, ALfloat airAbsorptionGainHF, // Calculate the coefficient for a HF (and eventually LF) decay damping // filter. -static __inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloat decayTime, ALfloat decayCoeff, ALfloat cw) +static inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloat decayTime, ALfloat decayCoeff, ALfloat cw) { ALfloat coeff, g; @@ -862,7 +844,14 @@ static __inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloa // Damping is done with a 1-pole filter, so g needs to be squared. g *= g; - coeff = lpCoeffCalc(g, cw); + if(g < 0.9999f) /* 1-epsilon */ + { + /* Be careful with gains < 0.001, as that causes the coefficient + * head towards 1, which will flatten the signal. */ + g = maxf(g, 0.001f); + coeff = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) / + (1 - g); + } // Very low decay times will produce minimal output, so apply an // upper bound to the coefficient. @@ -874,7 +863,7 @@ static __inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloa // Update the EAX modulation index, range, and depth. Keep in mind that this // kind of vibrato is additive and not multiplicative as one may expect. The // downswing will sound stronger than the upswing. -static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequency, ALverbState *State) +static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequency, ALreverbState *State) { ALuint range; @@ -904,7 +893,7 @@ static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequenc } // Update the offsets for the initial effect delay line. -static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint frequency, ALverbState *State) +static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint frequency, ALreverbState *State) { // Calculate the initial delay taps. State->DelayTap[0] = fastf2u(earlyDelay * frequency); @@ -912,7 +901,7 @@ static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint freq } // Update the early reflections gain and line coefficients. -static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat lateDelay, ALverbState *State) +static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat lateDelay, ALreverbState *State) { ALuint index; @@ -929,7 +918,7 @@ static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat la } // Update the offsets for the decorrelator line. -static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALverbState *State) +static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALreverbState *State) { ALuint index; ALfloat length; @@ -943,14 +932,14 @@ static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALverbState */ for(index = 0;index < 3;index++) { - length = (DECO_FRACTION * aluPow(DECO_MULTIPLIER, (ALfloat)index)) * + length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (ALfloat)index)) * LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER)); State->DecoTap[index] = fastf2u(length * frequency); } } // Update the late reverb gains, line lengths, and line coefficients. -static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix, ALfloat density, ALfloat decayTime, ALfloat diffusion, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALverbState *State) +static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix, ALfloat density, ALfloat decayTime, ALfloat diffusion, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State) { ALfloat length; ALuint index; @@ -977,7 +966,7 @@ static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix decayTime)); // Calculate the all-pass feed-back and feed-forward coefficient. - State->Late.ApFeedCoeff = 0.5f * aluPow(diffusion, 2.0f); + State->Late.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f); for(index = 0;index < 4;index++) { @@ -1008,7 +997,7 @@ static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix // Update the echo gain, line offset, line coefficients, and mixing // coefficients. -static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoTime, ALfloat decayTime, ALfloat diffusion, ALfloat echoDepth, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALverbState *State) +static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoTime, ALfloat decayTime, ALfloat diffusion, ALfloat echoDepth, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State) { // Update the offset and coefficient for the echo delay line. State->Echo.Offset = fastf2u(echoTime * frequency); @@ -1021,7 +1010,7 @@ static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoT State->Echo.DensityGain = CalcDensityGain(State->Echo.Coeff); // Calculate the echo all-pass feed coefficient. - State->Echo.ApFeedCoeff = 0.5f * aluPow(diffusion, 2.0f); + State->Echo.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f); // Calculate the echo all-pass attenuation coefficient. State->Echo.ApCoeff = CalcDecayCoeff(ECHO_ALLPASS_LENGTH, decayTime); @@ -1040,30 +1029,26 @@ static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoT } // Update the early and late 3D panning gains. -static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALverbState *State) +static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALreverbState *State) { ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], ReflectionsPan[2] }; ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], LateReverbPan[2] }; - const ALfloat *speakerGain; ALfloat ambientGain; ALfloat dirGain; ALfloat length; - ALuint index; - ALint pos; Gain *= ReverbBoost; - // Attenuate non-directional reverb according to the number of channels - ambientGain = aluSqrt(2.0f/Device->NumChan); + /* Attenuate reverb according to its coverage (dirGain=0 will give + * Gain*ambientGain, and dirGain=1 will give Gain). */ + ambientGain = minf(sqrtf(2.0f/Device->NumChan), 1.0f); - // Calculate the 3D-panning gains for the early reflections and late - // reverb. length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; if(length > 1.0f) { - length = 1.0f / aluSqrt(length); + length = 1.0f / sqrtf(length); earlyPan[0] *= length; earlyPan[1] *= length; earlyPan[2] *= length; @@ -1071,248 +1056,727 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; if(length > 1.0f) { - length = 1.0f / aluSqrt(length); + length = 1.0f / sqrtf(length); latePan[0] *= length; latePan[1] *= length; latePan[2] *= length; } - /* This code applies directional reverb just like the mixer applies - * directional sources. It diffuses the sound toward all speakers as the - * magnitude of the panning vector drops, which is only a rough - * approximation of the expansion of sound across the speakers from the - * panning direction. - */ - pos = aluCart2LUTpos(earlyPan[2], earlyPan[0]); - speakerGain = Device->PanningLUT[pos]; - dirGain = aluSqrt((earlyPan[0] * earlyPan[0]) + (earlyPan[2] * earlyPan[2])); + dirGain = sqrtf(earlyPan[0]*earlyPan[0] + earlyPan[2]*earlyPan[2]); + ComputeAngleGains(Device, atan2f(earlyPan[0], earlyPan[2]), (1.0f-dirGain)*F_PI, + lerp(ambientGain, 1.0f, dirGain) * Gain, State->Early.PanGain); - for(index = 0;index < MAXCHANNELS;index++) - State->Early.PanGain[index] = 0.0f; - for(index = 0;index < Device->NumChan;index++) - { - enum Channel chan = Device->Speaker2Chan[index]; - State->Early.PanGain[chan] = lerp(ambientGain, speakerGain[chan], dirGain) * Gain; - } - - - pos = aluCart2LUTpos(latePan[2], latePan[0]); - speakerGain = Device->PanningLUT[pos]; - dirGain = aluSqrt((latePan[0] * latePan[0]) + (latePan[2] * latePan[2])); - - for(index = 0;index < MAXCHANNELS;index++) - State->Late.PanGain[index] = 0.0f; - for(index = 0;index < Device->NumChan;index++) - { - enum Channel chan = Device->Speaker2Chan[index]; - State->Late.PanGain[chan] = lerp(ambientGain, speakerGain[chan], dirGain) * Gain; - } + dirGain = sqrtf(latePan[0]*latePan[0] + latePan[2]*latePan[2]); + ComputeAngleGains(Device, atan2f(latePan[0], latePan[2]), (1.0f-dirGain)*F_PI, + lerp(ambientGain, 1.0f, dirGain) * Gain, State->Late.PanGain); } -// This updates the EAX reverb state. This is called any time the EAX reverb -// effect is loaded into a slot. -static ALvoid ReverbUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffectslot *Slot) +static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot) { - ALverbState *State = (ALverbState*)effect; - ALuint frequency = Context->Device->Frequency; - ALboolean isEAX = AL_FALSE; - ALfloat cw, x, y, hfRatio; + ALuint frequency = Device->Frequency; + ALfloat lfscale, hfscale, hfRatio; + ALfloat cw, x, y; - if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) - { - State->state.Process = EAXVerbProcess; - isEAX = AL_TRUE; - } - else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb) - { - State->state.Process = VerbProcess; - isEAX = AL_FALSE; - } + if(Slot->EffectType == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) + State->IsEax = AL_TRUE; + else if(Slot->EffectType == AL_EFFECT_REVERB || EmulateEAXReverb) + State->IsEax = AL_FALSE; // Calculate the master low-pass filter (from the master effect HF gain). - if(isEAX) cw = CalcI3DL2HFreq(Slot->effect.Reverb.HFReference, frequency); - else cw = CalcI3DL2HFreq(LOWPASSFREQREF, frequency); - // This is done with 2 chained 1-pole filters, so no need to square g. - State->LpFilter.coeff = lpCoeffCalc(Slot->effect.Reverb.GainHF, cw); + if(State->IsEax) + { + hfscale = Slot->EffectProps.Reverb.HFReference / frequency; + ALfilterState_setParams(&State->LpFilter, ALfilterType_HighShelf, + Slot->EffectProps.Reverb.GainHF, + hfscale, 0.0f); + lfscale = Slot->EffectProps.Reverb.LFReference / frequency; + ALfilterState_setParams(&State->HpFilter, ALfilterType_LowShelf, + Slot->EffectProps.Reverb.GainLF, + lfscale, 0.0f); + } + else + { + hfscale = (ALfloat)LOWPASSFREQREF / frequency; + ALfilterState_setParams(&State->LpFilter, ALfilterType_HighShelf, + Slot->EffectProps.Reverb.GainHF, + hfscale, 0.0f); + } - if(isEAX) + if(State->IsEax) { // Update the modulator line. - UpdateModulator(Slot->effect.Reverb.ModulationTime, - Slot->effect.Reverb.ModulationDepth, + UpdateModulator(Slot->EffectProps.Reverb.ModulationTime, + Slot->EffectProps.Reverb.ModulationDepth, frequency, State); } // Update the initial effect delay. - UpdateDelayLine(Slot->effect.Reverb.ReflectionsDelay, - Slot->effect.Reverb.LateReverbDelay, + UpdateDelayLine(Slot->EffectProps.Reverb.ReflectionsDelay, + Slot->EffectProps.Reverb.LateReverbDelay, frequency, State); // Update the early lines. - UpdateEarlyLines(Slot->effect.Reverb.Gain, - Slot->effect.Reverb.ReflectionsGain, - Slot->effect.Reverb.LateReverbDelay, State); + UpdateEarlyLines(Slot->EffectProps.Reverb.Gain, + Slot->EffectProps.Reverb.ReflectionsGain, + Slot->EffectProps.Reverb.LateReverbDelay, State); // Update the decorrelator. - UpdateDecorrelator(Slot->effect.Reverb.Density, frequency, State); + UpdateDecorrelator(Slot->EffectProps.Reverb.Density, frequency, State); // Get the mixing matrix coefficients (x and y). - CalcMatrixCoeffs(Slot->effect.Reverb.Diffusion, &x, &y); + CalcMatrixCoeffs(Slot->EffectProps.Reverb.Diffusion, &x, &y); // Then divide x into y to simplify the matrix calculation. State->Late.MixCoeff = y / x; // If the HF limit parameter is flagged, calculate an appropriate limit // based on the air absorption parameter. - hfRatio = Slot->effect.Reverb.DecayHFRatio; - if(Slot->effect.Reverb.DecayHFLimit && - Slot->effect.Reverb.AirAbsorptionGainHF < 1.0f) + hfRatio = Slot->EffectProps.Reverb.DecayHFRatio; + if(Slot->EffectProps.Reverb.DecayHFLimit && + Slot->EffectProps.Reverb.AirAbsorptionGainHF < 1.0f) hfRatio = CalcLimitedHfRatio(hfRatio, - Slot->effect.Reverb.AirAbsorptionGainHF, - Slot->effect.Reverb.DecayTime); + Slot->EffectProps.Reverb.AirAbsorptionGainHF, + Slot->EffectProps.Reverb.DecayTime); + cw = cosf(F_2PI * hfscale); // Update the late lines. - UpdateLateLines(Slot->effect.Reverb.Gain, Slot->effect.Reverb.LateReverbGain, - x, Slot->effect.Reverb.Density, Slot->effect.Reverb.DecayTime, - Slot->effect.Reverb.Diffusion, hfRatio, cw, frequency, State); + UpdateLateLines(Slot->EffectProps.Reverb.Gain, Slot->EffectProps.Reverb.LateReverbGain, + x, Slot->EffectProps.Reverb.Density, Slot->EffectProps.Reverb.DecayTime, + Slot->EffectProps.Reverb.Diffusion, hfRatio, cw, frequency, State); - if(isEAX) + if(State->IsEax) { // Update the echo line. - UpdateEchoLine(Slot->effect.Reverb.Gain, Slot->effect.Reverb.LateReverbGain, - Slot->effect.Reverb.EchoTime, Slot->effect.Reverb.DecayTime, - Slot->effect.Reverb.Diffusion, Slot->effect.Reverb.EchoDepth, + UpdateEchoLine(Slot->EffectProps.Reverb.Gain, Slot->EffectProps.Reverb.LateReverbGain, + Slot->EffectProps.Reverb.EchoTime, Slot->EffectProps.Reverb.DecayTime, + Slot->EffectProps.Reverb.Diffusion, Slot->EffectProps.Reverb.EchoDepth, hfRatio, cw, frequency, State); // Update early and late 3D panning. - Update3DPanning(Context->Device, Slot->effect.Reverb.ReflectionsPan, - Slot->effect.Reverb.LateReverbPan, Slot->Gain, State); + Update3DPanning(Device, Slot->EffectProps.Reverb.ReflectionsPan, + Slot->EffectProps.Reverb.LateReverbPan, Slot->Gain, State); } else { - ALCdevice *Device = Context->Device; - ALfloat gain = Slot->Gain; - ALuint index; - /* Update channel gains */ - gain *= aluSqrt(2.0f/Device->NumChan) * ReverbBoost; - for(index = 0;index < MAXCHANNELS;index++) - State->Gain[index] = 0.0f; - for(index = 0;index < Device->NumChan;index++) - { - enum Channel chan = Device->Speaker2Chan[index]; - State->Gain[chan] = gain; - } + ALfloat gain = sqrtf(2.0f/Device->NumChan) * ReverbBoost * Slot->Gain; + SetGains(Device, gain, State->Gain); } } -// This destroys the reverb state. It should be called only when the effect -// slot has a different (or no) effect loaded over the reverb effect. -static ALvoid ReverbDestroy(ALeffectState *effect) + +static ALvoid ALreverbState_Destruct(ALreverbState *State) { - ALverbState *State = (ALverbState*)effect; - if(State) - { - free(State->SampleBuffer); - State->SampleBuffer = NULL; - free(State); - } + free(State->SampleBuffer); + State->SampleBuffer = NULL; } -// This creates the reverb state. It should be called only when the reverb -// effect is loaded into a slot that doesn't already have a reverb effect. -ALeffectState *ReverbCreate(void) +static void ALreverbState_Delete(ALreverbState *state) { - ALverbState *State = NULL; + free(state); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState); + + +typedef struct ALreverbStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALreverbStateFactory; + +static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(factory)) +{ + ALreverbState *state; ALuint index; - State = malloc(sizeof(ALverbState)); - if(!State) - return NULL; + state = malloc(sizeof(ALreverbState)); + if(!state) return NULL; + SET_VTABLE2(ALreverbState, ALeffectState, state); - State->state.Destroy = ReverbDestroy; - State->state.DeviceUpdate = ReverbDeviceUpdate; - State->state.Update = ReverbUpdate; - State->state.Process = VerbProcess; + state->TotalSamples = 0; + state->SampleBuffer = NULL; - State->TotalSamples = 0; - State->SampleBuffer = NULL; + ALfilterState_clear(&state->LpFilter); + ALfilterState_clear(&state->HpFilter); - State->LpFilter.coeff = 0.0f; - State->LpFilter.history[0] = 0.0f; - State->LpFilter.history[1] = 0.0f; + state->Mod.Delay.Mask = 0; + state->Mod.Delay.Line = NULL; + state->Mod.Index = 0; + state->Mod.Range = 1; + state->Mod.Depth = 0.0f; + state->Mod.Coeff = 0.0f; + state->Mod.Filter = 0.0f; - State->Mod.Delay.Mask = 0; - State->Mod.Delay.Line = NULL; - State->Mod.Index = 0; - State->Mod.Range = 1; - State->Mod.Depth = 0.0f; - State->Mod.Coeff = 0.0f; - State->Mod.Filter = 0.0f; + state->Delay.Mask = 0; + state->Delay.Line = NULL; + state->DelayTap[0] = 0; + state->DelayTap[1] = 0; - State->Delay.Mask = 0; - State->Delay.Line = NULL; - State->DelayTap[0] = 0; - State->DelayTap[1] = 0; - - State->Early.Gain = 0.0f; + state->Early.Gain = 0.0f; for(index = 0;index < 4;index++) { - State->Early.Coeff[index] = 0.0f; - State->Early.Delay[index].Mask = 0; - State->Early.Delay[index].Line = NULL; - State->Early.Offset[index] = 0; + state->Early.Coeff[index] = 0.0f; + state->Early.Delay[index].Mask = 0; + state->Early.Delay[index].Line = NULL; + state->Early.Offset[index] = 0; } - State->Decorrelator.Mask = 0; - State->Decorrelator.Line = NULL; - State->DecoTap[0] = 0; - State->DecoTap[1] = 0; - State->DecoTap[2] = 0; + state->Decorrelator.Mask = 0; + state->Decorrelator.Line = NULL; + state->DecoTap[0] = 0; + state->DecoTap[1] = 0; + state->DecoTap[2] = 0; - State->Late.Gain = 0.0f; - State->Late.DensityGain = 0.0f; - State->Late.ApFeedCoeff = 0.0f; - State->Late.MixCoeff = 0.0f; + state->Late.Gain = 0.0f; + state->Late.DensityGain = 0.0f; + state->Late.ApFeedCoeff = 0.0f; + state->Late.MixCoeff = 0.0f; for(index = 0;index < 4;index++) { - State->Late.ApCoeff[index] = 0.0f; - State->Late.ApDelay[index].Mask = 0; - State->Late.ApDelay[index].Line = NULL; - State->Late.ApOffset[index] = 0; + state->Late.ApCoeff[index] = 0.0f; + state->Late.ApDelay[index].Mask = 0; + state->Late.ApDelay[index].Line = NULL; + state->Late.ApOffset[index] = 0; - State->Late.Coeff[index] = 0.0f; - State->Late.Delay[index].Mask = 0; - State->Late.Delay[index].Line = NULL; - State->Late.Offset[index] = 0; + state->Late.Coeff[index] = 0.0f; + state->Late.Delay[index].Mask = 0; + state->Late.Delay[index].Line = NULL; + state->Late.Offset[index] = 0; - State->Late.LpCoeff[index] = 0.0f; - State->Late.LpSample[index] = 0.0f; + state->Late.LpCoeff[index] = 0.0f; + state->Late.LpSample[index] = 0.0f; } - for(index = 0;index < MAXCHANNELS;index++) + for(index = 0;index < MaxChannels;index++) { - State->Early.PanGain[index] = 0.0f; - State->Late.PanGain[index] = 0.0f; + state->Early.PanGain[index] = 0.0f; + state->Late.PanGain[index] = 0.0f; } - State->Echo.DensityGain = 0.0f; - State->Echo.Delay.Mask = 0; - State->Echo.Delay.Line = NULL; - State->Echo.ApDelay.Mask = 0; - State->Echo.ApDelay.Line = NULL; - State->Echo.Coeff = 0.0f; - State->Echo.ApFeedCoeff = 0.0f; - State->Echo.ApCoeff = 0.0f; - State->Echo.Offset = 0; - State->Echo.ApOffset = 0; - State->Echo.LpCoeff = 0.0f; - State->Echo.LpSample = 0.0f; - State->Echo.MixCoeff[0] = 0.0f; - State->Echo.MixCoeff[1] = 0.0f; + state->Echo.DensityGain = 0.0f; + state->Echo.Delay.Mask = 0; + state->Echo.Delay.Line = NULL; + state->Echo.ApDelay.Mask = 0; + state->Echo.ApDelay.Line = NULL; + state->Echo.Coeff = 0.0f; + state->Echo.ApFeedCoeff = 0.0f; + state->Echo.ApCoeff = 0.0f; + state->Echo.Offset = 0; + state->Echo.ApOffset = 0; + state->Echo.LpCoeff = 0.0f; + state->Echo.LpSample = 0.0f; + state->Echo.MixCoeff[0] = 0.0f; + state->Echo.MixCoeff[1] = 0.0f; - State->Offset = 0; + state->Offset = 0; - State->Gain = State->Late.PanGain; + state->Gain = state->Late.PanGain; - return &State->state; + return STATIC_CAST(ALeffectState, state); } + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory); + +ALeffectStateFactory *ALreverbStateFactory_getFactory(void) +{ + static ALreverbStateFactory ReverbFactory = { { GET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory) } }; + + return STATIC_CAST(ALeffectStateFactory, &ReverbFactory); +} + + +void ALeaxreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_DECAY_HFLIMIT: + if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayHFLimit = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALeaxreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALeaxreverb_setParami(effect, context, param, vals[0]); +} +void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_DENSITY: + if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Density = val; + break; + + case AL_EAXREVERB_DIFFUSION: + if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Diffusion = val; + break; + + case AL_EAXREVERB_GAIN: + if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Gain = val; + break; + + case AL_EAXREVERB_GAINHF: + if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.GainHF = val; + break; + + case AL_EAXREVERB_GAINLF: + if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.GainLF = val; + break; + + case AL_EAXREVERB_DECAY_TIME: + if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayTime = val; + break; + + case AL_EAXREVERB_DECAY_HFRATIO: + if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayHFRatio = val; + break; + + case AL_EAXREVERB_DECAY_LFRATIO: + if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayLFRatio = val; + break; + + case AL_EAXREVERB_REFLECTIONS_GAIN: + if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ReflectionsGain = val; + break; + + case AL_EAXREVERB_REFLECTIONS_DELAY: + if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ReflectionsDelay = val; + break; + + case AL_EAXREVERB_LATE_REVERB_GAIN: + if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.LateReverbGain = val; + break; + + case AL_EAXREVERB_LATE_REVERB_DELAY: + if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.LateReverbDelay = val; + break; + + case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: + if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.AirAbsorptionGainHF = val; + break; + + case AL_EAXREVERB_ECHO_TIME: + if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.EchoTime = val; + break; + + case AL_EAXREVERB_ECHO_DEPTH: + if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.EchoDepth = val; + break; + + case AL_EAXREVERB_MODULATION_TIME: + if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ModulationTime = val; + break; + + case AL_EAXREVERB_MODULATION_DEPTH: + if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ModulationDepth = val; + break; + + case AL_EAXREVERB_HFREFERENCE: + if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.HFReference = val; + break; + + case AL_EAXREVERB_LFREFERENCE: + if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.LFReference = val; + break; + + case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: + if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.RoomRolloffFactor = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_REFLECTIONS_PAN: + if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + LockContext(context); + props->Reverb.ReflectionsPan[0] = vals[0]; + props->Reverb.ReflectionsPan[1] = vals[1]; + props->Reverb.ReflectionsPan[2] = vals[2]; + UnlockContext(context); + break; + case AL_EAXREVERB_LATE_REVERB_PAN: + if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + LockContext(context); + props->Reverb.LateReverbPan[0] = vals[0]; + props->Reverb.LateReverbPan[1] = vals[1]; + props->Reverb.LateReverbPan[2] = vals[2]; + UnlockContext(context); + break; + + default: + ALeaxreverb_setParamf(effect, context, param, vals[0]); + break; + } +} + +void ALeaxreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_DECAY_HFLIMIT: + *val = props->Reverb.DecayHFLimit; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALeaxreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALeaxreverb_getParami(effect, context, param, vals); +} +void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_DENSITY: + *val = props->Reverb.Density; + break; + + case AL_EAXREVERB_DIFFUSION: + *val = props->Reverb.Diffusion; + break; + + case AL_EAXREVERB_GAIN: + *val = props->Reverb.Gain; + break; + + case AL_EAXREVERB_GAINHF: + *val = props->Reverb.GainHF; + break; + + case AL_EAXREVERB_GAINLF: + *val = props->Reverb.GainLF; + break; + + case AL_EAXREVERB_DECAY_TIME: + *val = props->Reverb.DecayTime; + break; + + case AL_EAXREVERB_DECAY_HFRATIO: + *val = props->Reverb.DecayHFRatio; + break; + + case AL_EAXREVERB_DECAY_LFRATIO: + *val = props->Reverb.DecayLFRatio; + break; + + case AL_EAXREVERB_REFLECTIONS_GAIN: + *val = props->Reverb.ReflectionsGain; + break; + + case AL_EAXREVERB_REFLECTIONS_DELAY: + *val = props->Reverb.ReflectionsDelay; + break; + + case AL_EAXREVERB_LATE_REVERB_GAIN: + *val = props->Reverb.LateReverbGain; + break; + + case AL_EAXREVERB_LATE_REVERB_DELAY: + *val = props->Reverb.LateReverbDelay; + break; + + case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: + *val = props->Reverb.AirAbsorptionGainHF; + break; + + case AL_EAXREVERB_ECHO_TIME: + *val = props->Reverb.EchoTime; + break; + + case AL_EAXREVERB_ECHO_DEPTH: + *val = props->Reverb.EchoDepth; + break; + + case AL_EAXREVERB_MODULATION_TIME: + *val = props->Reverb.ModulationTime; + break; + + case AL_EAXREVERB_MODULATION_DEPTH: + *val = props->Reverb.ModulationDepth; + break; + + case AL_EAXREVERB_HFREFERENCE: + *val = props->Reverb.HFReference; + break; + + case AL_EAXREVERB_LFREFERENCE: + *val = props->Reverb.LFReference; + break; + + case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: + *val = props->Reverb.RoomRolloffFactor; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_EAXREVERB_REFLECTIONS_PAN: + LockContext(context); + vals[0] = props->Reverb.ReflectionsPan[0]; + vals[1] = props->Reverb.ReflectionsPan[1]; + vals[2] = props->Reverb.ReflectionsPan[2]; + UnlockContext(context); + break; + case AL_EAXREVERB_LATE_REVERB_PAN: + LockContext(context); + vals[0] = props->Reverb.LateReverbPan[0]; + vals[1] = props->Reverb.LateReverbPan[1]; + vals[2] = props->Reverb.LateReverbPan[2]; + UnlockContext(context); + break; + + default: + ALeaxreverb_getParamf(effect, context, param, vals); + break; + } +} + +DEFINE_ALEFFECT_VTABLE(ALeaxreverb); + +void ALreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_REVERB_DECAY_HFLIMIT: + if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayHFLimit = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALreverb_setParami(effect, context, param, vals[0]); +} +void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_REVERB_DENSITY: + if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Density = val; + break; + + case AL_REVERB_DIFFUSION: + if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Diffusion = val; + break; + + case AL_REVERB_GAIN: + if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.Gain = val; + break; + + case AL_REVERB_GAINHF: + if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.GainHF = val; + break; + + case AL_REVERB_DECAY_TIME: + if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayTime = val; + break; + + case AL_REVERB_DECAY_HFRATIO: + if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.DecayHFRatio = val; + break; + + case AL_REVERB_REFLECTIONS_GAIN: + if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ReflectionsGain = val; + break; + + case AL_REVERB_REFLECTIONS_DELAY: + if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.ReflectionsDelay = val; + break; + + case AL_REVERB_LATE_REVERB_GAIN: + if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.LateReverbGain = val; + break; + + case AL_REVERB_LATE_REVERB_DELAY: + if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.LateReverbDelay = val; + break; + + case AL_REVERB_AIR_ABSORPTION_GAINHF: + if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.AirAbsorptionGainHF = val; + break; + + case AL_REVERB_ROOM_ROLLOFF_FACTOR: + if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + props->Reverb.RoomRolloffFactor = val; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALreverb_setParamf(effect, context, param, vals[0]); +} + +void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_REVERB_DECAY_HFLIMIT: + *val = props->Reverb.DecayHFLimit; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALreverb_getParami(effect, context, param, vals); +} +void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_REVERB_DENSITY: + *val = props->Reverb.Density; + break; + + case AL_REVERB_DIFFUSION: + *val = props->Reverb.Diffusion; + break; + + case AL_REVERB_GAIN: + *val = props->Reverb.Gain; + break; + + case AL_REVERB_GAINHF: + *val = props->Reverb.GainHF; + break; + + case AL_REVERB_DECAY_TIME: + *val = props->Reverb.DecayTime; + break; + + case AL_REVERB_DECAY_HFRATIO: + *val = props->Reverb.DecayHFRatio; + break; + + case AL_REVERB_REFLECTIONS_GAIN: + *val = props->Reverb.ReflectionsGain; + break; + + case AL_REVERB_REFLECTIONS_DELAY: + *val = props->Reverb.ReflectionsDelay; + break; + + case AL_REVERB_LATE_REVERB_GAIN: + *val = props->Reverb.LateReverbGain; + break; + + case AL_REVERB_LATE_REVERB_DELAY: + *val = props->Reverb.LateReverbDelay; + break; + + case AL_REVERB_AIR_ABSORPTION_GAINHF: + *val = props->Reverb.AirAbsorptionGainHF; + break; + + case AL_REVERB_ROOM_ROLLOFF_FACTOR: + *val = props->Reverb.RoomRolloffFactor; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} +void ALreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALreverb_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALreverb); diff --git a/jni/openal-soft-android/Alc/evtqueue.h b/jni/openal-soft-android/Alc/evtqueue.h new file mode 100644 index 00000000..95702d79 --- /dev/null +++ b/jni/openal-soft-android/Alc/evtqueue.h @@ -0,0 +1,31 @@ +#ifndef AL_EVTQUEUE_H +#define AL_EVTQUEUE_H + +#include "AL/al.h" + +#include "alMain.h" + +typedef struct MidiEvent { + ALuint64 time; + ALuint event; + union { + ALuint val[2]; + struct { + ALvoid *data; + ALsizei size; + } sysex; + } param; +} MidiEvent; + +typedef struct EvtQueue { + MidiEvent *events; + ALsizei pos; + ALsizei size; + ALsizei maxsize; +} EvtQueue; + +void InitEvtQueue(EvtQueue *queue); +void ResetEvtQueue(EvtQueue *queue); +ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt); + +#endif /* AL_EVTQUEUE_H */ diff --git a/jni/openal-soft-android/Alc/helpers.c b/jni/openal-soft-android/Alc/helpers.c index f219f4ae..f8a5f13b 100644 --- a/jni/openal-soft-android/Alc/helpers.c +++ b/jni/openal-soft-android/Alc/helpers.c @@ -21,10 +21,14 @@ #include "config.h" #include -#ifdef HAVE_DLFCN_H -#include +#include +#include +#include +#ifdef HAVE_MALLOC_H +#include #endif +#ifndef AL_NO_UID_DEFS #if defined(HAVE_GUIDDEF_H) || defined(HAVE_INITGUID_H) #define INITGUID #include @@ -44,23 +48,266 @@ DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xd DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2); DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2); +#ifdef HAVE_MMDEVAPI +#include +DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14); +#endif +#endif +#endif /* AL_NO_UID_DEFS */ + +#ifdef HAVE_DLFCN_H +#include +#endif +#ifdef HAVE_CPUID_H +#include +#endif +#ifdef HAVE_SYS_SYSCONF_H +#include +#endif +#ifdef HAVE_FLOAT_H +#include +#endif +#ifdef HAVE_IEEEFP_H +#include #endif #include "alMain.h" +#include "atomic.h" +#include "uintmap.h" +#include "compat.h" + + +extern inline RefCount IncrementRef(volatile RefCount *ptr); +extern inline RefCount DecrementRef(volatile RefCount *ptr); +extern inline int ExchangeInt(volatile int *ptr, int newval); +extern inline void *ExchangePtr(XchgPtr *ptr, void *newval); +extern inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval); +extern inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval); + +extern inline void LockUIntMapRead(UIntMap *map); +extern inline void UnlockUIntMapRead(UIntMap *map); +extern inline void LockUIntMapWrite(UIntMap *map); +extern inline void UnlockUIntMapWrite(UIntMap *map); + +extern inline ALuint NextPowerOf2(ALuint value); +extern inline ALint fastf2i(ALfloat f); +extern inline ALuint fastf2u(ALfloat f); + + +ALuint CPUCapFlags = 0; + + +void FillCPUCaps(ALuint capfilter) +{ + ALuint caps = 0; + +/* FIXME: We really should get this for all available CPUs in case different + * CPUs have different caps (is that possible on one machine?). */ +#if defined(HAVE_CPUID_H) && (defined(__i386__) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_X64)) + union { + unsigned int regs[4]; + char str[sizeof(unsigned int[4])]; + } cpuinf[3]; + + if(!__get_cpuid(0, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3])) + ERR("Failed to get CPUID\n"); + else + { + unsigned int maxfunc = cpuinf[0].regs[0]; + unsigned int maxextfunc = 0; + + if(__get_cpuid(0x80000000, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3])) + maxextfunc = cpuinf[0].regs[0]; + TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc); + + TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8); + if(maxextfunc >= 0x80000004 && + __get_cpuid(0x80000002, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]) && + __get_cpuid(0x80000003, &cpuinf[1].regs[0], &cpuinf[1].regs[1], &cpuinf[1].regs[2], &cpuinf[1].regs[3]) && + __get_cpuid(0x80000004, &cpuinf[2].regs[0], &cpuinf[2].regs[1], &cpuinf[2].regs[2], &cpuinf[2].regs[3])) + TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str); + + if(maxfunc >= 1 && + __get_cpuid(1, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3])) + { + if((cpuinf[0].regs[3]&(1<<25))) + { + caps |= CPU_CAP_SSE; + if((cpuinf[0].regs[3]&(1<<26))) + caps |= CPU_CAP_SSE2; + } + } + } +#elif defined(HAVE_WINDOWS_H) + HMODULE k32 = GetModuleHandleA("kernel32.dll"); + BOOL (WINAPI*IsProcessorFeaturePresent)(DWORD ProcessorFeature); + IsProcessorFeaturePresent = (BOOL(WINAPI*)(DWORD))GetProcAddress(k32, "IsProcessorFeaturePresent"); + if(!IsProcessorFeaturePresent) + ERR("IsProcessorFeaturePresent not available; CPU caps not detected\n"); + else + { + if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) + { + caps |= CPU_CAP_SSE; + if(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) + caps |= CPU_CAP_SSE2; + } + } +#endif +#ifdef HAVE_NEON + /* Assume Neon support if compiled with it */ + caps |= CPU_CAP_NEON; +#endif + + TRACE("Got caps:%s%s%s%s\n", ((caps&CPU_CAP_SSE)?((capfilter&CPU_CAP_SSE)?" SSE":" (SSE)"):""), + ((caps&CPU_CAP_SSE2)?((capfilter&CPU_CAP_SSE2)?" SSE2":" (SSE2)"):""), + ((caps&CPU_CAP_NEON)?((capfilter&CPU_CAP_NEON)?" Neon":" (Neon)"):""), + ((!caps)?" -none-":"")); + CPUCapFlags = caps & capfilter; +} + + +void *al_malloc(size_t alignment, size_t size) +{ +#if defined(HAVE_ALIGNED_ALLOC) + size = (size+(alignment-1))&~(alignment-1); + return aligned_alloc(alignment, size); +#elif defined(HAVE_POSIX_MEMALIGN) + void *ret; + if(posix_memalign(&ret, alignment, size) == 0) + return ret; + return NULL; +#elif defined(HAVE__ALIGNED_MALLOC) + return _aligned_malloc(size, alignment); +#else + char *ret = malloc(size+alignment); + if(ret != NULL) + { + *(ret++) = 0x00; + while(((ALintptrEXT)ret&(alignment-1)) != 0) + *(ret++) = 0x55; + } + return ret; +#endif +} + +void *al_calloc(size_t alignment, size_t size) +{ + void *ret = al_malloc(alignment, size); + if(ret) memset(ret, 0, size); + return ret; +} + +void al_free(void *ptr) +{ +#if defined(HAVE_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN) + free(ptr); +#elif defined(HAVE__ALIGNED_MALLOC) + _aligned_free(ptr); +#else + if(ptr != NULL) + { + char *finder = ptr; + do { + --finder; + } while(*finder == 0x55); + free(finder); + } +#endif +} + + +#if (defined(HAVE___CONTROL87_2) || defined(HAVE__CONTROLFP)) && (defined(__x86_64__) || defined(_M_X64)) +/* Win64 doesn't allow us to set the precision control. */ +#undef _MCW_PC +#define _MCW_PC 0 +#endif + +void SetMixerFPUMode(FPUCtl *ctl) +{ +#ifdef HAVE_FENV_H + fegetenv(STATIC_CAST(fenv_t, ctl)); +#if defined(__GNUC__) && defined(HAVE_SSE) + if((CPUCapFlags&CPU_CAP_SSE)) + __asm__ __volatile__("stmxcsr %0" : "=m" (*&ctl->sse_state)); +#endif + +#ifdef FE_TOWARDZERO + fesetround(FE_TOWARDZERO); +#endif +#if defined(__GNUC__) && defined(HAVE_SSE) + if((CPUCapFlags&CPU_CAP_SSE)) + { + int sseState = ctl->sse_state; + sseState |= 0x6000; /* set round-to-zero */ + sseState |= 0x8000; /* set flush-to-zero */ + if((CPUCapFlags&CPU_CAP_SSE2)) + sseState |= 0x0040; /* set denormals-are-zero */ + __asm__ __volatile__("ldmxcsr %0" : : "m" (*&sseState)); + } +#endif + +#elif defined(HAVE___CONTROL87_2) + + int mode; + __control87_2(0, 0, &ctl->state, NULL); + __control87_2(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC, &mode, NULL); +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + { + __control87_2(0, 0, NULL, &ctl->sse_state); + __control87_2(_RC_CHOP|_DN_FLUSH, _MCW_RC|_MCW_DN, NULL, &mode); + } +#endif + +#elif defined(HAVE__CONTROLFP) + + ctl->state = _controlfp(0, 0); + (void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC); +#endif +} + +void RestoreFPUMode(const FPUCtl *ctl) +{ +#ifdef HAVE_FENV_H + fesetenv(STATIC_CAST(fenv_t, ctl)); +#if defined(__GNUC__) && defined(HAVE_SSE) + if((CPUCapFlags&CPU_CAP_SSE)) + __asm__ __volatile__("ldmxcsr %0" : : "m" (*&ctl->sse_state)); +#endif + +#elif defined(HAVE___CONTROL87_2) + + int mode; + __control87_2(ctl->state, _MCW_RC|_MCW_PC, &mode, NULL); +#ifdef HAVE_SSE + if((CPUCapFlags&CPU_CAP_SSE)) + __control87_2(ctl->sse_state, _MCW_RC|_MCW_DN, NULL, &mode); +#endif + +#elif defined(HAVE__CONTROLFP) + + _controlfp(ctl->state, _MCW_RC|_MCW_PC); +#endif +} + #ifdef _WIN32 -void pthread_once(pthread_once_t *once, void (*callback)(void)) +extern inline int alsched_yield(void); + +void althread_once(althread_once_t *once, void (*callback)(void)) { LONG ret; while((ret=InterlockedExchange(once, 1)) == 1) - sched_yield(); + alsched_yield(); if(ret == 0) callback(); InterlockedExchange(once, 2); } -int pthread_key_create(pthread_key_t *key, void (*callback)(void*)) +int althread_key_create(althread_key_t *key, void (*callback)(void*)) { *key = TlsAlloc(); if(callback) @@ -68,17 +315,17 @@ int pthread_key_create(pthread_key_t *key, void (*callback)(void*)) return 0; } -int pthread_key_delete(pthread_key_t key) +int althread_key_delete(althread_key_t key) { InsertUIntMapEntry(&TlsDestructor, key, NULL); TlsFree(key); return 0; } -void *pthread_getspecific(pthread_key_t key) +void *althread_getspecific(althread_key_t key) { return TlsGetValue(key); } -int pthread_setspecific(pthread_key_t key, void *val) +int althread_setspecific(althread_key_t key, void *val) { TlsSetValue(key, val); return 0; @@ -99,8 +346,32 @@ void *GetSymbol(void *handle, const char *name) return ret; } +WCHAR *strdupW(const WCHAR *str) +{ + const WCHAR *n; + WCHAR *ret; + size_t len; + + n = str; + while(*n) n++; + len = n - str; + + ret = calloc(sizeof(WCHAR), len+1); + if(ret != NULL) + memcpy(ret, str, sizeof(WCHAR)*len); + return ret; +} + #else +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif +#include +#include +#include + void InitializeCriticalSection(CRITICAL_SECTION *cs) { pthread_mutexattr_t attrib; @@ -217,22 +488,15 @@ void *GetSymbol(void *handle, const char *name) #endif -void al_print(const char *func, const char *fmt, ...) +void al_print(const char *type, const char *func, const char *fmt, ...) { - char str[256]; - int i; + va_list ap; - i = snprintf(str, sizeof(str), "AL lib: %s: ", func); - if(i < (int)sizeof(str) && i > 0) - { - va_list ap; - va_start(ap, fmt); - vsnprintf(str+i, sizeof(str)-i, fmt, ap); - va_end(ap); - } - str[sizeof(str)-1] = 0; + va_start(ap, fmt); + fprintf(LogFile, "AL lib: %s %s: ", type, func); + vfprintf(LogFile, fmt, ap); + va_end(ap); - fprintf(LogFile, "%s", str); fflush(LogFile); } @@ -265,7 +529,7 @@ void SetRTPriority(void) static void Lock(volatile ALenum *l) { while(ExchangeInt(l, AL_TRUE) == AL_TRUE) - sched_yield(); + alsched_yield(); } static void Unlock(volatile ALenum *l) @@ -337,12 +601,6 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) ALsizei pos = 0; WriteLock(&map->lock); - if(map->size == map->limit) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - if(map->size > 0) { ALsizei low = 0; @@ -362,6 +620,12 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) if(pos == map->size || map->array[pos].key != key) { + if(map->size == map->limit) + { + WriteUnlock(&map->lock); + return AL_OUT_OF_MEMORY; + } + if(map->size == map->maxsize) { ALvoid *temp = NULL; @@ -379,10 +643,10 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) map->maxsize = newsize; } - map->size++; - if(pos < map->size-1) + if(pos < map->size) memmove(&map->array[pos+1], &map->array[pos], - (map->size-1-pos)*sizeof(map->array[0])); + (map->size-pos)*sizeof(map->array[0])); + map->size++; } map->array[pos].key = key; map->array[pos].value = value; diff --git a/jni/openal-soft-android/Alc/hrtf.c b/jni/openal-soft-android/Alc/hrtf.c index 006ab8ad..49bb97a3 100644 --- a/jni/openal-soft-android/Alc/hrtf.c +++ b/jni/openal-soft-android/Alc/hrtf.c @@ -27,79 +27,90 @@ #include "AL/alc.h" #include "alMain.h" #include "alSource.h" - -/* External HRTF file format (LE byte order): - * - * ALchar magic[8] = "MinPHR00"; - * ALuint sampleRate; - * - * ALushort hrirCount; // Required value: 828 - * ALushort hrirSize; // Required value: 32 - * ALubyte evCount; // Required value: 19 - * - * ALushort evOffset[evCount]; // Required values: - * { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827 } - * - * ALshort coefficients[hrirCount][hrirSize]; - * ALubyte delays[hrirCount]; // Element values must not exceed 127 - */ - -static const ALchar magicMarker[8] = "MinPHR00"; - -#define HRIR_COUNT 828 -#define ELEV_COUNT 19 - -static const ALushort evOffset[ELEV_COUNT] = { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827 }; -static const ALubyte azCount[ELEV_COUNT] = { 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1 }; +#include "alu.h" -static const struct Hrtf { +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + + +/* Current data set limits defined by the makehrtf utility. */ +#define MIN_IR_SIZE (8) +#define MAX_IR_SIZE (128) +#define MOD_IR_SIZE (8) + +#define MIN_EV_COUNT (5) +#define MAX_EV_COUNT (128) + +#define MIN_AZ_COUNT (1) +#define MAX_AZ_COUNT (128) + +struct Hrtf { ALuint sampleRate; - ALshort coeffs[HRIR_COUNT][HRIR_LENGTH]; - ALubyte delays[HRIR_COUNT]; -} DefaultHrtf = { - 44100, -#include "hrtf_tables.inc" + ALuint irSize; + ALubyte evCount; + + const ALubyte *azCount; + const ALushort *evOffset; + const ALshort *coeffs; + const ALubyte *delays; + + struct Hrtf *next; }; +static const ALchar magicMarker00[8] = "MinPHR00"; +static const ALchar magicMarker01[8] = "MinPHR01"; + +/* Define the default HRTF: + * ALubyte defaultAzCount [DefaultHrtf.evCount] + * ALushort defaultEvOffset [DefaultHrtf.evCount] + * ALshort defaultCoeffs [DefaultHrtf.irCount * defaultHrtf.irSize] + * ALubyte defaultDelays [DefaultHrtf.irCount] + * + * struct Hrtf DefaultHrtf + */ +#include "hrtf_tables.inc" + static struct Hrtf *LoadedHrtfs = NULL; -static ALuint NumLoadedHrtfs = 0; - -// Calculate the elevation indices given the polar elevation in radians. -// This will return two indices between 0 and (ELEV_COUNT-1) and an -// interpolation factor between 0.0 and 1.0. -static void CalcEvIndices(ALfloat ev, ALuint *evidx, ALfloat *evmu) +/* Calculate the elevation indices given the polar elevation in radians. + * This will return two indices between 0 and (Hrtf->evCount - 1) and an + * interpolation factor between 0.0 and 1.0. + */ +static void CalcEvIndices(const struct Hrtf *Hrtf, ALfloat ev, ALuint *evidx, ALfloat *evmu) { - ev = (F_PI_2 + ev) * (ELEV_COUNT-1) / F_PI; + ev = (F_PI_2 + ev) * (Hrtf->evCount-1) / F_PI; evidx[0] = fastf2u(ev); - evidx[1] = minu(evidx[0] + 1, ELEV_COUNT-1); + evidx[1] = minu(evidx[0] + 1, Hrtf->evCount-1); *evmu = ev - evidx[0]; } -// Calculate the azimuth indices given the polar azimuth in radians. This -// will return two indices between 0 and (azCount [ei] - 1) and an -// interpolation factor between 0.0 and 1.0. -static void CalcAzIndices(ALuint evidx, ALfloat az, ALuint *azidx, ALfloat *azmu) +/* Calculate the azimuth indices given the polar azimuth in radians. This + * will return two indices between 0 and (Hrtf->azCount[ei] - 1) and an + * interpolation factor between 0.0 and 1.0. + */ +static void CalcAzIndices(const struct Hrtf *Hrtf, ALuint evidx, ALfloat az, ALuint *azidx, ALfloat *azmu) { - az = (F_PI*2.0f + az) * azCount[evidx] / (F_PI*2.0f); - azidx[0] = fastf2u(az) % azCount[evidx]; - azidx[1] = (azidx[0] + 1) % azCount[evidx]; - *azmu = az - aluFloor(az); + az = (F_2PI + az) * Hrtf->azCount[evidx] / (F_2PI); + azidx[0] = fastf2u(az) % Hrtf->azCount[evidx]; + azidx[1] = (azidx[0] + 1) % Hrtf->azCount[evidx]; + *azmu = az - floorf(az); } -// Calculates the normalized HRTF transition factor (delta) from the changes -// in gain and listener to source angle between updates. The result is a -// normalized delta factor than can be used to calculate moving HRIR stepping -// values. +/* Calculates the normalized HRTF transition factor (delta) from the changes + * in gain and listener to source angle between updates. The result is a + * normalized delta factor that can be used to calculate moving HRIR stepping + * values. + */ ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]) { - ALfloat gainChange, angleChange; + ALfloat gainChange, angleChange, change; // Calculate the normalized dB gain change. newGain = maxf(newGain, 0.0001f); oldGain = maxf(oldGain, 0.0001f); - gainChange = aluFabs(aluLog10(newGain / oldGain) / aluLog10(0.0001f)); + gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f)); // Calculate the normalized listener to source angle change when there is // enough gain to notice it. @@ -109,136 +120,192 @@ ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], // No angle change when the directions are equal or degenerate (when // both have zero length). if(newdir[0]-olddir[0] || newdir[1]-olddir[1] || newdir[2]-olddir[2]) - angleChange = aluAcos(olddir[0]*newdir[0] + - olddir[1]*newdir[1] + - olddir[2]*newdir[2]) / F_PI; + angleChange = acosf(olddir[0]*newdir[0] + + olddir[1]*newdir[1] + + olddir[2]*newdir[2]) / F_PI; } // Use the largest of the two changes for the delta factor, and apply a // significance shaping function to it. - return clampf(angleChange*2.0f, gainChange*2.0f, 1.0f); + change = maxf(angleChange * 25.0f, gainChange) * 2.0f; + return minf(change, 1.0f); } -// Calculates static HRIR coefficients and delays for the given polar -// elevation and azimuth in radians. Linear interpolation is used to -// increase the apparent resolution of the HRIR dataset. The coefficients -// are also normalized and attenuated by the specified gain. +/* Calculates static HRIR coefficients and delays for the given polar + * elevation and azimuth in radians. Linear interpolation is used to + * increase the apparent resolution of the HRIR data set. The coefficients + * are also normalized and attenuated by the specified gain. + */ void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays) { ALuint evidx[2], azidx[2]; - ALfloat mu[3]; ALuint lidx[4], ridx[4]; + ALfloat mu[3], blend[4]; ALuint i; // Claculate elevation indices and interpolation factor. - CalcEvIndices(elevation, evidx, &mu[2]); + CalcEvIndices(Hrtf, elevation, evidx, &mu[2]); // Calculate azimuth indices and interpolation factor for the first // elevation. - CalcAzIndices(evidx[0], azimuth, azidx, &mu[0]); + CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]); // Calculate the first set of linear HRIR indices for left and right // channels. - lidx[0] = evOffset[evidx[0]] + azidx[0]; - lidx[1] = evOffset[evidx[0]] + azidx[1]; - ridx[0] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[0]) % azCount[evidx[0]]); - ridx[1] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[1]) % azCount[evidx[0]]); + lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0]; + lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1]; + ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]); + ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]); // Calculate azimuth indices and interpolation factor for the second // elevation. - CalcAzIndices(evidx[1], azimuth, azidx, &mu[1]); + CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]); // Calculate the second set of linear HRIR indices for left and right // channels. - lidx[2] = evOffset[evidx[1]] + azidx[0]; - lidx[3] = evOffset[evidx[1]] + azidx[1]; - ridx[2] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[0]) % azCount[evidx[1]]); - ridx[3] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[1]) % azCount[evidx[1]]); + lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0]; + lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1]; + ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]); + ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]); - // Calculate the normalized and attenuated HRIR coefficients using linear - // interpolation when there is enough gain to warrant it. Zero the - // coefficients if gain is too low. + /* Calculate 4 blending weights for 2D bilinear interpolation. */ + blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); + blend[1] = ( mu[0]) * (1.0f-mu[2]); + blend[2] = (1.0f-mu[1]) * ( mu[2]); + blend[3] = ( mu[1]) * ( mu[2]); + + /* Calculate the HRIR delays using linear interpolation. */ + delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + + Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] + + 0.5f) << HRTFDELAY_BITS; + delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + + Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] + + 0.5f) << HRTFDELAY_BITS; + + /* Calculate the sample offsets for the HRIR indices. */ + lidx[0] *= Hrtf->irSize; + lidx[1] *= Hrtf->irSize; + lidx[2] *= Hrtf->irSize; + lidx[3] *= Hrtf->irSize; + ridx[0] *= Hrtf->irSize; + ridx[1] *= Hrtf->irSize; + ridx[2] *= Hrtf->irSize; + ridx[3] *= Hrtf->irSize; + + /* Calculate the normalized and attenuated HRIR coefficients using linear + * interpolation when there is enough gain to warrant it. Zero the + * coefficients if gain is too low. + */ if(gain > 0.0001f) { gain *= 1.0f/32767.0f; - for(i = 0;i < HRIR_LENGTH;i++) + for(i = 0;i < Hrtf->irSize;i++) { - coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]), - lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]), - mu[2]) * gain; - coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]), - lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]), - mu[2]) * gain; + coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] + + Hrtf->coeffs[lidx[1]+i]*blend[1] + + Hrtf->coeffs[lidx[2]+i]*blend[2] + + Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain; + coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] + + Hrtf->coeffs[ridx[1]+i]*blend[1] + + Hrtf->coeffs[ridx[2]+i]*blend[2] + + Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain; } } else { - for(i = 0;i < HRIR_LENGTH;i++) + for(i = 0;i < Hrtf->irSize;i++) { coeffs[i][0] = 0.0f; coeffs[i][1] = 0.0f; } } - - // Calculate the HRIR delays using linear interpolation. - delays[0] = fastf2u(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]), - lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]), - mu[2]) * 65536.0f); - delays[1] = fastf2u(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]), - lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]), - mu[2]) * 65536.0f); } -// Calculates the moving HRIR target coefficients, target delays, and -// stepping values for the given polar elevation and azimuth in radians. -// Linear interpolation is used to increase the apparent resolution of the -// HRIR dataset. The coefficients are also normalized and attenuated by the -// specified gain. Stepping resolution and count is determined using the -// given delta factor between 0.0 and 1.0. +/* Calculates the moving HRIR target coefficients, target delays, and + * stepping values for the given polar elevation and azimuth in radians. + * Linear interpolation is used to increase the apparent resolution of the + * HRIR data set. The coefficients are also normalized and attenuated by the + * specified gain. Stepping resolution and count is determined using the + * given delta factor between 0.0 and 1.0. + */ ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep) { ALuint evidx[2], azidx[2]; ALuint lidx[4], ridx[4]; + ALfloat mu[3], blend[4]; ALfloat left, right; - ALfloat mu[3]; ALfloat step; ALuint i; // Claculate elevation indices and interpolation factor. - CalcEvIndices(elevation, evidx, &mu[2]); + CalcEvIndices(Hrtf, elevation, evidx, &mu[2]); // Calculate azimuth indices and interpolation factor for the first // elevation. - CalcAzIndices(evidx[0], azimuth, azidx, &mu[0]); + CalcAzIndices(Hrtf, evidx[0], azimuth, azidx, &mu[0]); // Calculate the first set of linear HRIR indices for left and right // channels. - lidx[0] = evOffset[evidx[0]] + azidx[0]; - lidx[1] = evOffset[evidx[0]] + azidx[1]; - ridx[0] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[0]) % azCount[evidx[0]]); - ridx[1] = evOffset[evidx[0]] + ((azCount[evidx[0]]-azidx[1]) % azCount[evidx[0]]); + lidx[0] = Hrtf->evOffset[evidx[0]] + azidx[0]; + lidx[1] = Hrtf->evOffset[evidx[0]] + azidx[1]; + ridx[0] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[0]) % Hrtf->azCount[evidx[0]]); + ridx[1] = Hrtf->evOffset[evidx[0]] + ((Hrtf->azCount[evidx[0]]-azidx[1]) % Hrtf->azCount[evidx[0]]); // Calculate azimuth indices and interpolation factor for the second // elevation. - CalcAzIndices(evidx[1], azimuth, azidx, &mu[1]); + CalcAzIndices(Hrtf, evidx[1], azimuth, azidx, &mu[1]); // Calculate the second set of linear HRIR indices for left and right // channels. - lidx[2] = evOffset[evidx[1]] + azidx[0]; - lidx[3] = evOffset[evidx[1]] + azidx[1]; - ridx[2] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[0]) % azCount[evidx[1]]); - ridx[3] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[1]) % azCount[evidx[1]]); + lidx[2] = Hrtf->evOffset[evidx[1]] + azidx[0]; + lidx[3] = Hrtf->evOffset[evidx[1]] + azidx[1]; + ridx[2] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[0]) % Hrtf->azCount[evidx[1]]); + ridx[3] = Hrtf->evOffset[evidx[1]] + ((Hrtf->azCount[evidx[1]]-azidx[1]) % Hrtf->azCount[evidx[1]]); // Calculate the stepping parameters. - delta = maxf(aluFloor(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f); + delta = maxf(floorf(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f); step = 1.0f / delta; - // Calculate the normalized and attenuated target HRIR coefficients using - // linear interpolation when there is enough gain to warrant it. Zero - // the target coefficients if gain is too low. Then calculate the - // coefficient stepping values using the target and previous running - // coefficients. + /* Calculate 4 blending weights for 2D bilinear interpolation. */ + blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); + blend[1] = ( mu[0]) * (1.0f-mu[2]); + blend[2] = (1.0f-mu[1]) * ( mu[2]); + blend[3] = ( mu[1]) * ( mu[2]); + + /* Calculate the HRIR delays using linear interpolation. Then calculate + * the delay stepping values using the target and previous running + * delays. + */ + left = (ALfloat)(delays[0] - (delayStep[0] * counter)); + right = (ALfloat)(delays[1] - (delayStep[1] * counter)); + + delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + + Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] + + 0.5f) << HRTFDELAY_BITS; + delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + + Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] + + 0.5f) << HRTFDELAY_BITS; + + delayStep[0] = fastf2i(step * (delays[0] - left)); + delayStep[1] = fastf2i(step * (delays[1] - right)); + + /* Calculate the sample offsets for the HRIR indices. */ + lidx[0] *= Hrtf->irSize; + lidx[1] *= Hrtf->irSize; + lidx[2] *= Hrtf->irSize; + lidx[3] *= Hrtf->irSize; + ridx[0] *= Hrtf->irSize; + ridx[1] *= Hrtf->irSize; + ridx[2] *= Hrtf->irSize; + ridx[3] *= Hrtf->irSize; + + /* Calculate the normalized and attenuated target HRIR coefficients using + * linear interpolation when there is enough gain to warrant it. Zero + * the target coefficients if gain is too low. Then calculate the + * coefficient stepping values using the target and previous running + * coefficients. + */ if(gain > 0.0001f) { gain *= 1.0f/32767.0f; @@ -247,12 +314,14 @@ ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat a left = coeffs[i][0] - (coeffStep[i][0] * counter); right = coeffs[i][1] - (coeffStep[i][1] * counter); - coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]), - lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]), - mu[2]) * gain; - coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]), - lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]), - mu[2]) * gain; + coeffs[i][0] = (Hrtf->coeffs[lidx[0]+i]*blend[0] + + Hrtf->coeffs[lidx[1]+i]*blend[1] + + Hrtf->coeffs[lidx[2]+i]*blend[2] + + Hrtf->coeffs[lidx[3]+i]*blend[3]) * gain; + coeffs[i][1] = (Hrtf->coeffs[ridx[0]+i]*blend[0] + + Hrtf->coeffs[ridx[1]+i]*blend[1] + + Hrtf->coeffs[ridx[2]+i]*blend[2] + + Hrtf->coeffs[ridx[3]+i]*blend[3]) * gain; coeffStep[i][0] = step * (coeffs[i][0] - left); coeffStep[i][1] = step * (coeffs[i][1] - right); @@ -273,38 +342,439 @@ ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat a } } - // Calculate the HRIR delays using linear interpolation. Then calculate - // the delay stepping values using the target and previous running - // delays. - left = (ALfloat)(delays[0] - (delayStep[0] * counter)); - right = (ALfloat)(delays[1] - (delayStep[1] * counter)); - - delays[0] = fastf2u(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]), - lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]), - mu[2]) * 65536.0f); - delays[1] = fastf2u(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]), - lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]), - mu[2]) * 65536.0f); - - delayStep[0] = fastf2i(step * (delays[0] - left)); - delayStep[1] = fastf2i(step * (delays[1] - right)); - - // The stepping count is the number of samples necessary for the HRIR to - // complete its transition. The mixer will only apply stepping for this - // many samples. + /* The stepping count is the number of samples necessary for the HRIR to + * complete its transition. The mixer will only apply stepping for this + * many samples. + */ return fastf2u(delta); } + +static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate) +{ + const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; + struct Hrtf *Hrtf = NULL; + ALboolean failed = AL_FALSE; + ALuint rate = 0, irCount = 0; + ALushort irSize = 0; + ALubyte evCount = 0; + ALubyte *azCount = NULL; + ALushort *evOffset = NULL; + ALshort *coeffs = NULL; + ALubyte *delays = NULL; + ALuint i, j; + + rate = fgetc(f); + rate |= fgetc(f)<<8; + rate |= fgetc(f)<<16; + rate |= fgetc(f)<<24; + + irCount = fgetc(f); + irCount |= fgetc(f)<<8; + + irSize = fgetc(f); + irSize |= fgetc(f)<<8; + + evCount = fgetc(f); + + if(rate != deviceRate) + { + ERR("HRIR rate does not match device rate: rate=%d (%d)\n", + rate, deviceRate); + failed = AL_TRUE; + } + if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE)) + { + ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n", + irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE); + failed = AL_TRUE; + } + if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT) + { + ERR("Unsupported elevation count: evCount=%d (%d to %d)\n", + evCount, MIN_EV_COUNT, MAX_EV_COUNT); + failed = AL_TRUE; + } + + if(failed) + return NULL; + + azCount = malloc(sizeof(azCount[0])*evCount); + evOffset = malloc(sizeof(evOffset[0])*evCount); + if(azCount == NULL || evOffset == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + + if(!failed) + { + evOffset[0] = fgetc(f); + evOffset[0] |= fgetc(f)<<8; + for(i = 1;i < evCount;i++) + { + evOffset[i] = fgetc(f); + evOffset[i] |= fgetc(f)<<8; + if(evOffset[i] <= evOffset[i-1]) + { + ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n", + i, evOffset[i], evOffset[i-1]); + failed = AL_TRUE; + } + + azCount[i-1] = evOffset[i] - evOffset[i-1]; + if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT) + { + ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", + i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT); + failed = AL_TRUE; + } + } + if(irCount <= evOffset[i-1]) + { + ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n", + i-1, evOffset[i-1], irCount); + failed = AL_TRUE; + } + + azCount[i-1] = irCount - evOffset[i-1]; + if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT) + { + ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", + i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT); + failed = AL_TRUE; + } + } + + if(!failed) + { + coeffs = malloc(sizeof(coeffs[0])*irSize*irCount); + delays = malloc(sizeof(delays[0])*irCount); + if(coeffs == NULL || delays == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + for(i = 0;i < irCount*irSize;i+=irSize) + { + for(j = 0;j < irSize;j++) + { + ALshort coeff; + coeff = fgetc(f); + coeff |= fgetc(f)<<8; + coeffs[i+j] = coeff; + } + } + for(i = 0;i < irCount;i++) + { + delays[i] = fgetc(f); + if(delays[i] > maxDelay) + { + ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay); + failed = AL_TRUE; + } + } + + if(feof(f)) + { + ERR("Premature end of data\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + Hrtf = malloc(sizeof(struct Hrtf)); + if(Hrtf == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + Hrtf->sampleRate = rate; + Hrtf->irSize = irSize; + Hrtf->evCount = evCount; + Hrtf->azCount = azCount; + Hrtf->evOffset = evOffset; + Hrtf->coeffs = coeffs; + Hrtf->delays = delays; + Hrtf->next = NULL; + return Hrtf; + } + + free(azCount); + free(evOffset); + free(coeffs); + free(delays); + return NULL; +} + + +static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate) +{ + const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; + struct Hrtf *Hrtf = NULL; + ALboolean failed = AL_FALSE; + ALuint rate = 0, irCount = 0; + ALubyte irSize = 0, evCount = 0; + ALubyte *azCount = NULL; + ALushort *evOffset = NULL; + ALshort *coeffs = NULL; + ALubyte *delays = NULL; + ALuint i, j; + + rate = fgetc(f); + rate |= fgetc(f)<<8; + rate |= fgetc(f)<<16; + rate |= fgetc(f)<<24; + + irSize = fgetc(f); + + evCount = fgetc(f); + + if(rate != deviceRate) + { + ERR("HRIR rate does not match device rate: rate=%d (%d)\n", + rate, deviceRate); + failed = AL_TRUE; + } + if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE)) + { + ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n", + irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE); + failed = AL_TRUE; + } + if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT) + { + ERR("Unsupported elevation count: evCount=%d (%d to %d)\n", + evCount, MIN_EV_COUNT, MAX_EV_COUNT); + failed = AL_TRUE; + } + + if(failed) + return NULL; + + azCount = malloc(sizeof(azCount[0])*evCount); + evOffset = malloc(sizeof(evOffset[0])*evCount); + if(azCount == NULL || evOffset == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + + if(!failed) + { + for(i = 0;i < evCount;i++) + { + azCount[i] = fgetc(f); + if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT) + { + ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", + i, azCount[i], MIN_AZ_COUNT, MAX_AZ_COUNT); + failed = AL_TRUE; + } + } + } + + if(!failed) + { + evOffset[0] = 0; + irCount = azCount[0]; + for(i = 1;i < evCount;i++) + { + evOffset[i] = evOffset[i-1] + azCount[i-1]; + irCount += azCount[i]; + } + + coeffs = malloc(sizeof(coeffs[0])*irSize*irCount); + delays = malloc(sizeof(delays[0])*irCount); + if(coeffs == NULL || delays == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + for(i = 0;i < irCount*irSize;i+=irSize) + { + for(j = 0;j < irSize;j++) + { + ALshort coeff; + coeff = fgetc(f); + coeff |= fgetc(f)<<8; + coeffs[i+j] = coeff; + } + } + for(i = 0;i < irCount;i++) + { + delays[i] = fgetc(f); + if(delays[i] > maxDelay) + { + ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay); + failed = AL_TRUE; + } + } + + if(feof(f)) + { + ERR("Premature end of data\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + Hrtf = malloc(sizeof(struct Hrtf)); + if(Hrtf == NULL) + { + ERR("Out of memory.\n"); + failed = AL_TRUE; + } + } + + if(!failed) + { + Hrtf->sampleRate = rate; + Hrtf->irSize = irSize; + Hrtf->evCount = evCount; + Hrtf->azCount = azCount; + Hrtf->evOffset = evOffset; + Hrtf->coeffs = coeffs; + Hrtf->delays = delays; + Hrtf->next = NULL; + return Hrtf; + } + + free(azCount); + free(evOffset); + free(coeffs); + free(delays); + return NULL; +} + + +static struct Hrtf *LoadHrtf(ALuint deviceRate) +{ + const char *fnamelist = NULL; + + if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist)) + return NULL; + while(*fnamelist != '\0') + { + struct Hrtf *Hrtf = NULL; + char fname[PATH_MAX]; + ALchar magic[8]; + ALuint i; + FILE *f; + + while(isspace(*fnamelist) || *fnamelist == ',') + fnamelist++; + i = 0; + while(*fnamelist != '\0' && *fnamelist != ',') + { + const char *next = strpbrk(fnamelist, "%,"); + while(fnamelist != next && *fnamelist && i < sizeof(fname)) + fname[i++] = *(fnamelist++); + + if(!next || *next == ',') + break; + + /* *next == '%' */ + next++; + if(*next == 'r') + { + int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate); + i += minu(wrote, sizeof(fname)-i); + next++; + } + else if(*next == '%') + { + if(i < sizeof(fname)) + fname[i++] = '%'; + next++; + } + else + ERR("Invalid marker '%%%c'\n", *next); + fnamelist = next; + } + i = minu(i, sizeof(fname)-1); + fname[i] = '\0'; + while(i > 0 && isspace(fname[i-1])) + i--; + fname[i] = '\0'; + + if(fname[0] == '\0') + continue; + + TRACE("Loading %s...\n", fname); + f = fopen(fname, "rb"); + if(f == NULL) + { + ERR("Could not open %s\n", fname); + continue; + } + + if(fread(magic, 1, sizeof(magic), f) != sizeof(magic)) + ERR("Failed to read header from %s\n", fname); + else + { + if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0) + { + TRACE("Detected data set format v0\n"); + Hrtf = LoadHrtf00(f, deviceRate); + } + else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0) + { + TRACE("Detected data set format v1\n"); + Hrtf = LoadHrtf01(f, deviceRate); + } + else + ERR("Invalid header in %s: \"%.8s\"\n", fname, magic); + } + + fclose(f); + f = NULL; + + if(Hrtf) + { + Hrtf->next = LoadedHrtfs; + LoadedHrtfs = Hrtf; + TRACE("Loaded HRTF support for format: %s %uhz\n", + DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate); + return Hrtf; + } + + ERR("Failed to load %s\n", fname); + } + + return NULL; +} + const struct Hrtf *GetHrtf(ALCdevice *device) { if(device->FmtChans == DevFmtStereo) { - ALuint i; - for(i = 0;i < NumLoadedHrtfs;i++) + struct Hrtf *Hrtf = LoadedHrtfs; + while(Hrtf != NULL) { - if(device->Frequency == LoadedHrtfs[i].sampleRate) - return &LoadedHrtfs[i]; + if(device->Frequency == Hrtf->sampleRate) + return Hrtf; + Hrtf = Hrtf->next; } + + Hrtf = LoadHrtf(device->Frequency); + if(Hrtf != NULL) + return Hrtf; + if(device->Frequency == DefaultHrtf.sampleRate) return &DefaultHrtf; } @@ -313,159 +783,46 @@ const struct Hrtf *GetHrtf(ALCdevice *device) return NULL; } -void InitHrtf(void) +void FindHrtfFormat(const ALCdevice *device, enum DevFmtChannels *chans, ALCuint *srate) { - char *fnamelist=NULL, *next=NULL; - const char *val; + const struct Hrtf *hrtf = &DefaultHrtf; - if(ConfigValueStr(NULL, "hrtf_tables", &val)) - next = fnamelist = strdup(val); - while(next && *next) + if(device->Frequency != DefaultHrtf.sampleRate) { - const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; - struct Hrtf newdata; - ALboolean failed; - ALchar magic[9]; - ALsizei i, j; - char *fname; - FILE *f; - - fname = next; - next = strchr(fname, ','); - if(next) + hrtf = LoadedHrtfs; + while(hrtf != NULL) { - while(next != fname) - { - next--; - if(!isspace(*next)) - { - *(next++) = '\0'; - break; - } - } - while(isspace(*next) || *next == ',') - next++; + if(device->Frequency == hrtf->sampleRate) + break; + hrtf = hrtf->next; } - if(!fname[0]) - continue; - TRACE("Loading %s\n", fname); - f = fopen(fname, "rb"); - if(f == NULL) - { - ERR("Could not open %s\n", fname); - continue; - } - - failed = AL_FALSE; - if(fread(magic, 1, sizeof(magicMarker), f) != sizeof(magicMarker)) - { - ERR("Failed to read magic marker\n"); - failed = AL_TRUE; - } - else if(memcmp(magic, magicMarker, sizeof(magicMarker)) != 0) - { - magic[8] = 0; - ERR("Invalid magic marker: \"%s\"\n", magic); - failed = AL_TRUE; - } - - if(!failed) - { - ALushort hrirCount, hrirSize; - ALubyte evCount; - - newdata.sampleRate = fgetc(f); - newdata.sampleRate |= fgetc(f)<<8; - newdata.sampleRate |= fgetc(f)<<16; - newdata.sampleRate |= fgetc(f)<<24; - - hrirCount = fgetc(f); - hrirCount |= fgetc(f)<<8; - - hrirSize = fgetc(f); - hrirSize |= fgetc(f)<<8; - - evCount = fgetc(f); - - if(hrirCount != HRIR_COUNT || hrirSize != HRIR_LENGTH || evCount != ELEV_COUNT) - { - ERR("Unsupported value: hrirCount=%d (%d), hrirSize=%d (%d), evCount=%d (%d)\n", - hrirCount, HRIR_COUNT, hrirSize, HRIR_LENGTH, evCount, ELEV_COUNT); - failed = AL_TRUE; - } - } - - if(!failed) - { - for(i = 0;i < HRIR_COUNT;i++) - { - ALushort offset; - offset = fgetc(f); - offset |= fgetc(f)<<8; - if(offset != evOffset[i]) - { - ERR("Unsupported evOffset[%d] value: %d (%d)\n", i, offset, evOffset[i]); - failed = AL_TRUE; - } - } - } - - if(!failed) - { - for(i = 0;i < HRIR_COUNT;i++) - { - for(j = 0;j < HRIR_LENGTH;j++) - { - ALshort coeff; - coeff = fgetc(f); - coeff |= fgetc(f)<<8; - newdata.coeffs[i][j] = coeff; - } - } - for(i = 0;i < HRIR_COUNT;i++) - { - ALubyte delay; - delay = fgetc(f); - newdata.delays[i] = delay; - if(delay > maxDelay) - { - ERR("Invalid delay[%d]: %d (%d)\n", i, delay, maxDelay); - failed = AL_TRUE; - } - } - - if(feof(f)) - { - ERR("Premature end of data\n"); - failed = AL_TRUE; - } - } - - fclose(f); - f = NULL; - - if(!failed) - { - void *temp = realloc(LoadedHrtfs, (NumLoadedHrtfs+1)*sizeof(LoadedHrtfs[0])); - if(temp != NULL) - { - LoadedHrtfs = temp; - TRACE("Loaded HRTF support for format: %s %uhz\n", - DevFmtChannelsString(DevFmtStereo), newdata.sampleRate); - LoadedHrtfs[NumLoadedHrtfs++] = newdata; - } - } - else - ERR("Failed to load %s\n", fname); + if(hrtf == NULL) + hrtf = LoadHrtf(device->Frequency); + if(hrtf == NULL) + hrtf = &DefaultHrtf; } - free(fnamelist); - fnamelist = NULL; + + *chans = DevFmtStereo; + *srate = hrtf->sampleRate; } -void FreeHrtf(void) +void FreeHrtfs(void) { - NumLoadedHrtfs = 0; - free(LoadedHrtfs); - LoadedHrtfs = NULL; + struct Hrtf *Hrtf = NULL; + + while((Hrtf=LoadedHrtfs) != NULL) + { + LoadedHrtfs = Hrtf->next; + free((void*)Hrtf->azCount); + free((void*)Hrtf->evOffset); + free((void*)Hrtf->coeffs); + free((void*)Hrtf->delays); + free(Hrtf); + } +} + +ALuint GetHrtfIrSize (const struct Hrtf *Hrtf) +{ + return Hrtf->irSize; } diff --git a/jni/openal-soft-android/Alc/hrtf_tables.inc b/jni/openal-soft-android/Alc/hrtf_tables.inc index 4ba1416e..9c6af6a1 100644 --- a/jni/openal-soft-android/Alc/hrtf_tables.inc +++ b/jni/openal-soft-android/Alc/hrtf_tables.inc @@ -1,839 +1,848 @@ -/* This data is Copyright 1994 by the MIT Media Laboratory. It is provided free - * with no restrictions on use, provided the authors are cited when the data is - * used in any research or commercial application. */ -/* Bill Gardner and Keith Martin */ +/* Elevation metrics */ +static const ALubyte defaultAzCount[19] = { 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1, }; +static const ALushort defaultEvOffset[19] = { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827, }; - /* HRIR Coefficients */ - { - { +5817, +7833, +3253, +2795, +1080, +403, +948, -690, -2207, -1110, +658, -33, -481, -949, -839, -287, -146, -103, +7, -47, -269, -105, -316, -221, -304, -497, -373, -231, -114, -14, +66, -62, }, - { +6586, +8107, +2781, +3167, +1095, +99, +922, -641, -2255, -1457, +602, +170, -469, -781, -818, -773, -258, +8, -111, -125, -368, -216, -345, -265, -298, -447, -408, -158, -22, +0, +63, -96, }, - { +5986, +7570, +2713, +2756, +1080, +403, +921, -758, -2112, -1067, +565, -93, -431, -738, -604, -361, -238, +10, +63, -88, -302, -101, -306, -243, -358, -488, -341, -224, -98, -1, +79, -55, }, - { +5571, +7005, +2499, +2549, +974, +438, +959, -688, -1966, -793, +755, -35, -305, -631, -545, -165, -118, -72, +26, -36, -228, -36, -253, -158, -261, -436, -311, -197, -85, +11, +82, -47, }, - { +5472, +6865, +2460, +2524, +978, +492, +1057, -561, -1857, -706, +813, -3, -353, -739, -587, -120, -98, -94, +21, -32, -228, -31, -232, -119, -204, -399, -293, -197, -124, -45, +34, -81, }, - { +5627, +7081, +2487, +2449, +858, +396, +981, -676, -2051, -899, +820, +82, -332, -774, -643, -127, -26, -14, +72, +27, -183, -16, -234, -142, -240, -422, -289, -151, -36, +63, +108, -65, }, - { +6172, +7677, +2541, +2564, +874, +397, +966, -927, -2421, -1117, +905, +38, -545, -990, -785, -200, -66, -60, +50, +17, -244, -35, -244, -146, -246, -433, -290, -139, -42, +40, +108, -37, }, - { +6521, +8320, +2827, +2690, +909, +230, +917, -1084, -2525, -1115, +652, -122, -480, -974, -823, -289, -150, +21, +73, -58, -296, -90, -299, -198, -317, -480, -327, -206, -64, +25, +103, -47, }, - { +6956, +8505, +2738, +3040, +1131, +209, +719, -1389, -2419, -516, +530, -857, -697, -801, -443, -77, -328, -117, +128, -70, -281, -49, -356, -233, -419, -579, -344, -271, -169, -16, +76, -98, }, - { +7928, +9215, +2040, +2470, +595, +264, +1348, -1308, -2698, -258, +1302, -836, -1179, -1210, -483, +125, -403, -370, +81, -61, -416, -45, -378, -208, -426, -708, -383, -223, -150, -20, +82, -119, }, - { +8205, +9593, +2241, +2306, +197, +241, +1480, -1080, -3081, -704, +1757, -153, -1144, -1906, -912, +311, -4, -441, -129, -99, -476, -104, -467, -207, -379, -660, -412, -194, -106, -31, +48, -172, }, - { +7822, +9388, +3008, +2690, +349, +155, +1066, -976, -3351, -1396, +1366, +202, -165, -1794, -1686, +63, +209, -110, -81, -164, -375, -114, -487, -174, -394, -771, -456, -312, -109, +27, +100, -71, }, - { +7342, +9001, +2833, +2968, +859, +118, +830, -1009, -2609, -1583, +1030, +177, -566, -888, -1564, -882, +55, +78, +62, +48, -275, -224, -531, -354, -242, -534, -487, -241, -107, +31, +92, -76, }, - { +7420, +8277, +2251, +3723, +1049, -308, +945, -518, -2311, -1945, +592, +496, -502, -565, -848, -1420, -265, +189, -293, -192, -468, -339, -342, -319, -275, -379, -474, -58, +77, -10, +55, -134, }, - { +6584, +7746, +2495, +3374, +1000, -52, +897, -756, -2030, -1406, +280, +34, -398, -477, -456, -856, -571, +107, +104, -158, -435, -199, -286, -253, -345, -425, -316, -178, -107, -66, +74, -62, }, - { +6049, +7215, +2251, +2809, +1129, +395, +858, -790, -1953, -1091, +399, -101, -343, -474, -371, -537, -334, +183, +103, -155, -328, -94, -287, -281, -418, -457, -307, -226, -82, +10, +91, -45, }, - { +5611, +6654, +2026, +2614, +1122, +421, +846, -730, -1795, -787, +486, -181, -199, -331, -331, -290, -184, +57, +64, -94, -264, -59, -241, -160, -276, -381, -321, -242, -63, +33, +98, -44, }, - { +5099, +6036, +1921, +2401, +945, +508, +937, -640, -1638, -506, +755, -23, -74, -266, -268, -108, -114, -39, +41, -26, -172, +33, -185, -102, -220, -366, -254, -174, -58, +33, +94, -28, }, - { +4863, +5622, +1644, +2154, +818, +547, +1098, -307, -1280, -210, +982, +96, -111, -376, -319, -58, -43, -22, +51, -10, -188, -3, -174, -47, -165, -316, -201, -114, -14, +20, +16, -134, }, - { +4874, +5742, +1871, +2357, +961, +630, +1147, -376, -1424, -337, +863, +34, -193, -499, -332, +8, -81, -97, +36, -13, -175, +46, -137, -17, -102, -297, -226, -178, -147, -83, +1, -91, }, - { +4960, +5827, +1797, +2194, +842, +622, +1162, -376, -1492, -421, +910, +56, -246, -568, -430, +32, +120, +83, +106, +18, -182, -19, -208, -85, -152, -240, -94, -64, -84, -82, -30, -123, }, - { +5228, +6194, +1872, +2175, +707, +445, +1001, -617, -1837, -723, +933, +227, -167, -586, -451, +10, +86, +68, +127, +106, -88, +66, -146, -70, -175, -339, -208, -74, +41, +139, +139, -76, }, - { +5697, +6722, +1953, +2283, +727, +469, +969, -882, -2258, -1037, +972, +175, -413, -806, -593, -28, +130, +87, +177, +163, -115, +43, -180, -84, -142, -297, -156, -24, +4, +49, +85, -29, }, - { +6473, +7408, +1826, +2417, +711, +442, +966, -1188, -2613, -1118, +1193, +107, -644, -1020, -716, -117, +16, -26, +92, +89, -223, +39, -164, -76, -190, -362, -208, -46, +24, +86, +145, -12, }, - { +7101, +8208, +1841, +2445, +711, +357, +985, -1505, -2879, -1121, +1181, +70, -658, -1173, -814, -168, -29, +29, +47, +36, -265, -40, -293, -166, -283, -429, -229, -63, +43, +81, +160, -20, }, - { +7271, +8783, +2298, +2617, +755, +48, +900, -1532, -2806, -1083, +615, -189, -449, -1001, -807, -311, -150, +184, +122, -88, -322, -71, -273, -179, -335, -451, -278, -188, -9, +60, +138, -32, }, - { +7519, +8972, +2519, +3099, +1077, -70, +527, -1818, -2665, -568, +208, -889, -424, -657, -398, -291, -483, +67, +222, -56, -219, -19, -307, -204, -436, -529, -306, -304, -126, +27, +128, -48, }, - { +8267, +9086, +2039, +3441, +1167, -66, +449, -2175, -2478, +261, +170, -1844, -741, -537, +19, +68, -620, -86, +289, -131, -285, +19, -414, -244, -560, -647, -289, -330, -230, -5, +89, -141, }, - { +9334, +10020, +1039, +2681, +800, -36, +1253, -2153, -2906, +675, +921, -2082, -1336, -748, +118, +362, -708, -352, +305, -89, -430, +16, -461, -267, -609, -817, -292, -288, -287, -70, +134, -107, }, - { +10490, +10443, +234, +2319, +106, +215, +1880, -2162, -3146, +928, +1870, -2011, -1861, -1339, +44, +548, -846, -647, +252, -93, -597, +65, -464, -180, -581, -943, -344, -209, -200, -20, +104, -191, }, - { +11090, +10859, +176, +1929, -492, +415, +2257, -1899, -3660, +617, +2693, -1436, -2083, -2245, -339, +944, -576, -854, +49, -173, -603, +64, -607, -194, -525, -910, -310, -113, -162, +10, +55, -268, }, - { +11123, +11231, +589, +1885, -762, +272, +2193, -1677, -4087, +10, +3036, -569, -1972, -2950, -747, +1099, +20, -922, -216, -122, -721, -53, -651, -153, -474, -845, -423, -135, -107, -57, +30, -304, }, - { +10803, +11222, +1474, +2265, -883, +91, +1845, -1667, -4470, -728, +2793, +190, -972, -3366, -1480, +1091, +471, -617, -486, -175, -639, -113, -591, -51, -507, -934, -502, -309, -106, -118, +53, -177, }, - { +10246, +10868, +2402, +2554, -531, +31, +1268, -1323, -4728, -1500, +2335, +359, +174, -2966, -2559, +743, +585, -219, -198, -287, -474, -103, -696, -72, -517, -1094, -493, -391, -81, +78, +133, -87, }, - { +9638, +10459, +2554, +3136, -109, -170, +1213, -1306, -4339, -2094, +2099, +264, +202, -1798, -3312, -170, +781, +126, +63, -260, -424, +20, -759, -504, -338, -983, -510, -236, -85, +153, +125, -96, }, - { +9150, +10114, +2114, +3243, +563, -199, +731, -1335, -3018, -2131, +1610, +397, -733, -785, -2524, -1463, +491, +266, +80, +156, -304, -383, -768, -471, -118, -592, -631, -225, -95, +87, +113, -96, }, - { +8454, +9243, +2047, +3497, +881, -249, +701, -1042, -2617, -2062, +1294, +712, -942, -676, -1397, -1797, -57, +250, -231, -14, -250, -237, -521, -454, -179, -387, -649, -192, -30, +13, +161, -121, }, - { +8323, +8323, +1685, +4494, +893, -823, +1049, -315, -2397, -2598, +672, +957, -622, -284, -950, -2240, -109, +425, -567, -229, -570, -475, -300, -391, -228, -295, -579, +83, +176, -48, +44, -175, }, - { +7274, +7900, +2262, +4107, +785, -714, +918, -662, -1986, -1894, +51, +378, -372, -108, -420, -1664, -750, +303, +73, -176, -577, -344, -248, -256, -255, -331, -406, -129, -13, -101, +50, -88, }, - { +6560, +7256, +2146, +3528, +960, -9, +858, -751, -1783, -1572, +54, +101, -313, -181, -229, -1133, -648, +400, +128, -265, -444, -160, -232, -331, -449, -399, -265, -206, -153, -62, +116, -28, }, - { +5980, +6790, +1905, +2935, +1217, +364, +757, -764, -1730, -1213, +165, -24, -228, -158, -154, -831, -410, +428, +110, -247, -340, -86, -256, -338, -480, -399, -278, -238, -61, +18, +103, -30, }, - { +5480, +6206, +1692, +2736, +1300, +391, +709, -692, -1565, -861, +226, -147, -68, -24, -127, -550, -217, +281, +49, -181, -257, -43, -247, -249, -345, -298, -274, -270, -50, +56, +119, -43, }, - { +4953, +5620, +1632, +2478, +1119, +519, +800, -639, -1430, -598, +380, -73, +141, +70, -109, -295, -151, +126, +65, -105, -195, +54, -97, -104, -271, -314, -265, -208, -14, +48, +99, +5, }, - { +4358, +4972, +1588, +2310, +986, +595, +869, -526, -1223, -277, +652, +34, +216, +141, -22, -120, -122, +1, +49, -14, -101, +99, -108, -54, -180, -284, -207, -160, -31, +53, +104, -2, }, - { +4049, +4526, +1367, +2016, +774, +619, +1057, -193, -943, +8, +975, +238, +224, +73, -43, -96, -105, -16, +104, +54, -140, +64, -50, +12, -174, -276, -142, -78, +11, +66, +70, -116, }, - { +3893, +4241, +1180, +1972, +964, +806, +1165, +33, -630, +212, +995, +139, -10, -165, -98, +59, +41, +7, +5, -42, -115, +70, -77, +64, -30, -184, -140, -90, -15, -39, -72, -166, }, - { +3974, +4515, +1563, +2245, +1024, +802, +1202, -117, -913, -34, +802, +109, -1, -233, -83, +92, -89, -104, +51, +9, -107, +121, -30, +82, +5, -192, -173, -173, -183, -127, -31, -91, }, - { +4054, +4585, +1487, +2101, +966, +877, +1249, -118, -989, -177, +776, +97, -55, -258, -131, +135, +150, +93, +56, -19, -114, +43, -129, +22, -1, -45, +2, -139, -203, -156, -63, -102, }, - { +4259, +4784, +1375, +1894, +699, +649, +1161, -136, -1098, -231, +956, +281, +11, -419, -371, +109, +241, +228, +268, +110, -100, +71, -147, -93, -92, -157, -42, +95, +87, -12, -90, -205, }, - { +4579, +5216, +1470, +1933, +626, +538, +991, -498, -1568, -608, +1002, +425, +4, -387, -268, +119, +196, +143, +174, +193, +16, +138, -48, -8, -110, -248, -134, +1, +116, +214, +157, -94, }, - { +5066, +5749, +1521, +2044, +640, +538, +926, -811, -2022, -949, +1051, +371, -252, -591, -377, +160, +302, +178, +234, +199, -60, +136, -88, +2, -40, -201, -104, +47, +67, +67, +148, +54, }, - { +5824, +6357, +1417, +2188, +604, +584, +938, -1093, -2439, -1140, +1270, +283, -550, -828, -547, +25, +209, +96, +231, +241, -75, +150, -72, -37, -72, -173, -85, +78, +65, +65, +106, -26, }, - { +6705, +7034, +1139, +2353, +584, +531, +931, -1467, -2777, -1121, +1528, +169, -787, -1030, -630, -42, +104, -4, +133, +171, -212, +119, -74, -14, -133, -284, -130, +49, +82, +127, +179, +14, }, - { +7494, +7838, +930, +2406, +628, +447, +939, -1854, -3086, -1058, +1655, +110, -889, -1206, -690, -58, +26, -36, +86, +157, -264, +21, -209, -75, -225, -353, -152, +18, +88, +139, +234, +25, }, - { +7942, +8659, +1161, +2413, +549, +251, +1028, -2079, -3182, -1091, +1258, +58, -663, -1281, -862, -154, +30, +213, +47, +25, -289, -45, -300, -173, -306, -391, -167, -32, +123, +117, +202, -22, }, - { +8068, +9218, +1660, +2593, +617, -151, +900, -2038, -3036, -1021, +535, -219, -391, -1036, -790, -354, -141, +391, +141, -138, -345, -47, -238, -167, -360, -407, -230, -180, +55, +90, +173, -18, }, - { +8265, +9463, +2020, +3087, +909, -384, +486, -2292, -2858, -489, -42, -958, -218, -589, -423, -435, -531, +296, +255, -79, -195, -39, -305, -178, -439, -471, -257, -338, -66, +74, +175, -25, }, - { +8828, +9479, +1858, +3692, +1200, -444, +108, -2595, -2598, +225, -443, -1837, -211, -338, +130, -297, -878, +233, +403, -155, -160, +68, -348, -198, -618, -577, -252, -401, -165, +50, +123, -106, }, - { +9769, +9532, +1154, +4053, +1153, -433, +152, -3044, -2341, +1209, -501, -2958, -549, -180, +526, +122, -1023, +24, +484, -243, -273, +98, -497, -249, -730, -696, -208, -420, -294, +24, +104, -194, }, - { +10963, +10314, -18, +3480, +928, -378, +839, -3146, -2679, +1815, +181, -3477, -1184, -280, +767, +456, -1173, -196, +557, -284, -445, +171, -561, -316, -811, -844, -191, -379, -352, -44, +133, -183, }, - { +12437, +11094, -1445, +2785, +310, -110, +1926, -3295, -3171, +2280, +1217, -3589, -1908, -710, +881, +724, -1458, -605, +653, -147, -678, +163, -557, -237, -805, -1040, -224, -349, -355, -12, +190, -216, }, - { +13565, +11394, -2213, +2503, -423, +267, +2542, -3317, -3490, +2485, +2267, -3594, -2432, -1318, +735, +938, -1508, -888, +536, -170, -812, +241, -591, -131, -780, -1195, -241, -201, -267, -8, +131, -283, }, - { +14365, +11785, -2502, +2065, -1128, +690, +3071, -3145, -4082, +2294, +3294, -3126, -2782, -2332, +449, +1450, -1337, -1152, +323, -232, -796, +274, -707, -133, -760, -1160, -175, -77, -224, +1, +81, -344, }, - { +14713, +12188, -2245, +1714, -1545, +697, +3166, -2769, -4728, +1796, +4066, -2366, -3022, -3257, +104, +1860, -844, -1416, +119, -254, -847, +177, -909, -97, -642, -1112, -239, -41, -190, +38, +3, -445, }, - { +14645, +12610, -1772, +1687, -1818, +544, +3067, -2552, -5197, +1109, +4450, -1369, -2921, -4051, -284, +2048, -140, -1537, -208, -123, -1018, +64, -886, -45, -602, -1050, -397, -58, -122, -90, +12, -460, }, - { +14311, +12744, -823, +2013, -2087, +348, +2751, -2573, -5594, +298, +4380, -359, -2003, -4793, -1003, +2181, +482, -1298, -654, -93, -995, -9, -758, +71, -678, -1141, -461, -235, -94, -220, +50, -343, }, - { +13776, +12639, +346, +2236, -2014, +116, +2251, -2236, -6147, -504, +3963, +239, -615, -5033, -2049, +2178, +726, -876, -698, -265, -701, -87, -865, +185, -648, -1310, -522, -464, -75, -87, +92, -171, }, - { +13149, +12169, +1402, +2459, -1565, +84, +1536, -1759, -6362, -1341, +3564, +365, +555, -4522, -3382, +1810, +905, -453, -324, -409, -562, -71, -953, +103, -691, -1468, -465, -480, -26, +135, +160, -111, }, - { +12380, +11681, +1885, +3275, -1333, -131, +1419, -1701, -5961, -2232, +3308, +405, +924, -3382, -4610, +1021, +1316, -94, -127, -370, -464, +43, -1042, -366, -474, -1380, -504, -384, +12, +312, +117, -135, }, - { +11903, +11393, +1499, +3646, -589, -712, +1361, -1471, -5102, -2585, +2953, +277, +167, -1768, -4726, -478, +1438, +247, +197, -198, -524, -85, -1094, -602, -205, -1156, -495, -151, -147, +245, +126, -155, }, - { +11277, +11106, +1068, +3696, +162, -535, +662, -1668, -3438, -2767, +2450, +580, -999, -611, -3766, -1971, +1197, +402, +51, +288, -364, -586, -1018, -564, +72, -690, -805, -170, -83, +153, +125, -123, }, - { +10588, +10248, +1041, +3990, +549, -596, +503, -1508, -2940, -2531, +2104, +852, -1356, -383, -2481, -2696, +537, +474, -251, +251, -199, -459, -926, -574, +197, -420, -1013, -187, +29, +54, +181, -131, }, - { +9521, +9264, +1317, +4316, +722, -767, +764, -816, -2661, -2833, +1508, +1326, -1203, -394, -1458, -2679, +165, +492, -606, -94, -331, -324, -381, -536, -231, -294, -717, -35, +53, -16, +190, -183, }, - { +9295, +8224, +1109, +5503, +566, -1438, +1272, -36, -2542, -3436, +897, +1558, -877, +95, -1150, -3243, +276, +686, -962, -210, -683, -628, -208, -496, -150, -199, -735, +279, +265, -118, +39, -219, }, - { +7955, +7915, +2062, +4941, +392, -1429, +1053, -497, -1939, -2532, -124, +882, -416, +352, -483, -2672, -726, +593, -30, -164, -732, -489, -159, -285, -145, -245, -559, -60, +99, -150, +30, -106, }, - { +7031, +7277, +2031, +4336, +697, -646, +955, -623, -1641, -2182, -233, +535, -317, +229, -165, -1960, -826, +699, +101, -378, -580, -260, -151, -369, -398, -280, -286, -150, -143, -139, +125, -38, }, - { +6295, +6730, +1892, +3559, +1033, +63, +744, -685, -1521, -1804, -171, +306, -225, +149, +4, -1512, -648, +773, +80, -370, -396, -159, -189, -414, -539, -344, -273, -228, -102, -44, +122, +2, }, - { +5567, +6186, +1652, +2969, +1443, +344, +573, -641, -1422, -1343, -105, +121, -57, +247, +28, -1174, -348, +731, +56, -360, -317, -47, -217, -426, -532, -288, -251, -274, -18, +48, +118, -19, }, - { +4996, +5539, +1497, +2838, +1501, +319, +538, -541, -1215, -962, -91, -26, +159, +383, +48, -835, -191, +492, -4, -250, -216, -31, -205, -289, -352, -182, -273, -311, -10, +79, +133, -33, }, - { +4369, +4911, +1493, +2561, +1337, +470, +618, -484, -1046, -662, +27, +2, +405, +487, +57, -528, -160, +283, +46, -156, -163, +53, -43, -114, -258, -209, -289, -247, +29, +65, +110, +22, }, - { +3634, +4210, +1572, +2321, +1183, +650, +679, -395, -859, -352, +291, +111, +541, +545, +126, -276, -117, +132, +29, -68, -30, +169, -23, -64, -184, -195, -205, -180, +9, +60, +105, +51, }, - { +3016, +3577, +1500, +2051, +987, +707, +858, -234, -596, +114, +631, +273, +558, +609, +229, -166, -145, -29, +96, +94, -41, +113, +28, +51, -118, -204, -138, -123, -4, +88, +117, +1, }, - { +2776, +3142, +1225, +1761, +847, +791, +1067, +272, -238, +302, +902, +413, +488, +421, +138, -130, -62, +38, +115, +77, -79, +99, +64, +85, -110, -151, -69, -33, +59, +61, +9, -164, }, - { +2597, +2855, +1075, +1771, +1129, +1005, +1152, +473, +68, +492, +881, +270, +197, +161, +118, +79, +88, +32, -20, -32, -27, +115, +32, +153, +68, -66, -90, -62, +9, -70, -139, -184, }, - { +2669, +3145, +1471, +2033, +1221, +1035, +1183, +275, -243, +270, +725, +249, +159, +52, +151, +138, -51, -81, +23, -1, -18, +190, +86, +173, +118, -82, -134, -156, -186, -160, -81, -98, }, - { +2819, +3343, +1567, +2048, +1169, +1075, +1248, +244, -402, -85, +455, +306, +297, +79, +134, +124, +55, +91, +34, -77, +10, +181, -46, +108, +219, +134, -56, -289, -273, -145, -92, -88, }, - { +2900, +3386, +1384, +1773, +1008, +1084, +1261, +225, -495, +12, +783, +242, +37, -53, -9, +253, +383, +202, +102, +70, -62, +11, -40, +64, +31, +110, +190, -6, -190, -236, -126, -117, }, - { +3231, +3701, +1275, +1612, +705, +788, +1133, +122, -729, -179, +937, +566, +221, -206, -199, +166, +308, +308, +335, +202, +36, +131, -62, -37, -38, -83, +43, +191, +169, +38, -106, -235, }, - { +3635, +4205, +1339, +1662, +626, +662, +937, -299, -1254, -578, +1037, +699, +166, -176, -99, +200, +312, +211, +211, +294, +129, +195, +63, +39, -40, -148, -70, +74, +192, +288, +163, -117, }, - { +4194, +4783, +1346, +1788, +630, +642, +840, -677, -1766, -952, +1124, +635, -123, -376, -187, +304, +462, +242, +276, +259, +18, +219, +17, +71, +61, -99, -59, +121, +125, +97, +206, +113, }, - { +4979, +5362, +1202, +1940, +602, +719, +840, -1009, -2235, -1155, +1361, +510, -477, -624, -359, +169, +423, +212, +324, +400, +17, +168, -5, +20, +47, -58, +31, +174, +74, +79, +86, +27, }, - { +6045, +6030, +859, +2185, +506, +725, +848, -1395, -2650, -1218, +1701, +338, -794, -842, -492, +56, +296, +67, +259, +328, -97, +236, +42, +27, -10, -99, -27, +180, +116, +105, +139, -10, }, - { +7127, +6787, +391, +2413, +495, +620, +850, -1887, -2997, -1109, +1985, +195, -1031, -1079, -541, +28, +148, +5, +155, +227, -224, +200, +4, -1, -101, -203, -81, +123, +136, +165, +254, +85, }, - { +8041, +7641, +54, +2482, +542, +525, +873, -2340, -3303, -988, +2101, +103, -1125, -1253, -590, +7, +85, -30, +110, +254, -288, +69, -159, -33, -202, -285, -79, +104, +146, +180, +291, +49, }, - { +8670, +8596, +151, +2444, +429, +355, +1004, -2691, -3423, -1007, +1694, +127, -881, -1445, -767, -93, +121, +297, -11, +97, -290, +1, -294, -164, -296, -328, -78, +89, +211, +122, +240, -5, }, - { +8845, +9339, +619, +2533, +443, -115, +1042, -2670, -3312, -1004, +882, -48, -483, -1247, -888, -243, +10, +511, +67, -76, -337, -56, -239, -164, -351, -335, -149, -114, +174, +149, +241, -25, }, - { +8992, +9809, +1188, +2897, +625, -583, +690, -2700, -3089, -635, -11, -646, -104, -790, -618, -507, -344, +619, +168, -148, -236, -69, -262, -132, -414, -375, -196, -304, +74, +121, +206, -26, }, - { +9299, +9977, +1439, +3466, +927, -820, +224, -3016, -2800, -12, -737, -1360, +110, -354, -169, -639, -802, +553, +363, -141, -128, +0, -287, -205, -550, -443, -225, -438, -58, +99, +221, -4, }, - { +10058, +9879, +1163, +4263, +1177, -922, -219, -3311, -2434, +862, -1303, -2457, +248, -70, +493, -501, -1236, +540, +538, -275, -74, +119, -379, -193, -775, -553, -189, -513, -161, +91, +140, -128, }, - { +11144, +9761, +369, +4862, +1071, -936, -203, -3855, -2065, +1997, -1565, -3828, +38, +198, +979, -90, -1513, +341, +661, -404, -156, +165, -600, -237, -878, -660, -142, -564, -301, +70, +104, -215, }, - { +12546, +10246, -966, +4691, +927, -833, +309, -4199, -2112, +2959, -1144, -4789, -535, +243, +1329, +364, -1689, +85, +795, -505, -386, +288, -677, -309, -1025, -827, -61, -516, -419, +27, +137, -278, }, - { +14045, +11382, -2788, +3760, +580, -650, +1686, -4408, -2934, +3566, -51, -5174, -1321, +73, +1428, +705, -1911, -307, +891, -369, -599, +281, -731, -286, -1048, -1082, -16, -454, -510, -50, +248, -211, }, - { +15970, +11714, -4486, +3446, -223, -120, +2672, -4778, -3223, +4216, +1130, -5477, -2203, -468, +1756, +960, -2402, -712, +1105, -303, -935, +391, -711, -185, -1048, -1265, -82, -424, -432, +54, +241, -341, }, - { +17220, +11916, -5327, +3210, -1072, +444, +3327, -4843, -3644, +4439, +2382, -5600, -2783, -1154, +1580, +1254, -2411, -1038, +941, -324, -1057, +499, -778, -47, -1032, -1459, -61, -214, -352, +22, +162, -398, }, - { +18240, +12274, -5799, +2731, -1899, +1079, +3952, -4749, -4376, +4334, +3662, -5208, -3266, -2349, +1378, +1910, -2296, -1381, +715, -370, -1038, +545, -912, -20, -1028, -1437, +31, -67, -319, +18, +102, -464, }, - { +18833, +12668, -5683, +2184, -2439, +1329, +4171, -4328, -5232, +3901, +4824, -4546, -3741, -3476, +1105, +2561, -1914, -1779, +533, -418, -1036, +485, -1184, +14, -859, -1412, +1, +27, -315, +91, +5, -584, }, - { +19008, +13162, -5318, +1926, -2788, +1224, +4180, -3950, -5962, +3321, +5549, -3543, -3998, -4445, +848, +2902, -1193, -2106, +263, -305, -1180, +327, -1267, +112, -828, -1285, -169, +16, -197, +33, -71, -637, }, - { +18737, +13681, -4618, +1963, -3145, +1044, +4007, -3789, -6476, +2407, +5985, -2289, -3707, -5492, +344, +3198, -328, -2230, -228, -74, -1401, +254, -1150, +181, -810, -1310, -322, -25, -144, -179, +21, -629, }, - { +18348, +13822, -3468, +2221, -3496, +867, +3623, -3756, -6961, +1517, +5968, -1098, -2716, -6475, -416, +3438, +367, -2015, -778, +7, -1351, +154, -986, +288, -914, -1395, -403, -225, -85, -331, +78, -475, }, - { +17731, +13756, -2024, +2354, -3509, +578, +3074, -3309, -7685, +628, +5586, -260, -1146, -7037, -1592, +3604, +681, -1553, -946, -177, -966, +4, -1088, +448, -897, -1594, -473, -493, -35, -196, +111, -266, }, - { +16988, +13672, -858, +2219, -2857, +446, +2261, -2723, -8186, -143, +5173, +8, +354, -6856, -3083, +3505, +877, -1058, -660, -442, -746, +8, -1186, +419, -932, -1761, -398, -679, +86, +39, +115, -97, }, - { +16138, +12803, +575, +2903, -2738, +274, +1624, -2112, -8167, -1458, +4911, +239, +1463, -6034, -4971, +3030, +1336, -611, -295, -547, -554, +6, -1339, +184, -852, -1914, -351, -543, +76, +333, +176, -169, }, - { +15265, +12532, +737, +3734, -2365, -148, +1753, -2212, -7519, -2381, +4804, +154, +1395, -4336, -6360, +1992, +1942, -242, -104, -546, -503, +190, -1457, -473, -403, -1767, -438, -339, +44, +430, +96, -165, }, - { +14708, +12215, +282, +4265, -1521, -1002, +1719, -1840, -6421, -2928, +4336, +115, +445, -2293, -6587, +102, +2286, +140, +231, -302, -617, -45, -1479, -669, -78, -1505, -452, -92, -181, +382, +108, -202, }, - { +13989, +12100, -300, +4352, -584, -894, +751, -1879, -4250, -3597, +3863, +484, -1133, -527, -5742, -1882, +2289, +370, +107, +366, -557, -756, -1254, -675, +260, -958, -884, -49, -127, +270, +110, -168, }, - { +13107, +11235, -316, +4649, +46, -886, +387, -2126, -3083, -3291, +3067, +1077, -1914, +82, -4188, -3391, +1793, +547, -349, +600, -246, -893, -1266, -562, +499, -574, -1293, -81, +40, +122, +177, -141, }, - { +12123, +10207, -26, +5040, +240, -1159, +554, -1339, -3049, -3489, +2834, +1553, -2088, +86, -2702, -3839, +1078, +690, -758, +264, -223, -525, -820, -718, +257, -322, -1226, +21, +75, +12, +282, -234, }, - { +10747, +9168, +566, +5397, +351, -1371, +926, -546, -2786, -3752, +1902, +1979, -1557, -9, -1749, -3706, +668, +745, -1061, -69, -419, -453, -245, -659, -216, -192, -848, +155, +137, -64, +205, -239, }, - { +10338, +7957, +561, +6771, -2, -2128, +1652, +306, -2773, -4474, +1333, +2284, -1324, +617, -1488, -4429, +966, +918, -1497, -98, -822, -796, -54, -649, -27, -96, -951, +551, +331, -223, +48, -268, }, - { +8720, +7871, +1937, +5955, -252, -2274, +1362, -265, -1942, -3385, -195, +1599, -597, +942, -704, -3945, -437, +923, -232, -93, -938, -655, -8, -340, +19, -166, -798, +69, +242, -236, +6, -124, }, - { +7602, +7369, +1980, +5375, +188, -1525, +1271, -440, -1548, -3046, -447, +1237, -466, +757, -218, -3077, -861, +1080, +8, -496, -751, -394, -12, -415, -286, -141, -377, -40, -114, -262, +138, -57, }, - { +6659, +6622, +2031, +4526, +599, -537, +864, -488, -1252, -2664, -491, +837, -265, +650, -6, -2474, -736, +1187, -23, -536, -523, -192, -58, -543, -514, -195, -232, -228, -227, -106, +203, +4, }, - { +5900, +6258, +1847, +3648, +1138, +55, +581, -518, -1216, -2232, -426, +663, -175, +546, +190, -2072, -582, +1218, -57, -487, -330, -182, -121, -530, -618, -248, -293, -250, -52, -43, +131, +41, }, - { +5056, +5699, +1640, +3073, +1682, +223, +366, -415, -1093, -1701, -428, +436, +76, +685, +156, -1697, -250, +1101, -72, -482, -271, -35, -164, -545, -578, -155, -255, -314, +31, +57, +129, +2, }, - { +4420, +5031, +1526, +2971, +1795, +154, +317, -287, -871, -1279, -467, +257, +332, +803, +167, -1309, -82, +802, -141, -342, -151, -34, -185, -411, -382, -26, -278, -370, +32, +101, +150, -29, }, - { +3741, +4414, +1550, +2755, +1697, +240, +358, -209, -641, -963, -482, +156, +636, +955, +153, -952, -130, +526, -22, -234, -141, -29, -17, -156, -225, -73, -393, -324, +91, +81, +127, +14, }, - { +2974, +3771, +1714, +2268, +1466, +609, +473, -195, -532, -642, -208, +371, +868, +928, +168, -618, -68, +350, +7, -152, -30, +198, +164, -106, -265, -109, -239, -204, +88, +59, +101, +117, }, - { +2091, +3036, +1907, +2129, +1391, +724, +464, -41, -262, -310, +40, +365, +939, +1032, +282, -384, -88, +174, -12, -37, +129, +229, +41, -48, -98, -70, -190, -179, +36, +72, +111, +99, }, - { +1445, +2433, +1850, +1781, +1171, +805, +720, +119, +17, +232, +387, +551, +917, +1092, +388, -310, -142, -4, +121, +154, +38, +139, +164, +94, -72, -106, -103, -116, +22, +112, +121, +28, }, - { +1185, +1993, +1603, +1441, +986, +909, +956, +692, +298, +365, +753, +730, +851, +889, +295, -301, -75, +80, +163, +139, -24, +148, +231, +110, -113, -59, -17, -3, +88, +93, +26, -171, }, - { +929, +1455, +1263, +1389, +1207, +1075, +1117, +1195, +937, +623, +608, +551, +588, +631, +253, -42, +158, +103, +4, +39, +49, +61, +131, +212, +119, +81, -26, +0, +138, -59, -235, -232, }, - { +822, +1583, +1506, +1563, +1699, +1350, +1018, +900, +685, +649, +736, +432, +188, +378, +360, +160, +134, -13, -136, -75, +123, +246, +203, +257, +240, +33, -106, -86, -100, -185, -187, -131, }, - { +1055, +2056, +2052, +1866, +1431, +1170, +1157, +723, +299, +248, +365, +522, +438, +367, +368, +108, -145, -117, +92, +69, +74, +249, +238, +249, +240, +27, -128, -200, -286, -220, -88, -53, }, - { +1205, +2171, +1980, +1773, +1441, +1300, +1201, +725, +193, -127, +142, +624, +550, +387, +335, +108, +110, +159, +2, -95, +146, +227, +29, +177, +403, +337, -41, -376, -330, -171, -140, -61, }, - { +1241, +2158, +1760, +1464, +1328, +1398, +1227, +684, +95, +70, +568, +408, +149, +304, +228, +314, +526, +203, +21, +102, +15, -27, +94, +161, +134, +344, +341, -75, -343, -352, -143, -62, }, - { +1622, +2444, +1530, +1228, +926, +1008, +1151, +744, -34, -42, +764, +765, +377, -38, -176, +304, +572, +431, +399, +163, +15, +139, +7, -83, +139, +174, +132, +311, +140, -144, -288, -260, }, - { +1988, +2810, +1493, +1199, +762, +896, +984, +329, -524, -369, +974, +1088, +421, +50, +39, +109, +262, +367, +396, +394, +294, +181, +60, +66, -63, -115, +123, +273, +319, +228, -43, -271, }, - { +2526, +3457, +1538, +1318, +724, +747, +744, -154, -1107, -804, +1097, +1060, +234, +52, +56, +324, +531, +217, +162, +419, +225, +256, +263, +67, +92, -2, -93, +88, +240, +428, +251, -76, }, - { +3196, +4012, +1429, +1473, +720, +771, +686, -545, -1618, -1131, +1253, +952, -133, -206, -51, +422, +646, +293, +343, +345, +85, +287, +111, +124, +185, +14, -5, +226, +158, +71, +246, +198, }, - { +4055, +4548, +1209, +1653, +679, +876, +676, -915, -2105, -1296, +1540, +778, -521, -439, -221, +267, +627, +274, +404, +557, +82, +190, +96, +57, +173, +67, +122, +268, +75, +91, +69, +85, }, - { +5274, +5182, +788, +1972, +519, +928, +689, -1324, -2574, -1398, +1954, +556, -880, -663, -380, +149, +471, +122, +381, +459, +18, +339, +145, +8, +122, +110, +27, +301, +132, +67, +132, +6, }, - { +6463, +5753, +204, +2322, +409, +883, +685, -1827, -2887, -1237, +2299, +272, -1164, -830, -425, +53, +394, -18, +257, +435, -217, +313, +174, +118, +26, -101, +42, +280, +156, +192, +176, +19, }, - { +7727, +6595, -464, +2628, +421, +701, +721, -2439, -3227, -1064, +2569, +149, -1378, -1132, -432, +91, +148, +15, +160, +263, -252, +291, +71, -34, -78, -110, -65, +186, +193, +201, +372, +187, }, - { +8674, +7441, -887, +2687, +475, +615, +762, -2918, -3490, -885, +2619, +32, -1422, -1271, -474, +50, +151, -43, +133, +383, -345, +103, -122, +5, -192, -218, -4, +192, +197, +219, +350, +56, }, - { +9426, +8468, -909, +2618, +320, +470, +937, -3379, -3580, -906, +2153, +153, -1146, -1581, -641, -54, +224, +390, -97, +193, -307, +44, -287, -162, -284, -252, +7, +204, +290, +112, +287, +9, }, - { +9648, +9372, -545, +2609, +289, -35, +1177, -3423, -3509, -971, +1312, +111, -652, -1474, -971, -83, +171, +613, -45, +26, -344, -79, -230, -165, -334, -249, -69, -50, +303, +195, +309, -45, }, - { +9794, +9998, +39, +2769, +379, -638, +980, -3266, -3261, -859, +205, -83, -237, -1162, -748, -518, -59, +946, +29, -268, -354, +5, -131, -183, -422, -257, -155, -194, +224, +120, +248, +7, }, - { +9981, +10397, +622, +3286, +610, -1141, +509, -3403, -3000, -195, -811, -998, +359, -548, -477, -751, -558, +952, +151, -164, -95, -136, -277, -86, -487, -322, -168, -469, +127, +155, +238, -39, }, - { +10400, +10438, +745, +3939, +894, -1363, +3, -3769, -2585, +471, -1670, -1614, +581, -153, +52, -948, -1056, +930, +424, -236, -31, +17, -267, -241, -666, -379, -196, -563, -20, +129, +269, +14, }, - { +11293, +10206, +442, +4923, +1094, -1505, -530, -3996, -2130, +1419, -2437, -2806, +924, +121, +806, -871, -1571, +1001, +618, -424, +58, +151, -379, -185, -956, -481, -127, -651, -119, +140, +160, -149, }, - { +12405, +9835, -281, +5828, +885, -1582, -583, -4592, -1654, +2615, -2996, -4362, +959, +504, +1380, -564, -2020, +895, +761, -610, +81, +185, -720, -204, -1012, -549, -116, -759, -235, +116, +85, -201, }, - { +13934, +9778, -1546, +6319, +686, -1381, -382, -5271, -1119, +3944, -3172, -5767, +686, +682, +1741, +77, -2181, +507, +979, -721, -237, +318, -773, -227, -1265, -756, +92, -716, -477, +162, +134, -400, }, - { +15591, +10583, -3448, +5772, +592, -1315, +577, -5494, -1701, +4790, -2265, -6627, -93, +745, +2160, +357, -2547, +377, +1130, -881, -407, +529, -934, -349, -1319, -885, +105, -673, -507, +45, +171, -344, }, - { +17313, +11801, -5808, +4851, +227, -980, +2385, -6012, -2746, +5567, -996, -7076, -952, +586, +2154, +773, -2812, -169, +1297, -600, -709, +461, -948, -242, -1337, -1246, +226, -600, -658, -10, +354, -281, }, - { +19637, +11754, -7792, +4845, -732, -208, +3348, -6604, -2889, +6378, +241, -7587, -1944, +32, +2714, +992, -3500, -540, +1647, -590, -1131, +670, -931, -134, -1354, -1421, +144, -583, -536, +136, +307, -469, }, - { +21056, +11745, -8787, +4783, -1622, +469, +3944, -6753, -3241, +6740, +1590, -8058, -2609, -411, +2588, +1199, -3554, -896, +1543, -588, -1309, +826, -1017, +54, -1317, -1707, +140, -326, -455, +92, +212, -518, }, - { +22470, +11991, -9701, +4389, -2684, +1431, +4782, -6942, -4015, +6909, +3084, -7923, -3158, -1809, +2522, +1950, -3598, -1289, +1296, -609, -1331, +920, -1125, +160, -1425, -1754, +339, -152, -445, +42, +154, -583, }, - { +23333, +12284, -9893, +3816, -3344, +2109, +5145, -6669, -4930, +6673, +4509, -7499, -3802, -2971, +2448, +2729, -3461, -1700, +1131, -635, -1249, +918, -1341, +144, -1300, -1646, +329, -23, -418, +82, +75, -652, }, - { +23907, +12687, -9670, +3149, -3819, +2297, +5278, -6129, -6015, +6230, +5855, -6823, -4412, -4207, +2246, +3493, -3012, -2245, +989, -670, -1278, +815, -1685, +265, -1083, -1694, +279, +79, -444, +187, -65, -803, }, - { +24068, +13242, -9317, +2853, -4157, +2181, +5293, -5711, -6874, +5677, +6685, -5741, -4828, -5227, +2103, +3851, -2196, -2705, +724, -483, -1476, +639, -1724, +395, -1100, -1511, +43, +72, -276, +84, -146, -836, }, - { +23835, +13868, -8722, +2737, -4517, +2057, +5139, -5437, -7512, +4767, +7374, -4441, -4873, -6362, +1764, +4214, -1258, -3060, +266, -145, -1812, +589, -1602, +416, -1030, -1500, -192, +122, -223, -168, -12, -862, }, - { +23307, +14493, -7616, +2886, -5061, +1805, +4905, -5438, -8024, +3633, +7772, -2910, -4088, -7840, +1069, +4716, -316, -3023, -501, +151, -1943, +531, -1399, +596, -1194, -1653, -168, -131, -123, -407, +123, -804, }, - { +22971, +14195, -6115, +3007, -5341, +1777, +4268, -5238, -8637, +2925, +7500, -1787, -2907, -8792, +313, +4922, +197, -2731, -1003, +162, -1684, +337, -1204, +594, -1286, -1645, -381, -303, -37, -516, +148, -504, }, - { +22070, +14375, -4392, +2868, -5223, +1286, +3714, -4447, -9674, +1907, +7159, -860, -973, -9579, -1209, +5344, +421, -2142, -1115, -130, -1112, +96, -1456, +898, -1239, -2004, -343, -667, +59, -231, +163, -308, }, - { +21240, +14393, -3174, +2492, -4298, +1094, +2745, -3688, -10265, +1178, +6777, -618, +645, -9443, -2927, +5381, +636, -1617, -791, -478, -882, +115, -1535, +816, -1293, -2149, -223, -878, +246, +6, +122, -102, }, - { +20341, +13345, -1099, +2866, -4191, +914, +1804, -2626, -10582, -327, +6635, -287, +2111, -8876, -5214, +5209, +1109, -1120, -336, -736, -608, +24, -1715, +729, -1303, -2434, -80, -706, +170, +364, +230, -221, }, - { +19164, +13059, -468, +4105, -4326, +617, +1911, -2785, -9817, -1770, +6595, -131, +2540, -7381, -7331, +4587, +2019, -857, -311, -599, -501, +196, -1861, -41, -744, -2295, -231, -641, +296, +624, -2, -206, }, - { +18422, +13001, -808, +4597, -3422, -211, +2249, -2884, -9087, -2495, +6668, -543, +1814, -4858, -8725, +3134, +2718, -437, +54, -836, -508, +440, -2036, -713, -94, -2244, -301, -159, -24, +549, +64, -190, }, - { +17855, +12583, -1366, +5362, -2553, -1443, +2178, -2151, -7613, -3290, +5904, -270, +528, -2457, -8756, +644, +3333, -90, +363, -320, -761, -106, -1922, -663, +147, -1870, -338, +6, -294, +558, +55, -269, }, - { +16989, +12653, -2050, +5407, -1459, -1174, +828, -2193, -4917, -4430, +5563, +243, -1454, -249, -7905, -1684, +3547, +136, +95, +521, -741, -985, -1507, -732, +567, -1249, -1016, +108, -174, +393, +77, -205, }, - { +15955, +11844, -2035, +5709, -643, -1173, +284, -2723, -3123, -4229, +4384, +1201, -2654, +769, -6230, -3909, +3368, +375, -503, +1015, -370, -1372, -1549, -501, +871, -801, -1619, +110, +41, +191, +164, -153, }, - { +15076, +10787, -1651, +6161, -494, -1528, +363, -1853, -3374, -4091, +4325, +1345, -2786, +774, -4553, -4709, +2401, +708, -854, +734, -248, -874, -1363, -746, +954, -560, -1815, +201, +149, +40, +297, -250, }, - { +13619, +9790, -1075, +6480, -296, -1830, +805, -986, -3179, -4836, +3833, +2526, -3239, +844, -2857, -5293, +1983, +856, -1538, +348, -255, -582, -521, -965, +224, -130, -1436, +334, +56, -57, +433, -405, }, - { +11990, +8803, -122, +6797, -290, -2053, +1262, -151, -2986, -4897, +2471, +2765, -2059, +507, -2148, -4881, +1467, +956, -1677, +43, -545, -596, -9, -842, -196, -59, -1007, +415, +207, -148, +219, -297, }, - { +12081, +7961, -53, +8316, -2153, -3098, +1599, -1374, -4780, -3918, +6091, +1729, -1658, +3619, -1653, -4298, +1906, +240, -2274, -904, -1646, -475, -581, -1417, -48, -621, -760, +583, -70, -397, +372, +38, }, - { +10221, +7710, +913, +7396, -744, -3594, +288, -1159, -3490, -2578, +4228, +2100, -676, +2348, -1090, -3898, +283, +166, -1419, -166, -1389, -451, +154, -1605, +30, -242, -1341, +92, +30, -175, +146, +10, }, - { +8688, +6964, +1507, +6729, -314, -2703, +315, -1206, -2584, -2071, +3004, +1882, -602, +1784, -753, -3344, +27, -28, -1040, +36, -1038, -169, +101, -1356, +51, -283, -1249, -154, -166, -180, +96, -77, }, - { +7115, +6222, +2194, +6013, +21, -1813, +346, -984, -1850, -1758, +2164, +1394, -547, +1436, -539, -2734, -356, -16, -801, -44, -393, +279, +133, -1115, -80, -420, -1086, -375, -460, -339, +102, +64, }, - { +5945, +5731, +2369, +5160, +628, -1311, +172, -355, -1302, -1644, +1506, +1052, -512, +980, -248, -2308, -600, +61, -662, +216, +230, +430, +21, -924, -262, -525, -975, -595, -515, -352, +24, +58, }, - { +4951, +5289, +2362, +4475, +1066, -1021, +399, +107, -1048, -1369, +919, +662, -450, +769, -110, -1957, -639, +150, -163, +531, +305, +258, +28, -774, -421, -578, -897, -479, -486, -369, -53, -38, }, - { +4363, +4902, +2175, +3906, +1203, -661, +681, +254, -736, -1138, +362, +420, -286, +700, -78, -1616, -376, +371, +225, +620, +133, +107, -31, -735, -442, -346, -613, -527, -506, -305, -33, +11, }, - { +3887, +4410, +1997, +3432, +1166, -200, +836, +280, -488, -1038, -68, +289, -94, +640, +127, -1246, -284, +556, +413, +412, -66, +15, -158, -547, -132, -220, -649, -561, -395, -212, +21, +92, }, - { +3376, +3956, +1885, +2975, +1204, +193, +869, +327, -309, -968, -279, +153, +258, +942, +175, -1108, -255, +727, +480, +101, -239, +78, +89, -338, -137, -200, -570, -519, -230, -33, +148, +121, }, - { +2882, +3708, +1714, +2272, +1421, +628, +806, +292, -242, -915, -154, +676, +462, +684, +167, -864, -170, +750, +347, -82, -16, +193, +144, -210, -259, -192, -347, -281, -16, +141, -8, -250, }, - { +2046, +3121, +1820, +2057, +1654, +693, +650, +385, +140, -232, -150, +593, +684, +440, +155, -506, -275, +602, +454, -11, +56, +206, +86, -187, -110, +2, -156, -45, +18, -158, -271, -285, }, - { +1488, +2866, +1983, +1297, +1310, +1249, +896, +455, +406, +318, +200, +433, +517, +126, +107, -107, -188, +504, +467, +57, +7, +98, +167, +102, +54, +69, +57, -187, -324, -266, -204, -157, }, - { +1053, +2185, +1754, +1283, +1374, +1384, +1276, +1018, +579, +445, +413, +125, +270, +305, -100, -39, +315, +357, +242, +93, +19, +226, +393, +295, +143, -27, -218, -292, -266, -226, -155, -132, }, - { +1057, +1688, +1471, +1786, +1766, +1650, +1060, +783, +933, +472, +248, +183, +76, +69, +137, +183, +238, +233, +230, +317, +365, +313, +253, +237, +26, -223, -314, -259, -170, -175, -164, -190, }, - { +1484, +2348, +1611, +1846, +1758, +1472, +1102, +423, +268, +233, +403, +262, +27, +176, +309, +97, -27, +318, +563, +614, +474, +195, -31, -203, -192, -193, -175, -172, -180, -189, -226, -227, }, - { +1189, +2150, +2013, +2091, +1722, +1365, +885, +462, +260, +102, +413, +490, +320, +96, +1, +58, +212, +334, +486, +716, +577, +224, -92, -268, -289, -245, -180, -118, -126, -201, -214, -200, }, - { +1538, +2422, +1826, +1858, +1328, +1049, +982, +559, +11, +288, +803, +359, +369, +46, -142, +244, +201, +241, +677, +674, +409, +408, -39, -390, -282, -219, -225, -163, -112, -102, -144, -262, }, - { +1451, +2242, +1550, +1542, +1259, +1129, +1099, +613, +12, +373, +659, +432, +541, +134, +290, +219, +14, +256, +292, +393, +633, +888, +287, -211, -275, -432, -238, -88, -138, -127, -59, -184, }, - { +1889, +2552, +1389, +1386, +798, +799, +1037, +440, -97, +313, +902, +615, +250, +224, +305, +196, +454, +188, +213, +467, +218, +428, +693, +519, -184, -445, -344, -230, -88, -89, -79, -137, }, - { +2363, +3156, +1398, +1195, +447, +518, +860, +263, -393, +80, +1073, +455, +343, +419, -4, +307, +535, +250, +536, +315, -34, +496, +401, +321, +495, -3, -404, -292, -153, -89, -99, -128, }, - { +2825, +3421, +1231, +1466, +685, +599, +704, -461, -1098, +100, +1264, +329, +295, +180, +24, +419, +226, +386, +756, +380, +127, +240, +62, +328, +348, +131, +263, +30, -341, -335, -68, -108, }, - { +3491, +4043, +1102, +1542, +710, +589, +566, -937, -1530, +137, +1469, +122, -70, -161, -43, +468, +450, +426, +430, +401, +160, +372, +284, +90, +60, +56, +234, +293, +163, -117, -305, -271, }, - { +4318, +4870, +895, +1479, +603, +516, +626, -1326, -2005, +237, +1656, -115, -219, -418, -328, +396, +406, +377, +591, +338, -178, +469, +312, +158, +217, -234, -8, +329, +210, +69, +187, -16, }, - { +5303, +5497, +566, +1592, +649, +557, +509, -1916, -2395, +604, +1814, -332, -334, -762, -437, +361, +208, +350, +554, +119, -140, +409, +18, +313, +179, -239, +98, -40, +40, +299, +419, +154, }, - { +6339, +6214, +236, +1676, +646, +546, +369, -2580, -2680, +1136, +1943, -586, -423, -1111, -529, +411, +162, +286, +376, -36, -255, +422, +29, +77, +2, -290, -43, +175, +135, +31, +367, +299, }, - { +7425, +6991, -61, +1742, +482, +489, +257, -3260, -2805, +1599, +1929, -688, -450, -1459, -633, +395, +140, +359, +251, -272, -354, +408, -47, +55, -274, -528, -51, +174, +73, +63, +482, +141, }, - { +8275, +7928, -159, +1756, +330, +237, +226, -3790, -2846, +1890, +1754, -690, -422, -1605, -800, +248, +185, +442, +143, -377, -482, +428, -180, -145, -222, -605, -186, -18, +24, +140, +387, +163, }, - { +8779, +8969, +132, +1669, +354, -215, +82, -3976, -2837, +1984, +1471, -648, -422, -1570, -842, -60, +130, +630, +84, -403, -597, +177, +30, -221, -403, -610, -358, +87, -64, -83, +409, +63, }, - { +8644, +10014, +1089, +1453, +493, -603, -298, -3906, -2820, +1754, +1240, -552, -546, -1453, -849, -345, +44, +672, +148, -531, -682, +196, +32, -233, -584, -609, -409, -84, -103, -217, +378, +199, }, - { +8306, +10593, +2458, +1598, +488, -758, -657, -3861, -2849, +1369, +1000, -322, -680, -1443, -722, -668, -37, +677, -45, -127, -673, -156, +70, -281, -443, -635, -631, -315, -160, -54, +479, +139, }, - { +8399, +10550, +3351, +2403, +311, -794, -759, -3852, -2757, +792, +477, +47, -726, -1554, -558, -902, -349, +816, +82, -285, -484, -159, +82, -356, -623, -644, -824, -243, +7, -98, +292, +151, }, - { +8816, +10302, +3569, +3594, +382, -1029, -763, -3770, -2393, +191, -597, +339, -557, -1492, -281, -1488, -279, +1005, -143, -84, -408, -266, +120, -345, -812, -549, -772, -407, -193, -80, +533, +172, }, - { +9548, +9994, +3253, +4643, +623, -1187, -749, -3597, -1800, -143, -2200, +304, -135, -1804, +254, -1488, -709, +1187, -140, -38, -318, -470, +133, -281, -894, -381, -819, -627, -170, -88, +384, +19, }, - { +10751, +9616, +2488, +5649, +553, -1161, -620, -3463, -848, -358, -3996, +121, +130, -2080, +871, -1563, -750, +1416, -465, -119, -39, -417, +70, -275, -1074, -309, -632, -645, -410, -224, +390, -12, }, - { +12014, +9312, +1365, +6755, +300, -1330, -113, -3321, +199, -72, -5935, -749, +987, -2491, +1095, -1087, -1039, +1478, -609, -197, +278, -296, -103, -265, -1088, -288, -651, -818, -474, -102, +420, -351, }, - { +13420, +9342, -277, +7865, +178, -2087, +567, -3307, +1525, +754, -7969, -2060, +1804, -2289, +1011, -875, -1158, +1512, -570, -399, +356, -20, -88, -202, -1219, -576, -573, -671, -574, -252, +223, -435, }, - { +14807, +9961, -2295, +8150, +567, -2864, +1147, -3390, +2627, +2008, -9297, -3776, +2200, -1711, +807, -518, -1276, +1360, -541, -609, +222, +438, +75, -495, -1315, -653, -426, -658, -1054, -304, +558, -512, }, - { +16799, +11079, -4722, +7037, +966, -2929, +1994, -3796, +2704, +3553, -9595, -5358, +1866, -912, +909, -200, -1483, +979, -455, -806, +207, +669, +68, -725, -1243, -745, -665, -630, -1077, -219, +691, -658, }, - { +18748, +11700, -6587, +6122, +943, -2914, +2664, -4426, +2804, +5554, -10085, -6616, +1486, -372, +1328, -285, -1517, +471, -396, -837, +75, +587, +104, -751, -1461, -967, -816, -312, -988, -264, +684, -677, }, - { +20863, +12866, -8572, +4385, +266, -1602, +3832, -5716, +2704, +6971, -9876, -6842, +1023, -479, +1689, -35, -1641, +123, -340, -939, -107, +662, +89, -932, -1675, -1081, -768, +37, -888, -310, +796, -570, }, - { +22765, +13783, -10202, +2941, -746, -81, +4256, -6846, +2898, +7803, -8917, -6979, +238, -972, +2079, +576, -1912, -370, -306, -915, -363, +634, -131, -948, -1776, -1303, -718, +235, -798, -279, +1030, -691, }, - { +24585, +14272, -11287, +1831, -1784, +1157, +4160, -7450, +3079, +8440, -7630, -7341, -269, -1716, +2654, +1114, -2449, -581, -181, -975, -680, +550, -325, -686, -1945, -1634, -616, +402, -659, -135, +1021, -867, }, - { +25869, +14987, -12073, +934, -2610, +1696, +3918, -7361, +2532, +9076, -6029, -7754, -590, -2620, +3019, +1624, -2920, -652, -46, -1264, -966, +600, -472, -467, -2153, -1908, -503, +517, -451, -126, +848, -860, }, - { +26886, +15454, -12309, +371, -3390, +1840, +3592, -7055, +1669, +9594, -4128, -8018, -1017, -3459, +3063, +2189, -3137, -722, +61, -1655, -1121, +760, -729, -326, -2158, -2099, -462, +648, -404, -166, +686, -817, }, - { +27684, +15653, -11980, +24, -4099, +1713, +3246, -6955, +802, +10113, -2356, -7981, -1587, -4226, +3032, +2573, -2987, -885, +150, -1954, -1167, +794, -988, -168, -2014, -2167, -434, +666, -569, -144, +540, -855, }, - { +27741, +16216, -11243, -193, -4856, +1352, +3238, -7293, -125, +10598, -852, -7518, -2157, -4853, +2670, +2868, -2470, -1300, +205, -1901, -1416, +672, -1092, +16, -1804, -2095, -591, +514, -688, -235, +476, -797, }, - { +27272, +16910, -10056, -159, -5917, +966, +3706, -8117, -996, +10790, +336, -6433, -2511, -5475, +1946, +3049, -1685, -1717, +71, -1629, -1727, +569, -1061, +184, -1403, -2279, -872, +450, -920, -127, +585, -861, }, - { +26292, +17598, -8440, +25, -7051, +509, +4314, -9076, -1994, +10815, +1175, -4930, -2295, -6533, +1145, +3192, -1111, -1763, -328, -1487, -1778, +538, -867, +358, -1413, -2301, -1193, +94, -600, -21, +592, -845, }, - { +24908, +18211, -6510, +265, -7874, +12, +4724, -9478, -3509, +10716, +2192, -3778, -1219, -7880, +248, +3471, -999, -1541, -792, -1628, -1421, +841, -1035, +457, -1363, -2591, -1213, -67, -308, +27, +657, -759, }, - { +23173, +18778, -4279, +420, -8200, -952, +4606, -8583, -5614, +10055, +3892, -3343, +694, -8935, -1196, +3813, -1288, -1146, -860, -1990, -933, +977, -1325, +807, -1645, -2747, -714, -417, -75, +218, +548, -805, }, - { +22000, +18365, -2003, +631, -8453, -1561, +3477, -6891, -7183, +8672, +5645, -3122, +2529, -8996, -3276, +3955, -1630, -956, -275, -2341, -1164, +1321, -1481, +629, -1309, -2933, -330, -280, -173, +221, +483, -718, }, - { +21112, +17584, -502, +1334, -8158, -2273, +2292, -5787, -7662, +7007, +7216, -2614, +3372, -7775, -5664, +3835, -1591, -1170, +244, -2374, -1158, +1090, -1550, +627, -758, -3019, +93, -274, -410, +438, +348, -800, }, - { +20632, +17088, -637, +2364, -7070, -3739, +1695, -4935, -8217, +5848, +8673, -2173, +3453, -6082, -7678, +3590, -1152, -1978, +580, -2279, -1275, +1124, -1750, +530, -17, -2783, -114, -166, -296, +284, +223, -679, }, - { +20783, +15919, -1263, +4036, -6965, -4754, +1892, -4346, -8539, +4539, +9671, -1610, +3670, -4797, -8663, +2624, -468, -2009, +28, -2355, -1460, +1576, -1563, +142, +565, -2599, -176, -95, -480, +333, +227, -736, }, - { +19898, +14834, -883, +5611, -7741, -5058, +2778, -4286, -8109, +2022, +9952, -268, +3452, -2598, -9652, +1195, +498, -1859, -458, -2733, -1925, +1990, -998, -244, +1156, -2794, -697, +541, -558, +197, +87, -769, }, - { +18353, +13734, -294, +6773, -7182, -5247, +2895, -3546, -8000, -248, +9510, +1071, +3101, -432, -9279, -621, +1397, -1978, -692, -2518, -2682, +1633, -584, +363, +1428, -3524, -1018, +1348, -563, -124, +38, -581, }, - { +17879, +12019, -1720, +8332, -4976, -5136, +2334, -3753, -7617, -1708, +9554, +1908, +1367, +1443, -7575, -1992, +1783, -1645, -1254, -2425, -2861, +887, -188, +457, +1489, -3426, -1450, +1731, -415, -317, +8, -369, }, - { +16652, +10730, -1605, +9069, -4100, -5114, +2342, -2722, -7212, -3184, +9140, +2114, -706, +3732, -5117, -4057, +2505, -1340, -2078, -1590, -2693, +151, -496, -93, +1733, -2286, -1942, +1173, +71, -202, +59, -356, }, - { +15156, +9682, -934, +8954, -3661, -4339, +2035, -2043, -6405, -3988, +8467, +1700, -1521, +4564, -3502, -4488, +2506, -991, -2469, -1109, -2320, -118, -899, -916, +1437, -1210, -1567, +612, -176, -55, +492, -295, }, - { +13768, +8771, -687, +8850, -3021, -3693, +1828, -1815, -5404, -4221, +7310, +1847, -1818, +4247, -2573, -4214, +2383, -697, -2275, -1002, -2080, -223, -830, -1342, +608, -827, -917, +655, -473, -208, +715, -175, }, - { +14260, +8470, -4402, +9252, +637, -4904, +113, -702, -4629, -3590, +7432, -364, -3180, +3406, -815, -2084, +3326, +846, -1128, +174, -1402, -361, -2087, -2634, -411, -921, -1460, -69, -168, +123, +619, -314, }, - { +12203, +8042, -2103, +8153, +36, -4209, +166, -837, -3973, -3102, +5672, +328, -1860, +2823, -972, -1947, +2514, +629, -644, +18, -1399, -247, -1603, -2116, -289, -1032, -1262, -81, -282, -111, +472, -81, }, - { +9978, +7761, -851, +7167, +518, -3404, +616, -905, -3552, -2875, +4478, +661, -1312, +2289, -665, -1823, +1788, +811, -693, -46, -1135, -436, -1105, -1539, -267, -710, -1155, -219, -156, -293, +133, -138, }, - { +8252, +7011, +325, +6475, +571, -2476, +1105, -925, -3370, -2437, +3577, +876, -1052, +1795, -250, -1885, +1251, +954, -652, -129, -973, -426, -862, -997, +85, -618, -1083, -201, -130, -385, -107, -293, }, - { +6990, +6408, +794, +5771, +1007, -1732, +1092, -813, -2841, -2294, +2966, +1185, -1180, +1392, +18, -1807, +929, +855, -550, -195, -860, -345, -413, -570, +52, -503, -888, -152, -282, -552, -210, -339, }, - { +6315, +5794, +807, +5067, +1552, -954, +511, -614, -2056, -2084, +2442, +1235, -1125, +916, +7, -1376, +711, +581, -457, -233, -563, +16, -83, -537, -90, -310, -669, -307, -465, -561, -130, -413, }, - { +5495, +5067, +1235, +4594, +1625, -330, +383, -413, -1595, -1679, +1966, +934, -895, +616, -4, -1020, +465, +389, -292, +92, -212, +95, -14, -517, -157, -268, -599, -430, -445, -406, -157, -409, }, - { +4664, +4577, +1540, +4071, +1781, +42, +302, -196, -1100, -1341, +1290, +763, -650, +297, +59, -796, +256, +526, +78, +88, -122, +237, -54, -604, -266, -281, -530, -328, -364, -356, -110, -313, }, - { +3851, +4119, +1861, +3768, +1681, +225, +590, +32, -804, -1149, +865, +588, -638, +296, +218, -632, +437, +631, +5, +112, +96, +233, -258, -721, -220, -100, -390, -319, -297, -172, -5, -185, }, - { +3336, +3750, +1919, +3488, +1574, +321, +813, +276, -570, -1058, +527, +383, -558, +511, +605, -444, +230, +571, +103, +183, +137, -15, -469, -450, -1, -70, -317, -262, -110, +31, -67, -427, }, - { +3049, +3510, +1714, +3215, +1488, +383, +1012, +442, -405, -1074, +260, +303, -38, +921, +427, -524, +201, +517, +216, +135, -99, -116, -221, -179, +46, -34, -244, -78, -50, -204, -303, -502, }, - { +2844, +3234, +1490, +2937, +1418, +496, +1224, +481, -359, -986, +230, +762, +253, +708, +333, -527, +155, +538, +90, +24, +59, +6, -45, -70, +130, +103, -256, -256, -271, -304, -297, -325, }, - { +2647, +2909, +1294, +2675, +1363, +698, +1331, +460, -184, -366, +335, +522, +431, +628, +210, -521, -47, +509, +303, +218, +56, +23, +150, +170, +182, -200, -553, -341, -197, -165, -211, -392, }, - { +2534, +2823, +1022, +1970, +1429, +1221, +1392, +703, +196, -392, +319, +726, +304, +316, -41, -517, +273, +763, +274, +109, +137, +366, +348, -105, -308, -391, -404, -192, -101, -238, -327, -356, }, - { +1989, +2468, +1081, +1801, +1546, +1331, +1957, +1126, +247, -246, -18, +528, +333, +129, -70, -149, +414, +761, +386, +169, +318, +372, +30, -395, -334, -284, -295, -143, -195, -279, -332, -341, }, - { +1620, +2490, +1471, +1655, +2013, +1585, +1301, +1138, +603, -161, -181, -90, -24, +524, +502, +148, +414, +612, +427, +246, +105, +30, -174, -325, -240, -291, -355, -203, -136, -260, -309, -267, }, - { +1263, +2410, +2075, +1764, +1891, +1970, +1489, +641, +109, -195, -152, +183, +214, +240, +589, +646, +460, +466, +334, +34, -111, -86, -179, -264, -241, -257, -328, -326, -184, -161, -161, -211, }, - { +1659, +2476, +1676, +2229, +1972, +1422, +1669, +708, -448, -272, +296, +223, +206, +469, +501, +694, +819, +331, -104, -205, -133, -45, -56, -253, -357, -286, -277, -167, -214, -215, -128, -196, }, - { +1539, +2551, +1891, +1969, +1762, +1252, +1228, +862, +110, -20, +303, +230, +166, +358, +647, +849, +752, +128, -158, -145, -243, -82, -52, -123, -279, -382, -292, -181, -163, -170, -155, -213, }, - { +1700, +2807, +1619, +1270, +1372, +1179, +1161, +1231, +504, +52, +504, +136, +92, +640, +736, +453, +675, +669, -252, -473, -51, +20, -170, -152, -154, -240, -345, -332, -109, -89, -138, -173, }, - { +1694, +2657, +1452, +968, +771, +1023, +1613, +1199, +359, +667, +624, -76, +382, +536, +594, +753, +564, +532, +330, -84, -457, -257, +116, +14, -260, -224, -186, -331, -270, -123, -32, -136, }, - { +1868, +2708, +1232, +929, +844, +827, +1033, +736, +424, +738, +823, +481, +179, +246, +857, +667, +444, +613, +612, +119, -110, -152, -501, -78, +116, -202, -290, -173, -262, -254, -131, -141, }, - { +2010, +2795, +1111, +875, +1109, +1106, +857, -4, -401, +861, +1319, +394, +265, +408, +467, +655, +737, +455, +536, +705, +304, -158, -205, -280, -395, +24, +44, -233, -199, -207, -233, -158, }, - { +2330, +2991, +964, +1027, +1208, +1180, +792, -487, -765, +646, +1124, +466, +294, +78, +501, +769, +452, +561, +675, +354, +514, +630, -115, -307, -312, -411, -176, +29, -28, -209, -223, -273, }, - { +2824, +3565, +965, +943, +1112, +1083, +667, -717, -987, +738, +1121, +2, +110, +106, +412, +576, +458, +606, +513, +519, +535, +409, +396, +221, -406, -363, -190, -297, -93, +42, -95, -282, }, - { +3349, +3983, +872, +1076, +1173, +1134, +531, -1288, -1216, +1017, +1171, -131, -155, -369, +349, +670, +365, +458, +453, +375, +399, +660, +331, +266, +204, -128, -309, -306, -200, -192, -42, -94, }, - { +3961, +4442, +707, +1254, +1277, +1123, +361, -1769, -1366, +1301, +1136, -328, -227, -538, +131, +409, +403, +542, +281, +118, +332, +560, +285, +456, +66, +169, +247, -283, -261, -198, -228, -289, }, - { +4686, +5052, +536, +1343, +1245, +1005, +207, -2188, -1265, +1645, +926, -588, -346, -640, +177, +285, +106, +548, +311, +27, +151, +303, +255, +325, +75, +299, +196, +155, +118, -260, -236, -300, }, - { +5534, +5563, +318, +1536, +1252, +806, -127, -2646, -995, +2082, +649, -787, -525, -824, +252, +141, +115, +500, +81, -14, +111, +227, +28, +135, -85, +201, +321, +171, +203, +214, -19, -500, }, - { +6386, +6175, +93, +1727, +1236, +541, -519, -3046, -559, +2421, +322, -926, -609, -965, +269, -57, +33, +671, -21, -197, +21, +165, +4, +40, -436, +106, +232, +49, +425, +144, +66, +0, }, - { +7130, +6925, -88, +1879, +1277, +209, -950, -3419, -58, +2693, -41, -998, -710, -991, +321, -320, -82, +770, -64, -189, -88, -19, +13, -38, -523, -42, -30, +68, +150, +89, +365, -23, }, - { +7792, +7702, -133, +1956, +1357, -128, -1415, -3772, +482, +2874, -375, -1048, -862, -936, +402, -512, -233, +760, -129, -149, -81, -155, -78, -100, -630, -36, -59, -442, +95, +280, +185, +75, }, - { +8084, +8648, +147, +1800, +1588, -465, -1801, -4057, +739, +3060, -585, -1055, -1095, -889, +484, -597, -294, +651, -254, -145, -54, -182, -110, -282, -564, -209, -393, -202, +61, +14, +171, +1, }, - { +7950, +9589, +964, +1429, +1845, -635, -2157, -4183, +602, +3177, -602, -1039, -1301, -965, +529, -614, -333, +613, -355, -295, -22, -253, -53, -255, -948, -322, -205, -347, -6, +31, +59, -71, }, - { +7608, +10215, +2256, +1215, +1866, -509, -2499, -4150, +252, +3102, -462, -1007, -1377, -1131, +543, -620, -361, +628, -344, -407, -176, -143, -39, -636, -843, -265, -361, -355, -99, +51, +143, +45, }, - { +7478, +10350, +3382, +1641, +1562, -364, -2671, -4182, +82, +2795, -422, -952, -1415, -1234, +496, -705, -369, +637, -288, -460, -139, -421, -273, -301, -1004, -427, -393, -387, -99, +121, +207, -128, }, - { +7601, +10277, +3938, +2546, +1409, -546, -2604, -4195, -39, +2430, -446, -937, -1542, -1235, +449, -844, -397, +623, -239, -176, -592, -583, -41, -478, -953, -587, -540, -343, +32, +110, -10, -156, }, - { +7999, +10060, +3982, +3415, +1699, -807, -2609, -3807, -190, +1946, -508, -758, -1860, -1306, +494, -1071, -466, +696, -160, -448, -342, -561, -316, -440, -936, -533, -717, -285, -33, -87, +138, +52, }, - { +8868, +9667, +3696, +4220, +1884, -786, -2974, -3169, -25, +1022, -611, -333, -2076, -1587, +587, -1486, -187, +551, -545, +152, -427, -718, -238, -557, -971, -356, -742, -544, -186, +78, +286, -144, }, - { +10008, +9228, +3019, +5173, +1730, -514, -3173, -2654, +674, -266, -982, +303, -2059, -1915, +478, -1617, -384, +327, -296, +313, -485, -639, -255, -549, -996, -197, -986, -652, +62, -23, +48, -97, }, - { +11234, +8968, +1867, +6284, +1449, -576, -2850, -2320, +1671, -1457, -1966, +1061, -1777, -2251, +610, -2387, -502, +717, -908, +856, -362, -807, -179, -457, -950, -356, -981, -565, +70, -205, +52, -184, }, - { +12424, +9043, +307, +7301, +1477, -1225, -2226, -1811, +2733, -2240, -3502, +1512, -1095, -2186, +52, -2767, -416, +476, -1043, +1163, -163, -967, -182, -310, -939, -309, -1033, -648, +172, -197, -66, -313, }, - { +13850, +9410, -1577, +7710, +1903, -2007, -1727, -1126, +3784, -2445, -5373, +1368, +274, -2547, -214, -2859, -931, +830, -1404, +1283, +192, -1142, -131, -304, -939, -130, -968, -870, +367, -211, -179, -446, }, - { +15689, +10650, -4191, +6439, +2855, -1819, -1216, -1122, +4356, -1735, -7082, +796, +1337, -2613, -354, -3165, -1020, +960, -1511, +1143, +338, -957, -254, -411, -1003, +93, -787, -961, +276, -120, -242, -590, }, - { +17568, +11974, -6732, +4560, +3824, -1109, -754, -1349, +4606, -843, -8100, -287, +1911, -2056, -658, -3260, -1157, +899, -1412, +975, +487, -915, -443, -511, -909, +161, -686, -992, +148, +70, -223, -830, }, - { +19484, +13084, -9012, +2638, +4382, +24, -354, -1619, +4661, +92, -8630, -1472, +1971, -1185, -834, -3443, -1007, +624, -1325, +1001, +434, -935, -492, -574, -862, +109, -756, -815, +84, +193, -327, -1033, }, - { +21524, +13678, -10956, +1222, +4385, +1297, -139, -2069, +5017, +1156, -9307, -2582, +2096, -601, -528, -3661, -796, +152, -1389, +1321, +257, -1041, -461, -535, -1092, +104, -751, -637, +26, +127, -265, -1109, }, - { +23605, +13718, -12574, +568, +3860, +2238, -103, -2760, +6167, +2019, -10424, -3226, +2099, -412, +299, -3787, -992, -294, -1323, +1597, -108, -1067, -318, -600, -1468, +200, -723, -642, -34, +135, -184, -1205, }, - { +25071, +14148, -13932, +471, +3008, +2768, -76, -3611, +7895, +2700, -11593, -3451, +1646, -185, +1383, -3748, -1496, -431, -1263, +1534, -312, -957, -121, -752, -1802, +171, -636, -694, -65, +159, -201, -1248, }, - { +26816, +13743, -14786, +862, +1921, +2946, -342, -4385, +10015, +2577, -12171, -3354, +671, +309, +2238, -3598, -1940, -465, -1278, +1149, -315, -796, +17, -1000, -2051, +76, -546, -729, -117, +138, -282, -1090, }, - { +27951, +14104, -15590, +1273, +860, +2927, -633, -4986, +11529, +2744, -11887, -3827, +2, +498, +2997, -3184, -2478, -171, -1514, +556, -142, -469, -72, -1148, -2207, -3, -362, -847, -143, +170, -197, -1176, }, - { +28803, +14580, -16123, +1472, -187, +3073, -1250, -5325, +12182, +3270, -11190, -4406, -641, +391, +3646, -2789, -2835, +205, -1933, -111, +62, -112, -330, -1167, -2390, +48, -212, -1112, -86, +341, -303, -1353, }, - { +30323, +13889, -15910, +1407, -1171, +3553, -2383, -5267, +12463, +3540, -10099, -4882, -1197, +116, +4331, -2625, -2785, +375, -2274, -723, +301, +72, -494, -1132, -2662, +359, -286, -1255, +88, +360, -528, -1375, }, - { +30968, +14210, -15671, +1048, -1781, +3667, -3019, -5566, +12074, +4371, -8903, -5378, -1555, -380, +4891, -2272, -2787, +479, -2516, -1197, +410, +143, -580, -995, -2832, +409, -254, -1218, +75, +188, -590, -1406, }, - { +30975, +15165, -15312, +546, -2218, +3398, -2954, -6444, +11217, +5687, -7852, -5572, -1909, -880, +5215, -1819, -2692, +359, -2645, -1443, +355, +103, -656, -709, -2922, +164, -25, -1239, -84, +72, -690, -1273, }, - { +30424, +16368, -14573, +92, -2674, +2748, -2205, -7930, +10058, +7372, -7052, -5344, -2312, -1403, +5238, -1260, -2430, -1, -2723, -1529, +312, -177, -560, -464, -2980, -55, -69, -1190, -231, -99, -594, -932, }, - { +29455, +17526, -13363, -127, -3235, +1964, -1140, -9860, +8781, +9245, -6389, -4845, -2498, -2034, +4995, -530, -2084, -491, -2825, -1345, +221, -559, -398, -274, -2983, -380, -142, -1168, -371, +10, -384, -724, }, - { +28118, +18400, -11563, -157, -4012, +1308, -199, -11792, +7222, +10997, -5639, -4233, -2301, -2934, +4504, +364, -1845, -1024, -2737, -1299, +240, -966, -422, -53, -3194, -483, -435, -1176, -132, +127, -258, -452, }, - { +26552, +19152, -9368, -160, -4867, +986, +473, -13162, +5114, +12399, -4354, -3860, -1375, -4191, +3967, +1296, -1787, -1124, -2703, -1337, +286, -1074, -1007, +244, -3127, -928, -436, -993, +94, +254, +31, -338, }, - { +24559, +20217, -7367, -220, -5053, +163, +912, -13440, +2241, +12957, -1945, -4140, -3, -5230, +2779, +2633, -1975, -895, -2652, -1685, +399, -1133, -1787, +451, -3100, -1099, -141, -1148, +476, +550, +59, -556, }, - { +23258, +20668, -6394, +41, -4001, -1343, +259, -12280, -447, +12376, +814, -4410, +990, -5553, +1277, +3778, -1842, -823, -2296, -2428, +66, -675, -2623, +69, -2488, -1174, +108, -1212, +763, +685, -33, -620, }, - { +23142, +19464, -5694, +1043, -3149, -2286, -1288, -10731, -2354, +11827, +2425, -4171, +1875, -6154, +693, +4142, -1325, -613, -2234, -3206, -20, -772, -3178, +251, -2328, -913, +289, -1277, +940, +736, -150, -671, }, - { +22552, +18662, -5393, +2289, -1879, -3683, -2436, -8894, -4473, +11069, +4563, -5019, +3166, -6153, -527, +5142, -1047, -592, -2109, -3335, -857, -775, -3407, +489, -1798, -1280, +535, -1129, +1014, +574, -236, -416, }, - { +22401, +17758, -5842, +3364, -812, -4784, -3176, -6717, -5712, +8976, +6974, -6176, +3397, -4371, -2591, +6388, -734, -1317, -1243, -3549, -1586, -824, -3469, +452, -886, -1990, +679, -751, +619, +748, -301, -324, }, - { +22309, +16537, -6181, +4660, -360, -5405, -3571, -5406, -6202, +6988, +8656, -6084, +2058, -2265, -3682, +6212, +772, -2272, -843, -3239, -2023, -881, -3727, +370, -424, -2103, +394, -539, +433, +863, -135, -441, }, - { +21791, +15541, -6192, +5616, -505, -5546, -3072, -4658, -6616, +5207, +9841, -5865, +904, -1208, -3643, +5823, +1664, -2499, -798, -2591, -2431, -478, -3918, -635, -47, -1868, +308, -596, +226, +890, +22, -361, }, - { +21324, +14642, -6583, +6799, -1051, -6105, -1417, -3904, -7362, +3483, +10991, -5815, -496, +549, -4041, +4979, +2787, -2309, -896, -2206, -2499, +60, -3674, -2156, -266, -1362, +446, -246, -422, +573, +555, -41, }, - { +20752, +13927, -7556, +7887, -383, -7140, -472, -2508, -7640, +1050, +11820, -4742, -2329, +2225, -4014, +3077, +4488, -1969, -1094, -1484, -3038, +789, -3176, -3637, -596, -1084, +354, +499, -803, -174, +1114, +269, }, - { +19965, +13135, -8141, +8473, +760, -7513, -787, -971, -6960, -1942, +12233, -3129, -3764, +3112, -3442, +1359, +4791, -618, -1183, -1102, -2895, +601, -2684, -3990, -954, -1401, +153, +1055, -625, -482, +888, +405, }, - { +19143, +11685, -8033, +9384, +754, -7209, -418, -807, -6484, -2771, +11238, -2375, -3772, +3580, -3133, +167, +4612, -12, -608, -927, -2580, +196, -2728, -3474, -1079, -1676, -444, +1107, -287, -167, +508, -54, }, - { +17857, +10290, -7109, +9878, +454, -6436, -46, -1046, -5905, -3006, +10009, -1912, -3542, +3960, -2520, -1113, +4554, +356, -838, +40, -2468, -172, -2487, -3471, -559, -1557, -1179, +703, -47, +127, +577, -318, }, - { +16296, +9009, -5714, +9900, +226, -5547, +70, -922, -5384, -3238, +8823, -1282, -3406, +3868, -1537, -1923, +3996, +793, -1145, +249, -1720, -492, -2325, -3083, -467, -1071, -1564, +201, -55, +203, +765, -336, }, - { +15841, +6997, -6669, +11869, +1968, -7696, -859, +385, -4403, -1539, +6206, -3126, -2033, +3213, -1498, -707, +2441, -260, -30, +640, -527, +1221, -934, -1381, +294, -1105, -1226, -270, -1487, -1152, -350, -611, }, - { +13568, +6667, -4985, +10337, +1992, -6022, -629, +40, -3621, -1574, +5221, -2329, -1990, +2774, -1185, -903, +2184, +6, -131, +493, -301, +1057, -963, -1225, +288, -1053, -961, -56, -1078, -893, -506, -522, }, - { +11497, +6501, -3490, +8587, +2327, -4433, -803, -59, -2956, -1671, +4442, -1603, -1990, +2273, -678, -964, +1803, +277, -100, +341, -258, +879, -733, -1205, +106, -817, -829, +182, -726, -774, -439, -507, }, - { +9657, +6295, -2357, +7055, +2839, -3195, -922, +87, -2426, -1717, +3756, -1022, -1971, +1799, -285, -852, +1503, +322, +17, +329, -329, +745, -562, -1092, +21, -498, -600, +37, -450, -530, -354, -499, }, - { +8080, +5958, -1527, +5929, +3206, -2314, -807, +279, -2098, -1713, +3210, -663, -1953, +1446, +14, -682, +1140, +403, +168, +150, -283, +600, -477, -850, +175, -366, -595, +17, -334, -374, -332, -390, }, - { +6742, +5563, -934, +5119, +3472, -1654, -579, +468, -1830, -1693, +2733, -440, -1854, +1199, +270, -615, +927, +597, +39, +58, -146, +541, -282, -642, +203, -260, -523, -66, -324, -342, -189, -288, }, - { +5645, +5082, -470, +4564, +3569, -1149, -280, +632, -1648, -1657, +2279, -195, -1747, +997, +500, -550, +854, +535, -56, +205, +54, +502, -244, -453, +284, -250, -567, -159, -320, -231, -40, -147, }, - { +4739, +4548, -15, +4161, +3424, -612, +92, +576, -1502, -1483, +1923, -133, -1573, +1049, +513, -481, +827, +418, +204, +407, -41, +456, -23, -319, +105, -295, -566, -165, -125, -78, -45, -303, }, - { +4000, +4116, +315, +3739, +3361, -78, +141, +471, -1088, -1423, +1428, +104, -1192, +778, +494, -118, +776, +531, +352, +301, +46, +496, -16, -403, -75, -250, -372, +7, -75, -290, -272, -334, }, - { +3315, +3731, +744, +3252, +3208, +505, +104, +326, -724, -1258, +1022, +253, -920, +621, +766, +320, +638, +429, +479, +312, +62, +342, -149, -425, +78, -14, -324, -163, -364, -342, -177, -191, }, - { +2721, +3507, +1076, +2691, +3219, +926, -155, +334, -235, -1266, +533, +565, -478, +790, +1052, +241, +481, +577, +434, +197, -68, +166, +67, -116, +62, -279, -535, -276, -242, -195, -120, -171, }, - { +2164, +3272, +1472, +2240, +2998, +1160, -8, +380, -347, -1061, +577, +981, +39, +670, +997, +273, +443, +502, +183, +101, +156, +367, +108, -320, -359, -368, -337, -186, -156, -185, -219, -252, }, - { +1934, +3190, +1503, +1841, +2991, +1228, -234, +344, -22, -479, +868, +985, +160, +811, +840, +155, +222, +329, +446, +340, +153, +57, -306, -454, -236, -196, -253, -198, -267, -270, -212, -218, }, - { +1850, +2863, +1570, +2109, +2264, +770, +377, +952, +272, -269, +977, +887, +259, +859, +502, -89, +465, +710, +360, -49, -274, -104, -140, -299, -180, -223, -354, -327, -223, -222, -195, -175, }, - { +1880, +2606, +1259, +1967, +2141, +1272, +1090, +983, +171, -143, +1137, +1038, +78, +386, +659, +433, +428, +299, -214, -286, +0, +94, -163, -340, -274, -342, -349, -267, -185, -155, -161, -219, }, - { +1397, +2225, +1498, +2218, +2597, +1375, +970, +1179, +446, +55, +983, +782, +92, +766, +779, +21, -117, -30, -43, +45, +38, -51, -292, -398, -291, -331, -321, -187, -130, -199, -179, -163, }, - { +1635, +3062, +2249, +1880, +1916, +1343, +1114, +965, +534, +333, +634, +1026, +601, -88, -96, -36, +19, +140, +79, -54, -187, -223, -327, -363, -331, -232, -228, -189, -124, -136, -165, -244, }, - { +1621, +2982, +2331, +1859, +1672, +1505, +1317, +1168, +916, +338, +486, +1012, +283, -527, -167, +103, +151, +173, -30, -202, -207, -185, -337, -340, -290, -264, -241, -183, -115, -121, -178, -226, }, - { +1602, +2643, +1775, +1564, +1563, +1546, +1646, +1829, +1322, +708, +618, +118, +151, +107, -304, -55, +284, +102, -151, -125, -138, -202, -309, -317, -234, -259, -302, -184, -120, -109, -170, -206, }, - { +1689, +2725, +1687, +1342, +1018, +1221, +1839, +1792, +1379, +895, +468, +478, +768, +67, -215, -9, -169, +55, +46, -227, -303, -177, -209, -261, -200, -191, -162, -205, -213, -154, -174, -239, }, - { +1884, +2685, +1171, +1190, +1175, +880, +977, +1283, +1525, +1401, +1097, +684, +686, +975, +274, -642, -241, -46, -48, +8, -211, -255, -203, -172, -169, -156, -217, -131, -186, -249, -160, -234, }, - { +1711, +2523, +1308, +1090, +1055, +1174, +1022, +299, +477, +1301, +1459, +1119, +863, +804, +1042, +601, -340, -501, -204, -29, -21, -94, -220, -196, -156, -184, -116, -170, -201, -183, -255, -271, }, - { +1817, +2536, +946, +809, +944, +1085, +1157, +217, -175, +767, +1098, +779, +1147, +1424, +1313, +1026, +631, +198, -302, -492, -270, -64, -131, -189, -253, -238, -160, -88, -70, -213, -184, -209, }, - { +2191, +2839, +854, +984, +1168, +1002, +768, -219, -19, +1063, +561, +60, +636, +861, +1348, +1294, +885, +891, +475, -73, -432, -506, -288, -67, -118, -220, -240, -103, -74, -138, -148, -245, }, - { +2451, +2833, +673, +1459, +1780, +1173, +305, -947, -35, +1449, +504, -211, +108, +410, +948, +640, +824, +1192, +884, +675, +272, -177, -565, -472, -224, -108, -84, -125, -187, -164, -89, -188, }, - { +3086, +3702, +648, +1075, +1515, +1169, +441, -1098, -143, +1309, +271, -221, +106, +208, +526, +378, +428, +792, +941, +752, +488, +344, +62, -247, -504, -376, -181, +22, -47, -250, -217, -168, }, - { +3569, +4097, +532, +1316, +1840, +1093, -29, -1514, +254, +1604, -129, -469, -58, +189, +685, +94, +33, +566, +399, +418, +683, +566, +398, +298, -51, -324, -429, -122, -77, -175, -112, -284, }, - { +4125, +4461, +378, +1609, +2191, +994, -587, -1865, +674, +1689, -401, -500, -250, +88, +680, -19, +36, +317, +78, +227, +154, +381, +584, +347, +348, +259, -144, -157, -249, -295, -182, -189, }, - { +4867, +5214, +256, +1466, +2150, +866, -894, -1915, +1051, +1495, -779, -414, -262, +45, +633, -205, +3, +311, -89, +0, -11, +125, +199, +237, +418, +383, +270, +312, -107, -370, -261, -364, }, - { +5316, +5480, +203, +2110, +2686, +411, -1842, -1931, +1799, +1361, -1123, -406, -380, +95, +608, -401, +32, +304, -272, -6, -184, -72, +198, -153, +69, +403, +277, +536, +348, -42, -176, -397, }, - { +5892, +6233, +160, +2100, +2860, +142, -2433, -1800, +2326, +963, -1427, -273, -439, +158, +610, -591, -43, +281, -390, -16, -246, -165, +68, -360, -9, +156, +82, +484, +326, +166, +189, -170, }, - { +6296, +6975, +282, +2083, +3088, -133, -3093, -1657, +2878, +590, -1820, -143, -472, +190, +638, -719, -106, +233, -510, -92, -328, -237, +113, -522, -223, +109, -26, +254, +179, +32, +200, +156, }, - { +6592, +7845, +648, +1757, +3189, -161, -3619, -1575, +3255, +370, -2151, -143, -426, +168, +727, -779, -195, +244, -572, -180, -428, -336, +66, -505, -282, -26, -117, +217, +77, -98, +16, -149, }, - { +6774, +8708, +1082, +1524, +3240, -264, -3922, -1540, +3434, +295, -2349, -304, -372, +149, +756, -675, -383, +223, -505, -236, -520, -494, -9, -552, -315, -62, -148, +121, +173, -299, -365, -62, }, - { +6908, +9422, +1625, +1424, +3190, -389, -4004, -1611, +3471, +335, -2543, -391, -396, +68, +811, -604, -534, +182, -441, -272, -536, -643, -94, -634, -428, -131, -91, +267, -223, -392, -234, -275, }, - { +7138, +10189, +2126, +1133, +2968, -382, -3722, -1762, +3018, +580, -2559, -606, -255, -134, +669, -325, -681, -12, -293, -317, -621, -648, -141, -715, -656, -53, -111, -126, -38, -347, -470, -236, }, - { +7313, +10455, +2943, +1070, +2390, +272, -3497, -2310, +2731, +755, -2380, -670, -474, -246, +602, -255, -558, -320, -482, -158, -477, -799, -319, -604, -503, -410, -501, +108, -160, -398, -359, -347, }, - { +7826, +10161, +3173, +1967, +2130, +423, -3555, -2463, +2451, +634, -1952, -839, -706, -181, +512, -312, -450, -587, -636, +17, -569, -882, -377, -371, -655, -672, -473, -170, -109, -345, -438, -377, }, - { +8467, +9477, +3103, +3430, +2024, +440, -3655, -2401, +2236, -26, -1277, -712, -1114, -26, +375, -495, -221, -726, -826, +29, -851, -620, -323, -809, -370, -647, -794, -102, -163, -412, -424, -337, }, - { +9286, +8516, +2179, +5700, +2660, -483, -3558, -1721, +1619, -1074, -311, -359, -1649, +39, +247, -528, -41, -857, -1059, -36, -827, -638, -733, -625, -208, -781, -693, -299, -176, -287, -276, -526, }, - { +10487, +8297, +724, +7001, +3276, -1546, -2976, -375, +714, -2874, +551, +663, -2103, -61, +34, -604, +320, -1061, -1370, +301, -1334, -957, -278, -1039, -89, -630, -732, -236, -218, -112, -316, -769, }, - { +11694, +8483, -1085, +7688, +4377, -2639, -2748, +1388, +290, -5170, +695, +2234, -2233, -376, -167, -879, +703, -1107, -1401, -21, -1755, -792, -436, -1099, +19, -701, -676, +56, -177, -420, -299, -499, }, - { +12813, +8986, -2960, +7720, +5822, -3441, -2888, +3186, +503, -7344, -143, +3835, -1619, -861, -365, -1277, +915, -643, -1945, -184, -1723, -1371, -165, -1036, -149, -608, -623, +361, -273, -675, -81, -360, }, - { +14282, +9854, -5144, +6666, +7543, -3247, -3573, +4303, +1159, -8673, -1552, +4734, -435, -1066, -737, -1669, +1323, -711, -2400, +154, -2059, -1735, -117, -896, -79, -641, -571, +431, -255, -662, -37, -376, }, - { +15850, +10514, -7059, +5564, +8654, -2773, -4154, +5402, +1737, -9668, -3061, +5015, +1018, -866, -1440, -1886, +1527, -978, -2388, +41, -2052, -1988, -323, -629, -13, -650, -699, +444, -203, -546, -140, -354, }, - { +17808, +11057, -9134, +4383, +9339, -1778, -4546, +6062, +2149, -10167, -4257, +4712, +2487, -456, -1988, -2239, +1739, -1173, -2546, +134, -2148, -2055, -395, -540, +91, -587, -935, +488, -19, -574, -174, -369, }, - { +20383, +11132, -11423, +3225, +9645, -449, -4728, +6097, +2297, -10259, -4895, +4011, +3369, +308, -2432, -2790, +2050, -1452, -2764, +266, -2368, -1811, -610, -479, +220, -714, -1063, +583, +89, -687, -231, -413, }, - { +22418, +11798, -13840, +2373, +9532, +812, -4649, +5776, +2876, -10183, -5672, +3197, +3848, +1355, -2692, -3324, +2269, -1738, -2840, +474, -2481, -1785, -640, -534, +229, -841, -1060, +727, -62, -819, -169, -447, }, - { +24894, +11396, -15645, +2370, +8933, +1292, -4281, +5629, +3954, -10488, -6364, +2682, +3969, +2394, -2882, -3405, +2175, -2174, -2424, +697, -2794, -1803, -440, -660, +159, -906, -842, +819, -413, -760, -126, -429, }, - { +26219, +12293, -17420, +2685, +7926, +1207, -3924, +5306, +5940, -10486, -7929, +2418, +4103, +2810, -2438, -3395, +1620, -2289, -1991, +723, -2963, -1849, -215, -902, +78, -722, -742, +870, -694, -718, -23, -517, }, - { +28416, +11175, -18030, +3639, +6517, +524, -3997, +5626, +7964, -10885, -9328, +2435, +4025, +2769, -1736, -3204, +870, -2252, -1569, +634, -3242, -1541, -240, -1235, +91, -529, -623, +850, -941, -678, +99, -756, }, - { +29176, +11689, -18551, +4399, +5252, -160, -4585, +5761, +10465, -11051, -10563, +2051, +3915, +2524, -384, -3448, +237, -1642, -1718, +678, -3401, -1225, -371, -1551, +5, -226, -521, +663, -896, -768, +144, -1146, }, - { +29021, +13077, -18841, +4810, +4427, -776, -5593, +5564, +12643, -10486, -11302, +1156, +3758, +2201, +1006, -3601, -405, -695, -2158, +611, -3242, -1002, -587, -1809, -96, +32, -433, +355, -533, -1081, -66, -1282, }, - { +30639, +12013, -18276, +5087, +3533, -892, -7519, +6359, +13438, -9871, -11200, +130, +3528, +2142, +1859, -3611, -530, -415, -2173, +244, -2952, -752, -1000, -1830, -214, +226, -496, +424, -528, -1428, -247, -1261, }, - { +31129, +12133, -17589, +4753, +3258, -1123, -8951, +6078, +13955, -8365, -10965, -1246, +3253, +2362, +2106, -3221, -543, -421, -2041, -9, -2564, -798, -1213, -1842, -312, +214, -362, +364, -897, -1374, -502, -1281, }, - { +30719, +13121, -16780, +4200, +3198, -1555, -9649, +4676, +14307, -6216, -10726, -2675, +2883, +2776, +1878, -2607, -273, -769, -1833, +57, -2369, -947, -1301, -1967, -305, +248, -529, +122, -1019, -1330, -719, -996, }, - { +29697, +14733, -15818, +3462, +3061, -1780, -9577, +2144, +14501, -3727, -10382, -3699, +2209, +3218, +1410, -1818, +264, -1375, -1409, +257, -2249, -1183, -1411, -1971, -160, -60, -974, +340, -1284, -1182, -516, -1030, }, - { +28002, +16846, -14478, +2412, +2676, -1519, -8873, -1372, +14440, -1063, -9859, -4131, +1096, +3328, +1195, -1203, +1073, -1927, -1076, +655, -2259, -1480, -1460, -1775, -599, -341, -1181, +468, -1245, -932, -470, -1164, }, - { +25869, +18455, -12266, +1637, +1978, -1262, -8280, -4934, +14128, +1672, -9443, -4041, -152, +2529, +1995, -1259, +1882, -1726, -1545, +1491, -2530, -1653, -1433, -2120, -1079, -408, -1374, +717, -856, -1223, -178, -1188, }, - { +24864, +17912, -9358, +1641, +576, -357, -8615, -7257, +13351, +3934, -9073, -3482, -838, +841, +3250, -1322, +2217, -796, -2111, +1754, -2153, -2158, -1467, -2434, -1624, -253, -1302, +874, -576, -1341, -96, -1263, }, - { +23420, +17860, -6501, +1165, -717, +588, -8140, -9637, +11644, +6449, -8639, -3126, -461, -1536, +4057, -378, +1614, +434, -2303, +1248, -1439, -2499, -1782, -2484, -2002, -134, -998, +651, -243, -1476, -235, -998, }, - { +22006, +18635, -5893, +1609, -295, -1121, -6611, -10352, +8438, +8556, -7366, -3845, +1086, -3469, +3525, +1549, +597, +1088, -1819, +227, -740, -2416, -2356, -1773, -2500, -256, -642, +230, -150, -1358, -351, -903, }, - { +22224, +17778, -6386, +3076, +518, -3282, -6409, -9035, +5543, +9128, -5573, -4587, +2339, -4194, +2628, +2481, +473, +849, -1362, -75, -999, -1551, -2497, -1277, -2514, -1057, -402, -20, +22, -1408, -555, -809, }, - { +22103, +17015, -6884, +4461, +1233, -5006, -6070, -7906, +2832, +9189, -3231, -5657, +3433, -4282, +1463, +3242, -717, +1493, -1177, -711, -254, -881, -2411, -866, -2491, -1884, -465, -353, +374, -1387, -1115, -592, }, - { +22560, +15777, -7251, +5550, +797, -5686, -5009, -7186, +427, +9113, -1133, -6601, +3854, -2859, -422, +3276, -587, +291, -113, -529, +173, -114, -2517, -809, -1886, -2312, -1324, -304, +246, -1137, -1252, -701, }, - { +22731, +15350, -9222, +6868, +2173, -7663, -4747, -4975, -1211, +7055, +1768, -6971, +2930, -1113, -1589, +2833, -506, -636, +510, +745, -151, +413, -2257, -1147, -1254, -2415, -1827, -858, -136, -928, -699, -812, }, - { +23304, +14017, -11279, +9072, +3099, -9814, -4178, -2550, -2580, +4834, +3988, -6788, +1843, +177, -2381, +2443, -295, -988, +882, +1070, +364, +564, -2129, -1074, -1171, -2223, -1782, -1409, -1115, -600, -62, -717, }, - { +23618, +12255, -12665, +11454, +3209, -11235, -3282, -912, -3248, +2468, +5358, -5978, +1078, +518, -3093, +2872, +91, -1576, +1462, +574, +484, +1620, -2554, -835, -966, -2532, -1116, -1629, -2136, -622, +243, -448, }, - { +23507, +10176, -12976, +13613, +2604, -11794, -2177, +221, -4379, +941, +6866, -5844, +60, +1571, -3421, +2227, +1420, -1610, +744, +868, +160, +1913, -1757, -1375, -527, -2462, -1299, -900, -2681, -1245, +284, -163, }, - { +22437, +8395, -11784, +14554, +1462, -10835, -1161, -107, -4923, +595, +7185, -5944, -419, +2664, -3581, +1327, +2496, -1354, +156, +805, -57, +1910, -1336, -1388, -199, -2269, -1525, -558, -2342, -1654, -242, -88, }, - { +20519, +7379, -9918, +14135, +1130, -9407, -1215, -80, -4674, -389, +7077, -5070, -1127, +3004, -2779, +575, +2442, -923, +375, +352, -401, +2124, -1583, -1128, +325, -2275, -1384, -459, -2045, -1486, -593, -444, }, - { +18163, +7171, -8342, +13120, +1703, -8708, -1203, +485, -4645, -1323, +6947, -3981, -1909, +3255, -1914, -231, +2372, -512, +246, +503, -605, +1638, -1102, -1353, +431, -1611, -1452, -256, -1866, -1326, -460, -644, }, - { +14734, +5366, -4938, +13261, +853, -8371, +138, +318, -3336, +134, +2204, -3293, +1697, +2006, -2237, -277, +1106, -520, -774, +253, -99, +68, -412, +780, +809, +219, +346, -370, -906, -336, -779, -1298, }, - { +12591, +5345, -3597, +11397, +1333, -6737, -45, +46, -2876, +145, +2069, -2657, +1229, +1805, -1739, -516, +791, -312, -657, +44, -12, +385, -291, +437, +830, +261, +90, -313, -700, -424, -611, -816, }, - { +10805, +5339, -2604, +9725, +1921, -5525, -310, +43, -2429, +58, +1959, -2032, +690, +1674, -1216, -766, +650, -159, -575, +29, +105, +445, -262, +423, +590, +102, +242, -169, -667, -426, -434, -541, }, - { +9340, +5201, -1982, +8478, +2304, -4592, -320, +86, -2009, +7, +1880, -1679, +320, +1616, -995, -817, +572, -17, -496, +83, +280, +281, -168, +371, +343, +122, +380, -5, -602, -322, -317, -483, }, - { +8188, +4843, -1495, +7540, +2395, -3667, -312, +176, -1589, -77, +1770, -1446, +114, +1442, -804, -782, +564, +82, -423, +254, +211, +181, -62, +208, +366, +208, +389, +140, -452, -279, -247, -426, }, - { +7139, +4447, -1005, +6621, +2495, -2780, -305, +313, -1320, -50, +1606, -1337, +16, +1312, -654, -711, +624, +129, -237, +218, +117, +290, -83, +217, +421, +287, +411, +153, -317, -192, -175, -342, }, - { +6157, +4147, -661, +5795, +2719, -2091, -278, +447, -1015, -108, +1345, -1106, -12, +1133, -544, -455, +616, +156, -87, +162, +222, +352, -56, +280, +494, +294, +391, +184, -187, +6, -183, -528, }, - { +5279, +3795, -302, +5095, +2792, -1423, -200, +524, -834, -167, +1181, -897, -46, +946, -299, -307, +520, +329, -7, +248, +337, +305, +68, +311, +476, +300, +386, +295, -101, -189, -428, -616, }, - { +4525, +3459, -28, +4546, +2834, -885, -89, +549, -694, -192, +1043, -644, -76, +759, -74, -153, +593, +505, +119, +343, +347, +334, +158, +340, +453, +359, +386, +40, -308, -328, -435, -568, }, - { +3930, +3246, +221, +4012, +2721, -518, +143, +558, -699, -125, +1073, -572, -271, +859, +240, +26, +775, +548, +199, +453, +346, +378, +240, +360, +327, +89, +121, -123, -319, -354, -529, -642, }, - { +3660, +3270, +329, +3382, +2495, -259, +336, +625, -667, -168, +978, -390, -146, +1158, +544, +64, +837, +706, +404, +422, +317, +415, +105, -19, +35, +69, +43, -172, -504, -539, -442, -551, }, - { +3142, +2802, +557, +3432, +2389, -71, +540, +456, -686, +42, +1063, -160, +119, +1196, +649, +468, +1015, +684, +339, +353, +244, +13, -220, -126, +48, +81, -160, -332, -500, -382, -372, -555, }, - { +2901, +2760, +686, +3156, +2256, -27, +369, +564, -227, +172, +1095, +54, +380, +1501, +986, +535, +850, +558, +60, -34, -144, -62, -229, -185, +27, -136, -229, -282, -406, -348, -382, -501, }, - { +2508, +2594, +1005, +2823, +1909, +401, +624, +677, +80, +149, +1195, +622, +765, +1450, +899, +441, +488, -3, -301, -63, -155, -197, -378, -249, +15, -114, -216, -325, -386, -326, -435, -465, }, - { +2206, +2342, +933, +2683, +2333, +903, +669, +761, +492, +499, +1258, +984, +954, +1127, +508, -78, +61, +24, -139, -253, -442, -276, -171, -30, -76, -244, -225, -191, -331, -440, -399, -321, }, - { +1974, +2815, +1553, +2323, +2233, +1046, +992, +1282, +753, +707, +1323, +599, +390, +690, +158, -204, -61, -149, -350, -307, -284, -187, -98, -47, -143, -282, -239, -272, -323, -315, -319, -272, }, - { +1654, +2776, +1836, +2401, +3022, +1959, +967, +1094, +948, +444, +652, +267, +140, +546, +166, -270, -194, -277, -387, -222, -184, -102, -101, -213, -211, -214, -174, -207, -336, -339, -249, -198, }, - { +1869, +3354, +2494, +2832, +2716, +1654, +1450, +1127, +173, -258, +546, +432, -146, +288, +167, -560, -266, -9, -321, -261, -193, -155, -101, -190, -238, -205, -240, -223, -233, -279, -241, -223, }, - { +2251, +4370, +3095, +2273, +2143, +1471, +1134, +828, +318, +171, +218, -108, -7, +202, -108, -329, -135, -186, -250, -123, -231, -173, -170, -206, -184, -240, -217, -223, -224, -243, -163, -183, }, - { +2659, +4415, +2723, +1899, +1660, +1369, +1422, +927, +331, +708, +366, -215, -222, -87, +228, -79, -456, -205, +38, -181, -201, -158, -281, -171, -233, -218, -175, -209, -188, -206, -158, -146, }, - { +2110, +3925, +2617, +1488, +1521, +1321, +1000, +1375, +1006, +577, +1002, +281, -242, +99, -57, -249, -82, -20, -257, -120, -41, -272, -333, -251, -182, -210, -176, -126, -157, -179, -176, -194, }, - { +1815, +3251, +2187, +1550, +1381, +941, +1057, +773, +515, +1445, +1370, +807, +715, +171, +116, +49, -344, -256, +25, -69, -365, -300, -115, -199, -312, -112, -74, -117, -199, -216, -192, -267, }, - { +1453, +2017, +1172, +1714, +1993, +1501, +661, -199, +441, +1198, +925, +1207, +1374, +1313, +1201, +202, -18, +29, -479, -298, -15, -198, -383, -148, -84, -172, -178, -112, -77, -224, -241, -216, }, - { +1882, +2639, +981, +885, +1287, +1149, +657, -264, +342, +1130, +630, +742, +1292, +1636, +1472, +886, +568, +182, -94, -158, -412, -373, +6, -144, -402, -52, +23, -169, -270, -217, -171, -242, }, - { +2138, +2960, +1101, +1064, +1446, +1136, +291, -438, +715, +1105, +64, +265, +594, +767, +1266, +1060, +858, +969, +438, -42, -101, -297, -344, -218, -121, -114, -231, -67, -73, -307, -272, -133, }, - { +2460, +3291, +1078, +1222, +1735, +1211, -80, -710, +954, +1086, -141, +205, +328, +431, +693, +253, +688, +1146, +655, +645, +331, -174, -61, -188, -361, -99, -16, -187, -277, -187, -156, -227, }, - { +2893, +3811, +1105, +1203, +1818, +1171, -395, -714, +1243, +818, -421, +245, +254, +371, +579, -124, +129, +613, +507, +652, +517, +400, +268, -71, -95, -9, -228, -164, -144, -359, -299, -148, }, - { +3308, +4221, +1114, +1356, +2071, +1044, -891, -658, +1576, +583, -594, +223, +142, +308, +585, -177, -43, +346, +34, +199, +317, +405, +505, +368, +236, +145, +52, -93, -322, -363, -224, -252, }, - { +3900, +4867, +998, +1260, +2220, +839, -1162, -422, +1621, +246, -664, +254, +85, +242, +512, -240, -75, +270, -146, -7, -102, +10, +325, +287, +509, +621, +248, +30, -87, -358, -365, -226, }, - { +4379, +5375, +1025, +1329, +2414, +620, -1641, -92, +1872, -196, -752, +327, -63, +215, +556, -301, -147, +211, -180, -88, -262, -176, -67, -67, +404, +602, +521, +379, +47, -155, -101, -270, }, - { +4917, +5923, +933, +1451, +2663, +215, -2061, +412, +1970, -661, -792, +379, -89, +99, +514, -309, -198, +208, -222, -155, -360, -296, -176, -258, +109, +365, +340, +336, +360, +108, +10, -101, }, - { +5325, +6387, +1044, +1617, +2857, -114, -2569, +894, +2226, -1191, -880, +471, -93, +10, +443, -288, -328, +216, -163, -257, -444, -325, -267, -361, +2, +132, +152, +154, +168, +115, +205, +89, }, - { +5680, +6946, +1250, +1595, +2986, -178, -3103, +1203, +2516, -1694, -900, +579, -179, -49, +355, -219, -348, +53, -131, -293, -494, -294, -363, -474, -96, +59, +126, -24, -77, -107, +65, +185, }, - { +6420, +7593, +839, +1808, +3146, -725, -3065, +1505, +2329, -1963, -819, +612, -243, -161, +340, -128, -458, -62, -108, -328, -544, -296, -472, -531, -38, -40, +40, -115, -239, -173, -70, -95, }, - { +6890, +8125, +798, +2033, +3239, -1037, -3175, +1581, +2439, -2196, -937, +706, -276, -254, +344, -74, -579, -163, -59, -291, -673, -428, -436, -541, -74, -59, -108, -153, -248, -283, -175, -228, }, - { +7112, +8504, +1011, +2420, +3353, -1361, -3255, +1549, +2556, -2243, -1200, +741, -167, -319, +199, +28, -584, -316, +19, -391, -797, -406, -435, -548, -248, -164, +60, -169, -402, -374, -175, -285, }, - { +7285, +8820, +1447, +2597, +3239, -1169, -3229, +1126, +2635, -2125, -1498, +885, -99, -519, +165, +47, -347, -428, -288, -299, -829, -481, -398, -641, -383, -145, +82, -141, -416, -423, -333, -478, }, - { +7520, +8869, +2021, +2814, +2876, -582, -3127, +494, +2536, -1844, -1576, +724, +34, -625, -7, +239, -155, -630, -485, -225, -859, -553, -623, -612, -241, -315, +42, -51, -367, -610, -501, -479, }, - { +7879, +8478, +2398, +3646, +2683, -425, -3110, +367, +2156, -1723, -1287, +263, +38, -359, -259, +217, +107, -737, -613, -82, -1068, -775, -685, -547, -228, -402, +0, +62, -472, -776, -425, -752, }, - { +8205, +7639, +2366, +5376, +3131, -1245, -3272, +1332, +1408, -2244, -393, -194, -320, +234, -603, -6, +519, -774, -631, -35, -1347, -848, -738, -677, -167, -469, +8, -127, -364, -733, -690, -706, }, - { +9071, +7121, +1359, +7044, +3754, -2464, -2808, +2381, +60, -2776, +793, -372, -1036, +563, -545, -275, +838, -803, -718, +19, -1374, -976, -1066, -680, +3, -628, -230, -55, -414, -742, -545, -882, }, - { +10148, +7203, -207, +7831, +4875, -3407, -2535, +3529, -1225, -3617, +2016, -129, -1945, +583, -98, -688, +1031, -623, -939, +116, -1314, -1178, -1259, -633, -72, -818, -379, -21, -446, -673, -502, -1013, }, - { +11044, +7769, -1943, +7882, +6483, -3989, -2591, +4784, -2149, -4901, +3054, +635, -2734, +50, +522, -825, +921, -244, -1180, +190, -1284, -1180, -1357, -904, -121, -897, -516, -101, -271, -733, -400, -911, }, - { +11990, +8411, -3500, +7279, +8002, -4096, -2789, +6028, -2844, -6395, +3677, +1736, -3160, -867, +846, -555, +671, +81, -1262, +34, -1076, -1221, -1513, -1089, -353, -964, -456, -261, -256, -672, -256, -770, }, - { +13335, +8653, -4769, +6560, +8870, -3919, -2715, +7255, -3621, -7665, +3846, +2827, -3088, -1854, +732, -91, +613, +191, -1151, -200, -889, -1355, -1616, -1202, -620, -945, -484, -248, -378, -527, -120, -768, }, - { +14852, +8670, -5913, +6073, +9001, -3654, -2195, +8358, -4463, -8616, +3590, +3721, -2575, -2699, +236, +272, +868, +133, -945, -394, -1059, -1238, -1780, -1341, -641, -1048, -561, -27, -440, -570, -19, -740, }, - { +16451, +8693, -7064, +5832, +8573, -3576, -1333, +9514, -5301, -9295, +3094, +4207, -1784, -3244, -399, +318, +1449, +54, -659, -662, -1314, -1021, -2073, -1203, -803, -1212, -404, +103, -451, -722, -56, -638, }, - { +18423, +8132, -8075, +6128, +7681, -4035, +138, +10573, -6216, -9800, +2747, +4350, -1192, -3295, -1042, +104, +2016, +289, -589, -954, -1505, -917, -2153, -1097, -1071, -1185, -298, +285, -530, -966, -69, -449, }, - { +20202, +8717, -10102, +5865, +7549, -3841, +390, +11057, -6161, -10160, +2346, +4324, -998, -3105, -1402, -423, +2652, +520, -1022, -905, -1505, -1084, -2016, -1271, -995, -1072, -334, +432, -570, -1222, +2, -286, }, - { +22529, +8456, -11824, +5892, +7303, -4055, +930, +11197, -5866, -10497, +2199, +4298, -1350, -2705, -1409, -1011, +2979, +873, -1590, -561, -1535, -1262, -1879, -1318, -879, -952, -350, +491, -720, -1269, +134, -272, }, - { +23974, +9134, -13513, +5844, +7038, -4057, +615, +11611, -4790, -11317, +1983, +4325, -1634, -2352, -1084, -1939, +3123, +1383, -1969, -242, -1583, -1428, -1611, -1435, -861, -839, -383, +423, -787, -1337, +408, -512, }, - { +25044, +9817, -14614, +5833, +6675, -4269, -71, +12212, -3614, -11890, +1484, +4440, -1786, -1990, -859, -2687, +2944, +1877, -2005, -175, -1440, -1495, -1418, -1531, -909, -716, -428, +289, -816, -1306, +466, -753, }, - { +26536, +9314, -14645, +5829, +6191, -4884, -796, +12908, -2788, -12074, +1081, +4219, -1691, -1613, -960, -3033, +2556, +2030, -1647, -335, -1214, -1268, -1603, -1435, -985, -580, -535, +122, -796, -1260, +177, -737, }, - { +27183, +9606, -14376, +5620, +5875, -5416, -2052, +13586, -1628, -12058, +571, +3654, -1110, -1358, -1213, -3155, +2048, +1957, -895, -643, -907, -799, -1977, -1199, -984, -549, -700, +25, -836, -1353, +35, -751, }, - { +27148, +10286, -13645, +5373, +5534, -6103, -3440, +14036, -378, -11705, -177, +2878, -226, -1089, -1747, -3125, +1710, +1453, +80, -816, -863, -89, -2314, -1012, -907, -744, -724, -326, -1037, -1054, -249, -864, }, - { +26584, +11121, -12486, +5232, +5105, -6806, -4740, +13839, +1078, -11022, -1066, +2034, +722, -813, -2405, -2897, +1499, +637, +937, -473, -1208, +661, -2238, -1145, -718, -867, -1215, -685, -932, -951, -292, -941, }, - { +25805, +11950, -11123, +5119, +4637, -7115, -6017, +12797, +2771, -10082, -1948, +1322, +1341, -452, -2821, -2640, +1355, -222, +1382, +402, -1584, +1029, -1649, -1467, -434, -1354, -1712, -685, -1153, -608, -115, -1081, }, - { +24754, +12672, -9499, +5075, +3967, -6831, -7500, +11069, +4769, -9261, -2671, +911, +1238, +136, -2811, -2628, +1336, -1074, +1459, +1369, -1523, +816, -817, -1570, -995, -1254, -2045, -954, -1214, -280, +201, -1144, }, - { +23625, +13743, -8416, +5130, +3177, -5952, -8511, +8195, +6835, -8201, -3226, +701, +799, +463, -2132, -2701, +1161, -1431, +1042, +2182, -1162, +681, -474, -1699, -1321, -1011, -2142, -1212, -1223, -47, +480, -1192, }, - { +22165, +15115, -7785, +5546, +2568, -5733, -8429, +4589, +8489, -6649, -4078, +663, +623, +133, -953, -2723, +670, -1020, -128, +2751, -525, +300, -532, -1412, -1518, -711, -1869, -1605, -920, -465, +529, -917, }, - { +22262, +14424, -6906, +6480, +1678, -6039, -7848, +2265, +8205, -4418, -5059, +773, +1015, -648, +127, -2327, +238, -660, -1047, +2455, +302, -278, -464, -941, -1372, -464, -1422, -1493, -1408, -881, +595, -495, }, - { +21426, +14579, -5798, +6478, +1251, -5676, -7497, -360, +8046, -2301, -6017, +896, +1618, -1474, +1197, -1714, -587, -84, -1747, +1143, +1103, -253, -569, -193, -1153, -2, -1077, -1593, -1678, -1403, +210, -122, }, - { +19944, +15360, -4754, +5956, +1176, -5025, -7238, -2954, +7860, -653, -6260, +621, +2153, -1709, +1912, -1547, -1249, +742, -2688, +57, +1079, +401, -432, +447, -710, -64, -484, -1682, -1600, -2206, -540, +94, }, - { +20147, +14018, -3775, +6372, +90, -4104, -7066, -4495, +7159, +825, -6523, +620, +3112, -2199, +2066, -1581, -1430, +939, -2947, -332, +348, +613, +1047, +312, -702, +618, -378, -1616, -1651, -2440, -1434, -218, }, - { +19984, +13391, -3853, +7072, -294, -4065, -6337, -5631, +5959, +2227, -6012, -65, +4276, -2601, +1149, -793, -2128, +1041, -2372, -946, +540, +152, +1289, +1452, -1002, +964, +82, -1959, -1450, -2309, -2165, -747, }, - { +20430, +12454, -5495, +8998, +65, -5776, -5336, -5251, +4459, +2909, -5003, -707, +4833, -2860, -19, +113, -2229, +469, -1412, -634, +320, -217, +361, +2809, -484, +184, +1137, -2340, -1770, -1410, -2528, -1555, }, - { +21692, +10456, -7798, +12335, +68, -8763, -3715, -3473, +2378, +2906, -3129, -2190, +5102, -2356, -1660, +915, -1539, -297, -715, +276, -315, -459, +27, +2282, +814, +228, +658, -1653, -2043, -1236, -2088, -2094, }, - { +22414, +8463, -8975, +14734, -856, -9903, -2019, -2434, +827, +2536, -1717, -3048, +4909, -1972, -2551, +1285, -549, -637, -715, +674, -143, -626, -627, +1991, +1177, +722, +464, -1119, -1865, -1815, -1391, -1829, }, - { +22530, +6646, -9511, +16483, -1322, -11024, -644, -496, -1479, +1598, +531, -3996, +3822, -711, -2705, +845, +188, -390, -681, +346, -68, -65, -1383, +1684, +1452, +284, +1178, -797, -2128, -1411, -1375, -1644, }, - { +21322, +5400, -8796, +17260, -1500, -11305, +474, +113, -2907, +1438, +1455, -4669, +3322, +481, -2925, +742, +471, -590, -202, +63, -265, +281, -1317, +1179, +1229, +431, +1123, -441, -2004, -992, -1149, -2020, }, - { +19175, +5030, -7462, +16622, -929, -10530, +416, +343, -3120, +766, +1767, -4343, +2822, +1079, -2638, +519, +570, -563, -289, +165, -315, +82, -803, +997, +763, +599, +901, -468, -1286, -794, -1066, -1838, }, - { +16819, +5384, -6370, +14965, +290, -9700, +208, +612, -3392, +183, +2183, -3797, +2080, +1803, -2493, -16, +1023, -550, -707, +329, -153, -121, -550, +1037, +727, +224, +746, -397, -1126, -361, -1019, -1629, }, - { +14912, +6709, -4328, +10591, -498, -7109, +111, -741, -770, +328, -733, -960, +2191, +30, -1474, -311, +350, -380, -1280, +108, +235, +180, +74, +223, +54, +624, +423, -99, +35, -79, -285, -105, }, - { +12603, +6186, -2629, +9885, -405, -6060, +108, -976, -537, +418, -737, -896, +2184, +171, -1454, -339, +212, -324, -1080, +111, +88, +93, +170, +250, +211, +621, +320, -131, +116, -1, -403, -106, }, - { +10408, +5748, -848, +8724, -167, -4613, -400, -1217, -70, +524, -929, -678, +2111, +202, -1239, -402, +223, -337, -970, +153, +57, +16, +164, +314, +375, +524, +121, +6, +131, -34, -146, -32, }, - { +8810, +5752, -110, +7195, +525, -3549, -713, -1201, +150, +589, -802, -524, +1697, +366, -971, -531, +153, -232, -820, +124, +74, +31, +92, +425, +518, +160, +114, +336, +59, -121, +192, +176, }, - { +7707, +5602, +35, +6275, +1122, -3180, -685, -740, +80, +415, -374, -403, +1135, +566, -689, -718, +117, -57, -675, +45, +161, +35, +47, +597, +362, +73, +358, +355, +34, +128, +414, +95, }, - { +7097, +5535, -192, +5388, +1340, -2724, -316, -506, -92, +415, +68, -445, +787, +694, -670, -663, +194, +20, -606, +105, +221, -83, +318, +654, +165, +211, +501, +464, +163, +305, +282, -143, }, - { +6452, +5181, -188, +4851, +1397, -2250, -47, -387, -147, +524, +273, -528, +602, +655, -502, -522, +157, +53, -489, +203, +143, +158, +611, +321, +242, +571, +633, +422, +125, +234, -5, -218, }, - { +5779, +4631, +28, +4565, +1363, -1816, +67, -196, +8, +488, +200, -488, +649, +572, -444, -381, +184, +6, -287, +343, +218, +465, +530, +350, +563, +605, +532, +190, +1, +83, -90, -218, }, - { +5208, +4384, +145, +3924, +1403, -1285, +290, -147, -75, +540, +306, -396, +492, +507, -283, -289, +166, +176, +48, +344, +475, +764, +468, +481, +475, +299, +347, +79, -73, +8, -92, -335, }, - { +4512, +3969, +359, +3651, +1556, -960, +277, -42, +99, +522, +205, -303, +469, +444, -138, -122, +272, +416, +283, +588, +781, +710, +302, +187, +175, +216, +260, +77, -143, -145, -168, -400, }, - { +3801, +3629, +701, +3369, +1505, -562, +487, -64, +147, +580, +155, -276, +520, +581, +54, +7, +535, +858, +532, +711, +669, +180, +6, +159, +92, +196, +192, -93, -202, -135, -272, -498, }, - { +3442, +3530, +703, +2812, +1660, -44, +424, -101, +187, +562, +336, -54, +523, +647, +416, +546, +884, +888, +356, +303, +242, +72, +10, +71, +14, +72, +66, -163, -241, -221, -397, -501, }, - { +2690, +3000, +1279, +2876, +1515, +205, +493, -52, +442, +658, +264, +192, +1000, +1052, +635, +643, +744, +413, +42, +208, +138, +112, -80, -143, -63, -30, +7, -171, -300, -327, -429, -392, }, - { +2478, +3269, +1270, +2133, +1692, +521, +531, +45, +514, +1060, +829, +686, +1118, +1030, +491, +45, +183, +420, +250, +132, -125, -159, -155, -121, -114, -108, -174, -265, -205, -328, -363, -352, }, - { +1870, +2687, +1568, +2459, +1988, +651, +612, +481, +1093, +1477, +1114, +836, +591, +278, +48, +164, +470, +379, -76, -182, +38, -195, -357, -228, -185, -143, -188, -137, -211, -282, -321, -361, }, - { +2002, +3298, +2072, +1782, +1264, +1387, +2004, +1233, +1029, +1042, +338, -15, +176, +284, +423, +207, -57, +116, -13, -210, -269, -453, -350, -132, -143, -177, -143, -97, -213, -359, -341, -306, }, - { +2146, +3307, +2355, +2752, +2119, +1859, +2021, +710, +97, +234, +110, +124, +235, +191, +340, -11, -121, +97, -245, -337, -346, -487, -277, -43, -78, -145, -151, -149, -204, -284, -366, -347, }, - { +2369, +3977, +3947, +3602, +1697, +1277, +778, -51, +139, +274, +157, +44, -14, +65, +388, -56, -226, -108, -386, -368, -349, -275, -166, -135, -161, -68, -48, -184, -269, -324, -303, -300, }, - { +2991, +5611, +4893, +2413, +32, +530, +1206, +716, -81, -249, -72, +167, +231, -189, +96, +62, -289, -321, -341, -226, -287, -249, -289, -147, -48, -120, -84, -169, -256, -385, -287, -211, }, - { +3480, +5919, +3215, +1230, +711, +1536, +1856, +445, -348, +146, +147, -235, +202, -60, -65, -10, -330, -145, -168, -321, -230, -233, -366, -152, -34, -139, -131, -161, -196, -267, -285, -233, }, - { +2004, +3234, +1971, +1898, +2099, +2208, +2155, +993, +558, +802, +440, -18, -153, -3, +129, -234, -279, -55, -99, -109, -245, -275, -242, -234, -224, -178, -205, -148, -89, -176, -206, -280, }, - { +1279, +2318, +1457, +1126, +1665, +2069, +1778, +1033, +1441, +1718, +1054, +741, +475, +244, +79, -171, -166, -218, -231, -69, -145, -125, -126, -248, -153, -180, -287, -235, -255, -196, -120, -109, }, - { +1453, +2492, +1452, +1154, +1435, +1406, +842, +362, +1287, +1720, +1252, +1179, +1008, +731, +566, +64, -227, -101, -154, -275, -230, -121, -97, -71, -157, -175, -212, -268, -250, -286, -220, -166, }, - { +1879, +2842, +1125, +1084, +1653, +1253, +390, -18, +973, +1151, +667, +1023, +1287, +1158, +966, +422, +174, +136, -200, -125, -209, -336, -116, -116, -96, -37, -181, -264, -245, -282, -257, -233, }, - { +2149, +3242, +1318, +1052, +1535, +1017, +118, +168, +1096, +645, +127, +653, +733, +907, +1209, +756, +503, +444, +179, +76, -160, -223, -173, -251, -109, -40, -121, -158, -228, -282, -247, -243, }, - { +2317, +3435, +1467, +1216, +1790, +944, -476, +147, +1327, +465, +25, +491, +329, +437, +651, +458, +687, +794, +439, +296, +209, +11, -156, -194, -142, -157, -160, -145, -173, -218, -241, -271, }, - { +2632, +3865, +1576, +1194, +1850, +818, -747, +351, +1336, +91, -24, +570, +326, +220, +377, +87, +100, +501, +607, +596, +401, +255, +179, -41, -117, -38, -173, -278, -200, -177, -186, -241, }, - { +2913, +4307, +1690, +1174, +1997, +721, -1042, +507, +1361, -158, -88, +596, +317, +156, +293, -13, -74, +80, +115, +344, +456, +579, +399, +152, +182, +78, -95, -162, -227, -292, -160, -212, }, - { +3419, +4851, +1663, +1035, +2035, +628, -1177, +737, +1236, -536, -64, +690, +334, +51, +172, -13, -135, -42, -10, -2, -68, +347, +513, +426, +347, +211, +168, -24, -193, -236, -186, -272, }, - { +3767, +5304, +1782, +1016, +2102, +463, -1378, +1048, +1239, -936, -179, +746, +362, +62, +89, -105, -187, -70, -33, -113, -245, -31, +98, +248, +442, +396, +305, +172, +12, -165, -166, -183, }, - { +4285, +5774, +1650, +1174, +2192, +50, -1405, +1467, +1118, -1334, -217, +829, +333, +12, +50, -124, -225, -140, -22, -146, -307, -135, -82, -31, +86, +236, +387, +312, +118, +25, +51, -123, }, - { +4848, +6188, +1491, +1445, +2261, -490, -1401, +1942, +965, -1671, -300, +836, +385, -47, +8, -178, -306, -200, +51, -186, -351, -153, -292, -30, +25, -103, +13, +150, +219, +188, +112, +17, }, - { +5454, +6649, +1314, +1669, +2321, -943, -1366, +2334, +803, -1890, -325, +781, +385, -83, +115, -228, -488, -225, +76, -126, -377, -187, -365, -53, +30, -174, -150, -173, -42, +89, +185, +106, }, - { +5926, +7107, +1339, +1747, +2383, -1252, -1530, +2755, +780, -2246, -303, +735, +323, -85, +73, -145, -589, -384, +135, -187, -469, -43, -386, -191, +46, -215, -180, -236, -326, -211, +7, +83, }, - { +6333, +7526, +1384, +2014, +2467, -1782, -1590, +3195, +714, -2494, -349, +719, +280, -145, +55, -69, -636, -504, +150, -221, -574, -43, -314, -228, -37, -138, -204, -369, -416, -299, -97, -205, }, - { +6696, +8017, +1498, +2006, +2624, -2005, -1798, +3417, +748, -2614, -432, +706, +173, -173, +53, -56, -573, -718, +132, -67, -717, -164, -301, -196, -38, -159, -197, -465, -469, -327, -185, -358, }, - { +6930, +8687, +1750, +1599, +2863, -1765, -2210, +3311, +900, -2491, -605, +596, +191, -265, +91, -35, -551, -808, +27, +34, -661, -338, -391, -71, -59, -282, -167, -426, -499, -386, -346, -349, }, - { +7032, +9112, +2294, +1319, +2928, -1295, -2725, +3058, +1141, -2349, -736, +409, +218, -319, +37, -5, -474, -896, -105, +108, -719, -327, -414, -210, -8, -342, -280, -290, -610, -529, -264, -398, }, - { +7290, +9148, +2788, +1517, +2890, -1004, -3145, +2936, +1182, -2207, -713, +170, +226, -310, -137, +66, -236, -1052, -288, +218, -703, -396, -407, -298, -61, -288, -332, -407, -637, -624, -99, -427, }, - { +8295, +8777, +2246, +2812, +2858, -1707, -2793, +3041, +460, -1834, -416, -196, +229, -361, -255, +143, -68, -1152, -427, +236, -539, -557, -489, -199, -168, -280, -301, -623, -729, -417, -190, -475, }, - { +8813, +8385, +2070, +3791, +3408, -2249, -3089, +3581, -338, -1829, +311, -486, -198, -209, -270, -126, +417, -1313, -692, +394, -483, -630, -627, -124, -246, -308, -391, -642, -737, -489, -253, -480, }, - { +9480, +7764, +1344, +5665, +3938, -3530, -2582, +4359, -1779, -1905, +1349, -610, -594, -360, -91, -401, +691, -1075, -1088, +435, -349, -619, -660, -124, -373, -324, -465, -444, -823, -782, -95, -634, }, - { +10219, +7759, +108, +6635, +4903, -4328, -2227, +5026, -3212, -2275, +2513, -596, -1046, -594, +196, -690, +587, -537, -1473, +302, -113, -638, -684, -100, -439, -459, -480, -472, -766, -889, -314, -724, }, - { +11359, +8080, -1537, +6725, +6202, -4589, -2055, +5443, -4331, -2746, +3483, -358, -1535, -803, +500, -787, +107, +0, -1473, -127, +202, -644, -687, +80, -605, -513, -488, -741, -549, -859, -768, -615, }, - { +12561, +8515, -3181, +6443, +7273, -4422, -1771, +5642, -5238, -3343, +4113, +235, -1988, -1143, +783, -757, -401, +173, -1070, -614, +288, -431, -703, +306, -751, -608, -594, -870, -585, -862, -824, -695, }, - { +13637, +9078, -4327, +5307, +8230, -3683, -1700, +6016, -6052, -3983, +4365, +989, -2192, -1647, +1018, -629, -785, -62, -507, -850, +26, -33, -720, +529, -810, -802, -657, -1006, -784, -809, -610, -865, }, - { +14620, +9720, -5196, +3985, +8621, -2703, -1406, +6384, -6867, -4537, +4323, +1689, -2163, -2167, +1076, -438, -1009, -536, -136, -784, -345, +300, -530, +532, -827, -847, -766, -1246, -914, -773, -428, -804, }, - { +16072, +9930, -6183, +3360, +8255, -2295, -119, +6470, -7878, -4616, +4153, +2063, -2029, -2471, +1020, -386, -950, -1040, -67, -497, -520, +425, -98, +296, -886, -669, -1038, -1392, -1030, -835, -225, -497, }, - { +17538, +10139, -7275, +3167, +7496, -2312, +1507, +6655, -8887, -4746, +4122, +2161, -1895, -2506, +749, -326, -908, -1248, -345, -284, -377, +510, +186, +31, -841, -583, -1261, -1430, -1259, -849, -50, -134, }, - { +18795, +10599, -8283, +2946, +6835, -2703, +2875, +7278, -9742, -5079, +4325, +2043, -1829, -2306, +376, -514, -590, -1442, -695, -362, +63, +785, +55, -22, -629, -692, -1264, -1504, -1464, -809, +17, +195, }, - { +19828, +11378, -9267, +2629, +6374, -3347, +3612, +8402, -10339, -5537, +4515, +1859, -1884, -1929, -100, -800, -262, -1561, -976, -577, +410, +1421, -419, +34, -250, -981, -1080, -1605, -1632, -802, +11, +380, }, - { +21206, +11505, -9851, +2389, +6035, -4347, +4232, +9433, -10759, -5759, +4577, +1581, -1877, -1583, -452, -1192, +46, -1648, -1025, -873, +537, +2263, -927, +52, +224, -1290, -882, -1564, -1935, -752, -159, +454, }, - { +21951, +12180, -10180, +1892, +5955, -5226, +3946, +10828, -10791, -5984, +4342, +1308, -1588, -1445, -711, -1558, +306, -1741, -844, -1199, +362, +3030, -1015, -204, +814, -1397, -873, -1354, -2329, -849, -416, +417, }, - { +22506, +12779, -10294, +1612, +5688, -5970, +3299, +11834, -10475, -5915, +3858, +872, -1070, -1438, -1116, -1691, +435, -1836, -594, -1442, -11, +3401, -605, -538, +1220, -1085, -1193, -1113, -2738, -1072, -644, +153, }, - { +23186, +13097, -10391, +2031, +4838, -6522, +2825, +12019, -9671, -5661, +3239, +340, -378, -1439, -1649, -1540, +599, -1995, -278, -1529, -462, +3340, +152, -492, +1137, -401, -1605, -1222, -2820, -1325, -987, -68, }, - { +22882, +14119, -9689, +1389, +4734, -6999, +1524, +12257, -8386, -5521, +2330, +28, +188, -1505, -1990, -1510, +944, -2230, -172, -1187, -1194, +2809, +1343, -197, +605, +402, -2099, -1365, -2620, -1824, -1038, -503, }, - { +21870, +15422, -8022, +32, +4928, -6961, -638, +12423, -6481, -5741, +1679, -358, +537, -1263, -2316, -1338, +1170, -2350, -127, -788, -1648, +1934, +2335, +603, -234, +775, -1895, -1692, -2402, -2007, -1134, -816, }, - { +21377, +15848, -6611, -135, +4095, -6589, -2340, +11613, -4347, -6089, +1401, -892, +589, -722, -2599, -1204, +1299, -2460, -64, -474, -1793, +1309, +2278, +1468, -710, +729, -1381, -1948, -2200, -1989, -1059, -1104, }, - { +21825, +15338, -6288, +1723, +2245, -6807, -2394, +9743, -2760, -5631, +785, -1266, +822, -455, -2395, -1291, +1244, -2162, -287, +63, -1716, +759, +1340, +2033, -170, +136, -645, -1936, -2205, -1413, -1181, -1687, }, - { +22088, +14986, -6294, +3940, +475, -7388, -1931, +7563, -1485, -4751, -302, -1228, +1282, -606, -1733, -1685, +1011, -1322, -834, +679, -1560, -371, +652, +2168, +634, +122, -548, -1338, -1967, -1463, -1230, -1785, }, - { +21218, +15763, -6154, +5244, -207, -8203, -1741, +5343, +1, -4070, -1324, -1042, +1940, -1042, -1041, -1719, +173, +234, -1546, +421, -980, -1263, -189, +2163, +1362, +537, -295, -894, -1836, -1649, -862, -1860, }, - { +20943, +15351, -5193, +5824, -681, -8421, -2182, +3733, +912, -3280, -2125, -629, +2393, -1338, -793, -1272, -318, +619, -1449, -542, -613, -929, -1049, +1622, +1869, +1834, -606, -1014, -899, -1858, -1052, -1583, }, - { +20467, +15036, -4299, +6074, -972, -8163, -2993, +2103, +1953, -2525, -2906, +84, +2478, -1496, -381, -1209, -661, +522, -1431, -1137, -494, -29, -1724, +1410, +1857, +2078, +198, -1222, -492, -1845, -1016, -1459, }, - { +19997, +14492, -3439, +6231, -1292, -7499, -3870, +428, +3016, -1672, -3589, +505, +3009, -1682, -424, -1271, -888, +168, -1633, -640, -998, +512, -655, +572, +1038, +2022, +1564, -1436, -837, -970, -1064, -1590, }, - { +19121, +13891, -1956, +5864, -1769, -5712, -5524, -1209, +4728, -1224, -4384, +1529, +2886, -1835, -216, -2037, -717, +368, -2459, +62, -470, -20, +501, +397, +27, +1794, +1472, -406, -774, -1035, -530, -1651, }, - { +18795, +12787, -866, +5679, -2785, -3778, -6009, -3416, +6104, -148, -5120, +1968, +2942, -2232, -361, -2334, -318, +255, -2810, +772, +147, -722, +931, +1048, -622, +926, +926, +464, +8, -1388, -195, -1234, }, - { +19769, +11583, -2448, +6778, -3321, -3974, -5178, -3690, +5661, +410, -4626, +1587, +2861, -2687, -704, -1965, -264, +354, -2735, +728, +431, -372, +846, +890, -556, +313, +642, +248, +534, -654, -743, -572, }, - { +20742, +9918, -4333, +9177, -3673, -5562, -3412, -3017, +4558, +903, -4422, +932, +3308, -2821, -1440, -1193, +107, +341, -2476, +352, +665, +234, +482, +681, -223, -107, +450, +161, +378, +311, -786, -592, }, - { +20393, +8513, -5551, +11591, -3341, -7618, -1960, -1344, +2974, +225, -3410, +284, +3332, -2616, -1768, -458, +23, +66, -1947, +502, +187, +334, +642, +553, -324, +98, +28, -212, +831, +137, -320, -307, }, - { +19863, +7195, -5891, +13080, -3237, -8975, -179, -735, +1159, +597, -2780, -566, +3377, -1932, -1835, -26, +57, -431, -1301, +563, -286, +265, +803, +515, -423, +180, +122, -246, +644, +165, -191, +77, }, - { +18658, +6850, -5751, +12388, -2703, -7823, +255, -1504, +610, +770, -2248, -983, +3161, -1268, -1738, +128, -21, -478, -1161, +338, -70, +251, +391, +591, -323, +20, +528, -36, +54, +115, -36, +34, }, - { +17076, +6736, -5238, +11355, -1525, -7217, -40, -1078, -147, +458, -1371, -990, +2637, -628, -1439, -189, +204, -339, -1390, +203, +285, +214, +63, +453, -132, +311, +558, +23, -66, -152, +62, -43, }, - { +13623, +7663, -736, +5443, -2593, -2244, -1530, -1649, +1729, -32, -2266, +999, +1978, -1230, -677, -1107, +219, -259, -1521, +393, -253, -340, +340, +425, +603, +1120, -212, -683, -191, -585, -148, +387, }, - { +11820, +7583, -426, +4965, -1356, -2529, -1167, -1245, +983, +124, -1778, +794, +1769, -842, -700, -980, +259, -378, -1380, +412, -355, -376, +513, +422, +537, +830, -258, -264, -158, -658, +7, +383, }, - { +10321, +7312, -105, +4864, -813, -2658, -650, -1140, +594, +154, -1345, +747, +1470, -560, -589, -773, +109, -428, -1061, +264, -409, -228, +464, +450, +557, +455, -229, +107, -87, -614, +63, +459, }, - { +8832, +6788, +754, +4529, -737, -2058, -537, -1141, +593, +102, -1073, +689, +1331, -427, -481, -535, -57, -390, -871, +136, -280, -172, +355, +496, +482, +211, +7, +299, +18, -389, +32, +568, }, - { +7264, +6341, +1804, +3830, -547, -1150, -702, -1198, +746, +193, -1033, +629, +1243, -340, -243, -463, -211, -272, -673, +38, -232, -89, +255, +491, +349, +237, +305, +440, +181, -306, +96, +481, }, - { +5764, +5793, +2760, +3310, -250, -431, -863, -1206, +942, +277, -1025, +490, +1124, +11, -135, -654, -133, +3, -652, -89, -115, -120, +324, +473, +214, +489, +656, +578, +94, -300, +162, +271, }, - { +4877, +5432, +2934, +2887, +9, -98, -665, -1051, +773, +328, -754, +397, +892, +204, -54, -717, +22, +137, -707, -136, -8, -16, +384, +457, +358, +804, +826, +406, -152, -241, +83, +160, }, - { +4273, +4974, +2996, +2688, +19, +236, -317, -1082, +645, +529, -499, +171, +725, +487, -28, -702, +171, +109, -663, +33, +8, +168, +685, +509, +520, +907, +639, +123, -222, -249, +142, +242, }, - { +3881, +4471, +2801, +2721, +214, +232, -276, -784, +726, +443, -495, +187, +790, +514, -89, -624, +292, +140, -590, +200, +269, +545, +770, +316, +532, +788, +265, -82, -82, -100, +41, +29, }, - { +3766, +4300, +2408, +2391, +333, +347, -106, -602, +651, +407, -345, +364, +720, +250, +52, -284, +220, +186, -143, +547, +529, +560, +390, +206, +482, +471, +188, -7, -119, -170, +39, -9, }, - { +3436, +3912, +2322, +2385, +450, +371, -77, -417, +729, +455, -307, +332, +707, +317, +188, -91, +487, +565, +170, +463, +431, +296, +60, +230, +424, +421, +106, -107, -113, -167, +28, -121, }, - { +3183, +3685, +2212, +2271, +537, +324, +19, -108, +778, +330, -270, +582, +667, +327, +729, +405, +569, +537, +26, +242, +252, -24, +148, +398, +218, +251, +64, -101, -137, -167, -61, -180, }, - { +2975, +3602, +2238, +1946, +368, +615, +350, -208, +659, +572, -66, +604, +1024, +904, +959, +291, +202, +264, -144, +133, +221, +2, +109, +243, +252, +133, -64, -129, -180, -137, -144, -273, }, - { +2802, +3321, +2156, +2179, +535, +317, +283, +375, +791, +445, +493, +1260, +1224, +697, +585, -84, -52, +130, -53, +215, +5, -34, +157, +233, +121, -41, -96, -197, -124, -177, -272, -304, }, - { +2567, +3351, +2539, +1843, +97, +744, +689, +452, +1235, +1224, +767, +951, +804, +213, +156, -203, +95, +139, -182, +93, +76, +25, +66, +145, -99, -130, -124, -168, -143, -326, -266, -289, }, - { +2718, +3449, +2308, +1797, +208, +761, +1522, +1644, +1223, +789, +460, +314, +454, -11, +113, +21, -170, +13, +13, +85, +59, -34, -70, +29, -183, -196, -119, -202, -174, -262, -320, -243, }, - { +2540, +3343, +2399, +2066, +1062, +1501, +1604, +1736, +1082, -140, -197, +490, +498, -164, -13, -43, -88, +38, +21, +50, -52, -74, -79, -137, -262, -173, -156, -121, -156, -298, -206, -189, }, - { +2234, +3727, +3392, +2599, +1296, +1388, +1575, +990, +120, +142, -3, +141, +343, -173, +83, -53, -176, +87, -65, -57, -14, -108, -214, -261, -285, -100, -90, -157, -152, -234, -209, -204, }, - { +2985, +5564, +3761, +1458, +757, +1364, +784, +451, +634, -7, -242, +3, +522, +51, -283, +33, -103, -187, +6, +14, -99, -195, -315, -245, -150, -121, -75, -132, -198, -215, -225, -243, }, - { +3536, +5654, +3321, +1733, +414, +394, +1272, +1090, -2, -98, +317, +30, +224, +141, -65, -151, -228, -176, -28, +9, -112, -143, -326, -205, -121, -146, -154, -155, -169, -220, -257, -233, }, - { +2423, +4490, +3856, +2307, +306, +542, +1485, +1042, +272, +121, +367, +345, +305, +76, +54, -98, -197, -211, -235, -76, +30, -102, -249, -110, -163, -144, -218, -256, -176, -211, -237, -223, }, - { +2207, +4508, +3055, +1310, +930, +958, +1117, +900, +798, +352, +193, +679, +614, +197, +54, +57, -131, -330, -215, -106, -182, -79, -43, -101, -76, -110, -233, -306, -312, -262, -203, -241, }, - { +2155, +4216, +2568, +1005, +1213, +966, +459, +898, +1067, +401, +559, +752, +475, +636, +473, -23, -19, +1, -327, -285, -98, -96, -180, -15, +129, -115, -171, -209, -363, -372, -286, -209, }, - { +2070, +3883, +2353, +1160, +1380, +728, +99, +912, +928, +215, +528, +873, +808, +593, +419, +448, +247, -17, -66, -137, -244, -204, -83, -38, -42, +64, -18, -242, -235, -315, -412, -310, }, - { +2125, +3872, +2333, +1117, +1382, +652, -82, +932, +929, -32, +165, +810, +760, +591, +704, +380, +171, +402, +223, -173, -55, +18, -230, -138, +84, +9, -127, -88, -152, -290, -286, -341, }, - { +2204, +3829, +2303, +1430, +1528, +266, -259, +1194, +944, -279, +37, +705, +496, +385, +633, +421, +252, +297, +317, +192, +43, +66, +57, +9, -58, -33, -24, -181, -247, -150, -214, -284, }, - { +2377, +4116, +2337, +1342, +1538, +248, -324, +1198, +907, -340, -9, +552, +446, +300, +373, +259, +71, +202, +429, +213, +40, +308, +228, +122, +212, +69, -122, -224, -230, -240, -255, -174, }, - { +2547, +4334, +2430, +1433, +1566, +87, -418, +1351, +878, -486, -33, +547, +363, +146, +403, +264, -240, -131, +304, +205, +66, +265, +312, +373, +311, +248, +138, -166, -373, -314, -205, -258, }, - { +2830, +4723, +2442, +1353, +1596, +57, -445, +1370, +794, -551, +26, +483, +302, +84, +326, +353, -232, -336, -50, +55, -20, +99, +386, +443, +376, +430, +300, -2, -200, -321, -318, -255, }, - { +3101, +5094, +2484, +1317, +1620, -48, -486, +1479, +713, -731, +26, +531, +246, -26, +207, +395, -120, -435, -199, -118, -261, -82, +201, +404, +445, +420, +397, +148, -80, -175, -230, -288, }, - { +3513, +5583, +2388, +1169, +1692, -102, -510, +1532, +632, -825, +39, +484, +162, -19, +107, +357, -62, -406, -271, -220, -305, -288, -44, +301, +381, +318, +417, +216, -33, -33, -125, -197, }, - { +3971, +6063, +2297, +1049, +1754, -235, -496, +1678, +453, -941, +114, +521, +25, -141, +100, +323, -30, -393, -314, -245, -341, -357, -157, +129, +280, +188, +259, +194, -7, -19, -69, -59, }, - { +4462, +6601, +2162, +929, +1825, -406, -449, +1847, +245, -1033, +198, +531, -55, -243, +34, +274, -46, -317, -280, -344, -378, -331, -147, -22, +200, +127, +86, +97, -172, -74, +29, -12, }, - { +4929, +7134, +2067, +832, +1905, -671, -420, +2107, +13, -1176, +285, +566, -115, -373, -56, +231, -88, -317, -242, -369, -432, -373, -60, -90, +32, +212, -22, -102, -274, -226, -80, -18, }, - { +5380, +7722, +2007, +689, +2018, -933, -447, +2383, -171, -1301, +369, +562, -128, -427, -220, +187, -78, -332, -233, -409, -419, -408, -34, +5, -132, +185, +51, -252, -327, -342, -282, -98, }, - { +5728, +8332, +2054, +461, +2152, -1109, -551, +2612, -297, -1395, +446, +591, -229, -430, -303, +22, -78, -336, -214, -416, -470, -471, -25, +180, -147, -54, +113, -193, -423, -380, -487, -230, }, - { +6113, +8894, +2133, +278, +2235, -1274, -667, +2769, -471, -1368, +504, +562, -301, -464, -281, -179, -193, -277, -163, -442, -520, -538, -26, +230, -9, -150, -82, -60, -486, -442, -508, -419, }, - { +6822, +9262, +1874, +539, +2127, -1579, -524, +2787, -765, -1217, +595, +512, -360, -580, -126, -403, -358, -224, -134, -389, -601, -579, +2, +211, +8, +23, -240, -219, -412, -487, -530, -498, }, - { +7515, +9472, +1708, +950, +1940, -1744, -475, +2685, -890, -1100, +601, +523, -322, -777, -22, -467, -558, -250, -104, -316, -558, -673, -18, +285, -56, +161, -229, -389, -420, -494, -565, -489, }, - { +7940, +9637, +1858, +1251, +1898, -1722, -763, +2646, -912, -1044, +619, +459, -176, -902, -97, -399, -684, -474, -18, -221, -503, -687, -201, +491, -97, +79, -100, -413, -500, -584, -564, -465, }, - { +8437, +9625, +1884, +1715, +2059, -1879, -1105, +2725, -1064, -1040, +741, +338, -154, -826, -248, -438, -648, -774, -57, -33, -524, -628, -313, +497, +49, -120, -60, -285, -620, -701, -513, -517, }, - { +9220, +9383, +1442, +2663, +2411, -2496, -1180, +2907, -1426, -1017, +899, +285, -271, -686, -239, -660, -556, -895, -297, +126, -442, -632, -203, +342, +145, -93, -144, -242, -638, -729, -500, -582, }, - { +9906, +8999, +886, +4046, +2822, -3537, -956, +3303, -2122, -1097, +1212, +287, -466, -677, -82, -821, -584, -919, -622, +120, -110, -798, -101, +317, +50, +139, -325, -314, -494, -726, -682, -494, }, - { +10165, +8622, +635, +5498, +3208, -4703, -409, +3974, -3274, -1343, +1812, +349, -758, -791, +168, -846, -676, -904, -937, -105, +296, -819, -186, +443, -101, +357, -353, -431, -390, -698, -845, -370, }, - { +10778, +9125, -461, +5499, +4480, -4885, -762, +4363, -3869, -1600, +2274, +309, -1021, -799, +442, -989, -823, -718, -1054, -519, +402, -449, -376, +548, -68, +372, -259, -484, -358, -718, -919, -405, }, - { +11808, +9598, -1631, +4810, +5752, -4539, -1177, +4391, -4229, -1790, +2570, +358, -1408, -786, +715, -1102, -1041, -581, -992, -885, +191, -44, -368, +438, +142, +323, -208, -398, -399, -804, -937, -537, }, - { +12864, +10102, -2814, +4041, +6509, -3716, -1366, +4112, -4371, -1965, +2757, +499, -1803, -807, +909, -1173, -1234, -559, -856, -1084, -225, +261, -140, +202, +383, +376, -191, -207, -486, -953, -891, -645, }, - { +13770, +10842, -3762, +2948, +6944, -2626, -1423, +3706, -4498, -2054, +2738, +733, -2151, -912, +1063, -1203, -1347, -631, -679, -1132, -639, +290, +229, +18, +464, +552, -134, -53, -593, -1082, -910, -725, }, - { +14673, +11578, -4475, +1691, +7096, -1713, -1082, +3280, -4814, -1919, +2563, +861, -2306, -1111, +1114, -1240, -1354, -818, -528, -1086, -897, +19, +528, +85, +343, +790, +8, -1, -705, -1107, -997, -856, }, - { +15287, +12615, -5054, +450, +7031, -997, -525, +3136, -5350, -1613, +2407, +806, -2180, -1353, +994, -1181, -1315, -1000, -400, -980, -938, -358, +637, +322, +261, +1020, +234, -8, -727, -1060, -1088, -991, }, - { +16341, +13198, -5831, -183, +6631, -925, +450, +3048, -6132, -1100, +2328, +438, -1973, -1456, +665, -1224, -1147, -1229, -302, -819, -969, -597, +502, +511, +258, +1295, +390, -116, -684, -1059, -1180, -1113, }, - { +17889, +13289, -7003, +251, +5613, -1102, +1630, +2856, -6736, -544, +2351, -201, -1577, -1545, +280, -1291, -936, -1371, -191, -616, -996, -677, +307, +583, +290, +1693, +557, -380, -523, -1129, -1279, -1128, }, - { +19421, +13294, -8130, +984, +4304, -1338, +2588, +2708, -7031, -194, +2313, -845, -1057, -1787, -127, -1222, -940, -1254, -198, -479, -881, -843, +201, +539, +228, +2168, +760, -747, -401, -1194, -1459, -1011, }, - { +20606, +13470, -8907, +1610, +3084, -1671, +3262, +2674, -6933, -54, +2126, -1222, -615, -2058, -501, -1073, -920, -1108, -226, -364, -678, -985, +112, +592, +23, +2550, +1067, -1061, -439, -1160, -1596, -844, }, - { +21678, +13397, -9105, +1972, +1964, -2147, +3689, +2647, -6634, +29, +1710, -1374, -333, -2266, -901, -865, -791, -1224, -108, -330, -517, -988, -65, +848, -297, +2505, +1436, -1115, -771, -1020, -1548, -824, }, - { +22043, +13828, -8808, +1968, +1087, -2691, +3735, +2813, -6153, -63, +1327, -1523, -22, -2413, -1231, -625, -620, -1517, +116, -296, -490, -687, -330, +1228, -654, +1883, +1897, -817, -1166, -848, -1353, -842, }, - { +21862, +14553, -8083, +1733, +298, -3191, +3378, +3080, -5574, -270, +1014, -1790, +389, -2456, -1466, -480, -483, -1820, +297, -178, -667, -4, -656, +1283, -726, +917, +2011, -106, -1245, -999, -903, -756, }, - { +21352, +15281, -6885, +1395, -334, -3665, +2670, +3546, -5077, -445, +803, -2146, +977, -2334, -1692, -440, -333, -2064, +440, -23, -774, +810, -1201, +1101, -364, -194, +1769, +892, -1065, -1132, -267, -995, }, - { +20861, +15614, -5482, +1081, -870, -4341, +1898, +3930, -4851, -435, +471, -2413, +1653, -2264, -1871, -605, -244, -2109, +276, +437, -945, +994, -1311, +557, +83, -748, +1003, +1546, -293, -1147, -222, -1064, }, - { +20341, +15837, -4243, +1301, -1450, -5105, +1347, +3961, -4522, -413, +325, -2497, +2316, -2115, -2138, -652, -297, -1870, +211, +677, -1276, +1047, -1153, -118, +720, -740, -74, +2033, +582, -1274, -145, -714, }, - { +19636, +16119, -3188, +1683, -1865, -5991, +823, +3722, -4115, -322, +190, -2340, +2786, -2019, -2280, -876, -206, -1208, -519, +732, -1211, +541, -669, -258, +512, +140, -566, +1174, +1263, -677, -170, -802, }, - { +18858, +16285, -2143, +1991, -1980, -6784, +50, +3403, -3485, -245, +189, -2095, +3079, -1823, -2721, -438, -196, -1206, -875, +432, -1124, +431, -376, -252, +414, +1193, -856, -296, +1960, -172, -317, -664, }, - { +18488, +15830, -1291, +2547, -2229, -7386, -730, +2796, -2460, -104, -268, -1138, +2825, -2015, -2015, -709, -496, -920, -1536, +112, -516, +216, -578, +707, +252, +875, +136, -1180, +1044, +302, +130, -464, }, - { +18032, +15462, -771, +3171, -2446, -7862, -1764, +2636, -1567, +5, -496, -701, +2816, -1760, -1991, -874, -746, -1167, -1739, +343, -701, +364, +15, +532, +203, +973, +810, -1570, -221, +371, +695, -210, }, - { +18183, +14237, -213, +3919, -3116, -7974, -2292, +2020, -153, +42, -1423, +627, +2562, -2113, -1333, -1554, -1186, -770, -1762, -91, -66, +691, -288, +385, +793, +1048, +304, -885, -866, -584, +1104, +190, }, - { +17916, +13240, +200, +4684, -3796, -7718, -2760, +1604, +850, +225, -1927, +1081, +2619, -2191, -1377, -2216, -746, -653, -2263, +733, +68, +56, +169, +482, +600, +1299, +31, -544, -723, -1663, +902, +562, }, - { +17044, +12267, +1399, +4803, -4676, -5966, -3841, +281, +3320, -114, -3303, +2279, +2401, -2496, -1283, -2365, -671, -464, -1900, +808, -230, -25, +729, +96, +303, +1800, +66, -835, -309, -1837, -28, +731, }, - { +17131, +11616, +1113, +3708, -4510, -4182, -4413, -204, +4141, -354, -3431, +2353, +1909, -2319, -1067, -2887, -24, -22, -2046, +700, -301, +199, +609, -123, +449, +1846, +102, -822, -495, -1668, -259, +595, }, - { +17804, +10827, -833, +4161, -4620, -3463, -2984, -1411, +4085, +122, -3689, +2063, +1883, -2404, -1128, -2081, +2, -158, -1877, +784, -113, -307, +389, +403, +575, +1373, +163, -658, -728, -1403, -144, +238, }, - { +17770, +9675, -2120, +5437, -4251, -3736, -2292, -788, +3134, -434, -2948, +1807, +1772, -2590, -638, -1520, -124, -311, -1778, +1073, -328, -581, +430, +559, +654, +1248, -5, -604, -701, -1222, +85, +89, }, - { +16983, +8744, -2777, +6694, -3792, -4443, -901, -815, +1755, -54, -2575, +1415, +1766, -2182, -536, -1198, -147, -428, -1414, +749, -461, -344, +355, +328, +855, +1312, -290, -626, -512, -1025, +51, +365, }, - { +15530, +7980, -1979, +6512, -3528, -3269, -860, -1658, +1879, -8, -2551, +1210, +1950, -1724, -587, -1052, -96, -226, -1441, +427, -306, -235, +212, +345, +877, +1182, -243, -745, -344, -674, -107, +390, }, - { +13644, +7839, +340, +4237, -4066, -2089, +181, -157, -98, -716, -1664, +1617, +1169, -1811, +342, -1102, -326, +22, -1305, +431, -226, -614, +436, +265, -325, +880, +370, -95, +206, -791, -194, -105, }, - { +11477, +7542, +1372, +3307, -3045, -1070, -418, -498, +213, -531, -1761, +1305, +1366, -1451, +150, -939, -219, -56, -1110, +275, -259, -524, +318, +167, -195, +840, +316, +6, -31, -753, +66, +40, }, - { +9185, +7569, +2375, +2356, -1914, -448, -695, -709, +367, -353, -1571, +1152, +1173, -975, +111, -735, -206, -120, -786, +213, -329, -455, +368, +102, -13, +690, +287, +199, -74, -549, +265, +253, }, - { +7687, +7172, +2505, +2384, -1188, -623, -434, -481, +255, -398, -1198, +1009, +1022, -762, +89, -484, -279, -47, -579, +42, -268, -226, +195, +11, +172, +581, +417, +303, -47, -184, +406, +81, }, - { +6794, +6483, +2410, +2627, -840, -796, -81, -127, -26, -355, -786, +799, +900, -672, +188, -249, -386, -6, -336, -8, -247, -119, +38, +96, +339, +606, +665, +312, -3, +47, +278, -125, }, - { +5907, +5826, +2525, +2670, -555, -752, +41, +149, -99, -234, -613, +533, +888, -428, +180, -214, -321, +180, -187, -225, -103, +27, -39, +368, +489, +694, +754, +175, -13, +28, +125, -216, }, - { +5068, +5227, +2668, +2678, -280, -715, +86, +472, -115, -212, -504, +385, +890, -299, +204, -116, -199, +274, -206, -202, +165, +190, +121, +464, +488, +765, +530, -95, +33, +85, +32, -285, }, - { +4430, +4893, +2607, +2422, +45, -558, +143, +594, -112, -70, -407, +181, +893, +9, +138, -80, -17, +293, -18, +126, +441, +150, +103, +549, +369, +433, +333, -10, +90, +43, -106, -245, }, - { +3711, +4345, +2802, +2585, +142, -598, +212, +846, -12, -130, -349, +202, +915, +136, +144, +26, +282, +585, +264, +261, +271, +98, +65, +247, +259, +366, +292, +2, +95, +26, -184, -171, }, - { +3270, +4161, +2763, +2345, +192, -419, +378, +857, +49, -39, -256, +254, +934, +196, +366, +592, +573, +461, +232, +248, -23, -159, +76, +241, +206, +248, +207, +95, +139, -106, -191, -197, }, - { +2943, +3918, +2802, +2227, +112, -304, +629, +924, +29, +150, -154, +182, +1323, +752, +534, +526, +437, +413, +22, -194, -72, +85, -38, +83, +224, +251, +213, +42, +65, -167, -226, -198, }, - { +2772, +3851, +2788, +1975, +65, -69, +845, +1077, -57, +182, +530, +759, +1311, +513, +472, +465, +64, +67, -3, -148, -49, +2, -85, +278, +204, -7, +177, +109, -60, -207, -187, -266, }, - { +2741, +3962, +2753, +1658, -41, +420, +934, +1003, +697, +759, +554, +442, +1100, +376, +43, +199, +55, +12, -47, -241, +16, +219, -40, +38, -37, +66, +191, +16, -90, -266, -234, -204, }, - { +3100, +4428, +2177, +1205, +75, +902, +1974, +1358, +427, +424, +567, +206, +484, +165, +130, +95, -110, -9, -43, +93, +142, -69, -204, -13, -9, +23, +198, -26, -264, -205, -104, -146, }, - { +3210, +4553, +1862, +1097, +1209, +1702, +1662, +1004, +308, +184, +225, +17, +388, +79, +50, +47, -163, +200, +252, -95, -147, -45, -164, -179, -57, +145, +35, -75, -120, -139, -145, -187, }, - { +2744, +4295, +2964, +2006, +764, +1468, +1817, +756, +4, +41, +245, +14, +163, +49, +70, +100, +168, +231, -53, -108, -40, -137, -327, -125, -50, -25, +121, +79, -87, -207, -216, -224, }, - { +3644, +5506, +2291, +880, +1111, +1504, +1276, +605, -113, -2, +218, +64, +212, -104, +192, +519, +136, -208, +41, +48, -219, -274, -268, -122, -133, +102, +215, +67, -186, -291, -229, -287, }, - { +3729, +5991, +1991, +263, +1099, +1310, +1186, +802, +62, -222, +346, +155, +106, +141, +330, +491, +26, -42, +16, -23, -226, -214, -280, -265, -52, +117, +214, +32, -128, -310, -288, -270, }, - { +2626, +5352, +3385, +581, +252, +872, +1262, +1271, +175, -237, +438, +384, +61, +61, +469, +546, +232, -19, -21, +71, -83, -296, -233, -189, -195, +42, +177, +99, -95, -207, -255, -295, }, - { +2086, +4619, +3769, +1305, +139, +491, +966, +1193, +432, -210, +327, +607, +212, +43, +405, +422, +412, +221, +64, +98, -131, -143, -94, -220, -249, -9, +178, +14, -136, -131, -163, -256, }, - { +2139, +4433, +3497, +1555, +347, +189, +878, +1324, +318, -496, +231, +753, +258, +26, +394, +493, +349, +186, +248, +240, -44, -89, -49, -142, -57, -56, +21, +118, -122, -273, -226, -136, }, - { +2311, +4528, +3281, +1515, +485, +155, +824, +1324, +265, -492, +160, +527, +142, +7, +422, +391, +265, +431, +202, +86, +149, +36, +38, -14, +14, +37, +95, +88, -115, -263, -276, -244, }, - { +2483, +4762, +3179, +1400, +563, +131, +828, +1336, +202, -523, +128, +527, +103, -226, +171, +342, +142, +412, +338, +45, +92, -94, +172, +187, +6, +205, +202, +105, -77, -196, -299, -324, }, - { +2726, +5137, +3097, +1180, +674, +184, +755, +1346, +184, -531, +98, +477, +195, -246, -36, +193, -87, +205, +506, +62, -30, -76, +59, +215, +91, +296, +329, +186, +97, -139, -324, -248, }, - { +3045, +5527, +3012, +1062, +756, +111, +709, +1423, +99, -641, +145, +477, +146, -204, -123, +100, -177, -119, +444, +91, -147, -88, -72, +196, +100, +177, +408, +293, +113, +30, -141, -297, }, - { +3436, +6020, +2910, +889, +868, +57, +655, +1504, +22, -713, +161, +469, +124, -165, -125, -15, -195, -258, +287, +219, -316, -262, -35, +129, +77, +61, +409, +298, +70, +141, -16, -144, }, - { +3894, +6586, +2783, +668, +954, -13, +635, +1573, -146, -783, +246, +445, +2, -172, -63, -91, -294, -318, +133, +279, -237, -506, -107, +75, +8, +47, +226, +248, +95, +53, -4, -57, }, - { +4405, +7200, +2656, +443, +1039, -128, +662, +1690, -398, -841, +393, +450, -138, -226, +1, -146, -386, -359, +40, +223, -89, -563, -227, +109, -110, -3, +147, +88, +56, +29, -5, -116, }, - { +4876, +7873, +2612, +205, +1070, -269, +712, +1849, -697, -944, +597, +475, -291, -315, +82, -190, -515, -429, -4, +168, -34, -473, -351, +121, -57, -127, +140, -117, -82, +81, -67, -139, }, - { +5345, +8532, +2640, -20, +1042, -466, +776, +2045, -1057, -1078, +828, +511, -446, -439, +123, -190, -656, -517, -117, +119, +9, -405, -323, -39, +71, -105, -9, -130, -314, -1, -54, -197, }, - { +5755, +9172, +2804, -162, +957, -687, +828, +2288, -1359, -1285, +1083, +619, -595, -549, +140, -166, -730, -627, -255, +75, +66, -414, -171, -94, -6, +93, -105, -228, -284, -205, -114, -134, }, - { +6053, +9828, +3094, -338, +874, -821, +750, +2423, -1504, -1522, +1217, +797, -715, -693, +145, -172, -790, -680, -456, -66, +242, -494, -151, +117, -189, +150, +39, -395, -358, -190, -293, -70, }, - { +6365, +10439, +3396, -513, +841, -814, +596, +2360, -1502, -1631, +1210, +940, -723, -805, +124, -197, -871, -667, -563, -359, +324, -281, -332, +308, -121, -25, +252, -378, -573, -197, -328, -115, }, - { +6691, +10976, +3599, -570, +917, -864, +376, +2212, -1463, -1679, +1089, +1036, -703, -886, +72, -213, -1017, -664, -582, -629, +140, +41, -340, +170, +189, -205, +228, -137, -721, -390, -282, -214, }, - { +7655, +11301, +2983, -165, +1190, -1185, +265, +2137, -1680, -1486, +973, +1045, -655, -1003, +145, -320, -1056, -774, -554, -718, -142, +148, -1, -9, +263, -7, +1, +12, -602, -637, -348, -173, }, - { +8725, +11372, +2035, +795, +1645, -1977, +191, +2335, -2001, -1434, +933, +1003, -589, -1155, +213, -455, -1024, -893, -641, -701, -356, -16, +344, +128, +51, +231, -87, -31, -405, -710, -562, -171, }, - { +9575, +11154, +1237, +2394, +2028, -3285, +418, +2886, -2551, -1615, +1186, +934, -650, -1197, +283, -624, -1011, -875, -759, -706, -442, -240, +477, +441, -54, +319, -30, -127, -305, -565, -677, -372, }, - { +10190, +10640, +774, +4347, +2002, -4744, +1042, +3458, -3410, -1873, +1669, +748, -934, -1066, +314, -877, -1066, -778, -875, -839, -432, -417, +363, +615, +59, +388, -7, -218, -333, -323, -683, -569, }, - { +11656, +10948, -887, +4545, +3052, -4722, +604, +3331, -3530, -1765, +1917, +460, -1170, -858, +331, -1145, -1038, -801, -770, -934, -391, -415, +118, +836, +219, +336, +68, -117, -415, -229, -603, -466, }, - { +13296, +11164, -2472, +4349, +3911, -4234, +37, +3058, -3561, -1609, +2035, +238, -1451, -733, +380, -1485, -961, -904, -594, -975, -451, -230, -189, +825, +484, +313, +29, -4, -374, -223, -531, -267, }, - { +14547, +11879, -3970, +3666, +4639, -3257, -708, +2677, -3398, -1566, +2096, +56, -1592, -844, +432, -1787, -948, -1000, -471, -858, -654, +26, -371, +599, +668, +477, -138, +127, -242, -320, -341, -194, }, - { +16244, +12044, -5188, +3051, +4787, -2203, -1047, +2078, -3288, -1206, +1927, -153, -1529, -1122, +410, -1934, -1051, -951, -400, -689, -749, +91, -214, +211, +759, +692, -292, +255, -104, -432, -82, -239, }, - { +17280, +12976, -6370, +2340, +4641, -1173, -1098, +1398, -2972, -1077, +1787, -398, -1249, -1610, +388, -1966, -1197, -775, -431, -518, -766, +52, -3, +3, +536, +1033, -423, +244, +74, -499, +32, -201, }, - { +18875, +13104, -7286, +2064, +3976, -486, -755, +780, -2840, -753, +1487, -511, -1136, -1879, +201, -1926, -1197, -654, -442, -429, -635, -89, +257, -23, +237, +1321, -511, +32, +268, -506, +24, +2, }, - { +20130, +13417, -7954, +1823, +3146, -160, -302, +339, -2656, -706, +1344, -730, -995, -2122, -28, -1814, -1115, -678, -496, -246, -631, -73, +307, +224, -38, +1338, -479, -375, +351, -455, +133, +122, }, - { +20900, +14050, -8284, +1502, +2221, -215, +187, +146, -2582, -775, +1230, -1057, -723, -2335, -281, -1549, -1106, -814, -527, -46, -662, -26, +311, +623, -314, +1032, -275, -849, +139, -141, +262, +150, }, - { +21506, +14520, -8163, +1322, +1076, -434, +702, +70, -2585, -746, +944, -1321, -256, -2471, -490, -1259, -1129, -1001, -507, +204, -799, +188, +407, +732, -431, +631, -175, -1085, -90, -20, +511, +450, }, - { +22045, +14638, -7551, +1339, -401, -605, +1069, +20, -2608, -672, +522, -1429, +425, -2597, -667, -990, -1249, -1112, -381, +216, -660, +423, +180, +808, -430, +149, -101, -901, -420, -144, +988, +646, }, - { +22374, +14605, -6584, +1379, -2012, -818, +1269, -52, -2715, -579, +90, -1306, +1138, -2771, -762, -975, -1284, -1081, -478, +502, -689, +317, +67, +770, -529, -3, +37, -932, -233, -321, +645, +1063, }, - { +21971, +14982, -5381, +1465, -3401, -1307, +1361, -157, -2826, -434, -42, -1263, +1888, -2842, -1101, -790, -1377, -899, -394, +320, -814, +398, -273, +728, -246, -176, +85, -530, -151, -691, +222, +1349, }, - { +21578, +15032, -3953, +1480, -4478, -2119, +1347, -259, -2912, +19, -196, -1128, +2559, -2963, -1432, -703, -946, -870, -888, +371, -914, +216, -287, +839, -198, -30, +401, -611, -215, -354, -239, +533, }, - { +20935, +14892, -2350, +1522, -5169, -3135, +939, +47, -2856, +331, -223, -886, +3031, -3198, -1627, +82, -1303, -1105, -934, +12, -879, +350, -351, +790, +317, +101, -59, -207, +109, -776, -140, -183, }, - { +19989, +14916, -1024, +1608, -5475, -4473, +295, +1065, -2834, +220, +84, -593, +2619, -2455, -1492, -396, -1160, -1373, -1255, +21, -642, +54, -86, +1220, -111, +160, +248, -322, +230, -981, +131, -465, }, - { +19442, +14440, -244, +2209, -5944, -5867, +441, +1708, -2969, +837, -323, -569, +3451, -2723, -1540, -344, -1757, -1134, -1142, -251, -519, +531, -17, +686, +62, +600, -73, -568, +824, -1013, -326, +77, }, - { +19215, +13282, +497, +2823, -6861, -6114, +314, +2076, -2340, +432, -449, +228, +3074, -2653, -1482, -1155, -1421, -644, -1745, -8, +375, -76, -205, +1100, -38, +316, +113, -497, +839, -778, -681, +216, }, - { +18399, +12398, +1273, +2931, -6997, -6116, +179, +2120, -1724, +857, -1704, +1041, +3221, -3315, -1375, -1169, -1113, -795, -1352, +352, -102, -102, +206, +701, -238, +511, +174, -405, +646, -548, -516, -399, }, - { +17103, +12076, +1628, +2442, -6317, -5062, -1021, +2253, +17, -617, -1910, +2032, +2182, -3218, -758, -1593, -918, +124, -1676, +57, +262, -74, -107, +549, -37, +456, +200, -287, +594, -479, -420, -621, }, - { +17339, +11281, -244, +2822, -5940, -4177, +36, +1140, -56, -183, -2196, +2015, +1763, -3155, -461, -1392, -347, -94, -1944, +612, +306, -660, +4, +659, -17, +432, +20, -3, +720, -783, -494, -283, }, - { +16567, +9681, +78, +3330, -6088, -2392, -403, +490, +834, -1104, -2339, +2535, +1400, -3259, +240, -1123, -378, -183, -1760, +840, -40, -771, +203, +636, -208, +524, +221, -45, +609, -787, -453, -228, }, - { +15277, +8488, +278, +3885, -5037, -2468, -191, +698, +82, -1238, -1833, +2336, +911, -2516, +590, -1228, -341, -135, -1481, +650, -204, -726, +413, +395, -341, +823, +281, -147, +494, -733, -476, -140, }, - { +14508, +10388, +2390, +614, -9568, -3171, +2824, +3138, -360, -1806, -3125, +365, +1587, -1832, +1166, -336, -464, +624, -617, +527, +1, -567, -177, -592, -325, +573, -499, -34, +977, -258, +261, -46, }, - { +12204, +10145, +3137, +1381, -8141, -4350, +1999, +2595, +500, -763, -2949, -365, +1128, -983, +987, -357, -350, +719, -509, +347, +303, -394, -148, -488, -492, +295, -634, +121, +1110, -75, +436, -20, }, - { +10618, +9407, +3284, +1743, -6720, -3899, +1478, +1813, +596, -356, -2413, -640, +1096, -622, +604, -220, -317, +679, -315, +187, +316, -151, -180, -467, -394, +122, -486, +261, +994, +154, +417, -67, }, - { +8737, +8566, +3830, +1870, -5294, -3295, +668, +1407, +736, -98, -1874, -761, +1017, -457, +347, -65, -252, +598, -129, +108, +374, +35, -238, -389, -303, +101, -170, +351, +816, +261, +307, -90, }, - { +7322, +7990, +4204, +1759, -4233, -2859, +204, +1225, +706, +89, -1428, -779, +812, -371, +310, +13, -255, +576, +48, +68, +394, +93, -230, -185, -105, +97, -62, +325, +596, +234, +208, -140, }, - { +5934, +7313, +4453, +1864, -3250, -2602, -73, +1073, +737, +266, -1100, -695, +649, -339, +267, +163, -183, +531, +195, +93, +388, +271, +42, +55, -87, -115, -13, +235, +333, +198, +167, -56, }, - { +5000, +6676, +4573, +2086, -2672, -2459, -188, +999, +803, +304, -865, -518, +450, -355, +364, +251, -120, +548, +192, +279, +680, +344, +32, +73, -196, -341, +1, +192, +208, +250, +135, -143, }, - { +4456, +6275, +4433, +1984, -2322, -2108, -127, +872, +815, +394, -642, -454, +355, -269, +459, +303, -78, +714, +511, +458, +618, +237, -33, -56, -404, -289, +129, +56, +240, +141, -2, +127, }, - { +3914, +5714, +4351, +2080, -2013, -1928, -97, +902, +872, +413, -420, -323, +306, -177, +447, +601, +422, +769, +448, +347, +442, +17, -200, -32, -412, -202, +177, -120, +89, +302, +138, +79, }, - { +3687, +5529, +4104, +1830, -1878, -1601, +73, +886, +904, +439, -190, -238, +213, +104, +832, +826, +315, +493, +327, +220, +233, -30, -126, -120, -318, -150, -96, +60, +301, +96, +30, +144, }, - { +3580, +5372, +3781, +1521, -1776, -1190, +327, +859, +987, +532, -67, +9, +629, +331, +636, +568, +95, +278, +193, +191, +184, -23, -203, -172, -324, -16, +176, -130, +89, +51, +115, +194, }, - { +3492, +5329, +3471, +1350, -1561, -940, +597, +949, +959, +721, +441, +128, +352, +175, +389, +425, +9, +204, +280, +156, +63, -22, -262, -158, +108, -5, -216, -107, +108, +31, +78, +239, }, - { +3432, +5245, +3183, +1194, -1128, -596, +840, +1170, +1253, +888, +199, -114, +53, +17, +302, +263, +132, +181, +140, +117, +66, -50, -59, +236, -176, -301, -113, -66, -72, -13, +269, +19, }, - { +3390, +5248, +2963, +1119, -596, -247, +1125, +1471, +935, +484, +120, -201, +1, -69, +296, +276, +64, +116, +141, +246, -26, +224, +239, -232, -240, -143, -165, -208, -22, +53, +4, +96, }, - { +3459, +5308, +2829, +1096, -226, +235, +1196, +1070, +638, +314, +33, -149, +26, -184, +259, +284, -110, +166, +359, +85, +180, +500, -207, -255, -125, -253, -294, -112, -3, -243, +82, +267, }, - { +3444, +5608, +3052, +1048, -153, +152, +952, +951, +500, +280, +174, -297, -12, -51, +82, +247, +11, +278, +212, +303, +571, -23, -220, +24, -291, -435, -178, -82, -257, -114, +197, +358, }, - { +3631, +5987, +3171, +840, -377, -261, +737, +1132, +564, +264, +192, -346, -126, +1, +155, +186, +152, +235, +119, +688, +415, -209, -47, -46, -307, -433, -160, -284, -252, +134, +257, +168, }, - { +3555, +6368, +3416, +601, -552, -585, +576, +1098, +540, +380, +255, -412, -120, +84, +90, +257, +276, +51, +139, +958, +303, -229, +70, -105, -327, -291, -183, -450, -241, +244, +389, -20, }, - { +3304, +6445, +3877, +542, -780, -691, +604, +1149, +403, +125, +220, -232, -86, +58, +247, +261, +126, +140, +91, +859, +535, -186, +15, -49, -295, -232, -192, -427, -225, +175, +356, +33, }, - { +3095, +6398, +4320, +718, -1060, -852, +617, +1319, +551, -131, -94, -318, -227, +167, +484, +239, +130, +167, -116, +734, +786, -134, -76, +64, -201, -204, -176, -362, -225, +158, +343, -8, }, - { +3043, +6443, +4566, +841, -1213, -1017, +635, +1471, +644, -187, -192, -362, -461, -72, +479, +445, +148, +181, -13, +421, +845, +87, -217, -18, -79, -55, -112, -366, -227, +211, +309, +49, }, - { +3132, +6650, +4683, +897, -1394, -1203, +748, +1560, +723, -251, -284, -272, -531, -243, +278, +347, +138, +203, +193, +288, +760, +331, -284, -258, -57, +43, +11, -256, -228, +216, +280, +136, }, - { +3367, +6988, +4849, +842, -1674, -1375, +807, +1795, +719, -420, -285, -270, -512, -280, +138, +254, -47, -57, +304, +307, +642, +594, -125, -511, -291, +9, +125, -134, -237, +289, +287, +139, }, - { +3586, +7407, +5080, +656, -1907, -1495, +823, +2057, +683, -633, -291, -228, -494, -258, +64, +194, -36, -286, +173, +318, +479, +623, +210, -460, -540, -128, +140, -101, -240, +315, +252, +163, }, - { +3913, +8036, +5294, +392, -2186, -1751, +902, +2457, +567, -915, -352, -187, -458, -275, +94, +106, -67, -364, +29, +257, +307, +466, +372, -273, -572, -259, +20, -46, -279, +200, +193, +90, }, - { +4032, +8688, +5666, +129, -2445, -1998, +927, +2764, +585, -1205, -445, -136, -465, -297, +145, +30, -86, -398, -75, +234, +196, +315, +365, -111, -602, -339, +4, +2, -305, +120, +111, -149, }, - { +4592, +9563, +5846, -404, -2900, -2105, +1130, +3189, +362, -1558, -421, -109, -448, -336, +218, +21, -218, -346, -123, +178, +175, +130, +357, -19, -545, -388, -95, -2, -115, +87, -12, -264, }, - { +5108, +10372, +5960, -878, -3340, -2212, +1378, +3487, +158, -1928, -397, -33, -497, -372, +269, +15, -353, -346, -123, +153, +121, -36, +345, +17, -453, -394, -151, -80, -129, +237, -86, -306, }, - { +5903, +11205, +5822, -1373, -3825, -2282, +1849, +3676, -196, -2204, -349, +96, -588, -398, +334, +40, -480, -394, -80, +155, +103, -202, +283, +76, -376, -305, -191, -130, -153, +273, -64, -333, }, - { +6463, +12077, +6105, -1736, -4427, -2497, +2172, +3937, -457, -2637, -316, +269, -650, -515, +328, +128, -574, -464, -145, +165, +112, -359, +102, +133, -284, -189, -158, -224, -158, +175, +22, -412, }, - { +6842, +12772, +6370, -1805, -4912, -2802, +2482, +4054, -577, -3009, -381, +505, -711, -614, +320, +143, -632, -456, -212, +124, +133, -429, -89, +129, -159, -163, +4, -302, -109, +98, -9, -351, }, - { +7495, +13436, +6402, -1641, -5389, -3222, +2902, +4096, -819, -3320, -508, +760, -709, -801, +367, +144, -733, -443, -242, +90, +109, -405, -353, -3, +96, -160, +135, -243, -147, +159, -109, -342, }, - { +8302, +13982, +6007, -1545, -5551, -3449, +3272, +3931, -1108, -3384, -659, +902, -637, -984, +381, +171, -829, -414, -266, +67, +40, -321, -455, -318, +312, -35, +128, -72, -215, +189, -55, -445, }, - { +9896, +14670, +4570, -1730, -5262, -3249, +3511, +3414, -1572, -3150, -826, +851, -414, -1191, +310, +159, -852, -430, -228, +45, -97, -288, -414, -643, +337, +260, +1, +181, -141, +21, +120, -543, }, - { +11175, +14744, +3448, -993, -4976, -3811, +3696, +3441, -2038, -3160, -852, +834, -325, -1343, +248, +102, -877, -401, -118, -49, -199, -292, -342, -788, +115, +605, -66, +267, +58, -136, +206, -540, }, - { +12433, +14644, +2289, -11, -4664, -4428, +3847, +3503, -2546, -3196, -721, +719, -321, -1413, +201, -27, -944, -298, +67, -214, -293, -242, -375, -807, -141, +822, +24, +219, +276, -175, +133, -469, }, - { +14253, +15077, +91, +194, -3679, -4227, +3554, +3173, -2873, -3182, -505, +510, -236, -1531, +106, -141, -941, -242, +293, -223, -457, -200, -494, -638, -319, +772, +318, +229, +335, -59, -21, -432, }, - { +16147, +15220, -1962, +114, -2901, -3609, +3134, +2739, -3044, -3270, -314, +358, -218, -1704, +85, -332, -895, -157, +414, -203, -648, -134, -650, -486, -341, +596, +483, +347, +229, -1, -55, -568, }, - { +17862, +15961, -4207, -422, -1951, -2655, +2484, +2264, -2914, -3618, -117, +208, -161, -1924, +25, -473, -800, -35, +478, -79, -937, -17, -769, -367, -225, +425, +413, +582, +113, -133, +87, -734, }, - { +19449, +16392, -5859, -1112, -1427, -1629, +1942, +1918, -2765, -3978, -8, +84, -134, -2062, -13, -566, -654, +37, +477, +32, -1157, +83, -816, -331, +13, +340, +96, +768, +67, -341, +213, -694, }, - { +21050, +17015, -7348, -2198, -1140, -508, +1499, +1662, -2610, -4451, +6, -138, -34, -2121, -29, -596, -503, +48, +407, +189, -1351, +208, -923, -200, +286, +156, -272, +696, +143, -514, +278, -464, }, - { +22180, +17691, -8318, -3153, -1264, +222, +1444, +1546, -2552, -4822, -136, -360, +172, -2054, -32, -523, -483, -7, +341, +375, -1419, +217, -913, -27, +273, +51, -545, +431, +314, -476, +252, -284, }, - { +23145, +18305, -8899, -3912, -1872, +754, +1676, +1457, -2542, -5140, -436, -571, +593, -1943, -18, -391, -590, -105, +360, +600, -1486, +265, -834, -64, +157, -1, -808, +207, +535, -343, +188, -148, }, - { +24201, +18791, -9169, -4533, -3193, +1197, +2201, +1353, -2588, -5477, -898, -646, +1316, -1907, +112, -361, -830, -56, +459, +703, -1301, +324, -1128, -106, +17, -169, -828, +111, +625, -123, +274, -146, }, - { +25039, +18854, -8960, -4922, -4675, +1488, +2597, +1309, -2785, -5629, -1226, -537, +1894, -1872, +177, -569, -818, +47, +414, +930, -1141, -66, -1306, -147, -197, -117, -643, -26, +588, +205, +269, -377, }, - { +25483, +18997, -8159, -5303, -6464, +1415, +3101, +1247, -3048, -5328, -1549, -448, +2627, -1908, -26, -525, -721, +144, +628, +830, -1334, -263, -1576, -203, -94, -5, -521, -41, +604, +221, +328, -313, }, - { +25310, +19394, -7240, -5364, -8082, +861, +3602, +1021, -2853, -4841, -1925, -274, +3034, -1996, -184, -315, -585, +480, +190, +564, -1199, -604, -1602, -1, -64, +5, -267, -39, +307, +300, +702, -524, }, - { +25187, +19126, -5747, -5306, -10048, +5, +3816, +1259, -2439, -4328, -2144, -285, +3285, -2132, -193, +313, -577, +11, -100, +308, -1123, -638, -1463, +80, -40, +174, -302, -152, +368, +273, +817, -512, }, - { +24584, +19059, -4370, -5103, -11540, -1206, +4149, +1948, -2239, -3792, -2260, -463, +3232, -1933, +310, +264, -1049, -39, -461, +305, -807, -683, -1310, +216, -69, -19, -134, -7, +199, +192, +1012, -495, }, - { +24229, +18498, -3219, -4673, -13052, -2239, +4802, +2529, -2152, -3029, -2527, -945, +3759, -1608, +81, +180, -1445, -83, -369, +279, -585, -589, -996, -15, -262, +176, +17, -164, +214, +234, +1010, -493, }, - { +23479, +17761, -2169, -4054, -14542, -2764, +5166, +3024, -1593, -2674, -3100, -489, +3855, -1932, +199, -475, -1408, +376, -646, +385, -160, -507, -1201, -125, -73, +89, +2, -134, +277, +184, +889, -456, }, - { +22902, +16611, -1241, -3921, -14659, -3126, +5151, +3820, -1738, -2209, -3026, -680, +3843, -2076, -205, -376, -1050, +290, -561, +675, -171, -734, -967, -54, -279, +107, +127, -143, +289, +105, +906, -440, }, - { +21520, +15491, -466, -3170, -14169, -3623, +5060, +3934, -933, -1908, -3770, -160, +3317, -2389, +45, -293, -930, +570, -302, +294, -117, -531, -816, -259, -393, +309, +177, -338, +355, +325, +623, -455, }, - { +20196, +14258, -26, -2087, -13378, -3959, +4522, +4579, -753, -2187, -3650, -282, +3062, -2403, +220, -314, -596, +900, -834, +333, +193, -640, -766, -353, -377, +474, -67, -401, +722, +187, +352, -286, }, - { +18562, +12495, +606, -395, -12713, -4067, +4718, +3983, -631, -1865, -4106, +267, +2676, -2530, +544, -90, -270, +517, -885, +629, +178, -816, -539, -358, -375, +420, -176, -225, +814, +58, +205, -176, }, - { +16507, +11335, +1670, +425, -11680, -3415, +3753, +3482, -140, -2175, -3676, +452, +2142, -2340, +899, +31, -525, +540, -719, +620, +74, -768, -288, -458, -444, +527, -237, -258, +969, -83, +155, -100, }, - { +15749, +11088, +540, -1465, -10587, +5, +4768, +1482, -1271, -1294, -2408, -204, +2109, -2180, +700, +142, -524, +394, -343, +524, -78, -510, -510, -119, -176, +83, +45, -8, -121, -132, +846, -57, }, - { +12780, +11168, +3101, -713, -10375, -2419, +3165, +2486, +741, -926, -2637, -901, +1193, -1380, +1171, +201, -695, +683, -287, +203, +326, -265, -402, +216, -760, -316, +56, -240, +385, +349, +800, +38, }, - { +10481, +10174, +3731, +12, -8189, -2627, +2287, +2162, +639, -620, -1980, -947, +827, -877, +947, +162, -591, +622, -179, +124, +414, -151, -214, +218, -687, -257, +155, -179, +273, +413, +653, +58, }, - { +8668, +9236, +4001, +664, -6447, -2669, +1688, +1709, +604, -245, -1509, -943, +653, -570, +711, +170, -456, +560, -83, +116, +460, +30, -144, +259, -390, -222, +102, -244, +172, +370, +519, +108, }, - { +7283, +8384, +4111, +1067, -5156, -2491, +1257, +1309, +661, +29, -1138, -850, +514, -376, +522, +237, -336, +496, +41, +153, +499, +232, +59, +319, -295, -329, -17, -275, -28, +319, +573, +102, }, - { +6272, +7691, +4060, +1222, -4187, -2162, +939, +1051, +723, +183, -806, -720, +436, -270, +454, +290, -208, +496, +100, +362, +696, +335, +52, +222, -281, -423, -148, -305, -83, +332, +591, +108, }, - { +5580, +7158, +3875, +1174, -3460, -1834, +755, +904, +761, +294, -524, -552, +331, -184, +477, +333, -134, +601, +379, +449, +583, +227, -20, +147, -340, -469, -157, -333, -172, +385, +542, +14, }, - { +5099, +6769, +3611, +1012, -2865, -1522, +671, +853, +823, +385, -298, -392, +284, -75, +496, +488, +66, +592, +366, +331, +409, +167, -75, +79, -239, -485, -266, -327, -145, +317, +622, +200, }, - { +4774, +6505, +3318, +801, -2367, -1254, +708, +915, +878, +465, -124, -221, +265, +118, +634, +457, -4, +374, +332, +279, +241, +173, -17, +50, -250, -474, -271, -392, +13, +518, +389, +79, }, - { +4533, +6373, +3052, +547, -1931, -979, +831, +1054, +874, +581, -34, -52, +431, +69, +479, +349, -93, +183, +314, +308, +170, +203, +2, -44, -122, -409, -440, -16, +135, +84, +235, +185, }, - { +4382, +6335, +2815, +384, -1572, -712, +951, +1234, +846, +634, +201, -204, +344, +11, +311, +320, -174, +46, +261, +434, +123, +92, +101, +62, -245, -261, -49, -321, -116, +108, +125, +189, }, - { +4310, +6316, +2697, +377, -1265, -560, +1000, +1283, +976, +592, +177, -342, +94, +124, +234, +277, -211, -42, +322, +339, +136, +155, +187, -53, -7, +128, -468, -481, -77, +89, +78, +112, }, - { +4220, +6370, +2803, +455, -1043, -593, +884, +1257, +898, +647, +131, -407, +17, -24, +259, +268, -143, -71, +248, +315, +54, +318, +56, +134, +452, -358, -580, -280, -245, +17, +207, +32, }, - { +4238, +6578, +2947, +418, -979, -561, +705, +1063, +778, +509, +327, -311, -141, -2, +117, +252, +15, +34, +169, +147, +205, +145, +62, +724, +153, -621, -342, -314, -253, +63, +216, -198, }, - { +4312, +6878, +3119, +203, -1024, -566, +664, +1052, +477, +317, +296, -326, +41, -20, +78, +256, -64, +129, +238, +109, +104, +11, +281, +812, -119, -527, -289, -348, -126, +151, +43, -331, }, - { +4243, +7275, +3432, -18, -1154, -711, +722, +1244, +373, +111, +88, -498, -48, +145, +283, +267, -58, +72, +167, +174, +186, -87, +222, +896, -239, -530, -150, -376, +16, +248, -104, -319, }, - { +4240, +7629, +3820, -212, -1418, -875, +841, +1446, +395, +35, -59, -651, -337, +57, +348, +394, +138, +74, +125, +94, +212, -51, +148, +896, -296, -557, -109, -348, +139, +310, -89, -337, }, - { +4267, +8079, +4161, -358, -1708, -1137, +1013, +1624, +419, -13, -148, -667, -486, -153, +260, +306, +109, +213, +291, +100, +122, +47, -84, +791, +19, -750, -253, -252, +190, +325, -24, -265, }, - { +4428, +8579, +4533, -649, -2161, -1157, +1152, +1818, +471, -285, -99, -625, -629, -167, +110, +208, -67, +58, +397, +149, +182, +241, -312, +521, +338, -764, -423, -220, +99, +352, +41, -277, }, - { +4663, +9147, +5017, -957, -2713, -1191, +1270, +2062, +456, -561, -64, -490, -728, -151, +48, +95, -93, -149, +333, +236, +4, +377, -80, +107, +501, -359, -693, -415, +113, +346, +3, -240, }, - { +4794, +9798, +5715, -1328, -3293, -1331, +1372, +2391, +376, -861, -165, -318, -751, -218, +113, -43, -176, -257, +208, +326, -101, +123, +104, -60, +376, +187, -610, -661, -80, +210, +60, -231, }, - { +4706, +10404, +6857, -1587, -4043, -1501, +1416, +2768, +428, -1274, -318, -83, -773, -321, +190, -68, -276, -333, +89, +301, +70, -126, -66, -7, +48, +426, +52, -740, -438, +212, -62, -314, }, - { +5492, +11533, +6802, -2410, -4639, -1493, +1942, +3028, +51, -1662, -327, +15, -748, -355, +194, -55, -404, -364, +59, +221, +123, -131, -285, -124, -44, +334, +429, -330, -642, -6, -1, -451, }, - { +5983, +12434, +7309, -2945, -5475, -1428, +2301, +3203, -66, -2148, -439, +316, -869, -393, +284, -166, -434, -371, -45, +257, +65, -121, -270, -467, -42, +274, +467, +199, -506, -380, +16, -415, }, - { +6553, +13345, +7759, -3488, -6279, -1393, +2735, +3371, -353, -2547, -584, +610, -877, -578, +354, -136, -577, -381, +10, +115, +137, -230, -229, -570, -338, +370, +460, +362, -28, -508, -363, -242, }, - { +7471, +14327, +7633, -4021, -6946, -1337, +3324, +3391, -814, -2875, -657, +809, -860, -751, +399, -191, -586, -460, +66, +94, +17, -214, -308, -558, -507, +258, +589, +343, +231, -149, -748, -423, }, - { +8279, +15118, +7553, -4198, -7540, -1469, +3893, +3301, -1178, -3117, -875, +1005, -790, -1000, +413, -197, -660, -436, +72, +94, -104, -258, -361, -556, -505, +12, +646, +436, +181, +263, -660, -907, }, - { +9124, +15874, +7171, -4175, -7769, -1782, +4384, +3236, -1562, -3240, -1066, +1125, -708, -1207, +337, -154, -693, -392, +105, +118, -192, -387, -322, -628, -341, -94, +398, +659, +143, +329, -199, -1184, }, - { +10600, +16582, +5950, -4368, -7541, -1867, +4737, +3086, -2067, -3335, -1044, +1123, -740, -1306, +237, -176, -627, -343, +172, +164, -330, -475, -330, -675, -210, +76, +40, +658, +284, +168, +174, -1087, }, - { +12376, +17175, +4171, -4522, -7036, -1733, +4785, +2866, -2442, -3529, -868, +972, -750, -1432, +142, -233, -536, -280, +203, +260, -566, -441, -421, -666, -125, +321, -234, +424, +421, +32, +318, -810, }, - { +14090, +17881, +2149, -4729, -6335, -1510, +4556, +2689, -2622, -3826, -676, +683, -672, -1544, +43, -207, -493, -179, +161, +384, -803, -320, -525, -640, -11, +437, -358, +48, +480, -16, +337, -499, }, - { +16479, +18100, -251, -5038, -5617, -895, +4158, +2494, -2872, -4087, -506, +369, -589, -1544, +53, -264, -351, -200, +196, +385, -925, -184, -637, -545, +96, +400, -519, -169, +313, +46, +383, -236, }, - { +18719, +18354, -2535, -5382, -5077, -235, +3760, +2374, -3095, -4427, -427, +22, -354, -1411, +7, -243, -275, -312, +263, +406, -941, -99, -688, -428, +90, +202, -566, -359, +122, +172, +472, -78, }, - { +20632, +18711, -4603, -5686, -4881, +473, +3484, +2242, -3308, -4836, -393, -315, +167, -1349, -10, -178, -419, -353, +354, +511, -957, -1, -751, -448, -19, +72, -604, -458, +57, +275, +400, +168, }, - { +22360, +19050, -6299, -6014, -5124, +1226, +3414, +2007, -3540, -5278, -311, -473, +850, -1407, +137, -306, -606, -202, +424, +682, -953, +71, -1092, -494, -36, -56, -597, -263, -49, +181, +480, +340, }, - { +23853, +19254, -7494, -6434, -5724, +1855, +3501, +1649, -3877, -5514, -94, -559, +1541, -1479, +150, -510, -585, -3, +419, +893, -1016, -259, -1392, -389, -165, +23, -418, -178, -252, +244, +451, +239, }, - { +25329, +18892, -8176, -6707, -6565, +2362, +3636, +1174, -4256, -5023, -220, -362, +2101, -1684, +93, -508, -345, +44, +530, +734, -1282, -474, -1490, -397, +61, +190, -464, -83, -222, +71, +299, +421, }, - { +26132, +18615, -8557, -6606, -7720, +2662, +3828, +564, -4070, -4493, -377, -142, +2382, -2009, +159, -193, -269, +57, +124, +489, -1273, -596, -1558, -23, +257, +40, -292, +5, -420, -52, +361, +377, }, - { +26097, +18760, -8279, -6563, -9338, +2395, +4427, +354, -3683, -4052, -417, -411, +2686, -2127, +394, +208, -612, -267, -183, +547, -1260, -477, -1400, +110, +235, +53, -183, -98, -337, -206, +404, +296, }, - { +26298, +17883, -7539, -6429, -11135, +2349, +5208, +297, -3531, -3208, -932, -479, +3059, -2027, +586, +52, -1210, -243, -201, +410, -847, -361, -1398, +182, +205, +3, -91, -95, -338, -279, +476, +239, }, - { +25890, +16998, -6703, -6158, -12691, +2616, +5823, +131, -2985, -2746, -1498, -267, +3567, -2288, +598, -395, -1379, +90, -420, +614, -490, -504, -1389, +217, +123, -23, -40, -116, -280, -344, +578, +55, }, - { +24947, +16037, -5788, -5689, -13461, +2608, +6096, +412, -2813, -2278, -1596, -192, +3523, -2540, +252, -341, -1212, +134, -205, +703, -394, -619, -1225, +253, -81, +26, +22, -90, -211, -394, +628, +37, }, - { +23244, +14939, -4628, -4799, -13452, +2196, +6207, +481, -2338, -1733, -1999, -166, +3296, -2924, +380, -214, -1290, +655, -260, +536, -282, -573, -1003, -3, -66, +82, +42, -31, -237, -351, +712, -93, }, - { +21175, +13481, -2942, -3774, -12857, +1570, +5657, +1162, -1877, -1714, -2063, -297, +2743, -2620, +466, -249, -749, +711, -463, +451, -19, -579, -1025, +20, -106, +79, +79, -61, -143, -304, +645, -60, }, - { +18636, +12183, -1209, -2590, -11846, +582, +5371, +1609, -1826, -1340, -2309, -463, +2623, -2468, +485, +42, -543, +537, -540, +593, +20, -722, -705, -39, -175, +121, +49, +1, -116, -325, +749, +25, }, - { +14783, +9489, -2982, -1023, -3993, +3280, +1929, -1888, -1700, +251, +285, -164, +1356, -1971, +151, -32, -982, +252, -342, +144, -27, -417, -521, +840, -3, +115, +200, -545, +44, -370, -154, +120, }, - { +12635, +9338, -1709, -1092, -3762, +2615, +2298, -1249, -1537, +64, +39, -164, +1209, -1626, +74, +120, -732, +178, -175, +161, -27, -373, -563, +683, +104, +109, +334, -384, -11, -279, -152, +39, }, - { +10824, +8969, -613, -1061, -3373, +2063, +2390, -782, -1282, -126, -128, -73, +1005, -1268, +42, +226, -527, +136, -29, +165, -13, -304, -520, +542, +230, +129, +323, -272, -56, -204, -196, -8, }, - { +9429, +8572, +94, -1038, -2958, +1688, +2332, -399, -1026, -257, -166, -8, +812, -970, +100, +281, -355, +129, +93, +200, -9, -181, -418, +422, +262, +108, +261, -198, -85, -190, -163, -35, }, - { +8397, +8228, +487, -1075, -2536, +1429, +2193, -104, -809, -286, -144, +0, +671, -693, +170, +287, -214, +140, +163, +259, +27, -77, -357, +258, +245, +93, +144, -149, -82, -138, -162, -157, }, - { +7612, +7949, +682, -1088, -2127, +1227, +2044, +150, -627, -240, -104, +9, +638, -490, +230, +309, -107, +161, +239, +304, +6, -19, -321, +91, +206, +63, +62, -59, -63, -155, -170, -131, }, - { +6952, +7827, +766, -1099, -1787, +1048, +1937, +367, -509, -160, +31, -46, +675, -344, +225, +366, -39, +163, +218, +347, -43, -35, -270, -73, +151, +125, +10, -31, -65, -114, -144, -245, }, - { +6683, +7602, +752, -1154, -1469, +1022, +1800, +518, -463, -59, +237, -126, +665, -182, +167, +400, +1, +65, +208, +350, -66, -128, -244, -86, +66, +169, -26, -43, +21, -177, -95, +91, }, - { +6328, +7603, +798, -1168, -1193, +1003, +1709, +558, -362, -97, +468, -68, +448, +37, +143, +230, +82, +36, +95, +341, -19, -201, -272, +32, -38, +101, +81, -48, -56, +78, +109, -161, }, - { +6163, +7555, +882, -1153, -951, +1060, +1636, +512, -380, -40, +469, +81, +403, -73, +284, +126, -61, +146, +60, +209, +16, -67, -335, -42, +24, +86, +40, -88, +270, +181, -136, -94, }, - { +6061, +7646, +945, -1152, -751, +1127, +1592, +462, -481, -102, +513, +8, +479, -8, +120, +232, -121, -17, +188, +182, -85, +28, -226, -217, -8, +203, -144, +134, +478, -84, -37, -109, }, - { +6159, +7784, +897, -1252, -582, +1290, +1597, +367, -567, -244, +423, +7, +359, +71, +248, +105, -133, +44, +12, +207, +16, -67, -239, -155, +10, -42, -17, +448, +145, -81, +130, -268, }, - { +6295, +8059, +874, -1507, -476, +1456, +1680, +362, -767, -349, +394, -179, +254, +82, +233, +237, -141, -70, +113, +103, -91, +65, -321, -165, +80, -154, +82, +449, -28, -5, +49, -241, }, - { +6464, +8458, +884, -1785, -437, +1608, +1780, +391, -878, -494, +409, -232, +50, -6, +273, +208, -116, +68, +65, +99, -84, -65, -354, -36, +94, -209, +217, +427, -208, -3, +52, -229, }, - { +6683, +8970, +878, -2165, -376, +1753, +1869, +420, -1047, -513, +453, -325, -68, -78, +177, +166, -163, +34, +201, +156, -170, -62, -410, -135, +213, -121, +156, +486, -231, -110, -45, -202, }, - { +7075, +9466, +776, -2530, -318, +1953, +1897, +349, -1235, -528, +610, -389, -209, -190, +180, +87, -332, -2, +206, +167, -129, -48, -464, -135, +204, -153, +111, +606, -167, -304, -61, -230, }, - { +7586, +10041, +588, -2915, -206, +2202, +1934, +234, -1428, -528, +819, -402, -344, -230, +142, +32, -392, -123, +176, +151, -193, +34, -366, -138, +241, -59, -155, +594, +203, -426, -180, -174, }, - { +8284, +10637, +233, -3349, -82, +2488, +1888, +4, -1707, -479, +1011, -436, -518, -321, +180, -80, -546, -130, +97, -3, -257, -57, -259, -35, +170, +42, -299, +295, +418, -294, -381, -148, }, - { +9095, +11203, -132, -3724, +50, +2818, +1819, -242, -2019, -371, +1236, -443, -675, -423, +213, -107, -683, -188, +152, -197, -308, -122, -264, +206, +142, +61, -245, -25, +422, +25, -540, -195, }, - { +9889, +11877, -498, -4104, +128, +3146, +1756, -530, -2290, -350, +1519, -489, -802, -515, +198, -156, -758, -285, +204, -324, -438, -107, -349, +396, +198, +14, -193, -173, +148, +358, -427, -465, }, - { +10582, +12562, -764, -4376, +91, +3406, +1737, -827, -2467, -415, +1769, -548, -939, -576, +195, -234, -826, -350, +190, -335, -585, -69, -435, +512, +288, -37, -200, -225, -129, +406, -34, -688, }, - { +11306, +13237, -1039, -4536, -26, +3591, +1718, -1098, -2614, -469, +1956, -571, -1083, -632, +173, -288, -912, -416, +136, -318, -675, -9, -461, +518, +395, -47, -243, -278, -292, +231, +360, -602, }, - { +12126, +13732, -1324, -4530, -169, +3644, +1688, -1289, -2721, -525, +2075, -627, -1199, -662, +140, -328, -973, -491, +59, -292, -671, -19, -361, +462, +431, -38, -247, -401, -359, +38, +478, -239, }, - { +13174, +14048, -1834, -4351, -231, +3530, +1631, -1424, -2802, -592, +2109, -667, -1235, -700, +112, -376, -980, -597, +19, -296, -588, -73, -240, +447, +337, +12, -264, -517, -447, +2, +295, +152, }, - { +13912, +14689, -2549, -4087, -276, +3213, +1690, -1511, -2845, -778, +2173, -760, -1162, -780, +32, -364, -1053, -628, -102, -130, -603, -57, -165, +414, +214, +87, -300, -593, -470, -60, +82, +348, }, - { +15735, +14399, -3901, -3481, -192, +2964, +1469, -1601, -3017, -661, +2045, -910, -920, -980, +113, -561, -1039, -685, -48, -104, -573, +16, -218, +402, +105, +138, -407, -536, -465, -206, -44, +459, }, - { +17507, +14116, -5426, -2751, -192, +2764, +1237, -1736, -3152, -642, +2056, -1032, -638, -1128, +153, -726, -1046, -569, -51, -121, -478, +1, -396, +547, -27, +111, -333, -501, -516, -340, +19, +317, }, - { +19177, +13698, -6887, -1985, -243, +2671, +917, -1892, -3302, -557, +2196, -1213, -249, -1266, +144, -850, -933, -377, -271, +44, -521, -211, -328, +623, -195, +277, -239, -659, -459, -299, -118, +155, }, - { +20876, +12896, -8162, -1221, -405, +2653, +504, -2083, -3425, -193, +2142, -1312, +212, -1534, +162, -820, -758, -426, -316, +25, -728, -166, -380, +694, -108, +401, -373, -670, -277, -461, -291, +192, }, - { +22269, +11988, -9087, -514, -824, +2741, +141, -2324, -3367, +226, +1930, -1209, +579, -1900, +451, -737, -828, -320, -621, -37, -648, -370, -319, +1024, -166, +363, -328, -614, -348, -565, -333, +183, }, - { +22436, +12036, -9756, +12, -1484, +2839, +192, -2651, -3134, +304, +2024, -1272, +960, -2016, +603, -606, -966, -471, -868, +179, -932, -258, -187, +1149, -274, +472, -264, -806, -269, -673, -333, +115, }, - { +22976, +10737, -9315, +116, -2333, +3251, +276, -2916, -2945, +644, +1634, -1050, +1433, -2250, +799, -568, -1370, -360, -902, +24, -701, -266, -133, +1143, -162, +431, -320, -856, -257, -656, -421, +206, }, - { +22156, +10670, -8825, +31, -3255, +3766, +558, -3195, -2534, +719, +1180, -629, +1637, -2399, +832, -768, -1413, -237, -975, +241, -538, -329, -188, +1315, -228, +362, -275, -900, -124, -757, -357, +287, }, - { +21278, +9846, -7554, -398, -3803, +4159, +764, -3114, -2412, +808, +1003, -456, +1754, -2523, +558, -585, -1493, -124, -765, +323, -452, -399, -154, +1291, -276, +265, -134, -876, -130, -701, -238, +296, }, - { +19461, +9711, -6136, -768, -4103, +4127, +1289, -3000, -2181, +873, +525, -145, +1756, -2618, +563, -484, -1372, +57, -547, +215, -362, -384, -264, +1161, -298, +275, -17, -893, -58, -554, -229, +265, }, - { +17277, +9611, -4621, -998, -4208, +3875, +1658, -2589, -1841, +534, +392, -46, +1442, -2298, +316, -236, -1201, +192, -408, +85, -140, -396, -437, +993, -150, +202, +81, -782, +50, -474, -177, +231, }, - { +14172, +9673, -3573, -888, -1759, +2079, +423, -1986, -1744, +555, +790, -69, +1145, -1353, +372, +59, -818, -47, -210, +85, -314, -228, -308, +651, -194, +55, +187, -514, -187, -359, -318, -25, }, - { +12049, +9447, -2228, -1231, -1752, +1946, +840, -1465, -1503, +155, +682, -24, +949, -1008, +142, +192, -555, +85, -44, +97, -161, -260, -418, +506, -91, +11, +275, -348, -145, -288, -275, -84, }, - { +10303, +9142, -1241, -1401, -1603, +1679, +1080, -926, -1326, -100, +605, -40, +855, -692, +34, +292, -275, +96, +72, +212, -127, -202, -437, +334, -5, -31, +233, -223, -120, -232, -200, -174, }, - { +9017, +8838, -619, -1486, -1392, +1440, +1205, -522, -1133, -209, +558, -14, +754, -391, +50, +313, -71, +90, +164, +296, -77, -139, -435, +174, +4, -91, +133, -78, -72, -176, -176, -213, }, - { +8142, +8597, -267, -1538, -1157, +1261, +1254, -258, -963, -244, +541, +75, +679, -187, +160, +270, +1, +140, +187, +302, -55, -83, -444, +4, -35, -132, +106, +52, -76, -189, -49, -190, }, - { +7622, +8383, -48, -1578, -899, +1181, +1234, -71, -944, -214, +551, +137, +707, -144, +260, +320, -94, +109, +245, +239, -123, -2, -426, -196, -30, -52, +38, -6, +17, -57, -187, -8, }, - { +7332, +8319, +57, -1601, -631, +1238, +1135, +21, -967, -327, +659, +76, +672, +38, +199, +349, -41, -97, +208, +331, -233, -127, -295, -155, -164, -26, -20, -11, +90, -178, +192, +245, }, - { +7317, +8418, -7, -1642, -367, +1419, +1147, -111, -974, -384, +550, +84, +565, +94, +364, +313, -68, -10, +86, +197, -143, -149, -385, -44, -17, -229, -53, +121, -114, +140, +435, -168, }, - { +7367, +8733, -36, -1826, -124, +1616, +1200, -184, -1158, -452, +570, -113, +408, +131, +319, +450, -22, -49, +185, +112, -380, -100, -266, -117, -72, -71, +10, -213, +51, +444, +58, -226, }, - { +7780, +9068, -243, -2044, +77, +1858, +1206, -274, -1289, -551, +596, -178, +200, -29, +344, +432, -90, +103, +283, +41, -414, -210, -414, +8, +0, -140, +15, -152, +111, +292, -78, -206, }, - { +8345, +9580, -574, -2318, +346, +2040, +1168, -408, -1458, -527, +676, -258, +1, -124, +320, +310, -183, +87, +370, +84, -415, -236, -480, -21, -74, -20, +45, -230, +106, +351, -132, -434, }, - { +9094, +10154, -1025, -2554, +632, +2229, +994, -595, -1621, -437, +874, -416, -132, -257, +352, +267, -420, +47, +366, +3, -398, -143, -510, +98, -129, -195, +92, -138, -60, +248, +111, -492, }, - { +10041, +10768, -1614, -2719, +916, +2381, +756, -898, -1763, -304, +1151, -599, -325, -310, +358, +208, -536, -91, +282, -46, -529, -37, -456, +197, -31, -321, -13, -176, -156, +116, +291, -363, }, - { +11107, +11413, -2234, -2770, +1108, +2450, +521, -1208, -1885, -154, +1431, -759, -498, -367, +419, +97, -627, -128, +121, -90, -589, -28, -356, +273, +33, -279, -81, -291, -313, -16, +331, +7, }, - { +12280, +12021, -2906, -2717, +1134, +2377, +314, -1466, -2001, -37, +1641, -947, -595, -443, +445, +1, -745, -215, +22, -112, -652, -10, -293, +280, +22, -180, -159, -383, -467, -188, +208, +307, }, - { +13475, +12606, -3625, -2517, +1014, +2161, +183, -1625, -2084, +8, +1791, -1103, -612, -507, +435, -57, -847, -324, -41, -71, -678, +57, -282, +263, -37, -62, -209, -455, -522, -398, +113, +417, }, - { +14812, +13011, -4511, -2154, +806, +1834, +70, -1725, -2175, +16, +1867, -1208, -532, -590, +417, -130, -929, -396, -58, -66, -662, +121, -368, +291, -144, -1, -180, -513, -541, -616, +106, +375, }, - { +16380, +13067, -5650, -1592, +605, +1495, -131, -1780, -2290, +40, +2010, -1367, -305, -662, +396, -248, -905, -354, -222, +46, -645, +6, -354, +338, -292, +124, -80, -658, -520, -638, -12, +271, }, - { +17982, +12702, -6846, -878, +421, +1177, -463, -1808, -2473, +274, +2108, -1572, +121, -826, +355, -267, -731, -513, -308, +176, -908, +60, -376, +313, -223, +268, -136, -780, -340, -699, -278, +268, }, - { +19157, +12247, -7860, -132, +149, +912, -724, -1957, -2452, +536, +2076, -1557, +521, -1124, +525, -122, -855, -442, -535, +76, -863, -69, -379, +601, -217, +257, -79, -739, -389, -790, -342, +200, }, - { +19711, +11522, -8169, +401, -329, +905, -928, -2048, -2370, +752, +2017, -1467, +767, -1174, +691, -185, -760, -679, -713, +177, -1039, -25, -158, +692, -291, +423, -59, -878, -408, -762, -397, +110, }, - { +19465, +10779, -7703, +460, -893, +1187, -817, -2234, -2246, +1019, +1640, -1190, +1218, -1460, +857, -119, -1111, -511, -817, +81, -770, -57, -137, +805, -201, +370, -136, -863, -389, -713, -437, +67, }, - { +18333, +10203, -6584, +85, -1382, +1684, -563, -2346, -2049, +928, +1357, -671, +1226, -1413, +733, -229, -1009, -521, -666, +153, -618, -188, -102, +925, -315, +267, -79, -795, -334, -687, -385, +130, }, - { +16441, +9946, -5138, -473, -1669, +2005, -91, -2252, -1996, +837, +1093, -412, +1392, -1542, +535, -11, -1080, -203, -475, +134, -478, -260, -105, +753, -285, +165, +32, -670, -301, -515, -295, +22, }, - { +13089, +9529, -4017, -237, +483, +1183, -334, -1490, -1552, +647, +1264, -471, +629, -605, +562, -36, -643, -387, -501, +84, -371, -60, -86, +640, -100, +137, -1, -574, -350, -440, -324, -139, }, - { +11898, +9621, -3405, -1165, +243, +1679, +179, -1312, -1709, +64, +1140, -239, +692, -458, +479, +250, -561, -188, -174, +41, -320, -165, -304, +589, -101, -43, +124, -435, -309, -354, -282, -103, }, - { +10997, +9658, -2780, -1802, -26, +1783, +569, -947, -1662, -248, +967, -127, +729, -294, +466, +390, -354, -145, +46, +95, -329, -112, -479, +387, +17, -149, +90, -226, -277, -280, -149, -147, }, - { +10403, +9825, -2433, -2099, -53, +1814, +738, -808, -1574, -372, +873, -167, +701, -213, +490, +502, -294, -53, +103, +45, -399, -57, -537, +124, +113, -120, +21, -185, -188, -248, -114, -74, }, - { +10392, +9882, -2497, -2112, +324, +1944, +702, -937, -1618, -322, +898, -262, +449, -113, +460, +482, -188, -10, +186, -20, -556, -166, -451, +104, +9, -20, +13, -185, -148, -338, -76, +107, }, - { +10862, +9834, -2867, -1780, +884, +2063, +422, -1170, -1644, -165, +979, -389, +198, -268, +566, +314, -335, +218, +172, -127, -560, -306, -505, +230, +61, -85, -17, -114, -234, -393, -69, +141, }, - { +11578, +9958, -3241, -1267, +1305, +1835, +61, -1353, -1523, +172, +1158, -610, -59, -256, +501, +100, -434, +87, +156, -173, -554, -216, -452, +238, -8, +72, -57, -233, -279, -439, -54, +128, }, - { +12590, +10282, -3669, -831, +1213, +1299, -204, -1324, -1305, +642, +1310, -929, -150, -265, +378, -166, -511, -226, -25, -77, -591, -30, -316, +195, -77, +192, -79, -444, -281, -501, -173, +158, }, - { +13820, +10820, -4370, -641, +688, +719, -208, -1170, -1120, +1054, +1422, -1268, +60, -395, +126, -158, -785, -547, -55, -15, -622, +139, -270, +187, +11, +211, -203, -518, -250, -711, -272, +251, }, - { +14973, +10840, -5035, -319, +215, +327, -180, -1056, -1001, +1357, +1436, -1376, +373, -623, +75, -133, -1012, -696, -148, +89, -603, +166, -149, +257, +111, +201, -249, -478, -375, -806, -271, +241, }, - { +15155, +10582, -5238, +16, +115, +211, -361, -1141, -1066, +1374, +1522, -1325, +512, -561, +33, -137, -860, -968, -261, +174, -757, +281, -16, +297, +93, +272, -236, -631, -384, -770, -341, +145, }, - { +14475, +9926, -4814, +144, +323, +523, -528, -1336, -1319, +1198, +1433, -1025, +675, -646, +308, -70, -834, -739, -508, +86, -551, +161, +29, +400, +61, +248, -225, -631, -389, -587, -390, -22, }, - { +11096, +9607, -2841, -481, +1236, +612, -162, -1033, -885, +1058, +1197, -645, +47, -150, +202, +5, -433, -652, -254, -16, -605, +40, +33, +357, +315, +288, -273, -769, -633, -453, +2, +259, }, - }, +/* HRIR Coefficients */ +static const ALshort defaultCoeffs[26496] = +{ + +6117, +8354, +3531, +2903, +1118, +342, +874, -822, -2447, -1309, +579, -133, -617, -1093, -998, -416, -244, -202, -84, -134, -375, -200, -416, -331, -408, -614, -489, -332, -207, -97, -7, -145, + +6958, +8678, +3013, +3274, +1145, +25, +847, -771, -2501, -1666, +534, +86, -597, -917, -967, -916, -367, -80, -198, -215, -475, -312, -442, -372, -399, -554, -517, -249, -103, -75, -5, -176, + +6349, +8083, +2935, +2854, +1109, +344, +851, -891, -2351, -1252, +506, -191, -559, -861, -745, -485, -327, -77, -17, -172, -405, -189, -402, -350, -459, -599, -449, -315, -184, -77, +13, -134, + +5910, +7494, +2698, +2625, +992, +373, +884, -825, -2197, -962, +698, -127, -425, -759, -697, -286, -213, -171, -64, -127, -336, -131, -355, -271, -368, -553, -428, -299, -179, -74, +4, -137, + +5808, +7380, +2660, +2585, +1001, +453, +998, -698, -2078, -854, +773, -100, -470, -857, -730, -241, -185, -179, -63, -114, -325, -112, -322, -220, -300, -507, -404, -297, -216, -122, -35, -168, + +5957, +7591, +2687, +2503, +871, +340, +913, -821, -2282, -1053, +775, -16, -459, -904, -784, -240, -114, -100, -12, -59, -285, -105, -334, -253, -340, -532, -400, -251, -127, -17, +33, -156, + +6515, +8209, +2752, +2639, +892, +326, +895, -1074, -2683, -1313, +854, -53, -682, -1135, -939, -316, -155, -153, -32, -64, -346, -124, -339, -249, -345, -543, -400, -232, -129, -39, +38, -120, + +6887, +8888, +3060, +2770, +926, +146, +833, -1245, -2800, -1317, +584, -231, -619, -1119, -983, -413, -244, -71, -9, -143, -405, -183, -399, -307, -420, -595, -439, -302, -153, -55, +34, -129, + +7340, +9090, +2964, +3130, +1162, +115, +612, -1577, -2702, -692, +458, -1019, -864, -943, -587, -190, -434, -226, +41, -162, -398, -144, -463, -353, -533, -708, -464, -374, -270, -103, +2, -187, + +8348, +9865, +2233, +2503, +594, +154, +1277, -1477, -3002, -433, +1280, -991, -1387, -1385, -643, +20, -514, -498, -16, -150, -545, -145, -486, -329, -539, -846, -509, -326, -250, -110, +9, -211, + +8668, +10241, +2446, +2335, +160, +133, +1408, -1244, -3403, -895, +1742, -269, -1341, -2123, -1100, +207, -94, -571, -238, -198, -607, -211, -581, -326, -492, -792, -539, -293, -202, -119, -28, -265, + +8261, +10052, +3261, +2775, +344, +65, +1000, -1138, -3661, -1615, +1337, +126, -290, -1970, -1899, -55, +143, -202, -175, -248, -492, -207, -591, -284, -495, -901, -578, -409, -197, -51, +38, -151, + +7749, +9628, +3084, +3049, +870, +16, +727, -1159, -2880, -1819, +969, +83, -717, -1031, -1759, -1055, -39, -9, -26, -31, -379, -324, -646, -479, -344, -651, -608, -341, -196, -48, +22, -160, + +7872, +8889, +2424, +3846, +1113, -405, +870, -636, -2562, -2175, +535, +438, -627, -691, -988, -1594, -378, +123, -383, -287, -574, -435, -436, -421, -370, -475, -575, -138, +9, -79, -10, -210, + +7007, +8290, +2692, +3507, +1037, -125, +838, -876, -2265, -1597, +225, -49, -510, -580, -573, -987, -677, +32, +42, -236, -535, -281, -374, -349, -433, -522, -408, -257, -182, -133, +15, -132, + +6475, +7694, +2419, +2913, +1152, +342, +794, -920, -2186, -1265, +352, -196, -457, -569, -494, -665, -413, +113, +33, -239, -428, -173, -379, -384, -517, -559, -408, -308, -159, -59, +31, -118, + +5981, +7105, +2165, +2692, +1134, +347, +767, -876, -2030, -957, +421, -294, -318, -441, -466, -416, -281, -39, -27, -194, -378, -156, -345, -274, -384, -498, -440, -344, -158, -51, +21, -134, + +5468, +6465, +2050, +2460, +952, +446, +858, -776, -1849, -646, +711, -106, -171, -377, -412, -225, -208, -139, -49, -122, -280, -59, -288, -217, -330, -482, -372, -276, -153, -54, +11, -123, + +5247, +6086, +1760, +2189, +842, +506, +1054, -433, -1470, -298, +965, +30, -189, -498, -477, -163, -126, -106, -24, -94, -283, -72, -247, -143, -266, -434, -302, -196, -110, -68, -52, -213, + +5232, +6232, +1996, +2383, +983, +625, +1098, -519, -1614, -432, +848, -66, -286, -585, -461, -110, -157, -165, -46, -92, -261, -20, -217, -109, -190, -394, -333, -281, -239, -151, -66, -182, + +5323, +6297, +1900, +2226, +867, +582, +1114, -514, -1700, -507, +886, -53, -362, -695, -545, -42, +42, -2, +24, -89, -290, -90, -302, -188, -238, -341, -202, -173, -185, -163, -115, -218, + +5574, +6674, +1997, +2183, +707, +407, +936, -776, -2047, -829, +914, +130, -285, -696, -573, -93, +9, -5, +50, +20, -186, -16, -247, -182, -271, -441, -315, -175, -47, +63, +58, -176, + +6045, +7217, +2109, +2333, +722, +394, +912, -1008, -2484, -1201, +940, +97, -533, -929, -717, -112, +69, +18, +107, +96, -204, -31, -262, -175, -230, -397, -254, -106, -72, -21, +17, -112, + +6856, +7935, +1962, +2469, +717, +365, +900, -1353, -2894, -1309, +1170, +26, -784, -1168, -861, -220, -61, -113, +16, +18, -323, -43, -253, -171, -282, -468, -311, -130, -56, +10, +78, -94, + +7514, +8789, +1982, +2483, +712, +262, +907, -1695, -3191, -1325, +1153, -23, -806, -1333, -975, -279, -115, -59, -35, -42, -373, -130, -392, -273, -384, -542, -334, -150, -38, +4, +93, -104, + +7708, +9393, +2471, +2673, +752, -59, +807, -1726, -3115, -1282, +555, -307, -586, -1146, -966, -429, -241, +103, +48, -175, -435, -160, -372, -287, -438, -565, -385, -281, -93, -15, +72, -115, + +7961, +9595, +2700, +3173, +1089, -199, +393, -2045, -2982, -748, +119, -1067, -577, -787, -541, -413, -602, -36, +144, -149, -336, -111, -417, -324, -553, -659, -425, -410, -226, -58, +56, -137, + +8750, +9725, +2189, +3527, +1193, -202, +307, -2424, -2793, +130, +87, -2091, -927, -659, -104, -33, -745, -205, +211, -231, -414, -73, -531, -374, -686, -789, -410, -438, -340, -94, +17, -238, + +9887, +10729, +1149, +2712, +812, -159, +1171, -2374, -3238, +573, +900, -2331, -1559, -881, +10, +282, -825, -483, +230, -178, -567, -74, -569, -393, -734, -962, -410, -384, -393, -161, +71, -197, + +11064, +11221, +279, +2282, +77, +57, +1829, -2384, -3518, +811, +1905, -2262, -2145, -1529, -99, +470, -985, -810, +158, -183, -755, -35, -580, -314, -703, -1105, -476, -311, -308, -116, +33, -294, + +11675, +11698, +209, +1859, -553, +242, +2236, -2105, -4055, +456, +2775, -1639, -2377, -2493, -525, +885, -700, -1033, -74, -269, -767, -30, -730, -335, -644, -1070, -436, -206, -262, -87, -13, -377, + +11801, +11992, +657, +1830, -875, +135, +2141, -1883, -4508, -144, +3105, -728, -2249, -3247, -939, +1040, -70, -1098, -336, -229, -882, -166, -780, -279, -597, -994, -559, -229, -208, -150, -49, -410, + +11441, +12041, +1632, +2283, -957, -39, +1816, -1840, -4880, -918, +2879, +121, -1146, -3647, -1711, +1051, +438, -745, -603, -262, -776, -209, -700, -151, -609, -1078, -625, -402, -194, -201, -9, -262, + +10865, +11676, +2584, +2613, -586, -83, +1224, -1524, -5125, -1724, +2382, +303, +58, -3199, -2831, +663, +561, -315, -300, -369, -601, -190, -808, -177, -617, -1246, -617, -484, -161, +7, +81, -166, + +10191, +11218, +2753, +3225, -135, -314, +1139, -1492, -4741, -2381, +2120, +202, +83, -1978, -3635, -327, +757, +52, -23, -340, -548, -69, -879, -641, -441, -1126, -641, -329, -170, +77, +67, -175, + +9689, +10846, +2307, +3298, +545, -344, +602, -1494, -3324, -2412, +1584, +308, -905, -920, -2772, -1685, +423, +196, -11, +88, -409, -493, -902, -608, -212, -710, -760, -321, -179, +12, +47, -183, + +8953, +9908, +2218, +3607, +920, -373, +599, -1197, -2905, -2314, +1261, +665, -1096, -819, -1580, -2014, -168, +187, -326, -97, -344, -334, -636, -572, -272, -489, -771, -288, -106, -59, +97, -199, + +8864, +8963, +1784, +4657, +969, -956, +982, -415, -2657, -2862, +633, +942, -750, -396, -1083, -2461, -216, +391, -668, -329, -673, -573, -389, -489, -318, -379, -677, +16, +122, -114, -18, -247, + +7756, +8469, +2432, +4304, +831, -834, +867, -757, -2207, -2102, -12, +321, -466, -174, -519, -1837, -871, +255, +23, -250, -677, -423, -326, -339, -330, -413, -490, -195, -73, -162, -2, -152, + +7061, +7757, +2298, +3660, +972, -50, +816, -871, -2023, -1762, +29, +39, -419, -270, -323, -1264, -738, +345, +74, -339, -535, -233, -317, -423, -530, -487, -350, -279, -220, -117, +68, -96, + +6469, +7209, +2035, +3061, +1233, +321, +690, -887, -1952, -1381, +126, -112, -325, -222, -261, -975, -473, +378, +46, -334, -435, -156, -344, -439, -577, -492, -370, -312, -132, -41, +48, -98, + +5924, +6587, +1791, +2840, +1306, +325, +630, -832, -1787, -1021, +168, -250, -169, -97, -250, -687, -289, +202, -37, -279, -361, -130, -348, -361, -448, -399, -386, -361, -133, -16, +50, -129, + +5282, +6011, +1719, +2545, +1130, +445, +720, -784, -1642, -749, +308, -187, +39, -21, -232, -423, -260, +27, -35, -215, -317, -45, -205, -222, -390, -439, -388, -320, -115, -45, +11, -94, + +4741, +5315, +1665, +2368, +986, +543, +781, -655, -1403, -392, +608, -36, +147, +49, -163, -239, -215, -100, -40, -117, -205, +8, -213, -171, -294, -397, -329, -264, -127, -36, +13, -103, + +4473, +4913, +1415, +2018, +802, +585, +981, -314, -1070, -10, +964, +194, +186, -38, -233, -201, -159, -68, +40, -54, -215, -5, -156, -100, -249, -363, -242, -160, -67, -14, -33, -215, + +4287, +4651, +1225, +2028, +1002, +772, +1151, -74, -767, +174, +960, +71, -57, -266, -220, -24, -57, -86, -63, -101, -197, +12, -123, -8, -137, -308, -225, -169, -123, -121, -128, -237, + +4337, +4965, +1624, +2246, +1058, +843, +1155, -266, -1056, -75, +799, +3, -60, -285, -202, -30, -153, -156, -30, -66, -178, +71, -100, -2, -76, -278, -279, -283, -274, -184, -98, -187, + +4443, +5025, +1531, +2119, +997, +856, +1205, -260, -1169, -213, +764, -10, -150, -366, -219, +89, +76, -16, -38, -108, -204, -23, -212, -56, -66, -154, -135, -246, -290, -240, -153, -192, + +4604, +5187, +1421, +1877, +708, +663, +1129, -291, -1278, -255, +968, +170, -109, -537, -478, +41, +175, +171, +207, -3, -219, -11, -242, -189, -190, -256, -119, -13, -31, -100, -174, -309, + +4923, +5652, +1529, +1902, +624, +528, +924, -671, -1743, -664, +996, +326, -100, -476, -372, +25, +128, +85, +100, +106, -73, +61, -152, -121, -199, -342, -237, -104, +32, +141, +70, -204, + +5421, +6220, +1615, +2041, +613, +476, +868, -945, -2209, -1062, +1028, +282, -361, -678, -462, +90, +247, +119, +166, +124, -141, +83, -164, -99, -131, -291, -197, -34, +4, +4, +72, -42, + +6190, +6818, +1507, +2236, +597, +518, +893, -1240, -2699, -1316, +1269, +222, -676, -957, -667, -54, +151, +26, +170, +185, -160, +80, -150, -125, -158, -266, -176, +4, -12, -12, +35, -111, + +7121, +7541, +1201, +2394, +583, +455, +869, -1653, -3075, -1304, +1541, +95, -937, -1178, -764, -132, +36, -84, +64, +109, -308, +44, -155, -103, -220, -385, -224, -28, +7, +54, +114, -67, + +7954, +8408, +983, +2438, +632, +359, +872, -2062, -3411, -1245, +1676, +31, -1048, -1363, -832, -150, -48, -120, +14, +94, -364, -58, -298, -170, -314, -457, -245, -56, +16, +70, +176, -53, + +8426, +9277, +1223, +2430, +532, +133, +944, -2316, -3533, -1292, +1244, -43, -818, -1449, -1029, -259, -53, +135, -32, -56, -402, -136, -404, -282, -407, -503, -267, -114, +46, +41, +136, -109, + +8583, +9860, +1762, +2634, +598, -282, +801, -2272, -3373, -1211, +481, -346, -524, -1183, -947, -470, -228, +324, +74, -228, -460, -132, -337, -273, -462, -518, -331, -270, -26, +19, +110, -100, + +8789, +10123, +2143, +3154, +907, -539, +350, -2551, -3191, -653, -134, -1144, -348, -706, -562, -559, -647, +213, +190, -170, -308, -125, -412, -293, -550, -593, -367, -441, -161, -3, +111, -113, + +9368, +10135, +1939, +3756, +1190, -650, -93, -2909, -2955, +75, -583, -2117, -371, -455, -4, -431, -1040, +118, +327, -275, -298, -31, -480, -340, -761, -730, -381, -524, -283, -44, +42, -215, + +10370, +10210, +1204, +4156, +1175, -623, -28, -3363, -2672, +1145, -623, -3309, -728, -270, +428, +27, -1178, -99, +420, -357, -415, +13, -626, -389, -869, -847, -326, -533, -414, -65, +33, -301, + +11635, +11075, -31, +3531, +952, -550, +724, -3443, -3032, +1791, +130, -3849, -1409, -370, +688, +391, -1323, -332, +504, -391, -598, +96, -680, -457, -950, -1002, -305, -479, -469, -136, +71, -286, + +13207, +11905, -1547, +2772, +301, -274, +1873, -3587, -3556, +2285, +1234, -3973, -2188, -835, +809, +672, -1631, -769, +602, -241, -847, +83, -674, -374, -941, -1208, -342, -448, -473, -101, +134, -318, + +14337, +12287, -2399, +2422, -469, +62, +2531, -3616, -3929, +2464, +2354, -3991, -2785, -1503, +623, +891, -1697, -1088, +457, -261, -1009, +151, -717, -276, -913, -1388, -372, -300, -384, -112, +67, -401, + +15087, +12820, -2744, +1910, -1184, +425, +3120, -3448, -4563, +2187, +3466, -3489, -3173, -2589, +266, +1446, -1532, -1382, +191, -327, -1016, +193, -847, -301, -888, -1367, -296, -177, -336, -114, +20, -474, + +15581, +13124, -2434, +1591, -1676, +521, +3195, -3036, -5227, +1724, +4250, -2658, -3404, -3573, -56, +1861, -986, -1649, +4, -355, -1041, +91, -1052, -239, -767, -1287, -362, -121, -296, -58, -65, -569, + +15601, +13452, -1914, +1563, -2007, +399, +3052, -2823, -5735, +1036, +4617, -1613, -3294, -4431, -451, +2051, -245, -1777, -331, -235, -1215, -48, -1032, -173, -736, -1221, -537, -142, -232, -189, -69, -580, + +15203, +13689, -870, +1955, -2244, +197, +2769, -2807, -6122, +172, +4587, -487, -2272, -5183, -1225, +2226, +446, -1489, -791, -175, -1171, -107, -880, -30, -790, -1309, -587, -320, -186, -316, -13, -442, + +14648, +13594, +409, +2248, -2137, -16, +2270, -2431, -6673, -665, +4167, +189, -766, -5403, -2316, +2230, +741, -1027, -813, -342, -840, -164, -978, +109, -745, -1474, -642, -547, -154, -159, +47, -247, + +13996, +13109, +1461, +2499, -1685, -37, +1524, -2013, -6863, -1546, +3712, +317, +445, -4840, -3714, +1807, +920, -566, -438, -485, -703, -148, -1075, +6, -791, -1647, -584, -567, -97, +72, +120, -190, + +13165, +12534, +1976, +3362, -1471, -314, +1381, -1961, -6484, -2520, +3399, +361, +831, -3679, -5026, +938, +1344, -192, -237, -452, -597, -58, -1183, -507, -582, -1548, -641, -480, -68, +246, +63, -219, + +12626, +12250, +1611, +3690, -681, -941, +1250, -1619, -5566, -2944, +3036, +177, +25, -1933, -5154, -665, +1470, +164, +107, -276, -664, -178, -1249, -762, -296, -1315, -631, -232, -234, +180, +66, -251, + +11980, +11934, +1167, +3735, +109, -727, +510, -1829, -3781, -3108, +2485, +496, -1203, -728, -4093, -2241, +1182, +347, -49, +233, -470, -711, -1173, -711, -7, -812, -944, -259, -161, +83, +61, -212, + +11247, +11010, +1120, +4114, +574, -764, +386, -1687, -3259, -2815, +2128, +825, -1544, -509, -2722, -2986, +467, +444, -350, +190, -276, -570, -1067, -700, +132, -512, -1156, -281, -35, -10, +123, -207, + +10116, +9947, +1402, +4469, +759, -942, +664, -954, -2962, -3136, +1495, +1323, -1375, -529, -1640, -2951, +60, +455, -723, -188, -423, -428, -490, -651, -326, -390, -839, -121, -11, -87, +128, -262, + +9934, +8876, +1128, +5737, +644, -1620, +1223, -109, -2816, -3751, +890, +1596, -1024, +3, -1280, -3531, +194, +690, -1086, -313, -780, -731, -285, -592, -233, -265, -834, +227, +227, -185, -20, -287, + +8502, +8500, +2204, +5212, +430, -1605, +1028, -561, -2155, -2773, -185, +874, -495, +321, -570, -2903, -846, +586, -74, -234, -828, -571, -225, -357, -205, -310, -640, -115, +58, -204, -18, -162, + +7584, +7772, +2171, +4547, +704, -725, +925, -716, -1861, -2401, -267, +505, -407, +183, -244, -2138, -927, +680, +60, -459, -671, -326, -222, -451, -469, -353, -358, -211, -203, -191, +84, -98, + +6877, +7100, +2027, +3726, +1015, +37, +675, -791, -1748, -2003, -196, +244, -318, +111, -88, -1694, -708, +748, +20, -457, -485, -226, -270, -512, -629, -427, -353, -293, -167, -97, +74, -60, + +6094, +6516, +1758, +3125, +1461, +313, +506, -750, -1620, -1508, -142, +48, -126, +224, -68, -1338, -382, +704, -7, -454, -398, -106, -300, -528, -626, -363, -337, -340, -80, +0, +68, -81, + +5474, +5821, +1573, +2970, +1494, +257, +449, -672, -1419, -1123, -157, -119, +81, +343, -71, -994, -247, +423, -94, -356, -314, -117, -307, -403, -455, -271, -389, -398, -91, +12, +63, -119, + +4706, +5219, +1556, +2650, +1342, +394, +527, -623, -1238, -816, -65, -106, +329, +424, -62, -677, -264, +193, -57, -276, -283, -47, -151, -234, -379, -329, -417, -360, -71, -27, +20, -78, + +3969, +4463, +1642, +2395, +1176, +599, +584, -518, -1032, -470, +216, +31, +488, +473, -5, -409, -215, +23, -78, -181, -137, +68, -136, -185, -309, -316, -333, -291, -98, -38, +10, -54, + +3424, +3827, +1536, +2086, +1002, +678, +738, -333, -681, +35, +605, +269, +533, +528, +71, -284, -241, -104, +39, -20, -139, +38, -65, -74, -225, -293, -257, -229, -78, +5, +12, -102, + +3209, +3445, +1231, +1747, +899, +784, +1000, +168, -305, +345, +880, +396, +496, +306, -68, -218, -102, -1, +55, -36, -135, +45, -28, -19, -180, -238, -160, -103, -27, -22, -94, -255, + +2989, +3191, +1074, +1836, +1186, +989, +1156, +381, -8, +502, +823, +223, +193, +66, +7, +5, -16, -56, -80, -81, -98, +68, +12, +88, -46, -191, -160, -138, -110, -149, -188, -250, + +3027, +3528, +1478, +2058, +1276, +1085, +1144, +149, -311, +281, +686, +149, +146, +19, +50, +25, -119, -132, -55, -57, -69, +143, +32, +105, +37, -167, -229, -266, -280, -209, -151, -192, + +3214, +3748, +1601, +2025, +1190, +1116, +1202, +89, -552, -87, +478, +220, +213, +9, +55, +81, -6, -61, -71, -93, -61, +81, -92, +76, +154, -10, -220, -365, -342, -251, -170, -159, + +3266, +3741, +1347, +1791, +1078, +1077, +1224, +91, -623, +51, +737, +114, -29, -162, -63, +235, +299, +125, +20, -78, -150, -17, -140, -29, -21, +31, +66, -141, -296, -306, -239, -221, + +3541, +4062, +1288, +1550, +718, +829, +1077, -44, -837, -142, +945, +448, +111, -311, -297, +101, +259, +279, +274, +70, -83, +51, -163, -131, -124, -170, -40, +66, +53, -44, -202, -351, + +3954, +4589, +1351, +1593, +636, +691, +854, -482, -1382, -587, +1032, +601, +79, -242, -184, +108, +254, +168, +138, +202, +51, +122, -43, -74, -123, -230, -173, -35, +112, +219, +65, -237, + +4535, +5212, +1390, +1740, +598, +607, +776, -814, -1908, -1025, +1099, +545, -214, -426, -239, +239, +413, +193, +207, +182, -47, +183, -57, -40, -30, -175, -148, +40, +73, +37, +118, +7, + +5318, +5785, +1269, +1968, +575, +658, +805, -1127, -2442, -1307, +1372, +466, -591, -725, -443, +119, +395, +164, +270, +354, -56, +110, -69, -55, -25, -139, -51, +109, +11, +15, +19, -56, + +6436, +6460, +882, +2236, +497, +666, +802, -1573, -2941, -1397, +1743, +286, -941, -976, -603, -18, +243, -4, +204, +282, -184, +170, -29, -57, -91, -187, -111, +112, +41, +27, +68, -96, + +7585, +7281, +373, +2458, +491, +542, +790, -2104, -3319, -1286, +2043, +126, -1200, -1227, -664, -50, +85, -70, +93, +172, -322, +133, -69, -86, -185, -297, -168, +53, +66, +96, +196, +7, + +8554, +8204, +13, +2518, +545, +433, +808, -2585, -3651, -1161, +2167, +23, -1301, -1412, -719, -73, +18, -111, +45, +202, -388, -7, -242, -122, -287, -383, -162, +38, +78, +115, +239, -27, + +9212, +9220, +103, +2448, +407, +223, +921, -2981, -3805, -1200, +1719, +26, -1055, -1626, -929, -188, +43, +226, -94, +18, -406, -89, -400, -275, -396, -440, -171, +13, +140, +43, +175, -97, + +9425, +9997, +611, +2554, +412, -263, +952, -2951, -3684, -1187, +857, -167, -621, -1410, -1053, -347, -65, +452, -3, -165, -453, -143, -340, -269, -451, -441, -242, -198, +101, +82, +181, -110, + +9602, +10483, +1219, +2947, +590, -759, +563, -2991, -3446, -797, -98, -815, -218, -921, -768, -633, -444, +563, +104, -246, -350, -155, -369, -240, -521, -488, -298, -401, -10, +50, +144, -115, + +9910, +10681, +1487, +3547, +923, -1024, +61, -3330, -3146, -137, -870, -1590, +8, -449, -298, -772, -939, +485, +312, -243, -240, -78, -399, -324, -669, -567, -332, -547, -156, +25, +160, -93, + +10699, +10561, +1144, +4345, +1148, -1198, -465, -3692, -2804, +756, -1507, -2809, +121, -169, +369, -651, -1433, +435, +473, -418, -220, +23, -526, -346, -932, -715, -318, -648, -289, -5, +58, -250, + +11865, +10458, +321, +5013, +1084, -1187, -415, -4235, -2391, +1999, -1758, -4266, -88, +147, +902, -193, -1705, +234, +619, -537, -297, +92, -743, -384, -1023, -815, -255, -684, -426, -12, +35, -330, + +13346, +11005, -1112, +4810, +949, -1079, +138, -4587, -2456, +3025, -1295, -5300, -712, +202, +1270, +293, -1889, -46, +762, -642, -552, +226, -817, -466, -1180, -995, -171, -630, -552, -62, +74, -399, + +14971, +12208, -3034, +3816, +594, -863, +1619, -4784, -3319, +3684, -109, -5706, -1550, +27, +1400, +652, -2108, -458, +869, -483, -776, +220, -858, -433, -1201, -1254, -117, -550, -640, -140, +204, -318, + +16995, +12596, -4875, +3443, -244, -334, +2668, -5173, -3649, +4366, +1153, -6044, -2514, -559, +1728, +927, -2652, -901, +1093, -410, -1143, +329, -841, -335, -1196, -1458, -195, -525, -564, -33, +194, -462, + +18241, +12894, -5826, +3138, -1130, +187, +3380, -5255, -4143, +4561, +2499, -6195, -3183, -1309, +1509, +1233, -2676, -1266, +894, -425, -1299, +432, -922, -204, -1176, -1686, -183, -313, -482, -86, +105, -535, + +19257, +13367, -6379, +2592, -1984, +792, +4070, -5179, -4919, +4384, +3882, -5784, -3709, -2594, +1250, +1947, -2577, -1645, +617, -476, -1302, +491, -1070, -197, -1169, -1676, -76, -162, -446, -100, +47, -614, + +19926, +13767, -6244, +2039, -2577, +1096, +4300, -4713, -5817, +3943, +5112, -5041, -4213, -3795, +981, +2627, -2147, -2070, +431, -519, -1281, +436, -1355, -148, -989, -1627, -104, -51, -433, -15, -50, -735, + +20240, +14125, -5799, +1784, -3007, +1064, +4265, -4313, -6590, +3386, +5836, -3972, -4474, -4840, +741, +2976, -1373, -2410, +167, -416, -1413, +247, -1435, -24, -966, -1480, -291, -55, -313, -65, -145, -781, + +20015, +14601, -5023, +1828, -3407, +908, +4058, -4144, -7140, +2450, +6274, -2630, -4153, -5964, +216, +3298, -453, -2534, -345, -178, -1641, +157, -1311, +64, -954, -1504, -457, -98, -260, -285, -55, -762, + +19554, +14863, -3770, +2150, -3733, +724, +3709, -4072, -7621, +1495, +6312, -1303, -3056, -6981, -603, +3594, +321, -2274, -920, -58, -1568, +72, -1120, +198, -1037, -1588, -525, -300, -179, -434, +24, -584, + +18917, +14814, -2183, +2351, -3715, +455, +3162, -3571, -8351, +569, +5938, -361, -1346, -7547, -1834, +3783, +700, -1769, -1070, -238, -1132, -62, -1211, +391, -1003, -1782, -585, -567, -111, -272, +77, -349, + +18106, +14727, -945, +2225, -3047, +302, +2302, -2969, -8873, -290, +5489, -62, +243, -7348, -3434, +3665, +911, -1246, -777, -513, -915, -51, -1324, +362, -1049, -1967, -506, -762, +16, -24, +82, -173, + +17254, +13805, +460, +2982, -2958, +154, +1644, -2479, -8779, -1643, +5145, +181, +1378, -6455, -5404, +3105, +1393, -741, -423, -612, -704, -72, -1484, +78, -955, -2125, -465, -626, +16, +278, +142, -257, + +16265, +13474, +690, +3849, -2566, -357, +1746, -2519, -8172, -2680, +5031, +100, +1311, -4691, -6912, +1980, +2040, -358, -216, -622, -649, +103, -1622, -626, -497, -1964, -571, -423, -30, +370, +49, -249, + +15646, +13159, +261, +4311, -1678, -1288, +1621, -1987, -7004, -3335, +4543, -14, +302, -2477, -7170, -48, +2406, +32, +137, -377, -773, -133, -1665, -841, -152, -1691, -589, -158, -270, +328, +50, -306, + +14914, +12999, -328, +4365, -702, -1133, +553, -2016, -4671, -4043, +4026, +360, -1378, -617, -6226, -2166, +2377, +298, -4, +327, -691, -899, -1434, -845, +201, -1106, -1032, -122, -210, +203, +45, -267, + +13958, +12124, -373, +4782, +21, -1129, +272, -2320, -3404, -3627, +3139, +1060, -2160, -3, -4519, -3752, +1820, +541, -476, +570, -311, -1038, -1434, -687, +457, -671, -1457, -167, -11, +62, +118, -218, + +12918, +10973, -67, +5240, +257, -1386, +443, -1503, -3392, -3835, +2924, +1581, -2328, -20, -2956, -4208, +1045, +694, -894, +202, -292, -645, -959, -841, +200, -409, -1380, -60, +24, -53, +228, -310, + +11453, +9857, +558, +5625, +370, -1608, +838, -661, -3107, -4122, +1928, +2028, -1762, -127, -1944, -4054, +595, +740, -1213, -166, -505, -568, -347, -773, -312, -278, -974, +83, +83, -136, +142, -319, + +11087, +8602, +495, +7107, +58, -2371, +1638, +267, -3072, -4860, +1382, +2390, -1510, +558, -1623, -4806, +939, +963, -1665, -194, -913, -908, -115, -747, -101, -144, -1056, +521, +304, -293, -8, -330, + +9334, +8472, +2057, +6324, -243, -2522, +1386, -290, -2159, -3680, -245, +1661, -676, +956, -788, -4263, -533, +965, -282, -154, -1031, -742, -56, -400, -21, -215, -885, +31, +223, -288, -38, -168, + +8202, +7850, +2127, +5711, +161, -1682, +1271, -489, -1744, -3323, -499, +1254, -540, +771, -297, -3344, -963, +1117, -26, -591, -845, -454, -64, -490, -350, -197, -438, -86, -170, -321, +106, -106, + +7291, +7027, +2168, +4730, +564, -540, +844, -580, -1481, -2901, -474, +853, -365, +616, -57, -2666, -805, +1195, -67, -613, -593, -252, -128, -623, -577, -254, -297, -288, -279, -138, +171, -54, + +6561, +6470, +2014, +3851, +1081, +55, +479, -597, -1428, -2456, -448, +615, -253, +562, +94, -2318, -595, +1226, -130, -587, -411, -244, -197, -635, -712, -320, -371, -307, -113, -95, +84, -14, + +5624, +5918, +1762, +3266, +1692, +206, +288, -499, -1267, -1883, -464, +389, +31, +706, +63, -1900, -243, +1098, -142, -584, -335, -87, -244, -648, -669, -209, -339, -372, -24, +17, +83, -55, + +4953, +5180, +1625, +3144, +1769, +106, +214, -394, -1053, -1453, -538, +193, +277, +807, +43, -1499, -93, +748, -239, -450, -232, -115, -285, -525, -481, -91, -398, -447, -39, +45, +83, -112, + +4115, +4607, +1619, +2888, +1682, +161, +244, -329, -812, -1141, -599, +67, +593, +924, +29, -1137, -210, +449, -129, -365, -249, -133, -121, -277, -340, -178, -530, -428, -2, -6, +39, -84, + +3177, +4024, +1786, +2341, +1485, +534, +375, -316, -681, -795, -329, +287, +817, +880, +57, -781, -190, +258, -112, -286, -153, +95, +56, -236, -403, -237, -370, -335, -19, -47, -2, +10, + +2412, +3137, +2012, +2211, +1367, +699, +342, -131, -395, -414, -56, +329, +935, +975, +138, -528, -171, +55, -126, -152, +41, +119, -74, -171, -229, -182, -327, -290, -76, -28, +10, -11, + +1837, +2561, +1897, +1806, +1200, +798, +563, +60, +7, +156, +349, +604, +923, +1022, +216, -431, -239, -64, +75, +24, -47, +67, +76, -40, -176, -179, -231, -224, -40, +27, +0, -75, + +1620, +2181, +1603, +1392, +1074, +916, +849, +620, +322, +470, +694, +763, +907, +764, +43, -376, -76, +71, +101, -3, -39, +86, +110, +0, -148, -121, -113, -69, +18, +9, -117, -268, + +1298, +1691, +1267, +1399, +1307, +1124, +1131, +1104, +891, +667, +567, +575, +628, +507, +105, -108, +52, +24, -45, -25, -34, +55, +160, +131, -29, -57, -79, -54, -16, -156, -247, -286, + +1179, +1848, +1466, +1730, +1760, +1293, +1046, +857, +729, +698, +565, +381, +236, +320, +318, +91, +9, -97, -187, -79, +91, +171, +186, +225, +142, -75, -156, -189, -210, -232, -263, -201, + +1352, +2405, +2052, +1820, +1528, +1334, +1064, +583, +298, +292, +336, +420, +473, +384, +247, -41, -172, -129, -4, +7, +46, +224, +188, +178, +173, -32, -241, -326, -370, -251, -162, -160, + +1579, +2518, +2005, +1719, +1482, +1383, +1139, +573, +88, -86, +163, +548, +481, +335, +281, +88, +49, -30, -101, -73, +80, +110, +12, +172, +343, +170, -228, -430, -393, -298, -216, -120, + +1583, +2450, +1680, +1499, +1447, +1389, +1184, +570, +27, +164, +464, +283, +128, +199, +220, +325, +423, +123, -72, -74, -43, -22, -19, +72, +115, +277, +185, -229, -439, -410, -283, -162, + +1893, +2685, +1508, +1157, +986, +1135, +1120, +583, -124, +57, +765, +643, +287, -137, -232, +275, +511, +407, +350, +8, -96, +73, -79, -165, +36, +100, +98, +172, -6, -229, -385, -374, + +2209, +3190, +1517, +1044, +774, +938, +848, +161, -496, -290, +950, +973, +315, -37, -73, +18, +254, +388, +315, +238, +180, +91, -63, -33, -110, -192, -12, +129, +232, +155, -164, -407, + +2814, +3765, +1508, +1224, +774, +836, +645, -346, -1219, -800, +1084, +985, +184, +33, +8, +229, +466, +169, +87, +354, +189, +192, +160, -56, +4, -65, -184, -15, +177, +366, +142, -203, + +3495, +4412, +1460, +1383, +688, +753, +615, -665, -1708, -1197, +1222, +875, -213, -223, -72, +363, +610, +259, +273, +267, +37, +270, +44, +9, +100, -45, -90, +149, +122, +13, +149, +90, + +4347, +4935, +1271, +1660, +643, +828, +646, -1007, -2278, -1449, +1567, +759, -633, -516, -277, +238, +622, +239, +355, +523, +20, +141, +46, -6, +111, -2, +46, +213, +21, +33, +1, +6, + +5621, +5545, +799, +2031, +504, +892, +652, -1492, -2860, -1584, +2032, +530, -1030, -782, -469, +89, +432, +59, +340, +429, -61, +279, +83, -74, +47, +39, -51, +241, +56, -19, +59, -78, + +6893, +6162, +149, +2382, +396, +828, +623, -2048, -3200, -1408, +2392, +211, -1344, -961, -526, -16, +350, -90, +203, +396, -312, +253, +114, +45, -53, -188, -37, +217, +87, +120, +108, -66, + +8235, +7080, -573, +2693, +417, +618, +659, -2697, -3569, -1230, +2683, +76, -1575, -1280, -539, +24, +87, -57, +104, +215, -351, +233, +5, -119, -156, -194, -147, +124, +129, +137, +322, +117, + +9244, +7992, -1030, +2743, +479, +517, +696, -3209, -3857, -1043, +2739, -57, -1623, -1427, -588, -20, +90, -120, +74, +343, -449, +31, -200, -78, -273, -310, -78, +136, +134, +157, +303, -20, + +10028, +9088, -1078, +2631, +294, +324, +855, -3729, -3984, -1086, +2220, +48, -1346, -1774, -793, -139, +148, +326, -185, +119, -427, -45, -395, -273, -382, -360, -77, +135, +222, +28, +223, -85, + +10294, +10035, -677, +2629, +250, -196, +1099, -3767, -3909, -1145, +1327, -1, -804, -1656, -1142, -169, +106, +562, -120, -57, -462, -169, -331, -270, -431, -351, -156, -128, +239, +131, +252, -134, + +10483, +10682, -44, +2812, +332, -824, +879, -3596, -3635, -1021, +145, -213, -350, -1319, -899, -635, -133, +919, -37, -375, -472, -69, -227, -286, -527, -354, -246, -281, +155, +54, +190, -76, + +10698, +11090, +572, +3361, +554, -1371, +356, -3757, -3360, -322, -956, -1204, +285, -664, -624, -896, -670, +916, +86, -272, -203, -223, -395, -193, -602, -435, -271, -578, +42, +87, +178, -136, + +11106, +11176, +704, +4050, +883, -1630, -180, -4140, -2927, +390, -1871, -1878, +528, -231, -70, -1098, -1213, +889, +383, -352, -139, -56, -382, -365, -792, -502, -300, -681, -116, +59, +212, -78, + +12036, +10896, +310, +5032, +1033, -1870, -823, -4447, -2503, +1349, -2741, -3214, +855, +29, +682, -1055, -1808, +920, +555, -599, -93, +53, -545, -351, -1135, -651, -258, -802, -256, +44, +72, -285, + +13249, +10533, -420, +6055, +876, -1900, -821, -5027, -1957, +2680, -3299, -4856, +928, +484, +1323, -695, -2251, +831, +740, -767, -47, +126, -881, -350, -1161, -698, -223, -889, -359, +46, +17, -320, + +14864, +10460, -1804, +6568, +665, -1731, -635, -5767, -1405, +4093, -3512, -6402, +622, +675, +1688, -26, -2440, +393, +956, -897, -408, +254, -945, -393, -1446, -932, -12, -855, -629, +79, +67, -544, + +16627, +11397, -3842, +5964, +612, -1624, +440, -5965, -2042, +5011, -2485, -7307, -214, +766, +2141, +296, -2808, +260, +1140, -1052, -587, +505, -1093, -517, -1488, -1064, +12, -788, -651, -39, +118, -479, + +18518, +12633, -6334, +4990, +229, -1244, +2367, -6506, -3133, +5859, -1129, -7799, -1129, +600, +2173, +719, -3075, -318, +1316, -740, -910, +425, -1093, -394, -1508, -1432, +145, -700, -804, -94, +327, -401, + +20973, +12619, -8500, +4951, -770, -461, +3392, -7134, -3315, +6719, +196, -8369, -2213, +3, +2743, +961, -3843, -722, +1691, -730, -1369, +644, -1082, -293, -1519, -1634, +52, -689, -686, +59, +271, -608, + +22297, +12836, -9690, +4807, -1655, +104, +4092, -7312, -3771, +7038, +1693, -8910, -3012, -482, +2558, +1188, -3919, -1129, +1548, -693, -1611, +794, -1184, -115, -1465, -1976, +34, -436, -598, -24, +171, -683, + +23980, +12855, -10608, +4407, -2867, +1228, +4914, -7539, -4560, +7253, +3208, -8777, -3558, -1999, +2512, +1964, -3980, -1552, +1290, -765, -1611, +896, -1300, -1, -1603, -2008, +250, -237, -601, -60, +99, -743, + +24531, +13684, -11034, +3704, -3405, +1665, +5463, -7291, -5568, +6806, +4893, -8341, -4325, -3233, +2310, +2880, -3885, -2013, +1022, -727, -1606, +925, -1552, -68, -1433, -1949, +261, -130, -552, -62, +43, -848, + +25399, +13806, -10659, +3086, -4032, +2086, +5508, -6663, -6694, +6473, +6232, -7551, -4944, -4555, +2202, +3628, -3339, -2592, +933, -785, -1566, +810, -1901, +111, -1220, -1934, +196, +16, -580, +86, -113, -983, + +25699, +14205, -10203, +2771, -4453, +2044, +5466, -6220, -7611, +5940, +7067, -6399, -5381, -5665, +2085, +3997, -2469, -3078, +674, -608, -1758, +594, -1930, +265, -1252, -1733, -62, +13, -409, -15, -218, -1005, + +25576, +14678, -9511, +2627, -4889, +1979, +5231, -5940, -8313, +5036, +7731, -5018, -5437, -6902, +1757, +4371, -1482, -3465, +202, -277, -2109, +514, -1803, +302, -1201, -1716, -327, +65, -365, -277, -95, -1022, + +24917, +15555, -8325, +2832, -5406, +1692, +5071, -5894, -8820, +3797, +8250, -3317, -4558, -8452, +986, +4981, -445, -3381, -624, +98, -2239, +474, -1567, +517, -1341, -1880, -275, -194, -234, -524, +73, -946, + +24560, +15279, -6686, +3008, -5680, +1683, +4433, -5659, -9447, +3055, +7994, -2069, -3264, -9450, +188, +5223, +139, -3059, -1138, +123, -1936, +284, -1347, +532, -1421, -1864, -486, -372, -126, -624, +111, -613, + +23630, +15485, -4781, +2918, -5523, +1209, +3879, -4787, -10506, +1989, +7668, -1020, -1165, -10262, -1408, +5686, +432, -2423, -1223, -173, -1294, +57, -1598, +885, -1360, -2222, -434, -735, -7, -301, +148, -390, + +22705, +15510, -3489, +2520, -4580, +974, +2845, -3997, -11138, +1148, +7254, -749, +544, -10123, -3273, +5720, +656, -1873, -901, -539, -1078, +82, -1698, +797, -1433, -2392, -307, -961, +186, -54, +102, -179, + +21833, +14435, -1480, +2989, -4502, +876, +1865, -3114, -11297, -386, +7023, -399, +2038, -9446, -5658, +5465, +1168, -1290, -470, -782, -783, -20, -1877, +659, -1411, -2696, -156, -783, +130, +317, +217, -316, + +20537, +13992, -708, +4279, -4744, +442, +1972, -3237, -10625, -1985, +6923, -199, +2505, -7991, -7936, +4778, +2128, -1048, -448, -664, -657, +84, -2053, -179, -858, -2526, -357, -737, +238, +571, -51, -298, + +19638, +14025, -1030, +4778, -3659, -452, +2274, -3224, -9891, -2808, +7103, -662, +1734, -5223, -9487, +3226, +2912, -583, -44, -906, -673, +388, -2239, -882, -152, -2483, -417, -219, -101, +496, +27, -274, + +19049, +13570, -1555, +5415, -2800, -1809, +2085, -2243, -8328, -3763, +6265, -489, +380, -2622, -9535, +545, +3560, -254, +273, -392, -940, -193, -2156, -847, +103, -2093, -472, -40, -391, +519, -11, -393, + +18168, +13590, -2249, +5443, -1644, -1455, +603, -2301, -5416, -4970, +5891, +62, -1742, -291, -8568, -1959, +3759, +29, -30, +506, -899, -1149, -1711, -913, +543, -1423, -1173, +54, -259, +333, +11, -312, + +17035, +12827, -2281, +5894, -726, -1489, +185, -2933, -3444, -4639, +4541, +1190, -2977, +751, -6689, -4331, +3534, +367, -666, +1029, -430, -1560, -1739, -617, +856, -909, -1806, +43, +2, +135, +104, -229, + +16109, +11603, -1857, +6452, -517, -1810, +245, -2043, -3755, -4481, +4547, +1368, -3096, +727, -4933, -5160, +2492, +733, -1012, +720, -307, -1028, -1535, -868, +957, -652, -2015, +138, +117, -22, +249, -321, + +14557, +10522, -1242, +6803, -315, -2135, +723, -1118, -3548, -5279, +4014, +2629, -3572, +779, -3115, -5769, +2018, +890, -1739, +290, -311, -714, -642, -1091, +163, -204, -1599, +276, +13, -124, +387, -488, + +12812, +9467, -224, +7139, -314, -2365, +1207, -230, -3341, -5355, +2557, +2879, -2315, +419, -2362, -5322, +1454, +982, -1883, -47, -628, -728, -93, -958, -294, -130, -1142, +362, +163, -228, +155, -376, + +13067, +8369, -144, +8730, -2405, -3459, +1450, -1502, -5332, -4279, +6473, +1714, -1900, +3709, -1903, -4707, +1918, +120, -2550, -1093, -1848, -621, -724, -1598, -147, -744, -877, +540, -151, -509, +318, -28, + +10904, +8241, +866, +7747, -891, -4073, +130, -1350, -3923, -2891, +4427, +2115, -885, +2373, -1299, -4343, +153, +77, -1658, -317, -1588, -605, +53, -1825, -85, -335, -1528, -11, -42, -273, +59, -76, + +9279, +7452, +1520, +7064, -405, -3081, +178, -1385, -2926, -2332, +3123, +1898, -776, +1781, -925, -3718, -102, -120, -1233, -82, -1199, -290, +2, -1550, -49, -380, -1428, -264, -245, -270, +11, -162, + +7668, +6712, +2160, +6267, +54, -2125, +134, -1110, -2049, -2036, +2189, +1460, -699, +1339, -688, -3011, -497, -119, -970, -142, -497, +186, +37, -1292, -184, -526, -1267, -503, -546, -437, +10, -9, + +6368, +6134, +2492, +5439, +623, -1515, +73, -449, -1505, -1848, +1544, +1044, -644, +955, -348, -2562, -737, -6, -786, +148, +175, +380, -63, -1068, -366, -637, -1119, -714, -616, -443, -44, +1, + +5309, +5691, +2463, +4700, +1132, -1190, +301, +59, -1194, -1566, +901, +654, -559, +719, -197, -2168, -766, +93, -248, +496, +263, +194, -53, -903, -530, -692, -1037, -585, -576, -463, -126, -99, + +4671, +5240, +2273, +4089, +1224, -820, +599, +183, -902, -1333, +289, +350, -412, +640, -190, -1832, -504, +307, +145, +562, +47, +10, -140, -891, -579, -467, -751, -658, -629, -412, -121, -71, + +4304, +4612, +2145, +3630, +1141, -235, +799, +247, -609, -1181, -104, +233, -152, +634, +32, -1399, -325, +524, +389, +368, -139, -41, -258, -648, -199, -313, -764, -659, -480, -282, -35, +38, + +3883, +4121, +1999, +3085, +1218, +245, +812, +308, -391, -1122, -309, +165, +293, +913, +46, -1198, -224, +714, +439, +55, -298, +56, +12, -400, -192, -282, -674, -589, -276, -72, +113, +77, + +3262, +3880, +1810, +2399, +1483, +674, +763, +273, -288, -1047, -181, +700, +489, +675, +71, -953, -158, +742, +296, -120, -45, +156, +92, -270, -319, -271, -421, -326, -57, +99, -64, -314, + +2385, +3308, +1933, +2191, +1681, +725, +640, +373, +136, -286, -143, +637, +683, +410, +103, -565, -257, +619, +421, -40, +28, +179, +55, -233, -135, -54, -204, -72, -29, -217, -320, -330, + +1874, +3072, +1941, +1419, +1419, +1279, +891, +484, +398, +297, +230, +463, +469, +136, +85, -228, -107, +538, +410, +40, -27, +98, +145, +77, +20, +54, +21, -272, -370, -309, -248, -206, + +1591, +2376, +1629, +1368, +1569, +1437, +1231, +1006, +583, +432, +297, +204, +299, +145, -140, +13, +312, +339, +220, +17, +14, +285, +382, +203, +101, -101, -334, -332, -302, -287, -184, -195, + +1470, +1787, +1502, +1987, +1911, +1545, +1043, +878, +865, +431, +197, +86, +12, +101, +92, +101, +251, +178, +190, +346, +300, +250, +251, +133, -107, -287, -400, -336, -238, -260, -239, -257, + +1914, +2455, +1662, +1958, +1844, +1522, +942, +380, +248, +262, +332, +128, +22, +126, +219, +6, -12, +304, +516, +586, +402, +88, -170, -256, -295, -306, -261, -267, -279, -273, -326, -327, + +1650, +2454, +1992, +2081, +1838, +1445, +722, +274, +244, +203, +344, +372, +259, +83, -81, -61, +209, +336, +515, +666, +466, +145, -229, -453, -374, -308, -238, -216, -280, -231, -312, -373, + +1972, +2726, +1615, +1875, +1444, +1065, +882, +237, +52, +429, +512, +299, +333, -155, -232, +94, +178, +234, +473, +659, +391, +136, -262, -514, -398, -381, -424, -222, -224, -324, -266, -374, + +1944, +2569, +1405, +1599, +1309, +1157, +866, +373, +250, +451, +528, +453, +471, +1, +55, +191, +129, +155, +283, +436, +597, +713, +68, -320, -396, -509, -294, -216, -242, -220, -186, -273, + +2213, +2847, +1259, +1256, +996, +980, +849, +260, -32, +445, +818, +478, +247, +265, +193, +76, +464, +202, +102, +347, +222, +450, +618, +397, -308, -565, -442, -327, -186, -168, -163, -249, + +2697, +3456, +1227, +1213, +572, +517, +850, +102, -387, +192, +924, +490, +415, +251, -28, +334, +487, +237, +455, +306, -44, +361, +407, +349, +369, -96, -484, -382, -224, -207, -148, -176, + +3120, +3716, +1221, +1448, +755, +624, +603, -564, -1136, +136, +1257, +246, +285, +171, -38, +383, +232, +372, +711, +324, +99, +204, -9, +285, +321, +68, +177, -36, -413, -443, -150, -173, + +3790, +4330, +1096, +1569, +784, +588, +463, -1059, -1653, +106, +1501, +73, -126, -239, -105, +460, +435, +368, +402, +389, +91, +309, +250, +37, -30, -24, +199, +248, +66, -210, -381, -373, + +4622, +5180, +929, +1541, +623, +502, +584, -1498, -2233, +215, +1742, -187, -310, -505, -413, +362, +388, +344, +575, +292, -268, +436, +270, +95, +161, -323, -90, +279, +151, -2, +128, -96, + +5681, +5925, +575, +1587, +609, +492, +477, -2071, -2626, +569, +1878, -446, -437, -854, -523, +332, +170, +294, +523, +68, -219, +380, -38, +251, +114, -335, +23, -101, -23, +248, +375, +75, + +6767, +6666, +205, +1705, +662, +498, +302, -2825, -2958, +1150, +2042, -710, -533, -1232, -642, +377, +122, +237, +348, -95, -351, +388, -30, +5, -60, -377, -119, +125, +76, -40, +330, +247, + +7914, +7510, -124, +1761, +488, +420, +174, -3558, -3104, +1640, +2028, -832, -567, -1607, -766, +361, +95, +311, +212, -352, -461, +375, -113, -24, -351, -633, -128, +128, +9, -5, +457, +80, + +8830, +8494, -246, +1750, +304, +130, +113, -4143, -3165, +1945, +1825, -857, -549, -1777, -958, +191, +133, +387, +88, -480, -608, +386, -265, -246, -302, -723, -280, -84, -50, +74, +350, +96, + +9314, +9665, +71, +1635, +346, -372, -34, -4328, -3176, +2030, +1536, -817, -547, -1732, -1016, -133, +66, +591, +24, -506, -733, +116, -40, -327, -495, -730, -460, +25, -137, -166, +374, -5, + +9168, +10764, +1097, +1383, +468, -796, -470, -4274, -3169, +1769, +1273, -725, -691, -1625, -1027, -452, -36, +630, +83, -652, -832, +127, -43, -349, -695, -737, -514, -168, -181, -314, +338, +138, + +8846, +11350, +2560, +1552, +433, -953, -869, -4243, -3192, +1361, +998, -476, -837, -1626, -886, -800, -125, +635, -124, -228, -816, -255, -7, -394, -552, -761, -755, -414, -246, -133, +444, +75, + +8964, +11306, +3527, +2438, +253, -982, -961, -4230, -3082, +755, +442, -71, -869, -1742, -700, -1038, -454, +793, +25, -389, -604, -243, +7, -464, -738, -765, -951, -330, -59, -171, +251, +95, + +9403, +11033, +3733, +3695, +308, -1271, -992, -4163, -2722, +92, -735, +217, -696, -1699, -422, -1673, -402, +984, -229, -198, -530, -373, +28, -463, -956, -681, -906, -518, -289, -162, +497, +102, + +10184, +10713, +3388, +4822, +577, -1450, -980, -3974, -2096, -266, -2455, +170, -229, -2033, +139, -1657, -867, +1176, -218, -154, -435, -585, +36, -392, -1039, -506, -950, -753, -269, -164, +336, -63, + +11469, +10305, +2546, +5881, +499, -1455, -857, -3843, -1101, -509, -4401, -50, +59, -2342, +782, -1732, -924, +1406, -569, -258, -144, -530, -49, -395, -1238, -446, -756, -782, -536, -315, +337, -105, + +12812, +9997, +1333, +7068, +255, -1649, -308, -3676, +7, -196, -6478, -1003, +993, -2770, +1003, -1205, -1230, +1463, -713, -345, +195, -392, -236, -389, -1244, -431, -777, -964, -608, -183, +371, -471, + +14298, +10024, -465, +8212, +114, -2512, +382, -3674, +1378, +663, -8685, -2459, +1859, -2562, +871, -988, -1367, +1466, -684, -580, +254, -110, -241, -347, -1398, -758, -715, -816, -729, -361, +154, -579, + +15791, +10811, -2667, +8435, +624, -3271, +1069, -3748, +2502, +2079, -10027, -4329, +2301, -1901, +666, -578, -1480, +1296, -627, -770, +123, +401, -53, -652, -1473, -822, -551, -788, -1234, -414, +540, -655, + +17964, +11856, -5206, +7310, +1001, -3366, +1912, -4139, +2658, +3650, -10394, -6002, +1938, -1051, +777, -287, -1664, +896, -566, -1001, +87, +651, -41, -918, -1419, -920, -813, -755, -1256, -323, +672, -811, + +20009, +12521, -7253, +6282, +961, -3398, +2583, -4837, +2731, +5771, -10940, -7407, +1508, -472, +1186, -388, -1734, +332, -519, -1043, -71, +553, -29, -952, -1661, -1165, -989, -425, -1171, -377, +657, -839, + +22177, +13864, -9457, +4361, +273, -2050, +3806, -6178, +2512, +7329, -10722, -7725, +990, -611, +1552, -139, -1889, -63, -466, -1163, -297, +596, -38, -1172, -1902, -1306, -955, -76, -1070, -458, +771, -742, + +24345, +14808, -11064, +2917, -761, -281, +4365, -7368, +2909, +8263, -9604, -7789, +243, -1094, +2044, +574, -2131, -536, -396, -1094, -498, +632, -243, -1137, -1962, -1496, -848, +190, -940, -375, +1054, -832, + +26147, +15550, -12303, +1685, -1810, +967, +4288, -7960, +2974, +9042, -8220, -8190, -317, -1893, +2641, +1163, -2716, -789, -273, -1142, -847, +531, -446, -868, -2137, -1852, -734, +364, -774, -243, +1065, -1025, + +27659, +16152, -13062, +755, -2711, +1616, +4052, -7901, +2526, +9678, -6491, -8602, -661, -2830, +3049, +1720, -3198, -833, -91, -1450, -1161, +618, -586, -618, -2344, -2144, -611, +510, -566, -204, +872, -1008, + +28303, +17220, -13451, +40, -3448, +1563, +3863, -7612, +1462, +10219, -4267, -9081, -1078, -3763, +2992, +2435, -3478, -882, -13, -1844, -1413, +823, -875, -471, -2328, -2410, -559, +601, -471, -315, +732, -991, + +29181, +17405, -13114, -304, -4240, +1458, +3452, -7492, +539, +10765, -2404, -8991, -1702, -4595, +2982, +2817, -3292, -1057, +74, -2172, -1478, +872, -1165, -289, -2195, -2469, -548, +634, -663, -287, +578, -1042, + +29321, +17827, -12348, -557, -5122, +1071, +3363, -7877, -467, +11248, -887, -8472, -2373, -5291, +2598, +3058, -2743, -1532, +107, -2142, -1752, +699, -1290, -111, -1997, -2388, -740, +468, -816, -385, +487, -985, + +28805, +18575, -11075, -519, -6256, +621, +3883, -8757, -1416, +11447, +404, -7310, -2751, -5966, +1821, +3238, -1902, -1967, -52, -1838, -2084, +568, -1247, +63, -1562, -2577, -1051, +401, -1056, -280, +613, -1053, + +27710, +19425, -9278, -279, -7398, +89, +4632, -9740, -2488, +11491, +1418, -5692, -2452, -7072, +956, +3436, -1270, -1977, -465, -1644, -2124, +549, -1018, +267, -1537, -2600, -1365, +17, -689, -160, +642, -1022, + +26524, +19729, -7061, +31, -8340, -267, +5003, -10177, -3987, +11429, +2435, -4362, -1321, -8478, +66, +3718, -1132, -1735, -895, -1806, -1690, +886, -1190, +400, -1479, -2883, -1377, -121, -394, -59, +689, -900, + +24731, +20271, -4631, +239, -8724, -1229, +4844, -9185, -6220, +10730, +4243, -3815, +672, -9539, -1506, +4100, -1430, -1335, -947, -2166, -1162, +1047, -1494, +767, -1758, -3042, -837, -474, -154, +165, +571, -941, + +23477, +19815, -2244, +479, -9027, -1898, +3618, -7399, -7878, +9201, +6108, -3552, +2583, -9590, -3747, +4198, -1760, -1193, -323, -2539, -1400, +1397, -1635, +542, -1400, -3228, -438, -316, -265, +162, +498, -845, + +22603, +18971, -668, +1272, -8642, -2638, +2333, -6179, -8347, +7433, +7800, -2940, +3459, -8248, -6239, +4034, -1687, -1398, +219, -2550, -1401, +1181, -1707, +569, -817, -3297, +15, -296, -506, +401, +364, -924, + +21958, +18536, -765, +2387, -7488, -4223, +1716, -5274, -8935, +6110, +9409, -2450, +3540, -6393, -8448, +3758, -1179, -2277, +576, -2418, -1529, +1177, -1880, +420, +14, -3051, -213, -188, -381, +229, +231, -793, + +22176, +17185, -1463, +4151, -7417, -5322, +1894, -4670, -9301, +4733, +10404, -1838, +3744, -5092, -9471, +2688, -467, -2307, -46, -2508, -1717, +1645, -1714, +18, +585, -2841, -290, -132, -583, +271, +215, -863, + +21283, +15947, -1061, +5846, -8289, -5644, +2856, -4640, -8855, +2098, +10641, -385, +3529, -2820, -10460, +1131, +531, -2119, -590, -2947, -2184, +2054, -1090, -387, +1198, -3026, -869, +546, -650, +116, +60, -894, + +19683, +14620, -396, +7001, -7790, -5818, +2880, -3841, -8800, -338, +10153, +959, +3167, -585, -10098, -824, +1447, -2278, -872, -2755, -2996, +1653, -697, +272, +1462, -3849, -1195, +1382, -669, -246, -11, -701, + +19043, +12870, -2025, +8715, -5341, -5810, +2282, -4136, -8408, -1971, +10181, +1931, +1229, +1395, -8274, -2327, +1832, -1907, -1520, -2677, -3203, +831, -255, +370, +1503, -3747, -1696, +1786, -499, -464, -64, -480, + +17772, +11494, -1905, +9490, -4457, -5781, +2323, -3030, -7953, -3525, +9683, +2138, -957, +3838, -5603, -4565, +2549, -1532, -2419, -1808, -2980, +12, -610, -213, +1746, -2508, -2211, +1172, +20, -342, -24, -448, + +16172, +10332, -1197, +9288, -3999, -4949, +1874, -2282, -7098, -4475, +8985, +1667, -1887, +4717, -3907, -5051, +2520, -1200, -2844, -1330, -2611, -280, -1072, -1112, +1423, -1375, -1811, +550, -258, -177, +416, -403, + +14861, +9191, -894, +9322, -3451, -4203, +1793, -2119, -6076, -4508, +7671, +1778, -2043, +4285, -2907, -4648, +2360, -879, -2603, -1241, -2298, -406, -1008, -1513, +521, -984, -1055, +584, -582, -325, +664, -263, + +15154, +9134, -4908, +9650, +694, -5568, -98, -860, -5127, -4048, +7837, -470, -3638, +3508, -972, -2437, +3394, +805, -1417, +31, -1653, -577, -2362, -2979, -580, -1077, -1684, -192, -259, +22, +565, -429, + +12672, +9048, -2546, +8370, +349, -5006, +73, -1080, -4272, -3672, +5900, +444, -2326, +2893, -1066, -2332, +2479, +666, -949, -82, -1657, -457, -1794, -2452, -454, -1165, -1497, -205, -372, -240, +406, -163, + +10640, +8312, -1031, +7498, +500, -3857, +463, -1057, -3977, -3222, +4691, +603, -1571, +2325, -824, -2114, +1780, +754, -897, -192, -1342, -620, -1307, -1779, -405, -857, -1348, -343, -250, -417, +44, -237, + +8848, +7462, +273, +6812, +521, -2799, +1008, -1064, -3777, -2718, +3754, +821, -1252, +1806, -375, -2145, +1225, +906, -817, -265, -1155, -585, -1036, -1174, -21, -762, -1257, -311, -233, -510, -203, -397, + +7576, +6767, +783, +6094, +949, -1930, +961, -934, -3200, -2533, +3115, +1137, -1365, +1382, -102, -2040, +908, +789, -690, -334, -1018, -480, -555, -707, -43, -640, -1047, -255, -386, -684, -317, -445, + +6758, +6214, +818, +5337, +1627, -1135, +432, -710, -2305, -2322, +2540, +1251, -1296, +892, -62, -1566, +663, +551, -577, -337, -682, -77, -179, -659, -184, -409, -797, -413, -574, -679, -216, -506, + +5676, +5613, +1210, +4774, +1859, -559, +347, -565, -1759, -1969, +1960, +1004, -1099, +525, -53, -1205, +350, +369, -435, -6, -319, -23, -94, -656, -285, -373, -741, -563, -562, -531, -260, -514, + +4838, +5040, +1571, +4251, +1972, -105, +267, -310, -1227, -1573, +1267, +789, -798, +205, +14, -944, +147, +508, -9, +9, -221, +150, -128, -742, -391, -376, -652, -447, -470, -469, -201, -405, + +3971, +4513, +1934, +3945, +1836, +92, +581, -63, -938, -1357, +811, +579, -793, +202, +181, -781, +327, +624, -92, +15, +0, +147, -352, -881, -357, -191, -505, -444, -412, -282, -88, -284, + +3487, +4143, +1924, +3589, +1775, +195, +713, +196, -635, -1287, +387, +393, -687, +361, +568, -535, +98, +502, -1, +100, +31, -150, -611, -593, -111, -190, -456, -382, -216, -81, -181, -553, + +3301, +3728, +1795, +3379, +1523, +332, +960, +396, -543, -1253, +191, +235, -129, +880, +351, -652, +117, +445, +130, +39, -216, -238, -343, -293, -61, -146, -363, -182, -162, -325, -424, -636, + +3158, +3429, +1574, +3069, +1415, +510, +1197, +428, -494, -1109, +222, +719, +168, +681, +275, -640, +81, +477, +19, -67, -36, -85, -122, -162, +45, -5, -361, -356, -380, -419, -409, -428, + +2927, +3070, +1345, +2819, +1417, +712, +1293, +444, -262, -476, +280, +510, +400, +568, +118, -618, -112, +442, +241, +165, -34, -72, +77, +111, +94, -334, -675, -432, -303, -274, -306, -497, + +2770, +2981, +1085, +2080, +1492, +1281, +1415, +707, +136, -480, +296, +711, +259, +268, -123, -614, +243, +742, +216, +47, +81, +319, +285, -194, -408, -500, -506, -280, -185, -330, -423, -456, + +2145, +2721, +1165, +1872, +1627, +1355, +2019, +1188, +250, -296, -84, +490, +282, +67, -115, -178, +405, +756, +354, +121, +267, +315, -30, -468, -422, -383, -385, -212, -269, -357, -406, -427, + +1842, +2681, +1515, +1848, +2108, +1608, +1340, +1172, +512, -174, -238, -168, -13, +491, +474, +113, +382, +613, +415, +165, +91, -47, -298, -384, -349, -382, -402, -278, -199, -319, -431, -344, + +1494, +2675, +2068, +1863, +2114, +2048, +1472, +644, +14, -248, -149, +107, +179, +299, +556, +612, +502, +443, +238, -13, -145, -180, -250, -339, -297, -336, -446, -377, -225, -244, -239, -265, + +1925, +2822, +1707, +2248, +2162, +1532, +1572, +666, -432, -363, +210, +212, +263, +498, +470, +699, +813, +253, -219, -217, -141, -158, -176, -306, -384, -385, -364, -200, -281, -326, -188, -200, + +1895, +2793, +1934, +2045, +1846, +1354, +1196, +799, +59, -3, +248, +165, +197, +407, +651, +831, +698, +67, -242, -221, -251, -169, -144, -186, -354, -464, -369, -235, -233, -217, -227, -253, + +2070, +3085, +1525, +1328, +1530, +1219, +1048, +1205, +562, -2, +387, +198, +130, +544, +658, +484, +722, +457, -348, -457, -175, -78, -253, -223, -258, -370, -406, -378, -222, -139, -199, -290, + +2157, +2952, +1156, +902, +1034, +1185, +1499, +1126, +501, +624, +479, -49, +331, +597, +587, +621, +629, +548, +175, -291, -470, -235, -85, -52, -278, -368, -303, -369, -323, -238, -97, -173, + +2202, +2907, +1140, +947, +996, +914, +968, +769, +506, +769, +808, +471, +171, +297, +838, +683, +510, +567, +580, +137, -151, -326, -508, -27, -10, -284, -285, -236, -358, -292, -161, -179, + +2228, +3053, +1096, +862, +1274, +1155, +755, +13, -357, +880, +1376, +402, +198, +406, +514, +671, +748, +486, +514, +663, +288, -200, -289, -329, -436, -55, -28, -272, -239, -283, -290, -193, + +2611, +3293, +974, +955, +1269, +1230, +755, -497, -748, +618, +1056, +494, +365, +41, +465, +810, +420, +494, +736, +416, +453, +551, -173, -405, -427, -456, -169, -36, -153, -282, -273, -363, + +3071, +3880, +1049, +902, +1063, +1099, +721, -721, -1094, +709, +1109, -47, +104, +119, +412, +545, +413, +580, +520, +543, +532, +362, +329, +140, -499, -431, -240, -372, -190, -30, -169, -356, + +3643, +4399, +965, +972, +1042, +1109, +628, -1277, -1336, +964, +1149, -203, -182, -383, +345, +664, +317, +410, +437, +373, +394, +662, +276, +180, +133, -200, -383, -376, -281, -286, -117, -162, + +4308, +4895, +774, +1151, +1170, +1121, +455, -1795, -1513, +1267, +1131, -396, -245, -566, +93, +375, +376, +540, +286, +94, +297, +541, +252, +439, +34, +129, +201, -368, -356, -264, -280, -354, + +5087, +5494, +565, +1262, +1166, +1002, +246, -2296, -1418, +1649, +899, -695, -391, -688, +139, +229, +44, +521, +312, -3, +101, +250, +192, +280, +43, +280, +150, +88, +29, -357, -310, -372, + +5947, +6051, +327, +1497, +1239, +800, -127, -2807, -1134, +2147, +640, -918, -589, -888, +220, +107, +62, +477, +59, -49, +73, +198, -35, +79, -132, +175, +309, +137, +146, +162, -75, -593, + +6826, +6642, +77, +1786, +1321, +527, -620, -3298, -663, +2560, +320, -1067, -693, -1064, +226, -95, -6, +673, -51, -262, -29, +141, -44, -11, -506, +62, +205, +6, +401, +111, +23, -56, + +7619, +7443, -127, +1929, +1356, +155, -1099, -3708, -137, +2846, -83, -1160, -806, -1101, +269, -385, -138, +769, -105, -266, -156, -64, -45, -101, -607, -105, -82, +19, +101, +44, +338, -87, + +8308, +8291, -181, +1996, +1443, -217, -1606, -4093, +424, +3041, -446, -1225, -972, -1051, +348, -589, -310, +757, -179, -230, -151, -213, -150, -169, -724, -105, -113, -531, +38, +251, +144, +14, + +8643, +9273, +110, +1817, +1665, -587, -2048, -4412, +705, +3223, -686, -1244, -1233, -1013, +428, -696, -381, +630, -323, -238, -129, -251, -193, -373, -663, -295, -481, -278, -3, -42, +123, -69, + +8492, +10281, +986, +1409, +1924, -770, -2443, -4558, +552, +3340, -711, -1234, -1461, -1100, +472, -719, -429, +587, -437, -400, -100, -332, -135, -347, -1076, -422, -280, -435, -79, -23, +2, -146, + +8125, +10926, +2345, +1150, +1899, -669, -2844, -4563, +156, +3228, -595, -1223, -1573, -1303, +463, -750, -482, +579, -448, -544, -287, -237, -139, -775, -987, -370, -466, -463, -189, -20, +78, -37, + +7991, +11060, +3529, +1603, +1541, -533, -3046, -4622, -35, +2877, -564, -1180, -1626, -1431, +402, -852, -505, +583, -405, -609, -263, -542, -401, -426, -1162, -560, -503, -504, -197, +50, +140, -226, + +8113, +10987, +4130, +2562, +1381, -747, -2977, -4641, -186, +2488, -599, -1166, -1769, -1438, +351, -1006, -539, +563, -351, -314, -744, -723, -154, -612, -1117, -726, -662, -455, -57, +40, -92, -256, + +8541, +10760, +4178, +3497, +1698, -1029, -2982, -4222, -351, +1963, -668, -970, -2110, -1515, +400, -1246, -614, +645, -262, -603, -476, -696, -449, -571, -1094, -668, -849, -390, -123, -169, +68, -29, + +9463, +10347, +3864, +4361, +1905, -1015, -3375, -3543, -178, +968, -787, -513, -2341, -1829, +501, -1686, -325, +497, -681, +38, -559, -871, -367, -691, -1137, -482, -872, -677, -284, +7, +225, -241, + +10674, +9874, +3106, +5362, +1727, -766, -3609, -3015, +543, -431, -1222, +153, -2336, -2209, +365, -1836, -554, +242, -426, +197, -633, -802, -399, -696, -1174, -325, -1145, -803, -31, -108, -43, -199, + +11979, +9620, +1869, +6561, +1461, -835, -3245, -2641, +1610, -1691, -2279, +974, -2010, -2575, +505, -2638, -686, +670, -1065, +774, -478, -978, -319, -585, -1119, -498, -1130, -708, -19, -296, -40, -290, + +13201, +9744, +157, +7624, +1518, -1581, -2587, -2110, +2716, -2532, -3960, +1424, -1264, -2535, -109, -3054, -615, +404, -1230, +1095, -263, -1158, -337, -435, -1109, -466, -1189, -812, +84, -300, -171, -443, + +14767, +10074, -1860, +8018, +1956, -2430, -2103, -1372, +3819, -2797, -5967, +1234, +173, -2924, -421, -3162, -1160, +752, -1619, +1210, +95, -1349, -306, -444, -1114, -283, -1142, -1053, +276, -314, -302, -597, + +16745, +11407, -4630, +6674, +3018, -2190, -1545, -1323, +4470, -2021, -7769, +629, +1347, -2958, -574, -3466, -1241, +900, -1709, +1083, +268, -1132, -420, -544, -1164, -33, -940, -1138, +189, -205, -362, -753, + +18725, +12859, -7380, +4619, +4068, -1417, -1079, -1554, +4711, -1055, -8876, -550, +1948, -2355, -915, -3587, -1380, +839, -1610, +894, +413, -1080, -618, -661, -1073, +37, -840, -1169, +44, -15, -345, -1019, + +20617, +14278, -9830, +2481, +4741, -181, -623, -1858, +4753, +25, -9421, -1889, +2095, -1425, -1076, -3758, -1263, +565, -1542, +933, +391, -1113, -672, -722, -1015, -8, -886, -996, +4, +105, -420, -1228, + +22971, +14648, -11936, +1010, +4670, +1158, -431, -2361, +5156, +1040, -10169, -3060, +2153, -790, -797, -4032, -1000, +16, -1618, +1257, +163, -1228, -657, -703, -1282, -23, -913, -801, -89, +33, -392, -1315, + +25010, +15029, -13660, +283, +4193, +2237, -295, -3037, +6357, +2181, -11344, -3815, +2283, -582, +157, -4078, -1205, -374, -1568, +1582, -149, -1216, -484, -731, -1677, +102, -841, -808, -116, +31, -256, -1422, + +26769, +15204, -15115, +212, +3256, +2746, -305, -3981, +8274, +2753, -12585, -4021, +1747, -336, +1272, -4084, -1750, -584, -1463, +1491, -429, -1113, -280, -912, -2029, +54, -759, -856, -175, +86, -304, -1461, + +28266, +15342, -16203, +581, +2138, +2848, -458, -4840, +10385, +2925, -13189, -4103, +831, +88, +2199, -3878, -2349, -502, -1510, +1038, -429, -929, -129, -1132, -2297, -63, -611, -925, -177, +40, -335, -1317, + +29815, +15252, -16897, +1083, +956, +2943, -891, -5377, +12108, +2999, -12962, -4416, +24, +360, +3011, -3485, -2819, -229, -1736, +410, -242, -574, -195, -1310, -2449, -114, -453, -1000, -245, +121, -272, -1376, + +30704, +15809, -17499, +1266, -67, +2973, -1441, -5841, +12884, +3441, -12109, -5095, -636, +265, +3716, -2998, -3240, +129, -2153, -287, -24, -180, -492, -1366, -2616, -99, -271, -1307, -188, +298, -393, -1578, + +31618, +16165, -17687, +1138, -966, +3162, -2242, -6103, +13031, +3994, -10855, -5814, -1132, -114, +4440, -2576, -3472, +441, -2571, -925, +179, +66, -731, -1305, -2901, +118, -240, -1556, +32, +256, -573, -1665, + +32352, +16428, -17457, +790, -1672, +3290, -2962, -6399, +12571, +4836, -9536, -6362, -1498, -662, +5052, -2203, -3513, +550, -2849, -1412, +253, +166, -883, -1139, -3109, +166, -209, -1529, +21, +58, -646, -1719, + +32443, +17279, -16999, +233, -2175, +3032, -2969, -7266, +11609, +6215, -8405, -6559, -1896, -1197, +5401, -1763, -3376, +385, -2990, -1689, +180, +133, -974, -846, -3214, -83, +9, -1520, -177, -60, -770, -1566, + +31892, +18478, -16118, -275, -2655, +2351, -2206, -8781, +10331, +8020, -7513, -6312, -2325, -1753, +5424, -1170, -3047, -34, -3062, -1782, +143, -158, -877, -571, -3280, -291, -54, -1441, -346, -233, -674, -1187, + +30789, +19780, -14759, -548, -3198, +1460, -1025, -10799, +8894, +10055, -6732, -5809, -2497, -2429, +5133, -346, -2659, -573, -3168, -1582, +53, -566, -705, -356, -3272, -629, -135, -1412, -494, -112, -434, -955, + +29203, +20906, -12769, -646, -3914, +632, +128, -12834, +7097, +11981, -5813, -5212, -2227, -3391, +4539, +673, -2372, -1121, -3072, -1520, +50, -953, -749, -83, -3467, -767, -412, -1439, -216, +10, -266, -671, + +27369, +21887, -10304, -719, -4689, +134, +1044, -14260, +4701, +13487, -4266, -4865, -1191, -4653, +3796, +1775, -2279, -1199, -3034, -1527, +71, -1028, -1358, +221, -3301, -1300, -376, -1263, +67, +149, +70, -544, + +25668, +22491, -8130, -702, -4924, -592, +1193, -14383, +1825, +13879, -1753, -4990, +70, -5585, +2485, +3061, -2364, -1028, -2910, -1941, +216, -1133, -2116, +371, -3234, -1474, -105, -1358, +438, +510, +66, -745, + +24445, +22594, -6916, -408, -4078, -1908, +266, -13241, -891, +13193, +1079, -5162, +987, -5936, +931, +4120, -2150, -1025, -2529, -2729, -156, -699, -2958, -77, -2635, -1480, +97, -1388, +718, +673, -84, -802, + +24036, +21606, -6204, +627, -3020, -3027, -1363, -11604, -2945, +12413, +3083, -5038, +1938, -6484, +131, +4636, -1658, -795, -2484, -3507, -351, -682, -3613, +80, -2402, -1272, +354, -1476, +898, +717, -205, -856, + +23746, +20456, -5957, +1984, -1938, -4319, -2729, -9544, -5054, +11531, +5123, -5779, +3222, -6434, -1058, +5531, -1261, -866, -2359, -3656, -1163, -839, -3784, +272, -1846, -1591, +565, -1292, +952, +517, -310, -562, + +23960, +19174, -6448, +3094, -1039, -5368, -3542, -7116, -6317, +9363, +7378, -6843, +3456, -4600, -3042, +6646, -852, -1642, -1443, -3885, -1943, -945, -3873, +318, -958, -2243, +620, -863, +528, +698, -367, -469, + +23567, +18274, -6810, +4250, -385, -6084, -3975, -5591, -6825, +6911, +9455, -6771, +1918, -2142, -4373, +6456, +835, -2708, -1024, -3507, -2457, -992, -4100, +133, -369, -2407, +311, -628, +321, +831, -178, -597, + +23143, +16836, -6902, +5727, -531, -6291, -3459, -5161, -7193, +5338, +10494, -6386, +648, -1274, -4124, +6012, +1743, -2864, -1093, -2840, -2832, -626, -4269, -880, -83, -2116, +209, -691, +146, +839, -37, -502, + +22711, +15714, -7208, +6876, -1112, -6813, -1895, -4170, -8096, +3464, +11809, -6438, -833, +596, -4557, +5103, +2952, -2724, -1144, -2460, -2916, -73, -4033, -2509, -346, -1558, +340, -324, -568, +509, +520, -161, + +21883, +15259, -8430, +8064, -235, -8167, -638, -2887, -8285, +800, +12561, -5050, -2930, +2356, -4439, +2991, +4720, -2205, -1490, -1642, -3457, +613, -3421, -4138, -736, -1237, +241, +437, -924, -343, +1118, +203, + +21336, +14054, -8898, +8815, +778, -8299, -1119, -1073, -7651, -2227, +13016, -3460, -4273, +3243, -3776, +1237, +5044, -803, -1471, -1297, -3268, +457, -2964, -4426, -1137, -1555, +51, +1032, -730, -630, +878, +351, + +20364, +12658, -8776, +9749, +928, -8029, -658, -913, -7055, -3196, +11978, -2563, -4312, +3779, -3422, -39, +4857, -93, -856, -1070, -2919, +46, -2987, -3874, -1261, -1841, -597, +1113, -366, -282, +474, -132, + +19013, +11105, -7802, +10307, +543, -7199, -275, -1181, -6482, -3416, +10634, -2108, -4042, +4151, -2777, -1409, +4761, +291, -1107, -73, -2791, -368, -2750, -3871, -721, -1726, -1380, +656, -107, +32, +532, -418, + +17238, +9876, -6359, +10305, +398, -6315, -102, -1089, -5867, -3730, +9349, -1363, -3939, +4046, -1704, -2280, +4126, +804, -1450, +148, -1982, -710, -2585, -3457, -636, -1203, -1796, +107, -115, +106, +736, -435, + +16850, +7680, -7300, +12520, +2285, -8479, -1087, +427, -4800, -1828, +6635, -3369, -2358, +3423, -1655, -892, +2571, -327, -160, +642, -662, +1201, -1048, -1605, +229, -1235, -1428, -365, -1650, -1331, -434, -718, + +14445, +7248, -5479, +10890, +2224, -6676, -847, +20, -3992, -1849, +5544, -2552, -2301, +2914, -1338, -1107, +2267, -66, -274, +451, -432, +1011, -1109, -1445, +210, -1200, -1152, -150, -1229, -1064, -619, -638, + +12262, +7034, -3826, +9064, +2556, -4912, -1000, -85, -3259, -1912, +4712, -1765, -2260, +2378, -779, -1142, +1866, +240, -211, +297, -362, +843, -852, -1395, +26, -936, -987, +115, -841, -918, -540, -612, + +10302, +6772, -2608, +7425, +3047, -3580, -1144, +38, -2705, -1968, +3948, -1167, -2245, +1845, -376, -1032, +1522, +265, -101, +261, -453, +682, -692, -1289, -83, -615, -752, -59, -567, -670, -472, -618, + +8655, +6443, -1690, +6216, +3422, -2584, -975, +289, -2316, -1951, +3369, -755, -2184, +1494, -28, -828, +1147, +375, +103, +99, -381, +549, -584, -1004, +111, -444, -718, -65, -432, -490, -423, -480, + +7221, +6029, -1043, +5350, +3704, -1861, -720, +491, -2015, -1932, +2857, -505, -2070, +1231, +249, -749, +916, +588, -26, +2, -231, +492, -373, -773, +146, -331, -639, -153, -420, -446, -268, -366, + +6149, +5337, -522, +4890, +3705, -1298, -409, +653, -1896, -1811, +2394, -329, -1930, +1021, +457, -665, +862, +483, -128, +133, -8, +453, -352, -564, +224, -355, -685, -251, -418, -327, -123, -232, + +5347, +4865, -12, +4345, +3331, -784, +8, +681, -1713, -1654, +1950, -310, -1698, +1128, +488, -580, +778, +296, +168, +368, -71, +403, -167, -481, +0, -380, -642, -237, -238, -203, -161, -399, + +4513, +4458, +327, +3862, +3291, -212, +50, +538, -1286, -1648, +1413, -6, -1274, +809, +432, -246, +709, +464, +342, +239, -48, +380, -170, -546, -158, -340, -484, -110, -208, -423, -383, -436, + +3737, +4010, +796, +3404, +3194, +416, -10, +338, -902, -1429, +1024, +156, -1024, +609, +727, +264, +595, +355, +422, +205, -29, +258, -264, -566, -23, -135, -442, -273, -489, -465, -296, -300, + +3244, +3768, +1128, +2910, +3135, +692, -253, +385, -416, -1327, +523, +399, -524, +860, +1068, +205, +374, +460, +341, +111, -88, +108, -72, -266, -80, -420, -614, -364, -338, -321, -247, -281, + +2573, +3501, +1542, +2422, +3009, +997, -86, +399, -529, -1166, +615, +927, +3, +728, +933, +166, +369, +430, +133, +29, +88, +270, -37, -461, -485, -479, -438, -286, -266, -299, -341, -359, + +2231, +3444, +1513, +2040, +3101, +1062, -319, +337, -154, -486, +938, +903, +105, +773, +781, +97, +163, +295, +372, +236, +56, -55, -435, -564, -350, -311, -370, -314, -370, -380, -309, -324, + +2099, +3103, +1628, +2260, +2332, +675, +355, +998, +218, -292, +974, +821, +239, +834, +457, -122, +408, +649, +268, -133, -357, -207, -248, -398, -297, -330, -451, -420, -307, -346, -285, -262, + +2122, +2791, +1338, +2074, +2185, +1299, +1098, +1022, +96, -224, +1143, +1002, +34, +360, +626, +337, +351, +217, -313, -387, -92, +1, -292, -456, -393, -443, -464, -373, -291, -249, -256, -321, + +1707, +2474, +1550, +2358, +2684, +1380, +926, +1182, +372, +34, +972, +722, +127, +725, +656, -121, -188, -80, -126, -77, -58, -130, -419, -521, -423, -415, -422, -288, -194, -281, -292, -289, + +2009, +3271, +2261, +2063, +1937, +1369, +1101, +993, +457, +278, +709, +981, +479, -169, -163, -155, -17, +78, -53, -120, -289, -340, -416, -495, -424, -327, -303, -303, -181, -220, -289, -318, + +2008, +3310, +2283, +1883, +1850, +1562, +1336, +1209, +776, +362, +614, +893, +94, -536, -228, +27, +139, +104, -127, -295, -281, -260, -428, -460, -357, -327, -324, -261, -177, -196, -244, -322, + +1917, +2862, +1700, +1658, +1732, +1613, +1699, +1958, +1364, +660, +516, +154, +109, -111, -309, -59, +186, +33, -209, -177, -238, -291, -369, -419, -336, -324, -384, -275, -151, -205, -230, -271, + +2083, +2983, +1506, +1369, +1260, +1246, +1868, +2065, +1340, +757, +550, +543, +648, -21, -250, -120, -176, +2, -56, -272, -389, -249, -240, -367, -275, -212, -264, -298, -255, -207, -278, -316, + +2198, +2902, +1108, +1182, +1319, +951, +937, +1441, +1654, +1337, +1100, +824, +681, +876, +211, -700, -323, -124, -65, -79, -310, -308, -251, -253, -245, -200, -273, -191, -287, -316, -203, -334, + +2056, +2797, +1106, +1111, +1388, +1207, +805, +382, +604, +1281, +1542, +1132, +810, +896, +1118, +443, -493, -486, -254, -141, -40, -152, -378, -280, -153, -282, -256, -141, -244, -319, -313, -273, + +2227, +2815, +713, +806, +1269, +1147, +860, +283, +11, +688, +1122, +928, +1193, +1393, +1389, +1011, +515, +126, -365, -592, -318, -110, -213, -289, -293, -274, -243, -88, -185, -280, -240, -271, + +2487, +3077, +731, +1027, +1384, +982, +654, -128, +18, +996, +561, +73, +591, +932, +1479, +1270, +870, +925, +448, -201, -501, -563, -415, -115, -143, -320, -310, -120, -171, -247, -175, -287, + +2775, +3186, +631, +1392, +1798, +1197, +294, -934, -91, +1380, +530, -194, +56, +369, +981, +652, +864, +1272, +870, +557, +177, -277, -677, -549, -265, -205, -167, -195, -284, -238, -143, -268, + +3354, +3952, +622, +1159, +1616, +1212, +384, -1193, -171, +1340, +276, -317, +73, +202, +505, +358, +412, +812, +941, +759, +457, +303, +14, -361, -589, -473, -252, -41, -106, -338, -312, -210, + +3851, +4360, +508, +1396, +1995, +1083, -118, -1646, +204, +1680, -168, -602, -109, +183, +637, +36, +22, +528, +357, +402, +649, +527, +382, +246, -154, -411, -536, -224, -139, -252, -213, -373, + +4411, +4791, +385, +1660, +2324, +1023, -690, -2047, +660, +1766, -479, -607, -315, +44, +662, -70, -18, +284, +30, +175, +102, +352, +562, +305, +304, +207, -224, -238, -340, -387, -265, -275, + +5196, +5589, +252, +1519, +2294, +877, -1040, -2105, +1073, +1563, -889, -523, -328, -3, +615, -267, -54, +275, -150, -65, -69, +83, +148, +190, +385, +349, +230, +269, -184, -470, -345, -462, + +5718, +5975, +175, +2056, +2782, +433, -1979, -2126, +1813, +1397, -1262, -508, -449, +38, +582, -483, -40, +268, -347, -79, -259, -144, +146, -223, +11, +368, +235, +504, +304, -118, -274, -506, + +6315, +6714, +139, +2135, +3020, +109, -2674, -1982, +2425, +978, -1604, -368, -505, +111, +586, -693, -117, +249, -464, -85, -325, -245, +4, -438, -62, +108, +23, +446, +291, +123, +139, -256, + +6745, +7502, +262, +2112, +3265, -191, -3399, -1845, +3011, +575, -2029, -233, -551, +131, +609, -828, -184, +190, -609, -176, -413, -318, +53, -619, -305, +55, -89, +207, +130, -29, +147, +100, + +7135, +8455, +528, +1753, +3383, -342, -3912, -1715, +3302, +347, -2377, -280, -478, +73, +666, -864, -309, +173, -675, -305, -523, -417, -31, -619, -370, -108, -188, +168, -8, -183, -48, -243, + +7313, +9335, +990, +1537, +3442, -503, -4294, -1670, +3510, +231, -2617, -467, -433, +51, +676, -780, -520, +145, -610, -381, -642, -599, -117, -669, -413, -163, -232, +54, +96, -400, -473, -157, + +7366, +10104, +1617, +1432, +3413, -641, -4433, -1789, +3563, +295, -2857, -581, -471, -47, +733, -715, -694, +95, -548, -428, -666, -773, -215, -762, -547, -237, -183, +203, -336, -503, -328, -397, + +7627, +10884, +2189, +1075, +3085, -556, -4178, -2011, +3118, +500, -2883, -799, -373, -262, +585, -455, -843, -134, -419, -461, -781, -795, -264, -872, -798, -151, -218, -232, -138, -459, -588, -350, + +7805, +11222, +3062, +1025, +2511, +140, -3881, -2575, +2792, +742, -2671, -862, -572, -376, +526, -340, -707, -443, -595, -287, -600, -934, -448, -730, -617, -528, -615, +39, -258, -504, -448, -459, + +8363, +10906, +3309, +2010, +2235, +305, -3931, -2743, +2509, +616, -2212, -1029, -818, -300, +441, -402, -584, -720, -757, -88, -693, -1025, -498, -478, -772, -805, -578, -256, -196, -436, -534, -482, + +9029, +10207, +3227, +3604, +2126, +318, -3990, -2699, +2282, -66, -1506, -870, -1243, -147, +313, -594, -347, -843, -960, -75, -980, -749, -429, -936, -470, -770, -924, -178, -239, -505, -518, -435, + +9921, +9094, +2287, +6032, +2825, -665, -3976, -1942, +1634, -1240, -452, -499, -1858, -63, +175, -661, -141, -1007, -1221, -134, -966, -783, -874, -746, -300, -913, -822, -399, -257, -376, -363, -634, + +11207, +8923, +714, +7384, +3504, -1787, -3331, -478, +667, -3182, +480, +632, -2340, -174, -41, -734, +254, -1209, -1563, +237, -1495, -1119, -374, -1179, -176, -742, -854, -326, -296, -187, -407, -889, + +12500, +9128, -1225, +8120, +4706, -2957, -3096, +1429, +224, -5655, +633, +2334, -2476, -521, -246, -1021, +659, -1250, -1598, -102, -1942, -946, -536, -1243, -56, -809, -795, -9, -245, -516, -388, -591, + +13676, +9715, -3224, +8146, +6300, -3786, -3252, +3385, +497, -7984, -273, +4084, -1795, -1036, -439, -1428, +900, -738, -2169, -270, -1884, -1560, -244, -1157, -225, -702, -726, +327, -337, -781, -147, -433, + +15154, +10710, -5567, +6975, +8141, -3612, -4028, +4575, +1224, -9451, -1863, +5048, -504, -1304, -849, -1887, +1317, -802, -2679, +65, -2243, -1967, -192, -1025, -170, -751, -680, +394, -331, -789, -111, -452, + +16751, +11590, -7670, +5697, +9423, -3002, -4671, +5673, +1938, -10472, -3508, +5316, +1125, -1098, -1562, -2113, +1531, -1067, -2689, -22, -2225, -2260, -408, -719, -88, -730, -829, +416, -248, -657, -207, -430, + +19048, +11932, -9850, +4534, +10090, -1984, -5054, +6461, +2293, -11027, -4690, +4999, +2637, -594, -2197, -2457, +1788, -1314, -2837, +89, -2336, -2296, -497, -623, +34, -680, -1066, +461, -55, -678, -251, -446, + +21615, +12285, -12393, +3218, +10447, -513, -5263, +6448, +2499, -11072, -5490, +4213, +3638, +192, -2622, -3085, +2128, -1593, -3108, +258, -2535, -2078, -721, -584, +167, -802, -1230, +548, +77, -824, -300, -503, + +23814, +13115, -14900, +2298, +10402, +898, -5101, +6133, +3297, -10978, -6160, +3330, +4213, +1402, -2845, -3633, +2406, -1782, -3197, +506, -2620, -1975, -705, -585, +213, -896, -1169, +725, -33, -930, -208, -501, + +26386, +12827, -16969, +2278, +9703, +1341, -4735, +5967, +4345, -11169, -7039, +2751, +4328, +2440, -3053, -3808, +2333, -2300, -2829, +717, -2947, -2030, -466, -759, +120, -952, -975, +828, -420, -898, -159, -497, + +27944, +13492, -18792, +2616, +8679, +1183, -4343, +5611, +6445, -11341, -8610, +2448, +4449, +2910, -2638, -3722, +1665, -2447, -2294, +737, -3191, -2075, -286, -1008, +16, -802, -857, +864, -755, -842, -70, -604, + +29685, +13246, -19821, +3525, +7289, +438, -4363, +5714, +8745, -11618, -10243, +2318, +4494, +2830, -1737, -3623, +798, -2252, -1923, +676, -3494, -1846, -281, -1396, -10, -574, -760, +810, -964, -876, +89, -884, + +30876, +13227, -20231, +4464, +5889, -395, -4997, +6035, +11190, -11731, -11571, +2002, +4359, +2564, -389, -3809, +115, -1644, -2030, +671, -3672, -1473, -429, -1750, -81, -276, -628, +609, -946, -950, +127, -1298, + +31278, +13828, -20217, +5005, +4867, -1003, -6198, +6112, +13378, -11330, -12204, +1134, +4093, +2243, +984, -3911, -507, -785, -2404, +550, -3517, -1127, -734, -1985, -167, -11, -527, +311, -626, -1201, -142, -1426, + +31763, +14606, -20213, +4922, +4300, -1334, -7821, +5934, +15019, -10488, -12296, -244, +3894, +2145, +1899, -3668, -996, -217, -2645, +278, -3186, -960, -1050, -2098, -246, +125, -509, +271, -479, -1663, -297, -1411, + +32059, +15063, -19624, +4534, +3996, -1550, -9300, +5401, +15706, -8935, -11963, -1825, +3576, +2337, +2148, -3207, -1061, -200, -2557, +23, -2815, -964, -1297, -2112, -372, +106, -371, +213, -866, -1642, -555, -1453, + +31594, +16148, -18709, +3873, +3953, -1965, -10020, +3854, +16002, -6585, -11621, -3362, +3109, +2803, +1915, -2572, -712, -591, -2348, +118, -2607, -1103, -1413, -2224, -397, +185, -559, -36, -1026, -1584, -771, -1168, + +30561, +17638, -17451, +3091, +3826, -2310, -9959, +1289, +16030, -3803, -11272, -4403, +2328, +3336, +1431, -1843, -11, -1291, -1874, +345, -2491, -1351, -1564, -2198, -272, -81, -1106, +216, -1299, -1439, -527, -1224, + +29054, +19377, -15810, +1898, +3337, -2040, -9228, -2236, +15567, -882, -10760, -4753, +1128, +3442, +1193, -1335, +949, -1929, -1501, +721, -2539, -1679, -1649, -1976, -762, -420, -1351, +363, -1271, -1184, -487, -1395, + +27602, +19984, -13330, +1384, +2220, -1553, -8967, -5440, +14956, +1794, -10257, -4554, -131, +2570, +2016, -1408, +1844, -1852, -1851, +1473, -2793, -1890, -1630, -2378, -1270, -515, -1540, +663, -952, -1427, -261, -1350, + +25630, +20290, -10249, +1324, +1107, -1114, -8918, -8485, +14115, +4665, -9857, -4277, -756, +606, +3451, -1301, +1865, -565, -2709, +1877, -2367, -2459, -1746, -2677, -1920, -340, -1413, +665, -508, -1675, -66, -1466, + +23903, +20683, -7286, +510, -377, -53, -7840, -11202, +11907, +7374, -9146, -4087, -105, -1982, +4052, -56, +1078, +860, -2851, +1241, -1622, -2794, -2100, -2674, -2293, -321, -1039, +386, -96, -1780, -277, -1191, + +22823, +20723, -6390, +1262, +38, -1708, -6903, -11540, +8654, +9407, -7731, -4726, +1287, -3835, +3356, +1929, +303, +1232, -2157, +96, -909, -2590, -2708, -1999, -2763, -486, -647, +74, -134, -1612, -437, -1074, + +23286, +19705, -6984, +2708, +768, -3874, -6807, -9892, +5577, +9767, -5818, -5461, +2601, -4494, +2384, +2776, +168, +931, -1602, -159, -1262, -1698, -2885, -1466, -2698, -1301, -450, -206, -5, -1620, -620, -969, + +23121, +19255, -7571, +3875, +1563, -5614, -6214, -8564, +2641, +9601, -3111, -6567, +3743, -4320, +945, +3692, -1043, +1590, -1282, -840, -479, -978, -2698, -1087, -2537, -2252, -520, -532, +376, -1513, -1259, -735, + +23895, +17231, -7926, +5603, +1022, -6360, -5559, -7729, +248, +9659, -1110, -7381, +4032, -2981, -753, +3497, -675, +212, -226, -663, -11, -138, -2841, -1009, -2052, -2616, -1508, -419, +202, -1307, -1387, -864, + +24342, +16471, -9991, +7124, +2357, -8386, -5329, -5315, -1440, +7468, +1850, -7622, +3025, -1191, -1868, +2925, -544, -837, +462, +724, -295, +355, -2494, -1379, -1397, -2680, -2066, -975, -223, -1077, -799, -950, + +24670, +15431, -12280, +9290, +3619, -10800, -4710, -2736, -2869, +4919, +4375, -7414, +1744, +298, -2787, +2517, -329, -1185, +786, +1117, +234, +534, -2350, -1334, -1274, -2503, -2002, -1594, -1255, -755, -99, -851, + +25053, +13472, -13783, +11903, +3737, -12350, -3755, -973, -3561, +2410, +5792, -6487, +903, +639, -3500, +2947, +120, -1823, +1427, +635, +328, +1654, -2795, -1081, -1079, -2818, -1321, -1807, -2368, -781, +236, -570, + +25116, +10992, -14060, +14345, +2919, -12891, -2578, +298, -4831, +849, +7344, -6355, -113, +1687, -3785, +2243, +1525, -1852, +673, +891, +28, +1939, -1939, -1636, -642, -2710, -1531, -1027, -2946, -1438, +260, -246, + +23985, +9052, -12782, +15373, +1674, -11878, -1468, -66, -5434, +491, +7676, -6469, -622, +2840, -3942, +1270, +2660, -1561, +29, +815, -200, +1925, -1493, -1644, -301, -2510, -1767, -674, -2584, -1874, -316, -165, + +21931, +7984, -10773, +14942, +1323, -10330, -1496, -41, -5153, -560, +7563, -5510, -1367, +3202, -3067, +472, +2598, -1083, +280, +328, -550, +2171, -1750, -1359, +265, -2505, -1617, -565, -2257, -1696, -689, -545, + +19430, +7714, -9051, +13883, +1898, -9550, -1479, +550, -5119, -1546, +7412, -4342, -2191, +3447, -2123, -382, +2504, -635, +149, +475, -754, +1639, -1244, -1582, +373, -1789, -1679, -351, -2065, -1520, -554, -754, + +15748, +5880, -5425, +14058, +1054, -9150, +6, +395, -3696, +26, +2379, -3599, +1707, +2155, -2493, -381, +1177, -628, -908, +221, -185, +13, -490, +744, +822, +168, +287, -448, -1045, -444, -892, -1472, + +13423, +5793, -3949, +12100, +1504, -7414, -200, +63, -3202, +36, +2192, -2942, +1203, +1913, -1964, -650, +802, -427, -791, -12, -102, +329, -386, +362, +832, +203, -6, -415, -837, -549, -728, -965, + +11547, +5785, -2873, +10302, +2118, -6063, -463, +55, -2706, -44, +2080, -2250, +641, +1766, -1389, -907, +655, -241, -693, -30, +34, +406, -343, +364, +574, +40, +171, -246, -795, -541, -534, -664, + +9992, +5645, -2205, +8952, +2516, -5038, -463, +97, -2247, -98, +1995, -1860, +247, +1695, -1144, -964, +569, -79, -605, +22, +220, +235, -242, +317, +304, +54, +320, -69, -720, -432, -411, -602, + +8782, +5267, -1688, +7925, +2586, -4032, -444, +186, -1797, -191, +1866, -1605, +27, +1498, -942, -933, +555, +32, -524, +199, +141, +118, -129, +149, +324, +142, +325, +78, -560, -385, -344, -545, + +7729, +4882, -1177, +6873, +2650, -3039, -407, +340, -1509, -165, +1693, -1465, -61, +1352, -781, -864, +627, +111, -305, +152, +24, +234, -129, +182, +391, +215, +338, +94, -398, -277, -266, -463, + +6682, +4405, -731, +6123, +2845, -2298, -387, +459, -1188, -176, +1393, -1251, -73, +1145, -660, -560, +620, +101, -161, +95, +165, +308, -117, +224, +453, +233, +340, +124, -276, -83, -284, -652, + +5690, +4114, -370, +5337, +2959, -1597, -302, +540, -969, -272, +1211, -1020, -123, +962, -388, -419, +496, +293, -68, +198, +277, +243, -1, +258, +446, +244, +316, +224, -197, -287, -538, -753, + +4886, +3783, -77, +4739, +3009, -1004, -171, +567, -808, -296, +1071, -732, -150, +762, -143, -243, +583, +495, +70, +295, +285, +282, +109, +300, +419, +303, +318, -41, -410, -429, -543, -696, + +4226, +3500, +214, +4230, +2888, -619, +78, +571, -807, -209, +1096, -674, -362, +872, +202, -45, +765, +519, +142, +420, +299, +326, +177, +298, +271, +19, +43, -216, -432, -470, -647, -770, + +3932, +3487, +332, +3583, +2646, -337, +285, +627, -784, -249, +992, -484, -225, +1185, +515, -8, +833, +683, +354, +372, +256, +357, +26, -114, -52, -13, -48, -275, -631, -669, -560, -678, + +3417, +3033, +572, +3583, +2497, -132, +512, +448, -821, -41, +1094, -215, +63, +1208, +613, +421, +1026, +661, +269, +268, +157, -77, -316, -230, -50, -15, -270, -450, -631, -506, -489, -682, + +3181, +2995, +715, +3281, +2345, -67, +347, +573, -324, +109, +1136, +26, +360, +1541, +983, +492, +841, +521, -21, -138, -249, -144, -314, -277, -62, -239, -335, -379, -509, -456, -497, -624, + +2727, +2772, +1072, +2985, +1995, +392, +618, +698, +14, +104, +1230, +616, +773, +1489, +881, +385, +451, -79, -396, -153, -251, -293, -476, -335, -58, -202, -314, -426, -485, -422, -544, -580, + +2494, +2557, +1043, +2809, +2364, +870, +612, +794, +496, +543, +1308, +960, +905, +1098, +463, -159, -22, -97, -245, -365, -543, -373, -259, -109, -161, -351, -340, -303, -434, -540, -495, -424, + +2244, +2930, +1654, +2496, +2296, +1063, +990, +1335, +682, +721, +1328, +513, +346, +642, +45, -321, -153, -280, -469, -425, -401, -290, -203, -148, -250, -401, -344, -391, -436, -433, -426, -380, + +2037, +3030, +1906, +2584, +3062, +1893, +990, +1134, +771, +385, +555, +134, +140, +441, -13, -448, -353, -397, -487, -345, -327, -238, -229, -306, -339, -347, -307, -358, -440, -470, -365, -304, + +2260, +3620, +2531, +2997, +2841, +1693, +1371, +1050, +54, -313, +437, +310, -186, +172, -15, -693, -347, -145, -477, -380, -271, -292, -232, -289, -368, -327, -359, -335, -337, -420, -362, -300, + +2676, +4646, +3139, +2421, +2169, +1461, +1102, +750, +196, +85, +103, -264, -85, +79, -270, -444, -278, -319, -366, -267, -356, -287, -310, -325, -320, -352, -353, -348, -336, -368, -283, -304, + +2949, +4690, +2841, +1992, +1689, +1410, +1437, +860, +277, +660, +273, -352, -345, -179, +121, -193, -595, -313, -69, -302, -301, -297, -388, -283, -359, -329, -293, -304, -317, -316, -248, -264, + +2663, +4197, +2446, +1659, +1599, +1195, +1150, +1390, +834, +702, +922, +74, -262, -12, -178, -353, -146, -141, -372, -189, -146, -406, -452, -309, -320, -299, -251, -248, -234, -286, -278, -279, + +2398, +3447, +2003, +1730, +1358, +984, +1031, +668, +683, +1466, +1326, +833, +547, +62, +124, -145, -512, -263, -44, -260, -496, -309, -241, -380, -321, -210, -197, -195, -288, -327, -348, -283, + +1987, +2518, +1256, +1700, +1770, +1374, +486, -161, +666, +1239, +1117, +1441, +1412, +1138, +952, +102, -154, -108, -471, -390, -130, -296, -423, -224, -149, -219, -273, -144, -187, -306, -316, -312, + +2277, +2839, +857, +1089, +1531, +1252, +447, -170, +485, +946, +625, +786, +1274, +1596, +1572, +803, +425, +213, -154, -308, -514, -316, -104, -287, -376, -112, -81, -229, -298, -346, -243, -269, + +2475, +3091, +1057, +1202, +1523, +1181, +155, -419, +779, +1083, +35, +243, +607, +800, +1330, +1039, +902, +962, +366, -99, -203, -378, -433, -305, -177, -196, -314, -134, -130, -427, -342, -186, + +2867, +3436, +954, +1406, +1896, +1116, -228, -668, +1005, +1052, -200, +160, +322, +441, +627, +249, +723, +1109, +691, +570, +250, -239, -146, -317, -437, -152, -136, -255, -367, -288, -235, -306, + +3223, +4037, +1059, +1327, +1971, +1123, -496, -724, +1262, +822, -504, +196, +267, +346, +542, -168, +79, +604, +516, +608, +511, +379, +188, -138, -157, -106, -291, -239, -240, -438, -390, -237, + +3604, +4513, +1093, +1460, +2232, +986, -1011, -692, +1601, +582, -689, +154, +137, +264, +549, -231, -112, +308, -5, +126, +288, +386, +454, +334, +190, +65, -9, -169, -440, -448, -309, -360, + +4214, +5204, +1001, +1333, +2363, +811, -1317, -468, +1657, +218, -774, +195, +54, +193, +477, -310, -143, +220, -205, -91, -167, -47, +273, +245, +485, +588, +199, -41, -178, -454, -469, -319, + +4699, +5772, +1037, +1391, +2580, +571, -1811, -137, +1930, -248, -876, +278, -102, +158, +529, -367, -232, +173, -250, -176, -332, -250, -145, -125, +369, +578, +501, +334, -24, -230, -185, -365, + +5288, +6343, +926, +1516, +2837, +116, -2274, +403, +2022, -767, -921, +321, -140, +29, +469, -385, -290, +151, -299, -257, -451, -381, -272, -339, +52, +314, +302, +289, +305, +49, -70, -194, + +5726, +6820, +1096, +1667, +3026, -179, -2850, +907, +2339, -1355, -1017, +450, -163, -66, +415, -378, -412, +166, -245, -345, -541, -415, -353, -452, -62, +81, +100, +97, +117, +54, +153, +24, + +6153, +7423, +1241, +1705, +3192, -342, -3363, +1287, +2593, -1875, -1019, +557, -240, -122, +319, -290, -434, +2, -201, -386, -582, -375, -458, -561, -160, +6, +81, -90, -141, -171, +10, +136, + +6828, +8181, +890, +1848, +3361, -805, -3382, +1527, +2488, -2165, -973, +617, -316, -246, +308, -188, -549, -125, -176, -412, -641, -381, -560, -633, -100, -94, -15, -180, -313, -244, -131, -157, + +7339, +8745, +841, +2086, +3460, -1152, -3508, +1614, +2597, -2420, -1103, +713, -354, -350, +308, -133, -681, -241, -127, -375, -784, -526, -527, -641, -141, -117, -177, -223, -325, -365, -249, -300, + +7574, +9152, +1067, +2490, +3582, -1504, -3603, +1572, +2713, -2475, -1389, +742, -241, -424, +146, -29, -689, -412, -49, -482, -922, -508, -528, -656, -326, -236, +0, -242, -494, -465, -250, -363, + +7771, +9477, +1527, +2680, +3445, -1316, -3581, +1119, +2776, -2355, -1714, +883, -172, -648, +99, -15, -445, -536, -388, -395, -960, -596, -496, -760, -479, -221, +19, -221, -514, -524, -422, -579, + +8021, +9527, +2130, +2911, +3042, -704, -3474, +429, +2652, -2057, -1809, +694, -37, -769, -100, +184, -247, -761, -609, -325, -1000, -680, -746, -736, -332, -408, -31, -128, -468, -729, -608, -586, + +8404, +9096, +2503, +3785, +2807, -578, -3480, +263, +2211, -1959, -1522, +174, -65, -508, -392, +128, +9, -898, -776, -193, -1245, -945, -832, -687, -337, -524, -93, -26, -595, -926, -547, -887, + +8807, +8295, +2417, +5558, +3298, -1393, -3611, +1274, +1418, -2498, -541, -286, -448, +137, -733, -107, +472, -919, -800, -132, -1516, -1020, -876, -819, -258, -573, -75, -222, -470, -870, -816, -827, + +9721, +7750, +1320, +7320, +3992, -2723, -3178, +2422, -20, -3129, +726, -465, -1243, +477, -680, -418, +820, -960, -919, -87, -1553, -1159, -1230, -839, -90, -743, -335, -154, -533, -893, -664, -1012, + +10870, +7707, -280, +8285, +5199, -3799, -2870, +3710, -1420, -4018, +2054, -220, -2214, +514, -188, -855, +1016, -762, -1123, +24, -1500, -1380, -1443, -763, -169, -955, -493, -100, -557, -806, -616, -1159, + +11833, +8327, -2134, +8341, +6953, -4401, -2931, +5077, -2393, -5396, +3185, +626, -3054, -50, +496, -988, +898, -338, -1369, +122, -1461, -1366, -1542, -1049, -218, -1029, -640, -181, -361, -866, -501, -1048, + +12829, +9031, -3811, +7670, +8588, -4509, -3175, +6408, -3118, -7036, +3841, +1817, -3527, -1043, +839, -699, +618, +2, -1465, -51, -1246, -1421, -1712, -1253, -467, -1107, -577, -354, -342, -807, -350, -891, + +14193, +9389, -5197, +6872, +9549, -4273, -3139, +7727, -3898, -8441, +3999, +3031, -3444, -2122, +727, -197, +556, +113, -1327, -318, -1040, -1564, -1813, -1380, -747, -1085, -601, -339, -469, -645, -199, -888, + +15661, +9657, -6466, +6233, +9751, -3871, -2723, +8959, -4623, -9557, +3687, +4006, -2825, -3063, +218, +188, +872, +40, -1085, -476, -1213, -1459, -1966, -1538, -758, -1196, -697, -106, -518, -710, -84, -846, + +17612, +9338, -7642, +6082, +9245, -3958, -1634, +10145, -5734, -10179, +3233, +4461, -2053, -3596, -499, +236, +1471, -53, -824, -783, -1511, -1205, -2322, -1376, -936, -1374, -531, +50, -558, -860, -125, -756, + +19463, +9219, -8893, +6261, +8413, -4281, -363, +11374, -6530, -10787, +2801, +4644, -1342, -3682, -1194, -39, +2157, +139, -767, -1072, -1682, -1101, -2364, -1296, -1186, -1329, -395, +235, -591, -1146, -127, -554, + +21650, +9391, -10922, +6081, +8229, -4220, +202, +11812, -6628, -11097, +2478, +4559, -1182, -3433, -1549, -554, +2784, +461, -1205, -1027, -1704, -1258, -2251, -1431, -1146, -1205, -447, +400, -669, -1391, -60, -370, + +23618, +9863, -13021, +6004, +8047, -4224, +416, +12157, -6101, -11654, +2261, +4560, -1406, -3057, -1488, -1343, +3208, +953, -1820, -705, -1697, -1485, -2065, -1531, -1035, -1118, -452, +413, -760, -1496, +104, -350, + +25507, +10091, -14633, +6037, +7728, -4437, +358, +12536, -5172, -12313, +2012, +4630, -1785, -2622, -1212, -2223, +3337, +1463, -2227, -360, -1728, -1658, -1788, -1625, -1024, -963, -484, +363, -873, -1530, +387, -597, + +26627, +10861, -15853, +5976, +7293, -4687, -371, +13070, -3740, -13126, +1550, +4641, -1970, -2334, -931, -3002, +3015, +1972, -2297, -262, -1622, -1706, -1631, -1718, -1043, -847, -523, +200, -913, -1491, +419, -863, + +27529, +11441, -16338, +5805, +6853, -5062, -1537, +13789, -2342, -13609, +1025, +4352, -1778, -2113, -836, -3461, +2445, +2244, -1905, -447, -1343, -1486, -1806, -1634, -1063, -761, -595, -38, -809, -1509, +121, -852, + +28224, +11700, -16026, +5571, +6480, -5603, -2945, +14554, -1154, -13550, +445, +3703, -1208, -1832, -1081, -3648, +1918, +2132, -1094, -755, -1071, -949, -2221, -1385, -1073, -728, -775, -144, -846, -1640, -17, -888, + +28214, +12317, -15132, +5336, +6093, -6385, -4398, +15063, +169, -13141, -349, +2865, -289, -1493, -1675, -3631, +1627, +1567, -67, -871, -1083, -137, -2567, -1204, -1005, -901, -818, -487, -1098, -1321, -264, -1047, + +27674, +13198, -13952, +5049, +5725, -7019, -5818, +14656, +1734, -12326, -1241, +1915, +642, -1155, -2395, -3373, +1425, +664, +785, -409, -1488, +642, -2474, -1372, -798, -1009, -1376, -899, -968, -1199, -318, -1143, + +26652, +14012, -12267, +5200, +5059, -7687, -7096, +13622, +3659, -11441, -2232, +1136, +1363, -745, -2920, -3117, +1275, -215, +1173, +578, -1926, +1018, -1813, -1727, -552, -1508, -1936, -882, -1218, -880, -117, -1274, + +25476, +14976, -10645, +5041, +4465, -7268, -8563, +11373, +5951, -10470, -2967, +695, +1268, -121, -2916, -3040, +1232, -1049, +1136, +1691, -1847, +783, -939, -1782, -1189, -1393, -2259, -1210, -1263, -527, +246, -1345, + +24418, +15887, -9483, +5106, +3650, -6572, -9308, +8066, +7947, -9122, -3698, +546, +799, +234, -2298, -3040, +979, -1401, +660, +2460, -1414, +581, -594, -1924, -1571, -1185, -2342, -1526, -1293, -276, +512, -1388, + +23795, +16122, -8471, +5677, +2738, -6335, -9272, +4879, +8930, -7283, -4533, +587, +584, -12, -1140, -3045, +596, -1168, -297, +2828, -664, +171, -697, -1636, -1755, -862, -2122, -1839, -1085, -590, +469, -1065, + +23181, +16390, -7741, +6442, +2203, -6740, -8434, +1898, +8933, -4752, -5617, +579, +1155, -849, +75, -2508, -62, -548, -1446, +2589, +243, -427, -620, -1078, -1599, -627, -1538, -1798, -1522, -1117, +586, -608, + +22030, +16813, -6552, +6365, +1905, -6491, -7923, -1054, +8742, -2377, -6611, +561, +1892, -1729, +1053, -1623, -1078, +90, -2143, +1121, +1073, -290, -801, -281, -1302, -213, -1096, -1925, -1798, -1686, +156, -224, + +21251, +16564, -5227, +6101, +1298, -5618, -7958, -3289, +8275, -752, -6864, +468, +2279, -1970, +1851, -1720, -1502, +720, -2997, -87, +1066, +346, -609, +374, -840, -207, -612, -1924, -1832, -2459, -669, -2, + +21059, +15707, -4300, +6487, +399, -4731, -7511, -5182, +7533, +993, -7053, +282, +3472, -2462, +1927, -1518, -1924, +1110, -3285, -499, +296, +615, +989, +279, -802, +498, -387, -1895, -1824, -2715, -1623, -344, + +21308, +14470, -4242, +7387, -252, -4583, -6956, -6093, +6238, +2376, -6555, -258, +4580, -2860, +1045, -858, -2358, +1013, -2617, -1140, +487, +118, +1239, +1477, -1144, +905, +15, -2196, -1670, -2549, -2403, -914, + +21749, +13551, -6010, +9423, +237, -6449, -5831, -5696, +4659, +3069, -5379, -988, +5203, -3101, -229, +148, -2474, +413, -1565, -777, +245, -263, +270, +2911, -521, +46, +1169, -2577, -2021, -1583, -2762, -1790, + +22949, +11670, -8631, +12918, +409, -9740, -4092, -3756, +2385, +3036, -3324, -2593, +5421, -2472, -2044, +991, -1723, -438, -884, +258, -444, -546, -80, +2348, +873, +112, +640, -1839, -2303, -1429, -2266, -2374, + +23912, +9195, -9740, +15651, -753, -10898, -2348, -2548, +736, +2645, -1865, -3420, +5193, -2092, -2914, +1332, -608, -827, -805, +690, -265, -735, -758, +2026, +1239, +685, +402, -1265, -2108, -2026, -1548, -2057, + +24116, +7253, -10354, +17453, -1244, -12053, -838, -452, -1755, +1608, +585, -4398, +4021, -759, -3062, +841, +208, -518, -792, +316, -185, -122, -1534, +1707, +1529, +201, +1161, -889, -2381, -1596, -1536, -1868, + +22899, +6009, -9723, +18156, -1387, -12297, +387, +197, -3319, +1403, +1627, -5089, +3452, +505, -3305, +713, +563, -709, -310, -26, -425, +286, -1418, +1157, +1256, +363, +1114, -493, -2226, -1184, -1308, -2261, + +20564, +5546, -8226, +17550, -828, -11490, +294, +435, -3523, +690, +1926, -4747, +2908, +1152, -2973, +467, +625, -707, -390, +101, -449, +40, -906, +959, +763, +546, +863, -551, -1476, -956, -1217, -2071, + +18013, +5812, -6919, +15896, +403, -10591, +67, +717, -3782, +91, +2336, -4162, +2130, +1919, -2779, -103, +1086, -691, -833, +297, -250, -202, -650, +1014, +731, +166, +703, -484, -1293, -477, -1156, -1837, + +15954, +7279, -4696, +11257, -415, -7760, +15, -732, -924, +300, -779, -1111, +2316, +31, -1667, -359, +362, -476, -1406, +77, +201, +160, +31, +184, +33, +618, +402, -142, -19, -131, -351, -177, + +13494, +6705, -2870, +10505, -334, -6612, +28, -1001, -670, +405, -783, -1035, +2308, +178, -1639, -390, +219, -411, -1192, +78, +48, +72, +135, +215, +200, +619, +296, -179, +63, -49, -474, -174, + +11237, +6344, -1097, +9098, -68, -4982, -506, -1321, -184, +563, -966, -831, +2204, +226, -1398, -487, +210, -400, -1067, +109, +7, -13, +137, +290, +364, +506, +81, -34, +85, -87, -211, -95, + +9435, +6226, -171, +7621, +609, -3889, -842, -1290, +79, +593, -877, -638, +1778, +372, -1115, -612, +133, -304, -919, +84, +28, -9, +49, +403, +518, +117, +63, +315, +9, -189, +148, +127, + +8281, +6134, -52, +6557, +1253, -3449, -792, -804, +3, +410, -398, -491, +1170, +585, -801, -816, +97, -92, -760, -8, +125, +10, +14, +591, +350, +20, +334, +355, -11, +73, +387, +50, + +7625, +5926, -212, +5732, +1440, -2973, -409, -538, -153, +402, +53, -528, +814, +714, -773, -751, +187, -25, -685, +71, +194, -126, +301, +656, +141, +177, +495, +460, +123, +277, +255, -206, + +6929, +5539, -213, +5156, +1489, -2470, -128, -421, -216, +512, +263, -626, +604, +666, -598, -609, +135, +2, -569, +170, +101, +124, +603, +290, +211, +558, +624, +396, +73, +189, -68, -300, + +6185, +4980, +12, +4844, +1476, -2007, +5, -218, -48, +475, +186, -579, +652, +583, -532, -454, +163, -44, -351, +323, +185, +454, +519, +323, +554, +596, +513, +149, -59, +27, -156, -301, + +5578, +4710, +139, +4160, +1511, -1429, +247, -167, -134, +535, +301, -478, +484, +512, -357, -355, +143, +139, +9, +323, +460, +774, +454, +456, +460, +265, +311, +29, -141, -56, -157, -425, + +4834, +4247, +381, +3890, +1667, -1077, +239, -52, +64, +515, +186, -374, +470, +446, -204, -178, +260, +402, +264, +582, +786, +717, +277, +144, +133, +174, +219, +36, -212, -220, -241, -491, + +4111, +3866, +739, +3569, +1573, -633, +462, -99, +98, +570, +132, -353, +509, +570, +1, -45, +535, +857, +514, +702, +653, +127, -67, +94, +33, +142, +132, -176, -297, -218, -361, -612, + +3730, +3751, +749, +2995, +1740, -73, +398, -128, +157, +562, +322, -106, +526, +653, +398, +535, +911, +896, +331, +268, +196, +17, -50, +13, -44, +14, +4, -239, -323, -300, -491, -605, + +2892, +3209, +1362, +3059, +1608, +182, +476, -76, +432, +661, +242, +160, +1034, +1084, +626, +638, +748, +381, -9, +164, +81, +56, -148, -220, -132, -95, -61, -252, -388, -412, -527, -492, + +2752, +3422, +1354, +2301, +1710, +560, +500, +0, +522, +1109, +816, +680, +1165, +1033, +440, -19, +152, +356, +205, +72, -219, -249, -230, -203, -210, -180, -256, -370, -297, -417, -460, -470, + +2213, +3015, +1710, +2495, +1858, +590, +641, +619, +1215, +1482, +1045, +756, +541, +266, +10, +87, +388, +325, -149, -273, -65, -313, -465, -315, -243, -222, -297, -239, -314, -374, -410, -472, + +2378, +3632, +1949, +1796, +1538, +1419, +1931, +1407, +1042, +906, +324, -55, +57, +281, +416, +73, -141, +104, -125, -338, -346, -567, -456, -178, -236, -293, -193, -168, -347, -459, -409, -412, + +2533, +3615, +2312, +2871, +2388, +1873, +1924, +743, -6, +118, +67, +58, +149, +131, +262, -115, -211, -1, -357, -465, -469, -597, -378, -114, -162, -284, -237, -201, -345, -426, -423, -455, + +2942, +4615, +3780, +3595, +1951, +1001, +577, -3, -9, +178, +100, -150, -79, +35, +232, -191, -343, -241, -527, -515, -469, -366, -285, -260, -253, -164, -168, -307, -405, -445, -401, -430, + +3532, +6354, +4764, +2112, +192, +502, +1060, +740, -280, -481, -6, +64, -3, -232, +35, -123, -425, -424, -500, -331, -403, -411, -380, -233, -195, -219, -156, -328, -390, -471, -421, -332, + +3754, +6378, +3302, +1176, +770, +1524, +1808, +405, -520, -9, +89, -401, +38, -134, -211, -179, -439, -279, -348, -439, -354, -411, -499, -252, -186, -273, -220, -306, -347, -364, -422, -391, + +2291, +3472, +1957, +1996, +2277, +2297, +2104, +987, +507, +706, +356, -152, -298, -91, -5, -385, -390, -196, -226, -195, -416, -447, -287, -389, -410, -244, -292, -350, -178, -230, -400, -417, + +1819, +2518, +1138, +1323, +2016, +2067, +1584, +1227, +1540, +1527, +1077, +599, +319, +222, -133, -344, -224, -354, -392, -98, -287, -313, -172, -348, -336, -273, -365, -452, -322, -244, -281, -244, + +1991, +2736, +1265, +1355, +1696, +1270, +711, +599, +1244, +1618, +1273, +1004, +935, +768, +344, -110, -219, -251, -264, -319, -400, -274, -131, -258, -317, -231, -396, -403, -299, -400, -335, -208, + +2251, +2968, +994, +1270, +1801, +1182, +278, +85, +960, +1169, +719, +996, +1351, +1194, +875, +354, +176, -35, -282, -178, -385, -406, -153, -263, -175, -84, -340, -346, -297, -435, -353, -295, + +2479, +3474, +1165, +1200, +1738, +845, +57, +328, +1004, +611, +199, +546, +759, +1002, +1149, +732, +519, +336, +110, +42, -306, -317, -221, -391, -190, -72, -254, -255, -285, -409, -356, -289, + +2648, +3711, +1310, +1382, +2036, +687, -508, +326, +1209, +455, +69, +381, +353, +462, +570, +467, +723, +755, +406, +258, +135, -71, -226, -267, -244, -225, -239, -248, -226, -295, -370, -333, + +2964, +4131, +1490, +1331, +2035, +615, -807, +460, +1251, +53, -30, +484, +328, +176, +292, +67, +31, +459, +630, +520, +346, +231, +64, -123, -179, -163, -253, -368, -325, -244, -286, -364, + +3240, +4589, +1670, +1277, +2158, +577, -1140, +581, +1323, -227, -122, +553, +290, +100, +235, -70, -152, +21, +69, +287, +434, +552, +333, +96, +114, -5, -177, -258, -330, -382, -258, -309, + +3730, +5196, +1638, +1123, +2168, +499, -1274, +755, +1209, -628, -139, +668, +292, -40, +122, -92, -234, -100, -101, -83, -135, +285, +479, +374, +279, +151, +85, -119, -293, -348, -282, -381, + +4119, +5684, +1732, +1126, +2228, +300, -1467, +1077, +1204, -1061, -263, +742, +305, -24, +37, -204, -274, -137, -131, -189, -340, -114, +44, +178, +404, +348, +234, +110, -83, -267, -257, -291, + +4622, +6186, +1693, +1242, +2320, -46, -1538, +1517, +1127, -1483, -304, +841, +294, -67, +5, -203, -308, -200, -102, -217, -386, -222, -141, -99, +23, +201, +346, +265, +65, -52, -11, -200, + +5193, +6638, +1553, +1499, +2388, -594, -1569, +2013, +985, -1862, -401, +847, +342, -127, -49, -265, -391, -279, -24, -258, -446, -237, -373, -107, -35, -174, -57, +100, +163, +130, +55, -58, + +5824, +7125, +1374, +1701, +2443, -1077, -1576, +2426, +806, -2127, -438, +769, +324, -176, +41, -326, -603, -328, -5, -213, -487, -284, -470, -142, -47, -263, -242, -262, -124, +12, +120, +33, + +6335, +7628, +1408, +1800, +2526, -1396, -1736, +2894, +798, -2493, -400, +738, +274, -165, +15, -222, -694, -482, +72, -261, -572, -116, -475, -277, -17, -291, -261, -317, -412, -297, -56, +28, + +6761, +8075, +1459, +2066, +2609, -1964, -1828, +3359, +727, -2782, -456, +715, +208, -232, -18, -148, -747, -627, +81, -302, -698, -121, -406, -325, -107, -219, -294, -466, -521, -391, -176, -288, + +7157, +8606, +1581, +2068, +2784, -2202, -2039, +3602, +767, -2899, -542, +707, +104, -260, -9, -128, -676, -844, +64, -130, -840, -253, -381, -284, -107, -233, -282, -564, -568, -421, -261, -447, + +7410, +9322, +1838, +1630, +3033, -1959, -2478, +3478, +916, -2764, -738, +578, +126, -372, +30, -107, -667, -935, -60, -32, -777, -452, -481, -148, -144, -362, -257, -530, -598, -498, -436, -437, + +7600, +9757, +2318, +1422, +3068, -1530, -2951, +3205, +1134, -2618, -848, +362, +153, -421, -49, -52, -609, -1028, -173, +13, -822, -437, -527, -269, -108, -428, -361, -411, -698, -654, -354, -475, + +8104, +9762, +2543, +1907, +2993, -1492, -3123, +3108, +1007, -2376, -799, +85, +225, -462, -207, +76, -422, -1156, -330, +104, -791, -492, -526, -345, -141, -393, -383, -537, -744, -705, -190, -505, + +8909, +9413, +2318, +2985, +3009, -1948, -3050, +3168, +425, -2046, -543, -270, +167, -483, -337, +79, -154, -1299, -550, +186, -643, -695, -585, -287, -262, -358, -406, -740, -843, -531, -265, -573, + +9426, +9025, +2181, +4009, +3640, -2472, -3407, +3777, -384, -2061, +272, -562, -296, -282, -348, -201, +397, -1463, -821, +375, -577, -753, -723, -199, -322, -387, -483, -747, -845, -590, -326, -571, + +10108, +8385, +1400, +6014, +4224, -3846, -2895, +4634, -1924, -2185, +1409, -691, -736, -445, -160, -496, +690, -1211, -1255, +419, -429, -745, -766, -201, -456, -411, -561, -544, -937, -907, -160, -739, + +10943, +8373, +46, +7110, +5244, -4697, -2467, +5334, -3432, -2574, +2681, -670, -1220, -664, +155, -796, +596, -633, -1639, +276, -169, -751, -786, -162, -512, -556, -561, -560, -872, -1006, -393, -823, + +12145, +8720, -1664, +7093, +6723, -4974, -2355, +5841, -4655, -3092, +3716, -397, -1752, -903, +493, -914, +75, -59, -1625, -196, +169, -746, -800, +30, -700, -607, -584, -846, -650, -980, -876, -718, + +13449, +9173, -3433, +6797, +7856, -4807, -2042, +6051, -5634, -3740, +4384, +233, -2242, -1265, +790, -884, -471, +114, -1201, -709, +233, -517, -817, +265, -855, -714, -702, -983, -688, -985, -936, -805, + +14554, +9843, -4692, +5589, +8876, -3969, -1993, +6452, -6471, -4465, +4658, +1064, -2464, -1808, +1040, -734, -892, -140, -587, -969, -47, -87, -824, +496, -902, -929, -759, -1132, -899, -928, -701, -988, + +15499, +10690, -5588, +4019, +9370, -2825, -1817, +6925, -7237, -5143, +4618, +1819, -2391, -2377, +1112, -527, -1082, -687, -144, -864, -451, +270, -610, +501, -919, -981, -876, -1386, -1039, -897, -490, -928, + +17184, +10743, -6654, +3458, +8941, -2496, -296, +6958, -8428, -5131, +4435, +2201, -2279, -2678, +1041, -465, -1059, -1191, -112, -563, -633, +396, -146, +255, -999, -772, -1178, -1541, -1165, -955, -285, -586, + +18439, +11433, -7884, +3086, +8223, -2330, +1154, +7363, -9381, -5433, +4476, +2299, -2058, -2772, +772, -429, -922, -1487, -412, -319, -459, +489, +179, +4, -920, -666, -1378, -1593, -1381, -989, -70, -199, + +20043, +11571, -8926, +2927, +7480, -2933, +2814, +7900, -10432, -5634, +4629, +2163, -2083, -2501, +322, -605, -660, -1666, -795, -420, +2, +773, +28, -86, -714, -788, -1426, -1661, -1631, -934, -18, +154, + +21100, +12438, -9991, +2658, +6924, -3598, +3640, +9112, -11048, -6263, +4923, +1936, -2083, -2127, -90, -1004, -241, -1755, -1109, -655, +353, +1477, -496, -26, -322, -1103, -1235, -1773, -1804, -950, -17, +340, + +22220, +13016, -10684, +2238, +6616, -4544, +3961, +10464, -11476, -6710, +4989, +1692, -2097, -1740, -471, -1509, +171, -1891, -1172, -1008, +446, +2361, -1007, -80, +206, -1448, -1059, -1719, -2148, -946, -187, +379, + +23160, +13514, -10970, +1648, +6564, -5582, +3717, +11856, -11585, -6851, +4668, +1415, -1888, -1527, -831, -1885, +423, -2020, -993, -1361, +246, +3145, -1090, -388, +815, -1543, -1101, -1488, -2586, -1060, -470, +329, + +23984, +13865, -11140, +1506, +6153, -6455, +3221, +12728, -11274, -6683, +4149, +879, -1350, -1515, -1321, -1966, +480, -2107, -735, -1620, -134, +3538, -695, -707, +1213, -1214, -1434, -1269, -3012, -1293, -736, +72, + +24782, +14120, -11236, +1961, +5253, -7111, +2788, +12880, -10420, -6360, +3471, +290, -601, -1551, -1881, -1800, +635, -2271, -409, -1692, -623, +3484, +102, -645, +1121, -484, -1860, -1402, -3095, -1550, -1113, -154, + +24478, +15178, -10478, +1270, +5126, -7637, +1416, +13108, -9038, -6194, +2475, -43, +4, -1635, -2240, -1773, +998, -2517, -301, -1320, -1403, +2910, +1377, -319, +543, +368, -2377, -1572, -2886, -2071, -1188, -610, + +23336, +16618, -8704, -223, +5298, -7565, -968, +13263, -6982, -6465, +1742, -449, +352, -1376, -2596, -1623, +1240, -2651, -286, -899, -1898, +1936, +2438, +528, -375, +750, -2161, -1941, -2664, -2274, -1304, -958, + +22712, +17229, -7217, -356, +4386, -7099, -2807, +12389, -4621, -6839, +1425, -975, +424, -777, -2826, -1526, +1422, -2734, -246, -516, -2068, +1271, +2387, +1470, -861, +696, -1581, -2206, -2447, -2243, -1214, -1282, + +22892, +17053, -6909, +1550, +2504, -7309, -2981, +10387, -2761, -6478, +847, -1462, +747, -527, -2541, -1653, +1330, -2326, -581, +131, -2018, +687, +1356, +2090, -263, +54, -772, -2199, -2423, -1678, -1280, -1950, + +22958, +16963, -6994, +3862, +804, -8094, -2421, +7964, -1267, -5599, -222, -1546, +1312, -701, -1892, -1941, +925, -1306, -1223, +805, -1822, -507, +577, +2232, +644, +10, -622, -1590, -2129, -1759, -1313, -2053, + +22795, +16811, -6665, +5414, -231, -8963, -2057, +5715, -140, -4502, -1495, -1224, +1967, -1203, -1238, -1944, +128, +141, -1762, +375, -1151, -1442, -293, +2236, +1381, +482, -421, -1050, -2081, -1865, -1013, -2075, + +22156, +16822, -5737, +5914, -531, -9248, -2574, +3914, +921, -3656, -2319, -843, +2476, -1480, -1050, -1438, -455, +614, -1691, -640, -770, -1051, -1218, +1623, +1962, +1863, -702, -1229, -1009, -2137, -1191, -1810, + +21420, +16785, -4799, +6154, -663, -9035, -3372, +2102, +2124, -2833, -3110, -133, +2641, -1601, -638, -1248, -923, +605, -1675, -1249, -658, -53, -1902, +1335, +2038, +2064, +272, -1486, -537, -2097, -1156, -1644, + +21361, +15629, -3750, +6528, -1323, -8215, -4323, +464, +3132, -1840, -3943, +437, +3186, -1861, -582, -1384, -980, +77, -1818, -753, -1149, +490, -779, +520, +1069, +2103, +1599, -1602, -997, -1118, -1205, -1803, + +20330, +15116, -2198, +6125, -1778, -6323, -6028, -1388, +5002, -1330, -4769, +1469, +3125, -2056, -350, -2178, -854, +367, -2722, -22, -540, -99, +456, +351, -11, +1824, +1553, -531, -893, -1195, -631, -1855, + +20062, +13940, -1073, +5901, -2918, -4148, -6485, -3763, +6395, -76, -5571, +1976, +3170, -2469, -500, -2482, -418, +183, -3077, +751, +150, -824, +890, +1089, -685, +923, +962, +419, -69, -1542, -261, -1391, + +21165, +12566, -2644, +7196, -3419, -4374, -5591, -3941, +6004, +491, -4989, +1625, +3132, -2899, -840, -2060, -308, +352, -2926, +725, +461, -401, +854, +946, -597, +286, +687, +245, +522, -714, -834, -655, + +22181, +10753, -4743, +9694, -3820, -6164, -3751, -3237, +4762, +962, -4786, +856, +3566, -3082, -1668, -1292, +74, +282, -2679, +317, +654, +206, +432, +672, -272, -199, +427, +115, +322, +278, -897, -731, + +21833, +9209, -6007, +12315, -3453, -8356, -2210, -1380, +3074, +222, -3684, +199, +3572, -2831, -2010, -495, +19, -33, -2094, +470, +147, +334, +628, +538, -358, +45, -17, -272, +825, +112, -396, -410, + +21222, +7854, -6428, +13904, -3314, -9841, -311, -717, +1107, +600, -2989, -732, +3598, -2074, -2105, -29, +34, -558, -1422, +552, -367, +238, +799, +488, -473, +119, +72, -314, +618, +130, -262, -1, + +19959, +7458, -6254, +13163, -2749, -8575, +168, -1541, +524, +795, -2410, -1167, +3370, -1359, -1981, +131, -37, -600, -1272, +322, -134, +241, +366, +572, -360, -40, +508, -76, -11, +77, -84, -39, + +18263, +7315, -5697, +12058, -1512, -7911, -155, -1097, -277, +440, -1476, -1163, +2794, -682, -1653, -226, +195, -447, -1525, +167, +243, +191, +5, +420, -166, +267, +536, -17, -141, -216, +13, -120, + +14574, +8295, -838, +5767, -2715, -2520, -1691, -1773, +1779, -38, -2463, +993, +2121, -1350, -803, -1187, +196, -325, -1656, +367, -300, -397, +308, +424, +622, +1154, -257, -779, -260, -661, -212, +363, + +12640, +8177, -514, +5232, -1427, -2829, -1332, -1356, +968, +94, -1951, +761, +1867, -950, -840, -1080, +224, -469, -1525, +376, -426, -453, +483, +403, +530, +830, -326, -345, -235, -760, -56, +349, + +11044, +7881, -148, +5139, -839, -2943, -771, -1231, +563, +131, -1472, +726, +1552, -637, -706, -854, +77, -516, -1176, +229, -479, -289, +444, +438, +558, +439, -291, +63, -149, -710, +13, +439, + +9448, +7315, +777, +4791, -766, -2291, -640, -1240, +566, +79, -1184, +670, +1401, -496, -584, -601, -102, -472, -972, +95, -341, -227, +329, +485, +481, +177, -40, +272, -35, -470, -18, +555, + +7784, +6813, +1919, +4053, -580, -1299, -807, -1308, +740, +180, -1143, +616, +1306, -404, -321, -523, -263, -345, -754, -11, -288, -134, +224, +482, +339, +206, +285, +426, +140, -377, +51, +463, + +6153, +6246, +2936, +3514, -265, -522, -963, -1330, +954, +278, -1137, +468, +1183, -27, -199, -727, -188, -39, -737, -145, -161, -167, +296, +467, +191, +475, +664, +574, +50, -370, +118, +236, + +5216, +5838, +3133, +3059, +1, -157, -756, -1165, +778, +326, -848, +372, +928, +178, -109, -801, -20, +104, -796, -199, -47, -58, +362, +449, +343, +811, +845, +385, -220, -311, +33, +113, + +4597, +5368, +3150, +2849, +47, +176, -392, -1164, +650, +523, -570, +155, +748, +467, -67, -777, +130, +87, -748, -20, -18, +143, +685, +510, +516, +926, +646, +76, -295, -314, +101, +201, + +4160, +4800, +2975, +2878, +215, +185, -346, -879, +720, +434, -577, +142, +805, +500, -153, -718, +261, +104, -689, +154, +246, +528, +763, +288, +509, +781, +225, -155, -161, -171, -27, -42, + +4047, +4610, +2554, +2523, +343, +309, -161, -677, +639, +395, -412, +331, +729, +219, -6, -351, +190, +142, -205, +534, +514, +540, +360, +158, +449, +446, +134, -82, -194, -248, -36, -79, + +3681, +4202, +2459, +2522, +468, +335, -124, -483, +720, +451, -371, +292, +718, +292, +137, -143, +474, +547, +124, +441, +403, +249, +3, +182, +383, +387, +48, -193, -191, -244, -51, -202, + +3418, +3958, +2332, +2406, +561, +275, -16, -147, +764, +316, -330, +555, +677, +300, +712, +391, +554, +506, -31, +195, +200, -92, +90, +358, +160, +198, -1, -186, -221, -248, -146, -268, + +3294, +3885, +2237, +2055, +440, +495, +330, -195, +594, +558, -92, +562, +1070, +915, +915, +255, +158, +177, -224, +85, +144, -90, +60, +179, +169, +71, -152, -244, -264, -222, -259, -374, + +3036, +3530, +2299, +2284, +540, +283, +250, +363, +785, +420, +481, +1288, +1245, +678, +546, -172, -123, +52, -133, +151, -76, -120, +87, +168, +37, -127, -184, -303, -217, -273, -383, -412, + +2951, +3684, +2445, +1884, +210, +635, +675, +547, +1250, +1227, +765, +965, +798, +86, +80, -228, +0, +39, -228, +30, -27, -42, +25, +53, -221, -186, -201, -304, -216, -403, -409, -382, + +2948, +3672, +2453, +1863, +191, +765, +1578, +1710, +1229, +774, +415, +256, +396, -103, +36, -65, -268, -80, -64, -3, -34, -116, -164, -71, -281, -296, -229, -301, -271, -378, -434, -341, + +2843, +3566, +2452, +2150, +1119, +1466, +1682, +1795, +928, -254, -261, +372, +403, -274, -165, -161, -184, -111, -88, -48, -200, -201, -180, -289, -413, -275, -295, -256, -268, -441, -348, -288, + +2564, +4101, +3460, +2647, +1410, +1412, +1574, +983, +11, +28, -27, +71, +225, -244, +4, -163, -265, +10, -151, -168, -99, -187, -352, -372, -357, -210, -195, -232, -258, -356, -289, -290, + +3244, +5969, +3950, +1503, +762, +1387, +767, +390, +603, -90, -364, -54, +452, -41, -367, -79, -184, -274, -111, -48, -196, -322, -399, -360, -258, -194, -183, -224, -289, -330, -316, -345, + +3784, +6054, +3526, +1790, +389, +352, +1278, +1092, -88, -197, +260, -59, +139, +65, -157, -256, -333, -279, -121, -80, -211, -244, -442, -312, -216, -247, -254, -250, -268, -326, -359, -335, + +2822, +5085, +3846, +2069, +435, +648, +1401, +1023, +236, -6, +341, +350, +172, -40, +34, -202, -361, -272, -304, -204, -29, -187, -395, -181, -217, -302, -314, -303, -311, -325, -288, -335, + +2707, +4855, +2989, +1364, +947, +1039, +1087, +968, +768, +256, +227, +682, +564, +111, +39, -39, -213, -415, -274, -193, -240, -136, -135, -139, -171, -174, -321, -402, -386, -337, -287, -323, + +2574, +4549, +2481, +1104, +1330, +907, +475, +1038, +988, +424, +619, +680, +540, +614, +433, -71, -59, -64, -397, -356, -134, -141, -286, +11, +52, -193, -195, -312, -434, -438, -356, -279, + +2422, +4172, +2328, +1283, +1472, +647, +125, +1006, +879, +224, +547, +905, +832, +557, +435, +418, +214, -78, -116, -201, -318, -253, -140, -84, -96, +29, -87, -310, -305, -394, -495, -381, + +2457, +4168, +2312, +1258, +1473, +568, -47, +1024, +903, -67, +189, +852, +771, +615, +723, +347, +177, +387, +190, -226, -97, -8, -307, -173, +62, -42, -182, -125, -211, -363, -347, -400, + +2479, +4135, +2339, +1562, +1610, +192, -248, +1300, +909, -337, +81, +690, +508, +388, +636, +433, +219, +291, +303, +164, +7, +21, +31, -36, -110, -67, -84, -238, -296, -215, -282, -331, + +2624, +4417, +2420, +1461, +1611, +190, -334, +1254, +921, -411, -37, +569, +431, +277, +366, +238, +20, +196, +411, +163, +23, +266, +197, +88, +161, +35, -197, -291, -298, -316, -320, -247, + +2857, +4661, +2448, +1599, +1644, -52, -369, +1426, +846, -542, -64, +578, +333, +106, +438, +207, -300, -149, +268, +191, +20, +247, +302, +342, +299, +211, +96, -235, -456, -375, -272, -328, + +3188, +5067, +2423, +1526, +1665, -114, -379, +1420, +746, -615, -22, +514, +244, +36, +349, +284, -291, -398, -114, +35, -95, +71, +386, +395, +370, +407, +245, -45, -298, -398, -392, -348, + +3392, +5464, +2575, +1426, +1705, -141, -510, +1546, +697, -819, -14, +541, +205, -81, +197, +362, -172, -517, -262, -166, -340, -129, +171, +384, +434, +397, +374, +107, -152, -237, -310, -366, + +3778, +5985, +2547, +1224, +1789, -132, -599, +1611, +647, -931, +4, +483, +130, -67, +79, +336, -105, -481, -339, -274, -374, -355, -90, +280, +364, +297, +401, +185, -84, -89, -184, -264, + +4238, +6510, +2468, +1077, +1860, -270, -600, +1756, +466, -1066, +75, +520, -27, -200, +61, +302, -74, -470, -390, -308, -412, -437, -214, +90, +251, +154, +227, +157, -56, -78, -125, -116, + +4791, +7085, +2292, +969, +1933, -473, -530, +1936, +231, -1156, +164, +537, -117, -309, +2, +238, -84, -390, -352, -407, -462, -398, -204, -73, +172, +87, +45, +57, -238, -129, -20, -64, + +5298, +7657, +2183, +875, +2016, -753, -494, +2218, -13, -1312, +267, +578, -182, -441, -93, +196, -122, -393, -302, -435, -513, -440, -113, -135, -14, +190, -70, -156, -337, -293, -128, -66, + +5772, +8287, +2120, +701, +2131, -1043, -540, +2502, -218, -1459, +344, +564, -207, -513, -279, +141, -129, -411, -314, -481, -509, -495, -83, -55, -189, +147, -1, -322, -411, -420, -358, -159, + +6156, +8940, +2162, +466, +2269, -1223, -655, +2753, -350, -1564, +441, +587, -308, -513, -366, -30, -129, -409, -289, -486, -560, -558, -73, +140, -206, -105, +70, -261, -507, -464, -575, -293, + +6742, +9493, +2028, +426, +2287, -1512, -626, +2857, -609, -1493, +499, +542, -410, -555, -338, -271, -242, -367, -235, -522, -637, -614, -88, +199, -77, -219, -130, -145, -572, -543, -605, -493, + +7455, +9892, +1817, +673, +2165, -1782, -526, +2877, -874, -1369, +613, +482, -471, -664, -187, -495, -430, -293, -210, -463, -712, -671, -39, +162, -43, -26, -317, -285, -509, -579, -619, -592, + +8019, +10193, +1826, +947, +2060, -1895, -616, +2838, -973, -1270, +603, +513, -417, -884, -78, -555, -646, -328, -167, -385, -659, -776, -74, +250, -111, +117, -295, -476, -508, -590, -658, -581, + +8488, +10358, +1977, +1265, +2015, -1887, -920, +2788, -1005, -1210, +617, +441, -268, -1020, -166, -487, -785, -574, -79, -286, -605, -796, -270, +464, -155, +23, -164, -502, -600, -692, -661, -560, + +9032, +10338, +2002, +1761, +2191, -2067, -1283, +2872, -1174, -1205, +746, +309, -249, -938, -329, -531, -744, -897, -123, -86, -627, -738, -388, +469, +0, -188, -125, -361, -727, -819, -607, -613, + +9864, +10088, +1523, +2776, +2578, -2733, -1373, +3075, -1563, -1189, +922, +251, -375, -786, -321, -773, -647, -1025, -380, +85, -536, -746, -274, +305, +98, -159, -216, -318, -746, -852, -593, -682, + +10598, +9701, +940, +4274, +3058, -3831, -1125, +3536, -2290, -1265, +1285, +276, -567, -754, -134, -923, -659, -1033, -713, +96, -164, -899, -154, +299, +14, +105, -391, -378, -574, -830, -773, -577, + +10878, +9347, +643, +5807, +3528, -5043, -576, +4279, -3492, -1535, +1951, +350, -873, -858, +153, -941, -755, -1006, -1030, -132, +274, -915, -234, +450, -136, +336, -408, -493, -454, -795, -947, -437, + +11510, +9866, -517, +5809, +4860, -5267, -967, +4693, -4147, -1854, +2440, +298, -1178, -888, +429, -1109, -918, -824, -1173, -606, +385, -531, -456, +537, -109, +345, -322, -566, -435, -822, -1034, -491, + +12635, +10354, -1762, +5073, +6221, -4898, -1391, +4717, -4535, -2049, +2756, +364, -1594, -867, +721, -1229, -1148, -678, -1099, -989, +154, -84, -438, +418, +119, +303, -273, -468, -478, -915, -1048, -631, + +13739, +10931, -3039, +4229, +7036, -3993, -1627, +4425, -4683, -2247, +2950, +515, -2020, -897, +930, -1302, -1368, -646, -958, -1207, -291, +233, -188, +154, +374, +357, -256, -270, -569, -1081, -1002, -747, + +14744, +11698, -4040, +3065, +7514, -2833, -1645, +3985, -4805, -2328, +2928, +769, -2368, -998, +1104, -1337, -1464, -742, -746, -1258, -738, +270, +219, -28, +461, +565, -183, -98, -674, -1208, -1015, -822, + +15661, +12563, -4797, +1712, +7684, -1798, -1303, +3560, -5128, -2181, +2756, +928, -2517, -1206, +1167, -1348, -1484, -913, -576, -1200, -996, -13, +556, +59, +345, +829, -12, -35, -778, -1229, -1099, -956, + +16364, +13610, -5417, +358, +7606, -1081, -694, +3363, -5713, -1853, +2574, +824, -2410, -1460, +1029, -1325, -1426, -1134, -452, -1081, -1063, -425, +647, +304, +234, +1059, +210, -50, -832, -1188, -1210, -1113, + +17301, +14490, -6249, -381, +7171, -884, +239, +3371, -6504, -1381, +2548, +400, -2128, -1591, +701, -1356, -1209, -1399, -313, -902, -1081, -684, +503, +524, +231, +1359, +398, -161, -776, -1179, -1300, -1239, + +19090, +14422, -7537, +119, +6088, -1186, +1568, +3110, -7218, -739, +2538, -295, -1756, -1656, +234, -1424, -1032, -1537, -233, -694, -1129, -779, +292, +571, +268, +1771, +559, -457, -623, -1262, -1420, -1267, + +20805, +14336, -8736, +920, +4704, -1494, +2649, +2925, -7561, -328, +2504, -973, -1224, -1901, -205, -1369, -1023, -1413, -248, -538, -1010, -940, +175, +531, +207, +2290, +770, -842, -494, -1328, -1610, -1150, + +22109, +14485, -9555, +1595, +3405, -1875, +3399, +2878, -7467, -159, +2320, -1375, -756, -2191, -602, -1235, -972, -1286, -262, -418, -788, -1088, +82, +594, -8, +2708, +1095, -1168, -535, -1285, -1751, -974, + +22911, +14859, -9889, +1889, +2263, -2415, +3753, +2933, -7127, -227, +1986, -1630, -415, -2450, -1051, -1037, -827, -1434, -165, -366, -647, -1068, -154, +882, -368, +2616, +1524, -1241, -905, -1145, -1703, -979, + +23245, +15363, -9604, +1856, +1322, -3040, +3776, +3098, -6633, -350, +1568, -1819, -103, -2618, -1435, -794, -655, -1757, +41, -318, -654, -746, -459, +1267, -738, +1911, +2006, -928, -1339, -994, -1484, -1026, + +23048, +16128, -8809, +1596, +486, -3594, +3405, +3364, -5994, -577, +1227, -2110, +338, -2650, -1697, -633, -515, -2058, +200, -158, -867, -14, -786, +1297, -792, +869, +2115, -163, -1403, -1180, -994, -927, + +22809, +16473, -7468, +1279, -304, -4094, +2691, +3769, -5530, -656, +858, -2440, +917, -2540, -1937, -596, -384, -2335, +377, -58, -950, +797, -1345, +1069, -434, -289, +1797, +898, -1234, -1327, -340, -1167, + +22287, +16759, -6019, +907, -957, -4847, +1807, +4137, -5333, -671, +434, -2757, +1592, -2484, -2177, -772, -331, -2403, +180, +397, -1148, +952, -1488, +457, +9, -900, +941, +1571, -432, -1370, -331, -1254, + +21687, +17120, -4653, +1201, -1531, -5605, +1233, +4224, -4907, -618, +334, -2824, +2339, -2255, -2444, -777, -345, -2119, +138, +690, -1476, +1035, -1282, -255, +720, -854, -197, +2118, +560, -1484, -235, -840, + +20812, +17571, -3517, +1604, -1925, -6559, +655, +3983, -4426, -559, +260, -2689, +2858, -2122, -2599, -1007, -244, -1381, -668, +771, -1403, +492, -756, -404, +502, +93, -695, +1167, +1322, -839, -247, -943, + +20139, +17539, -2371, +1932, -2101, -7422, -134, +3611, -3812, -412, +185, -2382, +3168, -1970, -3046, -567, -229, -1405, -1029, +419, -1307, +375, -467, -375, +380, +1214, -1001, -411, +2033, -274, -430, -799, + +19753, +17050, -1457, +2572, -2382, -8049, -965, +2983, -2716, -235, -326, -1321, +2916, -2171, -2296, -826, -571, -1104, -1712, +62, -637, +159, -684, +668, +232, +865, +69, -1322, +1025, +254, +67, -588, + +19313, +16611, -863, +3251, -2596, -8557, -2035, +2815, -1745, -84, -572, -839, +2943, -1918, -2229, -1014, -802, -1378, -1915, +318, -814, +322, -33, +499, +177, +995, +794, -1733, -313, +324, +698, -311, + +19432, +15373, -280, +4094, -3296, -8664, -2599, +2170, -225, -30, -1542, +594, +2691, -2281, -1544, -1686, -1307, -903, -1915, -153, -126, +698, -360, +340, +825, +1064, +273, -993, -998, -689, +1129, +142, + +19161, +14270, +164, +4902, -4023, -8420, -3080, +1712, +839, +173, -2097, +1066, +2771, -2396, -1584, -2406, -841, -783, -2457, +724, +24, +6, +115, +460, +603, +1331, -24, -638, -844, -1849, +898, +543, + +18185, +13294, +1396, +5056, -4975, -6537, -4217, +256, +3477, -142, -3597, +2330, +2565, -2744, -1485, -2544, -786, -568, -2073, +767, -278, -87, +712, +47, +286, +1855, +49, -975, -401, -2019, -110, +720, + +18313, +12559, +1145, +3915, -4788, -4611, -4800, -248, +4385, -385, -3737, +2444, +2059, -2542, -1236, -3085, -90, -60, -2227, +677, -342, +170, +590, -167, +444, +1928, +89, -943, -588, -1828, -345, +588, + +19047, +11703, -955, +4365, -4893, -3853, -3267, -1533, +4299, +134, -4009, +2112, +2030, -2635, -1305, -2227, -55, -224, -2038, +767, -148, -368, +345, +393, +586, +1413, +142, -763, -846, -1547, -218, +199, + +19014, +10464, -2335, +5732, -4481, -4151, -2526, -849, +3281, -472, -3208, +1847, +1902, -2824, -779, -1622, -183, -396, -1924, +1079, -378, -665, +394, +566, +672, +1279, -35, -701, -812, -1354, +31, +44, + +18162, +9492, -3044, +7090, -3964, -4906, -1033, -851, +1796, -66, -2783, +1424, +1900, -2369, -665, -1270, -198, -516, -1532, +747, -522, -404, +331, +314, +897, +1359, -338, -718, -601, -1136, +5, +342, + +16598, +8667, -2195, +6902, -3696, -3649, -980, -1771, +1921, -11, -2768, +1203, +2093, -1882, -722, -1121, -151, -296, -1570, +398, -363, -287, +171, +326, +918, +1214, -295, -849, -425, -762, -169, +362, + +14574, +8452, +258, +4430, -4365, -2407, +102, -220, -223, -832, -1852, +1615, +1202, -2022, +253, -1216, -444, -63, -1455, +368, -312, -727, +373, +217, -412, +849, +339, -186, +129, -916, -296, -195, + +12278, +8141, +1428, +3486, -3243, -1249, -493, -560, +165, -592, -1924, +1327, +1447, -1595, +92, -1011, -282, -108, -1214, +238, -313, -593, +289, +150, -236, +853, +317, -36, -85, -842, +19, -3, + +9818, +8134, +2487, +2440, -2082, -590, -823, -829, +309, -432, -1752, +1141, +1209, -1118, +27, -830, -297, -203, -900, +148, -415, -552, +316, +48, -77, +666, +249, +139, -158, -658, +206, +196, + +8218, +7700, +2637, +2474, -1307, -764, -546, -580, +192, -485, -1350, +993, +1042, -888, +8, -569, -372, -127, -680, -31, -355, -306, +131, -53, +119, +550, +383, +249, -130, -272, +357, +9, + +7260, +6952, +2528, +2729, -947, -957, -177, -207, -119, -455, -915, +762, +893, -798, +106, -330, -495, -95, -429, -94, -346, -203, -44, +24, +289, +567, +633, +250, -96, -40, +210, -228, + +6314, +6251, +2666, +2794, -629, -891, -34, +102, -183, -316, -716, +491, +887, -525, +110, -285, -414, +113, -262, -316, -185, -38, -118, +319, +459, +666, +731, +112, -104, -55, +52, -322, + +5417, +5613, +2827, +2816, -327, -838, +28, +455, -189, -286, -591, +343, +896, -378, +146, -174, -275, +223, -276, -286, +110, +144, +58, +429, +461, +747, +496, -173, -50, +14, -42, -390, + +4737, +5252, +2774, +2553, +28, -656, +97, +596, -174, -128, -477, +136, +904, -37, +86, -133, -68, +253, -71, +76, +414, +107, +44, +523, +339, +397, +292, -77, +23, -24, -184, -339, + +3981, +4689, +2974, +2705, +128, -673, +191, +862, -76, -188, -396, +170, +926, +95, +102, -7, +257, +567, +232, +227, +237, +46, +2, +205, +229, +329, +244, -63, +38, -31, -270, -262, + +3639, +4461, +2924, +2330, +166, -438, +386, +823, -29, -56, -316, +227, +932, +175, +339, +566, +570, +436, +183, +186, -95, -222, +17, +187, +153, +207, +145, +26, +72, -187, -282, -293, + +3259, +4171, +2982, +2255, +67, -366, +661, +923, -74, +111, -202, +162, +1330, +741, +513, +485, +402, +353, -62, -283, -157, +6, -120, +24, +146, +186, +148, -35, -33, -267, -322, -309, + +3122, +4118, +2900, +1944, +0, -98, +882, +1021, -181, +159, +515, +745, +1264, +473, +425, +351, -23, -30, -118, -265, -166, -97, -186, +192, +98, -114, +91, +11, -210, -322, -297, -412, + +3235, +4303, +2623, +1571, +77, +285, +881, +1185, +547, +613, +652, +402, +925, +370, -45, -8, +19, -59, -264, -364, +11, +81, -230, -1, -128, -117, +119, -34, -321, -411, -265, -385, + +3389, +4725, +2245, +1203, +58, +908, +2020, +1399, +334, +357, +538, +113, +387, +96, +39, -34, -209, -107, -173, -4, +62, -200, -339, -98, -124, -103, +123, -133, -427, -315, -196, -296, + +3432, +4882, +1947, +1109, +1266, +1747, +1687, +1007, +236, +86, +163, -84, +293, +0, -42, -68, -271, +122, +155, -210, -251, -156, -291, -288, -163, +38, -58, -180, -248, -250, -248, -317, + +3101, +4702, +2964, +1975, +929, +1541, +1764, +744, -57, -59, +188, -44, +87, -46, -2, +54, +100, +125, -120, -181, -166, -232, -402, -239, -149, -71, +43, -36, -164, -289, -356, -319, + +3896, +5904, +2447, +896, +1159, +1573, +1310, +595, -175, -62, +179, +2, +162, -166, +142, +495, +86, -291, -23, -10, -305, -361, -351, -199, -209, +43, +163, +6, -270, -382, -312, -377, + +4111, +6381, +2053, +273, +1154, +1396, +1209, +828, +5, -261, +331, +111, +75, +99, +333, +466, -15, -97, -25, -78, -294, -279, -352, -332, -105, +81, +175, -17, -195, -388, -359, -345, + +3095, +5772, +3360, +570, +281, +922, +1379, +1273, +83, -225, +436, +376, -8, +55, +499, +520, +210, -84, -45, +41, -164, -351, -289, -251, -244, +17, +144, +52, -153, -277, -319, -362, + +2581, +5083, +3747, +1205, +166, +554, +1050, +1250, +302, -212, +397, +598, +127, +67, +436, +383, +436, +172, +39, +53, -182, -180, -149, -287, -291, -5, +118, -12, -207, -177, -214, -333, + +2552, +4951, +3531, +1372, +349, +359, +972, +1271, +183, -443, +321, +679, +210, +58, +442, +429, +340, +218, +211, +180, -63, -124, -120, -161, -112, -103, +24, +72, -222, -300, -275, -209, + +2665, +4956, +3357, +1460, +482, +248, +879, +1296, +212, -508, +150, +505, +100, +12, +412, +341, +306, +406, +139, +62, +128, -3, -44, -39, -12, -31, +66, +41, -175, -338, -364, -294, + +2910, +5172, +3202, +1418, +526, +219, +908, +1323, +135, -544, +153, +494, +74, -268, +195, +282, +179, +422, +266, +64, +20, -95, +137, +155, -18, +190, +178, +50, -99, -282, -367, -378, + +3106, +5510, +3157, +1272, +654, +172, +826, +1393, +101, -594, +108, +460, +164, -335, -22, +133, -125, +219, +461, +52, -105, -110, +31, +176, +54, +285, +298, +145, +61, -223, -389, -316, + +3368, +5932, +3118, +1145, +758, +78, +765, +1468, +37, -717, +138, +457, +120, -290, -144, +62, -257, -129, +404, +63, -206, -153, -100, +152, +60, +155, +386, +264, +71, -31, -197, -377, + +3733, +6456, +3058, +942, +889, +25, +681, +1552, -15, -820, +148, +459, +69, -211, -190, -47, -265, -323, +274, +169, -372, -347, -72, +87, +21, +34, +374, +281, +11, +98, -68, -219, + +4188, +7066, +2967, +691, +995, -34, +635, +1651, -188, -887, +235, +437, -43, -227, -100, -139, -354, -381, +96, +266, -304, -584, -157, +39, -36, +7, +204, +218, +59, +6, -48, -108, + +4746, +7725, +2804, +457, +1072, -163, +664, +1759, -458, -963, +395, +430, -203, -287, -43, -200, -465, -426, -10, +200, -148, -659, -283, +63, -164, -51, +108, +49, +5, -21, -57, -176, + +5293, +8424, +2691, +200, +1075, -352, +722, +1883, -811, -1091, +593, +430, -407, -391, +9, -266, -633, -524, -73, +107, -103, -596, -428, +55, -134, -199, +69, -190, -167, +13, -143, -226, + +5863, +9141, +2667, +40, +1052, -543, +868, +2094, -1172, -1177, +878, +497, -546, -487, +104, -257, -732, -597, -153, +94, -40, -473, -388, -65, +22, -141, -52, -184, -372, -50, -90, -264, + +6256, +9830, +2894, -163, +970, -781, +879, +2372, -1514, -1408, +1131, +611, -714, -628, +124, -250, -817, -728, -318, +48, +3, -481, -237, -140, -63, +59, -165, -299, -349, -283, -158, -207, + +6594, +10538, +3188, -331, +878, -910, +803, +2530, -1667, -1658, +1306, +784, -813, -792, +152, -249, -880, -762, -546, -74, +192, -563, -200, +88, -247, +128, -7, -470, -416, -264, -343, -125, + +6837, +11211, +3624, -582, +873, -887, +585, +2486, -1630, -1804, +1272, +974, -837, -900, +104, -254, -971, -753, -648, -416, +302, -345, -395, +287, -167, -70, +229, -446, -659, -259, -391, -167, + +7304, +11778, +3694, -565, +932, -974, +429, +2281, -1610, -1825, +1167, +1061, -833, -962, +48, -273, -1134, -738, -667, -706, +131, -22, -389, +150, +154, -245, +198, -184, -827, -453, -344, -269, + +8235, +12147, +3165, -179, +1250, -1280, +244, +2247, -1802, -1646, +1035, +1095, -763, -1091, +127, -372, -1161, -866, -623, -801, -185, +121, -30, -44, +248, -32, -42, -16, -686, -726, -403, -227, + +9297, +12266, +2226, +787, +1787, -2113, +102, +2510, -2139, -1611, +994, +1052, -665, -1269, +199, -511, -1125, -991, -710, -778, -421, -49, +341, +106, +24, +220, -125, -69, -467, -801, -641, -218, + +10147, +12083, +1353, +2463, +2227, -3535, +293, +3115, -2724, -1863, +1270, +952, -736, -1330, +259, -696, -1131, -995, -849, -797, -533, -301, +461, +439, -103, +301, -72, -178, -379, -650, -774, -450, + +10811, +11594, +849, +4553, +2308, -5080, +959, +3783, -3596, -2129, +1832, +791, -1018, -1161, +326, -938, -1147, -869, -944, -907, -502, -461, +355, +652, +38, +401, -29, -244, -390, -373, -749, -645, + +12468, +11803, -955, +4782, +3329, -5109, +523, +3592, -3808, -2001, +2054, +456, -1328, -944, +309, -1271, -1148, -913, -864, -1037, -475, -486, +86, +849, +201, +318, +27, -164, -495, -300, -684, -554, + +14105, +12174, -2678, +4502, +4313, -4564, -152, +3309, -3818, -1885, +2202, +220, -1631, -822, +354, -1654, -1062, -1037, -689, -1076, -553, -275, -262, +847, +479, +306, -29, -31, -462, -290, -612, -344, + +15495, +12899, -4263, +3779, +5080, -3531, -900, +2885, -3629, -1828, +2258, +22, -1763, -951, +442, -1975, -1049, -1113, -557, -940, -769, +0, -446, +597, +677, +483, -199, +94, -302, -403, -398, -267, + +17119, +13318, -5617, +3044, +5263, -2373, -1299, +2236, -3473, -1545, +2114, -220, -1690, -1270, +432, -2146, -1156, -1068, -496, -761, -890, +68, -296, +183, +744, +728, -384, +229, -162, -523, -141, -307, + +18484, +13996, -6861, +2361, +5043, -1327, -1316, +1482, -3224, -1275, +1889, -488, -1425, -1754, +345, -2172, -1331, -893, -513, -608, -886, +7, -57, -56, +527, +1062, -513, +203, +21, -599, -22, -277, + +19664, +14808, -7930, +1852, +4472, -629, -944, +743, -2898, -1130, +1684, -714, -1190, -2160, +165, -2109, -1400, -723, -585, -442, -817, -87, +159, -22, +135, +1403, -577, -74, +264, -623, -30, -70, + +21117, +15043, -8651, +1665, +3562, -302, -433, +306, -2732, -998, +1479, -897, -1082, -2373, -85, -2001, -1270, -757, -612, -253, -784, -73, +231, +244, -130, +1411, -530, -488, +338, -544, +88, +69, + +22154, +15465, -8959, +1402, +2531, -346, +86, +155, -2719, -964, +1298, -1197, -837, -2538, -368, -1715, -1223, -911, -611, -54, -781, -33, +268, +653, -384, +1073, -318, -957, +90, -192, +241, +104, + +22859, +15907, -8818, +1234, +1297, -584, +637, +95, -2746, -892, +980, -1473, -344, -2665, -593, -1404, -1232, -1113, -586, +219, -920, +190, +386, +763, -501, +647, -217, -1200, -157, -60, +514, +428, + +23324, +16162, -8220, +1233, -271, -830, +1044, +4, -2761, -848, +545, -1644, +393, -2819, -805, -1116, -1381, -1232, -481, +245, -798, +446, +127, +832, -496, +109, -143, -1012, -512, -218, +1023, +636, + +23496, +16326, -7279, +1262, -1985, -1155, +1282, -135, -2863, -819, +135, -1617, +1191, -3031, -953, -1076, -1474, -1177, -641, +567, -852, +321, -9, +770, -595, -103, +21, -1077, -316, -427, +637, +1058, + +23095, +16685, -5961, +1382, -3468, -1694, +1418, -258, -2996, -670, +47, -1596, +2016, -3064, -1350, -839, -1582, -979, -545, +371, -989, +403, -350, +690, -257, -300, +78, -651, -207, -824, +183, +1360, + +23064, +16194, -4345, +1405, -4772, -2458, +1309, -309, -3246, -87, -265, -1329, +2641, -3203, -1669, -828, -1062, -1045, -1017, +329, -1074, +156, -379, +809, -266, -110, +348, -721, -327, -460, -318, +476, + +22166, +16307, -2720, +1513, -5503, -3602, +868, +57, -3167, +189, -262, -1102, +3165, -3419, -1892, +19, -1444, -1300, -1087, -50, -1052, +281, -440, +743, +297, +10, -121, -326, +62, -941, -205, -296, + +21370, +16040, -1198, +1538, -5866, -4987, +180, +1090, -3147, +120, +48, -770, +2709, -2688, -1726, -511, -1299, -1588, -1418, -44, -787, -13, -172, +1224, -173, +86, +190, -419, +152, -1134, +61, -580, + +20588, +15763, -447, +2263, -6362, -6502, +294, +1839, -3312, +732, -314, -780, +3610, -2936, -1826, -471, -1919, -1347, -1286, -339, -634, +489, -63, +635, +27, +550, -117, -722, +816, -1169, -430, +0, + +20517, +14351, +399, +2893, -7361, -6720, +201, +2186, -2610, +382, -514, +112, +3193, -2866, -1734, -1281, -1564, -810, -1919, -87, +325, -151, -301, +1086, -74, +249, +48, -598, +812, -904, -810, +141, + +19676, +13347, +1269, +2990, -7493, -6742, +83, +2235, -1954, +838, -1855, +980, +3383, -3609, -1607, -1296, -1241, -963, -1499, +306, -188, -169, +134, +680, -311, +474, +114, -498, +603, -657, -632, -512, + +18294, +12994, +1651, +2477, -6776, -5594, -1193, +2361, -74, -729, -2110, +2060, +2280, -3521, -925, -1755, -1040, +4, -1831, -24, +217, -146, -194, +523, -89, +412, +148, -368, +547, -585, -520, -748, + +18558, +12123, -346, +2881, -6362, -4645, -59, +1181, -164, -263, -2409, +2048, +1834, -3453, -616, -1525, -435, -206, -2101, +563, +264, -775, -79, +639, -65, +370, -42, -65, +678, -907, -609, -386, + +17685, +10480, -40, +3473, -6519, -2739, -508, +476, +794, -1230, -2572, +2593, +1476, -3576, +141, -1207, -497, -277, -1926, +798, -90, -892, +128, +624, -265, +467, +194, -122, +569, -901, -567, -322, + +16309, +9199, +186, +4082, -5385, -2804, -279, +710, -5, -1375, -2021, +2397, +953, -2773, +531, -1321, -456, -212, -1629, +612, -269, -841, +361, +372, -412, +797, +264, -230, +451, -838, -585, -226, + +15571, +11264, +2379, +478, -10208, -3446, +2999, +3275, -500, -1930, -3348, +266, +1652, -1984, +1186, -362, -580, +611, -665, +483, -71, -639, -236, -683, -414, +551, -551, -99, +973, -315, +229, -109, + +13108, +11000, +3186, +1280, -8696, -4695, +2112, +2705, +415, -824, -3163, -516, +1162, -1069, +990, -408, -449, +725, -557, +276, +252, -440, -211, -595, -598, +266, -697, +52, +1118, -108, +414, -97, + +11346, +10103, +3442, +1763, -7242, -4319, +1504, +1898, +542, -443, -2642, -793, +1114, -726, +553, -274, -403, +642, -397, +111, +268, -218, -281, -579, -486, +53, -591, +203, +993, +104, +363, -159, + +9333, +9181, +4026, +1891, -5737, -3665, +628, +1442, +686, -179, -2080, -924, +1011, -560, +271, -128, -344, +546, -210, +21, +313, -35, -349, -508, -402, +17, -265, +291, +786, +199, +233, -195, + +7824, +8565, +4450, +1794, -4594, -3174, +140, +1252, +671, +30, -1593, -927, +798, -461, +248, -40, -339, +534, -12, -10, +342, +33, -332, -281, -185, +20, -144, +273, +558, +171, +139, -239, + +6337, +7830, +4715, +1908, -3553, -2897, -163, +1081, +702, +211, -1249, -839, +616, -437, +196, +111, -267, +479, +135, +12, +326, +212, -47, -34, -177, -218, -105, +167, +266, +120, +84, -158, + +5342, +7158, +4878, +2188, -2903, -2714, -263, +1026, +804, +276, -973, -621, +425, -432, +323, +229, -177, +523, +156, +236, +666, +314, -37, +11, -270, -439, -68, +145, +155, +196, +77, -226, + +4764, +6717, +4705, +2043, -2555, -2349, -213, +866, +792, +353, -756, -574, +302, -362, +407, +259, -158, +679, +475, +400, +570, +170, -131, -157, -526, -408, +47, -28, +159, +57, -96, +32, + +4181, +6120, +4609, +2151, -2225, -2162, -181, +900, +848, +365, -518, -436, +242, -269, +393, +570, +370, +732, +393, +271, +373, -75, -324, -138, -536, -326, +93, -221, -12, +223, +50, -24, + +4015, +5982, +4273, +1823, -2038, -1791, +35, +933, +871, +389, -235, -337, +148, +75, +824, +806, +274, +455, +265, +150, +178, -130, -231, -188, -435, -270, -151, -8, +202, +32, -30, +38, + +3935, +5782, +3945, +1507, -1917, -1335, +323, +927, +964, +503, -86, -55, +602, +326, +626, +524, +61, +238, +130, +138, +142, -108, -297, -233, -424, -97, +144, -211, +2, +11, +59, +102, + +3902, +5745, +3557, +1311, -1656, -1075, +626, +1068, +893, +711, +517, +29, +271, +228, +356, +317, +28, +184, +167, +138, +52, -157, -344, -161, +13, -100, -239, -186, +14, +16, +22, +148, + +3628, +5656, +3399, +1258, -1213, -703, +858, +1220, +1301, +913, +184, -182, +3, -30, +266, +240, +91, +140, +96, +72, +8, -109, -120, +190, -242, -389, -174, -137, -134, -75, +225, -41, + +3635, +5627, +3156, +1153, -667, -305, +1152, +1542, +949, +463, +84, -274, -67, -129, +266, +232, +17, +66, +88, +199, -87, +174, +189, -310, -329, -218, -244, -286, -93, -9, -62, +33, + +3750, +5696, +2978, +1126, -254, +215, +1221, +1141, +606, +286, +8, -220, -48, -224, +233, +223, -143, +120, +323, +31, +156, +458, -282, -324, -203, -336, -370, -173, -80, -307, +26, +219, + +3708, +6007, +3252, +1084, -197, +131, +973, +976, +487, +259, +136, -370, -69, -106, +43, +210, -33, +247, +171, +273, +554, -86, -293, -37, -371, -530, -251, -143, -337, -184, +155, +321, + +3943, +6405, +3364, +855, -445, -300, +746, +1177, +555, +245, +158, -422, -186, -48, +127, +143, +129, +192, +83, +689, +384, -278, -109, -102, -392, -521, -225, -363, -322, +86, +221, +118, + +3963, +6788, +3553, +597, -677, -627, +588, +1136, +500, +391, +206, -514, -153, +22, +70, +197, +285, -39, +123, +985, +227, -286, +1, -155, -441, -352, -267, -542, -311, +209, +364, -112, + +3772, +6899, +3947, +501, -937, -727, +636, +1168, +340, +109, +160, -312, -140, -4, +244, +180, +122, +45, +73, +884, +451, -250, -58, -111, -413, -290, -294, -523, -289, +122, +331, -74, + +3462, +6882, +4502, +695, -1202, -904, +656, +1374, +518, -169, -142, -383, -288, +151, +492, +188, +134, +104, -153, +774, +761, -195, -124, +19, -277, -262, -247, -438, -285, +127, +319, -81, + +3402, +6922, +4775, +801, -1378, -1083, +663, +1537, +602, -245, -249, -453, -540, -124, +493, +404, +124, +134, -71, +426, +838, +18, -287, -73, -153, -110, -193, -451, -296, +175, +269, -23, + +3560, +7157, +4846, +842, -1601, -1246, +801, +1630, +679, -335, -317, -376, -611, -299, +272, +320, +96, +184, +134, +295, +750, +284, -376, -324, -110, -14, -46, -352, -273, +168, +253, +68, + +3781, +7518, +5064, +780, -1878, -1426, +861, +1887, +678, -490, -323, -360, -585, -337, +124, +225, -92, -87, +272, +304, +648, +580, -207, -590, -353, -33, +88, -214, -276, +256, +259, +93, + +4023, +8013, +5260, +520, -2126, -1537, +904, +2110, +621, -684, -367, -338, -545, -334, +31, +151, -90, -326, +98, +316, +484, +602, +136, -551, -624, -186, +88, -177, -281, +258, +226, +119, + +4437, +8672, +5470, +189, -2426, -1777, +1004, +2534, +471, -984, -417, -281, -536, -313, +40, +69, -119, -424, -33, +239, +301, +445, +325, -371, -639, -347, -13, -119, -335, +161, +141, +68, + +4952, +9349, +5539, -179, -2758, -2011, +1219, +2888, +279, -1276, -463, -211, -592, -300, +102, -4, -169, -480, -76, +194, +168, +301, +339, -242, -691, -395, -6, -107, -357, +112, +26, -204, + +5239, +10282, +5947, -647, -3196, -2226, +1311, +3315, +161, -1681, -491, -173, -597, -373, +170, -45, -294, -440, -175, +126, +127, +78, +331, -124, -648, -478, -149, -83, -176, +24, -84, -362, + +5839, +11149, +6005, -1123, -3665, -2327, +1613, +3627, -71, -2065, -429, -99, -639, -410, +251, -61, -421, -436, -166, +117, +55, -75, +317, -59, -558, -473, -198, -174, -157, +173, -146, -406, + +6264, +12031, +6260, -1503, -4165, -2511, +1902, +3881, -220, -2443, -428, +51, -706, -495, +320, -9, -559, -492, -144, +113, +44, -260, +228, +46, -480, -381, -268, -203, -217, +218, -114, -429, + +6813, +12945, +6569, -1945, -4848, -2783, +2188, +4127, -523, -2951, -443, +204, -809, -654, +274, +56, -695, -599, -243, +84, +37, -469, +12, +64, -398, -293, -252, -328, -254, +98, -55, -527, + +7209, +13717, +6921, -1967, -5316, -3090, +2544, +4308, -606, -3304, -485, +501, -832, -729, +300, +116, -725, -556, -280, +71, +96, -513, -156, +86, -225, -237, -54, -372, -184, +51, -70, -428, + +7996, +14426, +6885, -1822, -5825, -3511, +3030, +4353, -912, -3620, -593, +764, -830, -921, +358, +119, -837, -534, -312, +44, +63, -481, -430, -53, +49, -227, +88, -308, -219, +114, -168, -425, + +8882, +15071, +6412, -1835, -5966, -3673, +3408, +4119, -1227, -3662, -763, +899, -746, -1111, +359, +151, -942, -516, -330, +17, -16, -403, -535, -393, +280, -94, +75, -119, -291, +140, -109, -538, + +10567, +15752, +4909, -1935, -5684, -3567, +3668, +3636, -1744, -3453, -930, +847, -522, -1336, +279, +135, -969, -534, -297, -7, -169, -364, -497, -748, +299, +223, -60, +142, -209, -44, +74, -643, + +11943, +15859, +3693, -1168, -5342, -4152, +3859, +3672, -2239, -3456, -946, +824, -414, -1484, +211, +82, -987, -499, -174, -100, -272, -362, -415, -898, +70, +599, -127, +237, +12, -204, +166, -634, + +13286, +15772, +2438, -128, -4984, -4823, +4009, +3750, -2786, -3502, -799, +696, -411, -1556, +156, -56, -1055, -395, +29, -275, -377, -305, -450, -921, -205, +832, -22, +179, +243, -241, +88, -561, + +15203, +16245, +66, +61, -3930, -4645, +3668, +3392, -3154, -3516, -581, +453, -338, -1692, +34, -193, -1068, -347, +256, -295, -574, -274, -592, -759, -402, +757, +277, +182, +289, -131, -87, -538, + +17246, +16423, -2122, -11, -3063, -3961, +3236, +2949, -3315, -3590, -360, +310, -300, -1854, +21, -379, -1001, -238, +408, -257, -762, -185, -742, -584, -408, +586, +464, +330, +189, -58, -105, -673, + +19117, +17194, -4525, -594, -2040, -2928, +2541, +2436, -3174, -3955, -153, +154, -238, -2084, -35, -538, -893, -103, +477, -124, -1066, -60, -862, -458, -281, +408, +389, +584, +66, -198, +49, -844, + +20721, +17777, -6299, -1368, -1442, -1849, +1965, +2056, -2976, -4357, -43, +20, -202, -2215, -94, -626, -745, -20, +462, +11, -1311, +50, -912, -421, -24, +317, +54, +773, +39, -439, +197, -803, + +22510, +18390, -7885, -2507, -1141, -610, +1490, +1800, -2821, -4825, -36, -196, -92, -2264, -98, -656, -568, +0, +406, +174, -1496, +186, -1014, -271, +276, +136, -341, +713, +119, -602, +263, -543, + +23764, +19077, -8920, -3523, -1276, +188, +1429, +1689, -2771, -5201, -193, -427, +128, -2191, -88, -582, -532, -60, +345, +366, -1555, +193, -996, -85, +266, +23, -631, +431, +299, -553, +232, -344, + +24818, +19733, -9528, -4328, -1918, +770, +1688, +1610, -2757, -5522, -511, -645, +585, -2065, -55, -440, -631, -162, +378, +612, -1616, +251, -901, -119, +151, -32, -905, +195, +543, -403, +171, -190, + +25942, +20257, -9828, -5006, -3337, +1229, +2251, +1491, -2816, -5884, -1016, -737, +1357, -2026, +75, -408, -894, -120, +477, +717, -1428, +314, -1223, -176, -2, -219, -932, +91, +634, -169, +260, -194, + +26806, +20370, -9612, -5429, -4920, +1516, +2696, +1428, -3018, -6052, -1361, -633, +1984, -1981, +130, -617, -894, -5, +427, +963, -1258, -100, -1423, -216, -233, -165, -732, -55, +587, +188, +254, -445, + +27209, +20584, -8793, -5848, -6861, +1389, +3245, +1326, -3300, -5756, -1708, -571, +2761, -2008, -124, -572, -811, +83, +640, +854, -1485, -319, -1727, -286, -130, -52, -610, -82, +598, +192, +317, -394, + +26893, +21151, -7832, -5916, -8592, +716, +3831, +1043, -3056, -5275, -2081, -436, +3209, -2095, -313, -337, -686, +446, +148, +578, -1361, -677, -1772, -79, -85, -62, -326, -96, +288, +256, +729, -628, + +26953, +20650, -6193, -5839, -10706, -128, +4025, +1350, -2673, -4655, -2334, -397, +3476, -2270, -280, +333, -640, -63, -135, +292, -1261, -713, -1609, +24, -62, +134, -367, -195, +342, +253, +839, -600, + +26223, +20702, -4716, -5564, -12304, -1451, +4411, +2099, -2421, -4083, -2432, -598, +3439, -2035, +238, +317, -1138, -105, -496, +286, -908, -750, -1436, +173, -78, -80, -177, -33, +173, +164, +1062, -575, + +25928, +19969, -3485, -5141, -13936, -2549, +5094, +2717, -2372, -3260, -2726, -1115, +3984, -1704, +8, +193, -1565, -173, -413, +254, -689, -651, -1111, -74, -302, +129, -24, -206, +176, +212, +1048, -582, + +25176, +19122, -2331, -4479, -15530, -3096, +5493, +3261, -1783, -2862, -3340, -611, +4094, -2064, +150, -498, -1520, +306, -690, +346, -212, -559, -1329, -185, -92, +42, -36, -161, +240, +170, +921, -542, + +24482, +17970, -1385, -4296, -15673, -3520, +5482, +4107, -1928, -2384, -3245, -840, +4078, -2209, -307, -382, -1158, +232, -617, +670, -229, -809, -1085, -111, -314, +49, +102, -188, +256, +76, +933, -522, + +23018, +16730, -558, -3503, -15157, -4048, +5380, +4222, -1077, -2064, -4052, -288, +3518, -2565, -42, -296, -1035, +526, -341, +255, -181, -591, -933, -333, -446, +264, +149, -398, +317, +312, +625, -550, + +21612, +15388, -80, -2338, -14307, -4401, +4806, +4911, -877, -2366, -3925, -404, +3244, -2585, +155, -320, -674, +881, -905, +291, +164, -706, -883, -428, -426, +443, -108, -467, +714, +169, +330, -367, + +19859, +13489, +594, -510, -13595, -4524, +5021, +4279, -755, -2023, -4414, +179, +2843, -2732, +498, -73, -330, +471, -963, +610, +149, -898, -638, -432, -427, +380, -223, -282, +814, +29, +168, -248, + +17742, +12321, +1537, +213, -12421, -3676, +4012, +3612, -294, -2291, -3920, +331, +2249, -2515, +892, +37, -643, +510, -767, +581, +11, -855, -358, -539, -531, +491, -270, -331, +960, -123, +115, -173, + +16821, +11926, +463, -1706, -11380, -169, +5057, +1524, -1492, -1439, -2644, -359, +2193, -2391, +635, +125, -644, +317, -422, +472, -172, -610, -637, -211, -252, -7, -26, -80, -218, -217, +829, -147, + +13656, +11995, +3238, -883, -11164, -2746, +3338, +2611, +688, -1041, -2888, -1083, +1213, -1539, +1161, +189, -818, +634, -355, +123, +274, -342, -515, +152, -873, -436, -4, -321, +327, +309, +783, -46, + +11207, +10925, +3942, -83, -8816, -2936, +2399, +2271, +597, -709, -2174, -1110, +823, -992, +937, +143, -694, +584, -237, +52, +375, -217, -303, +162, -792, -361, +105, -252, +214, +381, +632, -19, + +9243, +9941, +4245, +657, -6939, -2976, +1760, +1792, +578, -304, -1653, -1098, +643, -655, +689, +159, -542, +528, -131, +56, +430, -13, -221, +210, -469, -319, +52, -319, +110, +335, +494, +43, + +7775, +9004, +4364, +1074, -5566, -2771, +1288, +1356, +632, -19, -1266, -996, +487, -456, +486, +214, -418, +456, -8, +91, +463, +193, -8, +266, -378, -438, -88, -360, -112, +272, +544, +30, + +6749, +8329, +4226, +1199, -4454, -2378, +954, +1109, +723, +141, -897, -819, +428, -339, +428, +308, -281, +463, +96, +331, +672, +327, +10, +166, -357, -510, -211, -393, -151, +319, +576, +31, + +5988, +7653, +4116, +1168, -3765, -2038, +743, +915, +737, +259, -623, -668, +285, -262, +442, +295, -206, +564, +342, +402, +543, +169, -105, +70, -443, -594, -251, -433, -272, +334, +502, -77, + +5467, +7250, +3847, +1019, -3110, -1692, +669, +871, +822, +369, -365, -484, +245, -133, +474, +473, +20, +567, +337, +288, +369, +117, -150, +13, -324, -594, -356, -414, -226, +271, +602, +138, + +5122, +6973, +3542, +803, -2565, -1389, +713, +947, +893, +463, -170, -291, +235, +82, +633, +446, -49, +345, +308, +240, +201, +133, -77, -9, -324, -573, -352, -476, -45, +494, +363, +16, + +4855, +6836, +3247, +531, -2098, -1103, +840, +1094, +882, +577, -75, -121, +401, +26, +454, +321, -151, +130, +276, +269, +118, +152, -61, -115, -199, -507, -538, -83, +76, +24, +184, +126, + +4686, +6807, +3020, +381, -1698, -797, +985, +1300, +880, +654, +193, -260, +327, -18, +295, +312, -217, +5, +244, +427, +89, +60, +69, +22, -305, -328, -97, -385, -172, +69, +91, +154, + +4632, +6769, +2880, +360, -1379, -630, +1032, +1346, +1008, +601, +155, -416, +54, +91, +208, +254, -266, -94, +300, +314, +94, +118, +154, -112, -59, +83, -557, -570, -137, +42, +28, +65, + +4540, +6825, +2991, +442, -1145, -666, +903, +1315, +922, +656, +103, -490, -32, -70, +234, +239, -193, -130, +219, +288, +5, +292, +9, +89, +428, -439, -684, -356, -314, -42, +168, -24, + +4565, +7043, +3133, +398, -1092, -628, +698, +1105, +781, +505, +302, -393, -208, -57, +80, +210, -27, -27, +131, +97, +164, +95, +10, +715, +96, -727, -439, -390, -341, +7, +168, -278, + +4628, +7376, +3330, +175, -1131, -632, +658, +1096, +468, +306, +276, -396, -10, -64, +41, +226, -104, +83, +212, +65, +61, -40, +256, +815, -181, -624, -368, -423, -196, +109, -11, -411, + +4617, +7799, +3588, -63, -1282, -806, +761, +1267, +342, +103, +9, -566, -109, +89, +288, +207, -102, +37, +103, +149, +142, -173, +222, +878, -329, -612, -244, -446, -47, +197, -164, -416, + +4660, +8175, +3965, -277, -1581, -952, +885, +1487, +358, +16, -136, -742, -411, +6, +351, +359, +99, +41, +67, +54, +185, -145, +158, +875, -393, -637, -194, -414, +89, +273, -162, -421, + +4721, +8663, +4296, -438, -1910, -1208, +1075, +1666, +396, -64, -205, -776, -575, -199, +234, +288, +60, +190, +260, +39, +105, -43, -107, +796, -78, -840, -343, -310, +149, +286, -89, -348, + +4872, +9194, +4729, -774, -2386, -1225, +1197, +1899, +429, -345, -152, -738, -728, -229, +85, +167, -114, +11, +383, +94, +153, +194, -391, +530, +269, -869, -518, -280, +55, +314, -13, -367, + +5066, +9823, +5271, -1107, -2955, -1313, +1335, +2152, +396, -624, -133, -598, -828, -241, +24, +42, -162, -203, +299, +184, -39, +336, -145, +68, +454, -442, -819, -503, +69, +300, -63, -319, + +5153, +10511, +6095, -1484, -3588, -1456, +1423, +2504, +356, -975, -219, -396, -876, -284, +78, -92, -239, -325, +171, +296, -163, +80, +60, -117, +343, +144, -711, -771, -136, +164, +7, -305, + +5279, +11273, +7005, -1898, -4346, -1576, +1570, +2874, +319, -1413, -325, -192, -896, -360, +145, -111, -363, -399, +61, +261, +19, -193, -117, -56, -9, +423, -34, -872, -482, +162, -138, -388, + +6056, +12428, +7017, -2743, -5015, -1595, +2092, +3133, -74, -1835, -369, -82, -887, -433, +159, -124, -505, -444, +1, +176, +57, -207, -371, -191, -116, +297, +399, -455, -738, -65, -85, -546, + +6550, +13417, +7566, -3351, -5854, -1576, +2466, +3359, -262, -2321, -480, +199, -992, -483, +233, -211, -561, -459, -82, +172, +17, -196, -387, -532, -129, +223, +460, +107, -612, -458, -73, -511, + +7012, +14309, +8271, -3829, -6828, -1561, +2860, +3523, -456, -2805, -697, +575, -1040, -702, +326, -213, -692, -488, -58, +49, +67, -318, -318, -681, -441, +323, +421, +317, -109, -624, -463, -340, + +8016, +15374, +8120, -4423, -7514, -1497, +3500, +3557, -967, -3143, -754, +778, -1014, -873, +371, -263, -697, -565, +8, +40, -65, -294, -389, -676, -607, +208, +557, +311, +173, -239, -863, -535, + +8871, +16239, +8063, -4588, -8132, -1638, +4115, +3491, -1344, -3391, -963, +994, -922, -1121, +393, -248, -762, -536, +34, +55, -184, -324, -431, -662, -593, -42, +629, +427, +134, +214, -755, -1041, + +9741, +17020, +7674, -4576, -8426, -2000, +4611, +3393, -1757, -3551, -1213, +1115, -851, -1378, +299, -217, -824, -499, +46, +51, -282, -489, -415, -741, -447, -171, +355, +641, +79, +272, -284, -1349, + +11312, +17790, +6362, -4799, -8173, -2096, +4973, +3237, -2301, -3658, -1190, +1112, -886, -1482, +185, -250, -754, -451, +117, +102, -439, -579, -427, -793, -304, +10, -28, +635, +235, +100, +114, -1241, + +13177, +18485, +4498, -4942, -7590, -1947, +5032, +3048, -2673, -3843, -991, +968, -867, -1596, +107, -286, -639, -361, +165, +232, -672, -529, -499, -772, -195, +286, -298, +389, +407, -34, +287, -927, + +15061, +19221, +2298, -5197, -6823, -1696, +4782, +2846, -2873, -4171, -778, +660, -800, -1706, -5, -268, -588, -254, +120, +358, -929, -400, -614, -747, -72, +413, -441, -8, +458, -76, +301, -594, + +17417, +19661, -218, -5533, -6027, -1097, +4358, +2666, -3090, -4449, -601, +308, -686, -1718, -14, -284, -463, -238, +124, +408, -1064, -243, -713, -651, +62, +367, -575, -268, +316, -31, +381, -321, + +19867, +19942, -2698, -5917, -5419, -356, +3943, +2529, -3315, -4768, -533, -59, -432, -1576, -30, -272, -359, -356, +203, +452, -1089, -118, -778, -495, +49, +184, -640, -440, +103, +121, +489, -151, + +22000, +20274, -4928, -6244, -5183, +422, +3657, +2387, -3535, -5191, -499, -408, +124, -1486, -39, -209, -489, -410, +327, +558, -1091, -6, -842, -510, -62, +53, -686, -527, +27, +247, +412, +120, + +23867, +20630, -6764, -6611, -5435, +1219, +3584, +2132, -3790, -5664, -426, -579, +849, -1544, +115, -346, -693, -253, +402, +737, -1086, +70, -1208, -570, -77, -89, -681, -321, -84, +142, +497, +304, + +25427, +20921, -8048, -7062, -6069, +1884, +3693, +1754, -4141, -5893, -210, -678, +1594, -1604, +126, -548, -678, -23, +392, +982, -1152, -266, -1531, -447, -207, -3, -478, -227, -288, +201, +484, +187, + +26670, +20956, -8821, -7361, -6968, +2286, +3959, +1161, -4414, -5482, -257, -597, +2261, -1827, +18, -485, -493, +96, +432, +895, -1493, -446, -1665, -450, +33, +175, -509, -150, -228, -15, +349, +351, + +27247, +21029, -9279, -7221, -8186, +2443, +4316, +433, -4111, -5058, -277, -461, +2624, -2135, +8, -68, -470, +172, -50, +659, -1495, -578, -1725, -94, +295, -26, -297, -74, -411, -173, +430, +303, + +27900, +20315, -8903, -7184, -9921, +2431, +4704, +385, -3980, -4367, -496, -493, +2857, -2265, +375, +207, -681, -337, -225, +556, -1409, -535, -1534, +66, +228, +14, -233, -136, -400, -267, +410, +268, + +27607, +19995, -8273, -6960, -11863, +2111, +5727, +206, -3669, -3625, -950, -750, +3372, -2159, +511, +126, -1428, -249, -334, +460, -1027, -385, -1566, +110, +211, -88, -105, -186, -370, -401, +501, +177, + +27622, +18453, -7307, -6733, -13561, +2585, +6218, +129, -3285, -2980, -1630, -393, +3761, -2468, +529, -441, -1518, +13, -480, +602, -588, -563, -1536, +165, +105, -89, -91, -163, -357, -425, +580, -7, + +26712, +17271, -6277, -6285, -14362, +2609, +6500, +415, -3110, -2459, -1751, -325, +3747, -2769, +192, -404, -1346, +67, -259, +700, -500, -685, -1381, +215, -122, -46, -21, -142, -291, -476, +628, -31, + +24769, +16230, -5111, -5257, -14397, +2104, +6670, +474, -2600, -1910, -2144, -355, +3491, -3153, +319, -229, -1416, +584, -304, +502, -383, -651, -1149, -88, -115, +8, -18, -89, -321, -449, +713, -173, + +22531, +14663, -3328, -4140, -13801, +1449, +6057, +1180, -2109, -1891, -2239, -499, +2901, -2827, +365, -277, -887, +650, -524, +392, -96, -669, -1178, -67, -149, -9, +23, -125, -229, -396, +626, -144, + +19895, +13154, -1419, -2898, -12707, +438, +5719, +1680, -2070, -1480, -2520, -641, +2754, -2677, +403, +34, -653, +479, -618, +548, -55, -828, -839, -119, -236, +37, -10, -61, -202, -414, +734, -50, + +15813, +10164, -3306, -1259, -4293, +3357, +1973, -2111, -1944, +200, +219, -308, +1352, -2193, +64, -117, -1126, +153, -436, +60, -137, -521, -663, +805, -86, +19, +120, -674, -64, -483, -254, +28, + +13540, +9962, -1922, -1329, -4062, +2676, +2356, -1429, -1777, +3, -53, -302, +1192, -1816, -26, +30, -863, +65, -256, +68, -137, -483, -700, +634, +28, +18, +255, -495, -126, -392, -252, -65, + +11634, +9561, -699, -1265, -3629, +2134, +2474, -898, -1471, -172, -210, -167, +1001, -1414, -33, +173, -616, +55, -78, +97, -92, -391, -629, +503, +182, +60, +264, -359, -148, -296, -278, -94, + +10116, +9195, +85, -1190, -3168, +1756, +2451, -457, -1159, -296, -215, -72, +824, -1068, +57, +267, -418, +80, +67, +164, -62, -236, -495, +399, +241, +62, +228, -255, -153, -255, -222, -97, + +8972, +8865, +505, -1212, -2723, +1474, +2315, -138, -916, -335, -184, -65, +679, -767, +131, +280, -267, +100, +140, +232, -22, -124, -428, +222, +224, +45, +106, -204, -143, -199, -220, -223, + +8143, +8550, +717, -1226, -2288, +1267, +2150, +132, -720, -286, -144, -49, +640, -554, +197, +300, -154, +119, +220, +280, -45, -61, -392, +43, +178, +16, +16, -111, -123, -218, -232, -196, + +7519, +8353, +812, -1237, -1913, +1117, +2025, +376, -587, -178, -1, -84, +685, -393, +217, +358, -60, +126, +213, +332, -84, -72, -329, -119, +124, +96, -34, -68, -117, -163, -197, -307, + +7138, +8193, +814, -1279, -1576, +1064, +1902, +541, -519, -85, +237, -175, +678, -205, +145, +407, -22, +33, +193, +347, -106, -168, -290, -132, +40, +147, -63, -81, -15, -226, -137, +56, + +6765, +8188, +868, -1293, -1277, +1051, +1806, +584, -405, -124, +486, -108, +449, +28, +127, +224, +67, +7, +73, +339, -51, -243, -320, +0, -67, +74, +55, -80, -93, +50, +86, -210, + +6619, +8107, +942, -1282, -1022, +1117, +1715, +528, -435, -63, +479, +47, +396, -99, +275, +103, -92, +116, +36, +186, -20, -104, -395, -86, -10, +55, +1, -128, +248, +155, -185, -146, + +6506, +8197, +996, -1294, -821, +1178, +1651, +459, -560, -146, +509, -44, +460, -45, +85, +200, -171, -75, +154, +145, -147, -20, -290, -290, -60, +165, -210, +91, +457, -145, -98, -174, + +6582, +8378, +972, -1387, -629, +1360, +1678, +371, -630, -289, +430, -31, +347, +59, +235, +84, -170, +9, -19, +188, -18, -105, -290, -206, -28, -83, -58, +442, +120, -133, +100, -328, + +6729, +8662, +933, -1675, -529, +1529, +1750, +352, -860, -415, +386, -244, +217, +58, +206, +210, -193, -125, +73, +64, -149, +23, -388, -231, +36, -212, +36, +433, -79, -64, +4, -312, + +6891, +9095, +950, -1986, -500, +1682, +1851, +373, -983, -585, +394, -308, -13, -44, +240, +173, -175, +14, +14, +51, -151, -125, -432, -103, +46, -279, +169, +405, -280, -72, +3, -309, + +7140, +9633, +936, -2394, -433, +1844, +1940, +403, -1165, -606, +441, -410, -140, -123, +140, +125, -224, -22, +162, +113, -243, -123, -493, -210, +171, -184, +103, +464, -305, -188, -101, -278, + +7579, +10153, +808, -2790, -377, +2061, +1958, +319, -1378, -620, +599, -484, -299, -248, +140, +31, -407, -65, +163, +117, -205, -114, -553, -215, +158, -225, +53, +587, -241, -398, -127, -310, + +8098, +10746, +572, -3255, -297, +2282, +1951, +145, -1630, -671, +779, -545, -492, -334, +56, -74, -517, -231, +85, +61, -318, -68, -487, -259, +155, -163, -275, +532, +118, -570, -295, -288, + +8856, +11416, +228, -3688, -131, +2625, +1937, -65, -1888, -582, +1023, -544, -642, -393, +130, -159, -647, -205, +40, -68, -349, -125, -337, -110, +114, -18, -391, +244, +381, -387, -478, -229, + +9699, +12034, -166, -4109, -4, +2965, +1853, -341, -2231, -485, +1256, -561, -825, -509, +157, -201, -806, -277, +86, -284, -419, -202, -354, +141, +75, -8, -343, -105, +372, -52, -654, -293, + +10543, +12775, -545, -4510, +87, +3328, +1796, -636, -2510, -451, +1566, -593, -960, -599, +156, -239, -879, -366, +153, -404, -550, -174, -435, +353, +148, -50, -279, -255, +87, +310, -515, -582, + +11200, +13601, -758, -4805, +51, +3618, +1817, -936, -2667, -529, +1865, -619, -1077, -658, +152, -290, -948, -411, +137, -381, -707, -102, -513, +487, +276, -91, -256, -301, -183, +365, -56, -808, + +11970, +14337, -1048, -4982, -71, +3819, +1800, -1224, -2823, -587, +2067, -657, -1227, -698, +129, -342, -1036, -477, +85, -363, -801, -49, -525, +479, +403, -110, -295, -362, -353, +170, +366, -705, + +12952, +14790, -1411, -4961, -192, +3874, +1746, -1433, -2954, -613, +2172, -717, -1346, -744, +115, -409, -1087, -567, +16, -356, -787, -59, -428, +439, +419, -85, -317, -480, -441, -15, +471, -306, + +13912, +15283, -1898, -4796, -288, +3733, +1713, -1566, -3031, -703, +2247, -785, -1394, -782, +55, -432, -1125, -661, -51, -311, -721, -96, -300, +422, +338, -39, -314, -612, -519, -71, +296, +100, + +14855, +15823, -2738, -4516, -305, +3389, +1721, -1674, -3103, -885, +2277, -894, -1325, -878, -28, -456, -1189, -726, -166, -184, -719, -109, -219, +375, +189, +34, -370, -698, -563, -131, +49, +307, + +16338, +16003, -4097, -3971, -183, +3015, +1641, -1812, -3218, -959, +2300, -1062, -1053, -1052, -10, -553, -1252, -711, -213, -61, -766, +9, -305, +359, +93, +64, -446, -677, -520, -329, -54, +380, + +18251, +15738, -5808, -3185, -135, +2789, +1385, -1959, -3407, -901, +2346, -1243, -701, -1229, +42, -723, -1269, -588, -226, -66, -699, +25, -533, +532, -57, +38, -378, -632, -576, -478, +14, +227, + +20108, +15232, -7463, -2359, -182, +2680, +993, -2135, -3628, -757, +2465, -1466, -282, -1397, +30, -889, -1150, -413, -456, +70, -740, -222, -483, +617, -261, +207, -289, -809, -541, -427, -149, +45, + +21818, +14565, -8920, -1528, -323, +2633, +590, -2360, -3741, -408, +2485, -1626, +257, -1681, +37, -834, -979, -443, -529, +77, -986, -154, -547, +693, -157, +334, -410, -839, -327, -606, -328, +75, + +23103, +13939, -10069, -743, -746, +2659, +301, -2677, -3587, -100, +2394, -1612, +709, -2069, +297, -672, -1108, -278, -883, +30, -908, -351, -497, +1045, -177, +252, -316, -804, -379, -726, -359, +57, + +23945, +13086, -10548, -173, -1474, +2865, +166, -2907, -3401, +227, +2202, -1525, +1022, -2203, +552, -677, -1107, -549, -996, +157, -1089, -304, -261, +1165, -310, +418, -308, -941, -344, -785, -396, +51, + +24255, +12118, -10245, -13, -2426, +3265, +310, -3204, -3183, +647, +1733, -1352, +1565, -2480, +734, -599, -1582, -399, -1019, +24, -846, -257, -242, +1202, -199, +374, -346, -1003, -311, -777, -466, +127, + +23709, +11520, -9531, -151, -3388, +3855, +550, -3483, -2789, +731, +1250, -841, +1752, -2633, +801, -862, -1583, -318, -1087, +206, -657, -373, -274, +1353, -271, +302, -334, -1032, -204, -865, -432, +235, + +22428, +11143, -8405, -496, -4041, +4230, +889, -3448, -2615, +728, +1070, -660, +1947, -2748, +486, -621, -1697, -171, -896, +282, -583, -459, -269, +1324, -316, +161, -148, -1048, -191, -833, -297, +216, + +20761, +10556, -6721, -940, -4366, +4259, +1328, -3270, -2442, +888, +519, -254, +1808, -2851, +481, -564, -1534, -32, -625, +157, -458, -456, -349, +1175, -358, +206, -68, -1025, -144, -651, -305, +204, + +18483, +10322, -5051, -1232, -4488, +3998, +1699, -2851, -2083, +521, +346, -174, +1484, -2533, +230, -316, -1365, +115, -496, +12, -245, -474, -558, +987, -219, +124, +13, -912, -46, -573, -264, +159, + +15151, +10407, -3905, -1083, -1883, +2118, +367, -2185, -1952, +542, +790, -175, +1158, -1491, +303, +11, -942, -141, -277, +14, -417, -305, -403, +619, -260, -27, +128, -617, -289, -452, -406, -109, + +12885, +10154, -2446, -1435, -1886, +1994, +819, -1625, -1685, +115, +676, -116, +950, -1122, +70, +152, -656, +7, -100, +33, -249, -339, -518, +467, -154, -64, +221, -437, -240, -376, -360, -167, + +11026, +9815, -1373, -1604, -1732, +1727, +1082, -1042, -1489, -153, +594, -120, +851, -783, -35, +259, -348, +25, +24, +163, -205, -275, -535, +286, -60, -104, +181, -299, -203, -314, -276, -258, + +9638, +9479, -718, -1704, -1525, +1463, +1205, -627, -1291, -289, +532, -105, +728, -476, -29, +265, -147, +9, +102, +238, -168, -228, -548, +99, -70, -181, +55, -160, -166, -274, -267, -318, + +8752, +9179, -333, -1745, -1266, +1296, +1255, -331, -1103, -308, +517, +6, +654, -256, +108, +218, -57, +66, +139, +248, -132, -162, -550, -73, -107, -216, +35, -13, -164, -279, -126, -282, + +8140, +9001, -85, -1784, -995, +1204, +1247, -134, -1072, -291, +536, +70, +685, -204, +206, +280, -165, +40, +195, +187, -211, -72, -529, -292, -102, -127, -36, -76, -58, -138, -270, -89, + +7821, +8936, +29, -1810, -714, +1265, +1138, -40, -1096, -420, +649, +5, +642, -11, +138, +306, -111, -183, +147, +285, -330, -213, -387, -248, -250, -102, -97, -86, +22, -265, +130, +187, + +7807, +9028, -50, -1866, -441, +1451, +1138, -195, -1118, -490, +518, +2, +517, +35, +307, +254, -153, -103, +7, +126, -244, -245, -496, -140, -99, -332, -144, +49, -205, +61, +387, -266, + +7883, +9354, -84, -2058, -175, +1671, +1191, -268, -1313, -554, +542, -204, +353, +81, +268, +401, -95, -139, +119, +41, -495, -190, -362, -215, -155, -154, -74, -308, -29, +393, -17, -331, + +8309, +9731, -294, -2293, +42, +1934, +1203, -363, -1445, -664, +574, -270, +131, -85, +298, +391, -163, +29, +228, -28, -529, -302, -516, -77, -71, -224, -65, -236, +37, +234, -157, -305, + +8910, +10272, -662, -2606, +320, +2118, +1145, -521, -1640, -652, +647, -370, -95, -197, +260, +249, -276, +1, +311, +7, -540, -340, -597, -115, -162, -109, -41, -330, +23, +288, -224, -561, + +9705, +10883, -1159, -2876, +618, +2308, +939, -735, -1827, -569, +847, -551, -252, -350, +282, +190, -540, -53, +297, -89, -533, -247, -636, +1, -229, -304, +0, -239, -164, +169, +30, -627, + +10729, +11542, -1791, -3053, +931, +2475, +682, -1055, -1976, -419, +1145, -742, -457, -399, +293, +130, -657, -195, +215, -136, -668, -129, -569, +112, -117, -431, -109, -273, -261, +33, +231, -480, + +11880, +12255, -2434, -3089, +1163, +2572, +450, -1357, -2085, -232, +1467, -892, -621, -438, +381, +30, -732, -214, +65, -162, -709, -100, -437, +212, -28, -368, -165, -380, -411, -90, +291, -64, + +13138, +12910, -3157, -3037, +1198, +2492, +221, -1627, -2212, -103, +1693, -1094, -727, -513, +408, -69, -857, -306, -36, -187, -773, -78, -367, +223, -33, -259, -244, -476, -574, -270, +164, +260, + +14397, +13579, -3910, -2827, +1090, +2265, +96, -1784, -2287, -52, +1872, -1249, -736, -567, +401, -118, -956, -410, -92, -132, -795, +4, -347, +213, -84, -122, -283, -544, -622, -487, +74, +387, + +15830, +13982, -4898, -2472, +856, +1874, -58, -1916, -2412, -69, +1931, -1394, -672, -679, +358, -219, -1064, -512, -131, -146, -801, +55, -460, +223, -217, -78, -273, -623, -663, -737, +48, +327, + +17467, +14082, -6145, -1897, +641, +1483, -284, -1985, -2544, -62, +2082, -1574, -443, -758, +315, -348, -1052, -474, -316, -34, -792, -77, -456, +264, -381, +42, -169, -787, -651, -765, -87, +204, + +19204, +13692, -7428, -1120, +469, +1144, -634, -1991, -2737, +205, +2197, -1785, +24, -916, +275, -357, -852, -637, -399, +114, -1061, -13, -468, +245, -296, +208, -219, -909, -451, -819, -365, +209, + +20434, +13223, -8548, -342, +182, +828, -924, -2160, -2725, +468, +2161, -1789, +445, -1242, +435, -205, -999, -575, -649, -4, -1029, -158, -482, +542, -293, +181, -169, -874, -514, -927, -442, +127, + +21071, +12403, -8865, +245, -318, +823, -1130, -2243, -2635, +724, +2101, -1684, +725, -1293, +626, -269, -883, -830, -829, +105, -1203, -105, -238, +653, -371, +371, -143, -1016, -532, -886, -493, +33, + +20789, +11662, -8363, +332, -911, +1138, -984, -2430, -2493, +1026, +1715, -1379, +1228, -1581, +803, -170, -1256, -633, -926, +9, -905, -125, -208, +782, -256, +313, -208, -993, -501, -825, -526, -5, + +19596, +11016, -7150, -54, -1442, +1677, -696, -2554, -2277, +940, +1405, -817, +1246, -1536, +683, -288, -1142, -645, -762, +96, -739, -256, -171, +923, -379, +209, -146, -915, -439, -791, -471, +64, + +17572, +10705, -5607, -659, -1779, +2017, -199, -2475, -2231, +834, +1110, -554, +1413, -1693, +462, -69, -1229, -319, -565, +61, -598, -344, -187, +729, -361, +89, -38, -790, -417, -617, -384, -60, + +13984, +10256, -4374, -387, +520, +1170, -465, -1651, -1737, +620, +1299, -598, +593, -692, +507, -106, -759, -500, -601, +13, -482, -134, -166, +603, -169, +64, -79, -688, -462, -543, -415, -231, + +12758, +10312, -3687, -1357, +269, +1735, +98, -1444, -1892, +26, +1171, -327, +678, -523, +452, +210, -645, -277, -231, -18, -408, -233, -377, +567, -155, -104, +72, -516, -401, -434, -355, -174, + +11716, +10426, -3021, -2050, -38, +1840, +528, -1068, -1835, -336, +989, -214, +710, -348, +420, +365, -440, -231, -16, +39, -429, -185, -574, +332, -35, -237, +26, -307, -370, -373, -221, -235, + +11134, +10529, -2662, -2372, -80, +1872, +687, -929, -1758, -466, +868, -263, +670, -278, +447, +463, -382, -147, +37, -28, -515, -135, -648, +44, +50, -206, -64, -271, -287, -346, -196, -161, + +11076, +10636, -2726, -2397, +319, +2006, +654, -1075, -1802, -427, +898, -371, +393, -170, +406, +444, -274, -100, +119, -97, -686, -259, -554, +17, -61, -105, -68, -278, -240, -444, -157, +31, + +11612, +10554, -3129, -2035, +925, +2135, +343, -1322, -1834, -253, +981, -508, +127, -339, +524, +263, -428, +146, +113, -216, -691, -403, -615, +161, -3, -171, -98, -195, -334, -500, -145, +70, + +12375, +10683, -3543, -1496, +1375, +1878, -63, -1524, -1717, +100, +1163, -755, -161, -335, +443, +21, -544, +0, +88, -275, -693, -316, -565, +159, -85, -8, -150, -333, -390, -555, -137, +51, + +13451, +11029, -4018, -1046, +1272, +1286, -363, -1499, -1496, +592, +1316, -1108, -273, -352, +296, -275, -635, -344, -118, -175, -740, -127, -424, +105, -164, +113, -179, -568, -399, -627, -271, +78, + +14734, +11620, -4801, -879, +695, +632, -389, -1350, -1318, +1007, +1424, -1500, -74, -505, -4, -282, -945, -711, -166, -124, -792, +39, -391, +77, -83, +118, -326, -662, -381, -867, -393, +164, + +15985, +11630, -5516, -532, +203, +208, -354, -1214, -1189, +1341, +1442, -1615, +268, -744, -62, -254, -1183, -868, -259, -11, -770, +72, -261, +154, +24, +109, -377, -617, -514, -967, -389, +157, + +16167, +11377, -5735, -169, +103, +84, -542, -1299, -1254, +1362, +1544, -1556, +422, -670, -103, -248, -1015, -1157, -377, +88, -926, +197, -106, +201, +13, +190, -354, -777, -517, -923, -458, +58, + +15468, +10670, -5248, +0, +346, +442, -693, -1493, -1502, +1200, +1468, -1209, +625, -745, +218, -158, -964, -895, -623, +11, -688, +93, -44, +335, -4, +183, -327, -757, -508, -710, -494, -108, + +11864, +10338, -3078, -621, +1333, +599, -268, -1143, -1003, +1077, +1244, -764, -17, -195, +147, -60, -510, -758, -332, -70, -719, -16, -15, +316, +287, +250, -355, -886, -747, -549, -54, +215, +}; - /* HRIR Delays */ - { 12, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12, } +/* HRIR Delays */ +static const ALubyte defaultDelays[828] = +{ + 12, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 27, 26, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 24, 25, 26, 26, 26, 26, 26, 25, 24, 24, 23, 22, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 23, 22, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 22, 22, 22, 22, 21, 21, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 6, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 19, 20, 20, 20, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 17, 16, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 7, 6, 6, 6, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 16, 16, 15, 15, 14, 13, 12, 11, 10, 9, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 14, 14, 13, 12, 11, 10, 10, 10, 11, 12, +}; + +/* Default HRTF Definition */ +static const struct Hrtf DefaultHrtf = { + 44100, 32, 19, defaultAzCount, defaultEvOffset, + defaultCoeffs, defaultDelays, NULL +}; diff --git a/jni/openal-soft-android/Alc/midi/base.c b/jni/openal-soft-android/Alc/midi/base.c new file mode 100644 index 00000000..25dd19d9 --- /dev/null +++ b/jni/openal-soft-android/Alc/midi/base.c @@ -0,0 +1,278 @@ + +#include "config.h" + +#include +#include +#include + +#include "midi/base.h" + +#include "alMidi.h" +#include "alMain.h" +#include "alError.h" +#include "alThunk.h" +#include "evtqueue.h" +#include "rwlock.h" +#include "alu.h" + + +/* Microsecond resolution */ +#define TICKS_PER_SECOND (1000000) + +/* MIDI events */ +#define SYSEX_EVENT (0xF0) + + +void InitEvtQueue(EvtQueue *queue) +{ + queue->events = NULL; + queue->maxsize = 0; + queue->size = 0; + queue->pos = 0; +} + +void ResetEvtQueue(EvtQueue *queue) +{ + ALsizei i; + for(i = 0;i < queue->size;i++) + { + if(queue->events[i].event == SYSEX_EVENT) + { + free(queue->events[i].param.sysex.data); + queue->events[i].param.sysex.data = NULL; + } + } + + free(queue->events); + queue->events = NULL; + queue->maxsize = 0; + queue->size = 0; + queue->pos = 0; +} + +ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt) +{ + ALsizei pos; + + if(queue->maxsize == queue->size) + { + if(queue->pos > 0) + { + /* Queue has some stale entries, remove them to make space for more + * events. */ + for(pos = 0;pos < queue->pos;pos++) + { + if(queue->events[pos].event == SYSEX_EVENT) + { + free(queue->events[pos].param.sysex.data); + queue->events[pos].param.sysex.data = NULL; + } + } + memmove(&queue->events[0], &queue->events[queue->pos], + (queue->size-queue->pos)*sizeof(queue->events[0])); + queue->size -= queue->pos; + queue->pos = 0; + } + else + { + /* Queue is full, double the allocated space. */ + void *temp = NULL; + ALsizei newsize; + + newsize = (queue->maxsize ? (queue->maxsize<<1) : 16); + if(newsize > queue->maxsize) + temp = realloc(queue->events, newsize * sizeof(queue->events[0])); + if(!temp) + return AL_OUT_OF_MEMORY; + + queue->events = temp; + queue->maxsize = newsize; + } + } + + pos = queue->pos; + if(queue->size > 0) + { + ALsizei high = queue->size - 1; + while(pos < high) + { + ALsizei mid = pos + (high-pos)/2; + if(queue->events[mid].time < evt->time) + pos = mid + 1; + else + high = mid; + } + while(pos < queue->size && queue->events[pos].time <= evt->time) + pos++; + + if(pos < queue->size) + memmove(&queue->events[pos+1], &queue->events[pos], + (queue->size-pos)*sizeof(queue->events[0])); + } + + queue->events[pos] = *evt; + queue->size++; + + return AL_NO_ERROR; +} + + +void MidiSynth_Construct(MidiSynth *self, ALCdevice *device) +{ + InitEvtQueue(&self->EventQueue); + + RWLockInit(&self->Lock); + + self->Soundfonts = NULL; + self->NumSoundfonts = 0; + + self->Gain = 1.0f; + self->State = AL_INITIAL; + + self->LastEvtTime = 0; + self->NextEvtTime = UINT64_MAX; + self->SamplesSinceLast = 0.0; + self->SamplesToNext = 0.0; + + self->SamplesPerTick = (ALdouble)device->Frequency / TICKS_PER_SECOND; +} + +void MidiSynth_Destruct(MidiSynth *self) +{ + ALsizei i; + + for(i = 0;i < self->NumSoundfonts;i++) + DecrementRef(&self->Soundfonts[i]->ref); + free(self->Soundfonts); + self->Soundfonts = NULL; + self->NumSoundfonts = 0; + + ResetEvtQueue(&self->EventQueue); +} + + +ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) +{ + ALCdevice *device = context->Device; + ALsoundfont **sfonts; + ALsizei i; + + if(self->State != AL_INITIAL && self->State != AL_STOPPED) + return AL_INVALID_OPERATION; + + sfonts = calloc(1, count * sizeof(sfonts[0])); + if(!sfonts) return AL_OUT_OF_MEMORY; + + for(i = 0;i < count;i++) + { + if(ids[i] == 0) + sfonts[i] = ALsoundfont_getDefSoundfont(context); + else if(!(sfonts[i]=LookupSfont(device, ids[i]))) + { + free(sfonts); + return AL_INVALID_VALUE; + } + } + + for(i = 0;i < count;i++) + IncrementRef(&sfonts[i]->ref); + sfonts = ExchangePtr((XchgPtr*)&self->Soundfonts, sfonts); + count = ExchangeInt(&self->NumSoundfonts, count); + + for(i = 0;i < count;i++) + DecrementRef(&sfonts[i]->ref); + free(sfonts); + + return AL_NO_ERROR; +} + +extern inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain); +extern inline ALfloat MidiSynth_getGain(const MidiSynth *self); +extern inline void MidiSynth_setState(MidiSynth *self, ALenum state); +extern inline ALenum MidiSynth_getState(const MidiSynth *self); + +void MidiSynth_stop(MidiSynth *self) +{ + ResetEvtQueue(&self->EventQueue); + + self->LastEvtTime = 0; + self->NextEvtTime = UINT64_MAX; + self->SamplesSinceLast = 0.0; + self->SamplesToNext = 0.0; +} + +extern inline void MidiSynth_reset(MidiSynth *self); + +ALuint64 MidiSynth_getTime(const MidiSynth *self) +{ + ALuint64 time = self->LastEvtTime + (self->SamplesSinceLast/self->SamplesPerTick); + return clampu64(time, self->LastEvtTime, self->NextEvtTime); +} + +extern inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self); + +void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate) +{ + ALdouble sampletickrate = srate / TICKS_PER_SECOND; + + self->SamplesSinceLast = self->SamplesSinceLast * sampletickrate / self->SamplesPerTick; + self->SamplesToNext = self->SamplesToNext * sampletickrate / self->SamplesPerTick; + self->SamplesPerTick = sampletickrate; +} + +extern inline void MidiSynth_update(MidiSynth *self, ALCdevice *device); + +ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2) +{ + MidiEvent entry; + ALenum err; + + entry.time = time; + entry.event = event; + entry.param.val[0] = param1; + entry.param.val[1] = param2; + + err = InsertEvtQueue(&self->EventQueue, &entry); + if(err != AL_NO_ERROR) return err; + + if(entry.time < self->NextEvtTime) + { + self->NextEvtTime = entry.time; + + self->SamplesToNext = (self->NextEvtTime - self->LastEvtTime) * self->SamplesPerTick; + self->SamplesToNext -= self->SamplesSinceLast; + } + + return AL_NO_ERROR; +} + +ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size) +{ + MidiEvent entry; + ALenum err; + + entry.time = time; + entry.event = SYSEX_EVENT; + entry.param.sysex.size = size; + entry.param.sysex.data = malloc(size); + if(!entry.param.sysex.data) + return AL_OUT_OF_MEMORY; + memcpy(entry.param.sysex.data, data, size); + + err = InsertEvtQueue(&self->EventQueue, &entry); + if(err != AL_NO_ERROR) + { + free(entry.param.sysex.data); + return err; + } + + if(entry.time < self->NextEvtTime) + { + self->NextEvtTime = entry.time; + + self->SamplesToNext = (self->NextEvtTime - self->LastEvtTime) * self->SamplesPerTick; + self->SamplesToNext -= self->SamplesSinceLast; + } + + return AL_NO_ERROR; +} diff --git a/jni/openal-soft-android/Alc/midi/base.h b/jni/openal-soft-android/Alc/midi/base.h new file mode 100644 index 00000000..f900c941 --- /dev/null +++ b/jni/openal-soft-android/Alc/midi/base.h @@ -0,0 +1,128 @@ +#ifndef AL_MIDI_BASE_H +#define AL_MIDI_BASE_H + +#include "alMain.h" +#include "atomic.h" +#include "evtqueue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ALsoundfont; + +typedef size_t (*ReaderCb)(void *ptr, size_t size, void *stream); +typedef struct Reader { + ReaderCb cb; + void *ptr; + int error; +} Reader; +#define READ(x_, buf_, len_) ((x_)->cb((buf_), (len_), (x_)->ptr)) +#define READERR(x_) ((x_)->error) + +ALboolean loadSf2(Reader *stream, struct ALsoundfont *sfont, ALCcontext *context); + + +struct MidiSynthVtable; + +typedef struct MidiSynth { + EvtQueue EventQueue; + + ALuint64 LastEvtTime; + ALuint64 NextEvtTime; + ALdouble SamplesSinceLast; + ALdouble SamplesToNext; + + ALdouble SamplesPerTick; + + /* NOTE: This rwlock is for the state and soundfont. The EventQueue and + * related must instead use the device lock as they're used in the mixer + * thread. + */ + RWLock Lock; + + struct ALsoundfont **Soundfonts; + ALsizei NumSoundfonts; + + volatile ALfloat Gain; + volatile ALenum State; + + const struct MidiSynthVtable *vtbl; +} MidiSynth; + +void MidiSynth_Construct(MidiSynth *self, ALCdevice *device); +void MidiSynth_Destruct(MidiSynth *self); +ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); +inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain) { self->Gain = gain; } +inline ALfloat MidiSynth_getGain(const MidiSynth *self) { return self->Gain; } +inline void MidiSynth_setState(MidiSynth *self, ALenum state) { ExchangeInt(&self->State, state); } +inline ALenum MidiSynth_getState(const MidiSynth *self) { return self->State; } +void MidiSynth_stop(MidiSynth *self); +inline void MidiSynth_reset(MidiSynth *self) { MidiSynth_stop(self); } +ALuint64 MidiSynth_getTime(const MidiSynth *self); +inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self) +{ + if(self->EventQueue.pos == self->EventQueue.size) + return UINT64_MAX; + return self->EventQueue.events[self->EventQueue.pos].time; +} +void MidiSynth_setSampleRate(MidiSynth *self, ALdouble srate); +inline void MidiSynth_update(MidiSynth *self, ALCdevice *device) +{ MidiSynth_setSampleRate(self, device->Frequency); } +ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2); +ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size); + + +struct MidiSynthVtable { + void (*const Destruct)(MidiSynth *self); + + ALenum (*const selectSoundfonts)(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); + + void (*const setGain)(MidiSynth *self, ALfloat gain); + void (*const setState)(MidiSynth *self, ALenum state); + + void (*const stop)(MidiSynth *self); + void (*const reset)(MidiSynth *self); + + void (*const update)(MidiSynth *self, ALCdevice *device); + void (*const process)(MidiSynth *self, ALuint samples, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); + + void (*const Delete)(MidiSynth *self); +}; + +#define DEFINE_MIDISYNTH_VTABLE(T) \ +DECLARE_THUNK(T, MidiSynth, void, Destruct) \ +DECLARE_THUNK3(T, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) \ +DECLARE_THUNK1(T, MidiSynth, void, setGain, ALfloat) \ +DECLARE_THUNK1(T, MidiSynth, void, setState, ALenum) \ +DECLARE_THUNK(T, MidiSynth, void, stop) \ +DECLARE_THUNK(T, MidiSynth, void, reset) \ +DECLARE_THUNK1(T, MidiSynth, void, update, ALCdevice*) \ +DECLARE_THUNK2(T, MidiSynth, void, process, ALuint, ALfloatBUFFERSIZE*restrict) \ +DECLARE_THUNK(T, MidiSynth, void, Delete) \ + \ +static const struct MidiSynthVtable T##_MidiSynth_vtable = { \ + T##_MidiSynth_Destruct, \ + \ + T##_MidiSynth_selectSoundfonts, \ + T##_MidiSynth_setGain, \ + T##_MidiSynth_setState, \ + T##_MidiSynth_stop, \ + T##_MidiSynth_reset, \ + T##_MidiSynth_update, \ + T##_MidiSynth_process, \ + \ + T##_MidiSynth_Delete, \ +} + + +MidiSynth *FSynth_create(ALCdevice *device); +MidiSynth *DSynth_create(ALCdevice *device); + +MidiSynth *SynthCreate(ALCdevice *device); + +#ifdef __cplusplus +} +#endif + +#endif /* AL_MIDI_BASE_H */ diff --git a/jni/openal-soft-android/Alc/midi/dummy.c b/jni/openal-soft-android/Alc/midi/dummy.c new file mode 100644 index 00000000..71c03efb --- /dev/null +++ b/jni/openal-soft-android/Alc/midi/dummy.c @@ -0,0 +1,95 @@ + +#include "config.h" + +#include +#include +#include +#include + +#include "alMain.h" +#include "alError.h" +#include "evtqueue.h" +#include "rwlock.h" +#include "alu.h" + +#include "midi/base.h" + +typedef struct DSynth { + DERIVE_FROM_TYPE(MidiSynth); +} DSynth; + +static void DSynth_Construct(DSynth *self, ALCdevice *device); +static DECLARE_FORWARD(DSynth, MidiSynth, void, Destruct) +static DECLARE_FORWARD3(DSynth, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) +static DECLARE_FORWARD1(DSynth, MidiSynth, void, setGain, ALfloat) +static DECLARE_FORWARD1(DSynth, MidiSynth, void, setState, ALenum) +static DECLARE_FORWARD(DSynth, MidiSynth, void, stop) +static DECLARE_FORWARD(DSynth, MidiSynth, void, reset) +static DECLARE_FORWARD1(DSynth, MidiSynth, void, update, ALCdevice*) +static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); +static void DSynth_Delete(DSynth *self); +DEFINE_MIDISYNTH_VTABLE(DSynth); + + +static void DSynth_Construct(DSynth *self, ALCdevice *device) +{ + MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device); + SET_VTABLE2(DSynth, MidiSynth, self); +} + + +static void DSynth_processQueue(DSynth *self, ALuint64 time) +{ + EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; + + while(queue->pos < queue->size && queue->events[queue->pos].time <= time) + queue->pos++; +} + +static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloatBUFFERSIZE*restrict UNUSED(DryBuffer)) +{ + MidiSynth *synth = STATIC_CAST(MidiSynth, self); + + if(synth->State != AL_PLAYING) + return; + + synth->SamplesSinceLast += SamplesToDo; + synth->SamplesToNext -= SamplesToDo; + while(synth->SamplesToNext < 1.0f) + { + ALuint64 time = synth->NextEvtTime; + if(time == UINT64_MAX) + { + synth->SamplesToNext = 0.0; + break; + } + + synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick; + synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0); + synth->LastEvtTime = time; + DSynth_processQueue(self, time); + + synth->NextEvtTime = MidiSynth_getNextEvtTime(synth); + if(synth->NextEvtTime != UINT64_MAX) + synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick; + } +} + + +static void DSynth_Delete(DSynth *self) +{ + free(self); +} + + +MidiSynth *DSynth_create(ALCdevice *device) +{ + DSynth *synth = calloc(1, sizeof(*synth)); + if(!synth) + { + ERR("Failed to allocate DSynth\n"); + return NULL; + } + DSynth_Construct(synth, device); + return STATIC_CAST(MidiSynth, synth); +} diff --git a/jni/openal-soft-android/Alc/midi/fluidsynth.c b/jni/openal-soft-android/Alc/midi/fluidsynth.c new file mode 100644 index 00000000..9d58f87b --- /dev/null +++ b/jni/openal-soft-android/Alc/midi/fluidsynth.c @@ -0,0 +1,843 @@ + +#include "config.h" + +#include +#include +#include + +#include "midi/base.h" + +#include "alMain.h" +#include "alError.h" +#include "alMidi.h" +#include "evtqueue.h" +#include "rwlock.h" +#include "alu.h" + +#ifdef HAVE_FLUIDSYNTH + +#include + + +/* MIDI events */ +#define SYSEX_EVENT (0xF0) + +/* MIDI controllers */ +#define CTRL_BANKSELECT_MSB (0) +#define CTRL_BANKSELECT_LSB (32) +#define CTRL_ALLNOTESOFF (123) + + +static int getGenInput(ALenum input) +{ + switch(input) + { + case AL_ONE_SOFT: return FLUID_MOD_NONE; + case AL_NOTEON_VELOCITY_SOFT: return FLUID_MOD_VELOCITY; + case AL_NOTEON_KEY_SOFT: return FLUID_MOD_KEY; + case AL_KEYPRESSURE_SOFT: return FLUID_MOD_KEYPRESSURE; + case AL_CHANNELPRESSURE_SOFT: return FLUID_MOD_CHANNELPRESSURE; + case AL_PITCHBEND_SOFT: return FLUID_MOD_PITCHWHEEL; + case AL_PITCHBEND_SENSITIVITY_SOFT: return FLUID_MOD_PITCHWHEELSENS; + } + return input&0x7F; +} + +static int getGenFlags(ALenum input, ALenum type, ALenum form) +{ + int ret = 0; + + switch(type) + { + case AL_UNORM_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE; break; + case AL_UNORM_REV_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE; break; + case AL_SNORM_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE; break; + case AL_SNORM_REV_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE; break; + } + switch(form) + { + case AL_LINEAR_SOFT: ret |= FLUID_MOD_LINEAR; break; + case AL_CONCAVE_SOFT: ret |= FLUID_MOD_CONCAVE; break; + case AL_CONVEX_SOFT: ret |= FLUID_MOD_CONVEX; break; + case AL_SWITCH_SOFT: ret |= FLUID_MOD_SWITCH; break; + } + /* Source input values less than 128 correspond to a MIDI continuous + * controller. Otherwise, it's a general controller. */ + if(input < 128) ret |= FLUID_MOD_CC; + else ret |= FLUID_MOD_GC; + + return ret; +} + +static enum fluid_gen_type getSf2Gen(ALenum gen) +{ + switch(gen) + { + case AL_MOD_LFO_TO_PITCH_SOFT: return GEN_MODLFOTOPITCH; + case AL_VIBRATO_LFO_TO_PITCH_SOFT: return GEN_VIBLFOTOPITCH; + case AL_MOD_ENV_TO_PITCH_SOFT: return GEN_MODENVTOPITCH; + case AL_FILTER_CUTOFF_SOFT: return GEN_FILTERFC; + case AL_FILTER_RESONANCE_SOFT: return GEN_FILTERQ; + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: return GEN_MODLFOTOFILTERFC; + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: return GEN_MODENVTOFILTERFC; + case AL_MOD_LFO_TO_VOLUME_SOFT: return GEN_MODLFOTOVOL; + case AL_CHORUS_SEND_SOFT: return GEN_CHORUSSEND; + case AL_REVERB_SEND_SOFT: return GEN_REVERBSEND; + case AL_PAN_SOFT: return GEN_PAN; + case AL_MOD_LFO_DELAY_SOFT: return GEN_MODLFODELAY; + case AL_MOD_LFO_FREQUENCY_SOFT: return GEN_MODLFOFREQ; + case AL_VIBRATO_LFO_DELAY_SOFT: return GEN_VIBLFODELAY; + case AL_VIBRATO_LFO_FREQUENCY_SOFT: return GEN_VIBLFOFREQ; + case AL_MOD_ENV_DELAYTIME_SOFT: return GEN_MODENVDELAY; + case AL_MOD_ENV_ATTACKTIME_SOFT: return GEN_MODENVATTACK; + case AL_MOD_ENV_HOLDTIME_SOFT: return GEN_MODENVHOLD; + case AL_MOD_ENV_DECAYTIME_SOFT: return GEN_MODENVDECAY; + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: return GEN_MODENVSUSTAIN; + case AL_MOD_ENV_RELEASETIME_SOFT: return GEN_MODENVRELEASE; + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOMODENVHOLD; + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOMODENVDECAY; + case AL_VOLUME_ENV_DELAYTIME_SOFT: return GEN_VOLENVDELAY; + case AL_VOLUME_ENV_ATTACKTIME_SOFT: return GEN_VOLENVATTACK; + case AL_VOLUME_ENV_HOLDTIME_SOFT: return GEN_VOLENVHOLD; + case AL_VOLUME_ENV_DECAYTIME_SOFT: return GEN_VOLENVDECAY; + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: return GEN_VOLENVSUSTAIN; + case AL_VOLUME_ENV_RELEASETIME_SOFT: return GEN_VOLENVRELEASE; + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOVOLENVHOLD; + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOVOLENVDECAY; + case AL_ATTENUATION_SOFT: return GEN_ATTENUATION; + case AL_TUNING_COARSE_SOFT: return GEN_COARSETUNE; + case AL_TUNING_FINE_SOFT: return GEN_FINETUNE; + case AL_TUNING_SCALE_SOFT: return GEN_SCALETUNE; + } + ERR("Unhandled generator: 0x%04x\n", gen); + return 0; +} + +static int getSf2LoopMode(ALenum mode) +{ + switch(mode) + { + case AL_NONE: return 0; + case AL_LOOP_CONTINUOUS_SOFT: return 1; + case AL_LOOP_UNTIL_RELEASE_SOFT: return 3; + } + return 0; +} + +static int getSampleType(ALenum type) +{ + switch(type) + { + case AL_MONO_SOFT: return FLUID_SAMPLETYPE_MONO; + case AL_RIGHT_SOFT: return FLUID_SAMPLETYPE_RIGHT; + case AL_LEFT_SOFT: return FLUID_SAMPLETYPE_LEFT; + } + return FLUID_SAMPLETYPE_MONO; +} + +typedef struct FSample { + DERIVE_FROM_TYPE(fluid_sample_t); + + ALfontsound *Sound; + + fluid_mod_t *Mods; + ALsizei NumMods; +} FSample; + +static void FSample_Construct(FSample *self, ALfontsound *sound, ALsoundfont *sfont) +{ + fluid_sample_t *sample = STATIC_CAST(fluid_sample_t, self); + memset(sample->name, 0, sizeof(sample->name)); + sample->start = sound->Start; + sample->end = sound->End; + sample->loopstart = sound->LoopStart; + sample->loopend = sound->LoopEnd; + sample->samplerate = sound->SampleRate; + sample->origpitch = sound->PitchKey; + sample->pitchadj = sound->PitchCorrection; + sample->sampletype = getSampleType(sound->SampleType); + sample->valid = 1; + sample->data = sfont->Samples; + + sample->amplitude_that_reaches_noise_floor_is_valid = 0; + sample->amplitude_that_reaches_noise_floor = 0.0; + + sample->refcount = 0; + + sample->notify = NULL; + + sample->userdata = self; + + self->Sound = sound; + + self->NumMods = 0; + self->Mods = calloc(sound->ModulatorMap.size, sizeof(self->Mods[0])); + if(self->Mods) + { + ALsizei i; + + self->NumMods = sound->ModulatorMap.size; + for(i = 0;i < self->NumMods;i++) + { + ALsfmodulator *mod = sound->ModulatorMap.array[i].value; + fluid_mod_set_source1(&self->Mods[i], getGenInput(mod->Source[0].Input), + getGenFlags(mod->Source[0].Input, mod->Source[0].Type, + mod->Source[0].Form)); + fluid_mod_set_source2(&self->Mods[i], getGenInput(mod->Source[1].Input), + getGenFlags(mod->Source[1].Input, mod->Source[1].Type, + mod->Source[1].Form)); + fluid_mod_set_amount(&self->Mods[i], mod->Amount); + fluid_mod_set_dest(&self->Mods[i], getSf2Gen(mod->Dest)); + self->Mods[i].next = NULL; + } + } +} + +static void FSample_Destruct(FSample *self) +{ + free(self->Mods); + self->Mods = NULL; + self->NumMods = 0; +} + + +typedef struct FPreset { + DERIVE_FROM_TYPE(fluid_preset_t); + + char Name[16]; + + int Preset; + int Bank; + + FSample *Samples; + ALsizei NumSamples; +} FPreset; + +static char* FPreset_getName(fluid_preset_t *preset); +static int FPreset_getPreset(fluid_preset_t *preset); +static int FPreset_getBank(fluid_preset_t *preset); +static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int velocity); + +static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *parent, ALsoundfont *sfont) +{ + STATIC_CAST(fluid_preset_t, self)->data = self; + STATIC_CAST(fluid_preset_t, self)->sfont = parent; + STATIC_CAST(fluid_preset_t, self)->free = NULL; + STATIC_CAST(fluid_preset_t, self)->get_name = FPreset_getName; + STATIC_CAST(fluid_preset_t, self)->get_banknum = FPreset_getBank; + STATIC_CAST(fluid_preset_t, self)->get_num = FPreset_getPreset; + STATIC_CAST(fluid_preset_t, self)->noteon = FPreset_noteOn; + STATIC_CAST(fluid_preset_t, self)->notify = NULL; + + memset(self->Name, 0, sizeof(self->Name)); + self->Preset = preset->Preset; + self->Bank = preset->Bank; + + self->NumSamples = 0; + self->Samples = calloc(1, preset->NumSounds * sizeof(self->Samples[0])); + if(self->Samples) + { + ALsizei i; + self->NumSamples = preset->NumSounds; + for(i = 0;i < self->NumSamples;i++) + FSample_Construct(&self->Samples[i], preset->Sounds[i], sfont); + } +} + +static void FPreset_Destruct(FPreset *self) +{ + ALsizei i; + + for(i = 0;i < self->NumSamples;i++) + FSample_Destruct(&self->Samples[i]); + free(self->Samples); + self->Samples = NULL; + self->NumSamples = 0; +} + +static ALboolean FPreset_canDelete(FPreset *self) +{ + ALsizei i; + + for(i = 0;i < self->NumSamples;i++) + { + if(fluid_sample_refcount(STATIC_CAST(fluid_sample_t, &self->Samples[i])) != 0) + return AL_FALSE; + } + return AL_TRUE; +} + +static char* FPreset_getName(fluid_preset_t *preset) +{ + return ((FPreset*)preset->data)->Name; +} + +static int FPreset_getPreset(fluid_preset_t *preset) +{ + return ((FPreset*)preset->data)->Preset; +} + +static int FPreset_getBank(fluid_preset_t *preset) +{ + return ((FPreset*)preset->data)->Bank; +} + +static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int vel) +{ + FPreset *self = ((FPreset*)preset->data); + ALsizei i; + + for(i = 0;i < self->NumSamples;i++) + { + FSample *sample = &self->Samples[i]; + ALfontsound *sound = sample->Sound; + fluid_voice_t *voice; + ALsizei m; + + if(!(key >= sound->MinKey && key <= sound->MaxKey && vel >= sound->MinVelocity && vel <= sound->MaxVelocity)) + continue; + + voice = fluid_synth_alloc_voice(synth, STATIC_CAST(fluid_sample_t, sample), channel, key, vel); + if(voice == NULL) + return FLUID_FAILED; + + fluid_voice_gen_set(voice, GEN_MODLFOTOPITCH, sound->ModLfoToPitch); + fluid_voice_gen_set(voice, GEN_VIBLFOTOPITCH, sound->VibratoLfoToPitch); + fluid_voice_gen_set(voice, GEN_MODENVTOPITCH, sound->ModEnvToPitch); + fluid_voice_gen_set(voice, GEN_FILTERFC, sound->FilterCutoff); + fluid_voice_gen_set(voice, GEN_FILTERQ, sound->FilterQ); + fluid_voice_gen_set(voice, GEN_MODLFOTOFILTERFC, sound->ModLfoToFilterCutoff); + fluid_voice_gen_set(voice, GEN_MODENVTOFILTERFC, sound->ModEnvToFilterCutoff); + fluid_voice_gen_set(voice, GEN_MODLFOTOVOL, sound->ModLfoToVolume); + fluid_voice_gen_set(voice, GEN_CHORUSSEND, sound->ChorusSend); + fluid_voice_gen_set(voice, GEN_REVERBSEND, sound->ReverbSend); + fluid_voice_gen_set(voice, GEN_PAN, sound->Pan); + fluid_voice_gen_set(voice, GEN_MODLFODELAY, sound->ModLfo.Delay); + fluid_voice_gen_set(voice, GEN_MODLFOFREQ, sound->ModLfo.Frequency); + fluid_voice_gen_set(voice, GEN_VIBLFODELAY, sound->VibratoLfo.Delay); + fluid_voice_gen_set(voice, GEN_VIBLFOFREQ, sound->VibratoLfo.Frequency); + fluid_voice_gen_set(voice, GEN_MODENVDELAY, sound->ModEnv.DelayTime); + fluid_voice_gen_set(voice, GEN_MODENVATTACK, sound->ModEnv.AttackTime); + fluid_voice_gen_set(voice, GEN_MODENVHOLD, sound->ModEnv.HoldTime); + fluid_voice_gen_set(voice, GEN_MODENVDECAY, sound->ModEnv.DecayTime); + fluid_voice_gen_set(voice, GEN_MODENVSUSTAIN, sound->ModEnv.SustainAttn); + fluid_voice_gen_set(voice, GEN_MODENVRELEASE, sound->ModEnv.ReleaseTime); + fluid_voice_gen_set(voice, GEN_KEYTOMODENVHOLD, sound->ModEnv.KeyToHoldTime); + fluid_voice_gen_set(voice, GEN_KEYTOMODENVDECAY, sound->ModEnv.KeyToDecayTime); + fluid_voice_gen_set(voice, GEN_VOLENVDELAY, sound->VolEnv.DelayTime); + fluid_voice_gen_set(voice, GEN_VOLENVATTACK, sound->VolEnv.AttackTime); + fluid_voice_gen_set(voice, GEN_VOLENVHOLD, sound->VolEnv.HoldTime); + fluid_voice_gen_set(voice, GEN_VOLENVDECAY, sound->VolEnv.DecayTime); + fluid_voice_gen_set(voice, GEN_VOLENVSUSTAIN, sound->VolEnv.SustainAttn); + fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, sound->VolEnv.ReleaseTime); + fluid_voice_gen_set(voice, GEN_KEYTOVOLENVHOLD, sound->VolEnv.KeyToHoldTime); + fluid_voice_gen_set(voice, GEN_KEYTOVOLENVDECAY, sound->VolEnv.KeyToDecayTime); + fluid_voice_gen_set(voice, GEN_ATTENUATION, sound->Attenuation); + fluid_voice_gen_set(voice, GEN_COARSETUNE, sound->CoarseTuning); + fluid_voice_gen_set(voice, GEN_FINETUNE, sound->FineTuning); + fluid_voice_gen_set(voice, GEN_SAMPLEMODE, getSf2LoopMode(sound->LoopMode)); + fluid_voice_gen_set(voice, GEN_SCALETUNE, sound->TuningScale); + fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, sound->ExclusiveClass); + for(m = 0;m < sample->NumMods;m++) + fluid_voice_add_mod(voice, &sample->Mods[m], FLUID_VOICE_OVERWRITE); + + fluid_synth_start_voice(synth, voice); + } + + return FLUID_OK; +} + + +typedef struct FSfont { + DERIVE_FROM_TYPE(fluid_sfont_t); + + char Name[16]; + + FPreset *Presets; + ALsizei NumPresets; + + ALsizei CurrentPos; +} FSfont; + +static int FSfont_free(fluid_sfont_t *sfont); +static char* FSfont_getName(fluid_sfont_t *sfont); +static fluid_preset_t* FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum); +static void FSfont_iterStart(fluid_sfont_t *sfont); +static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset); + +static void FSfont_Construct(FSfont *self, ALsoundfont *sfont) +{ + STATIC_CAST(fluid_sfont_t, self)->data = self; + STATIC_CAST(fluid_sfont_t, self)->id = FLUID_FAILED; + STATIC_CAST(fluid_sfont_t, self)->free = FSfont_free; + STATIC_CAST(fluid_sfont_t, self)->get_name = FSfont_getName; + STATIC_CAST(fluid_sfont_t, self)->get_preset = FSfont_getPreset; + STATIC_CAST(fluid_sfont_t, self)->iteration_start = FSfont_iterStart; + STATIC_CAST(fluid_sfont_t, self)->iteration_next = FSfont_iterNext; + + memset(self->Name, 0, sizeof(self->Name)); + self->CurrentPos = 0; + self->NumPresets = 0; + self->Presets = calloc(1, sfont->NumPresets * sizeof(self->Presets[0])); + if(self->Presets) + { + ALsizei i; + self->NumPresets = sfont->NumPresets; + for(i = 0;i < self->NumPresets;i++) + FPreset_Construct(&self->Presets[i], sfont->Presets[i], STATIC_CAST(fluid_sfont_t, self), sfont); + } +} + +static void FSfont_Destruct(FSfont *self) +{ + ALsizei i; + + for(i = 0;i < self->NumPresets;i++) + FPreset_Destruct(&self->Presets[i]); + free(self->Presets); + self->Presets = NULL; + self->NumPresets = 0; + self->CurrentPos = 0; +} + +static int FSfont_free(fluid_sfont_t *sfont) +{ + FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); + ALsizei i; + + for(i = 0;i < self->NumPresets;i++) + { + if(!FPreset_canDelete(&self->Presets[i])) + return 1; + } + + FSfont_Destruct(self); + free(self); + return 0; +} + +static char* FSfont_getName(fluid_sfont_t *sfont) +{ + return STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->Name; +} + +static fluid_preset_t *FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum) +{ + FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); + ALsizei i; + + for(i = 0;i < self->NumPresets;i++) + { + FPreset *preset = &self->Presets[i]; + if(preset->Bank == (int)bank && preset->Preset == (int)prenum) + return STATIC_CAST(fluid_preset_t, preset); + } + + return NULL; +} + +static void FSfont_iterStart(fluid_sfont_t *sfont) +{ + STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->CurrentPos = 0; +} + +static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset) +{ + FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); + if(self->CurrentPos >= self->NumPresets) + return 0; + *preset = *STATIC_CAST(fluid_preset_t, &self->Presets[self->CurrentPos++]); + preset->free = NULL; + return 1; +} + + +typedef struct FSynth { + DERIVE_FROM_TYPE(MidiSynth); + DERIVE_FROM_TYPE(fluid_sfloader_t); + + fluid_settings_t *Settings; + fluid_synth_t *Synth; + int *FontIDs; + ALsizei NumFontIDs; + + ALboolean ForceGM2BankSelect; + ALfloat GainScale; +} FSynth; + +static void FSynth_Construct(FSynth *self, ALCdevice *device); +static void FSynth_Destruct(FSynth *self); +static ALboolean FSynth_init(FSynth *self, ALCdevice *device); +static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); +static void FSynth_setGain(FSynth *self, ALfloat gain); +static void FSynth_setState(FSynth *self, ALenum state); +static void FSynth_stop(FSynth *self); +static void FSynth_reset(FSynth *self); +static void FSynth_update(FSynth *self, ALCdevice *device); +static void FSynth_processQueue(FSynth *self, ALuint64 time); +static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); +static void FSynth_Delete(FSynth *self); +DEFINE_MIDISYNTH_VTABLE(FSynth); + +static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename); + + +static void FSynth_Construct(FSynth *self, ALCdevice *device) +{ + MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device); + SET_VTABLE2(FSynth, MidiSynth, self); + + STATIC_CAST(fluid_sfloader_t, self)->data = self; + STATIC_CAST(fluid_sfloader_t, self)->free = NULL; + STATIC_CAST(fluid_sfloader_t, self)->load = FSynth_loadSfont; + + self->Settings = NULL; + self->Synth = NULL; + self->FontIDs = NULL; + self->NumFontIDs = 0; + self->ForceGM2BankSelect = AL_FALSE; + self->GainScale = 0.2f; +} + +static void FSynth_Destruct(FSynth *self) +{ + ALsizei i; + + for(i = 0;i < self->NumFontIDs;i++) + fluid_synth_sfunload(self->Synth, self->FontIDs[i], 0); + free(self->FontIDs); + self->FontIDs = NULL; + self->NumFontIDs = 0; + + if(self->Synth != NULL) + delete_fluid_synth(self->Synth); + self->Synth = NULL; + + if(self->Settings != NULL) + delete_fluid_settings(self->Settings); + self->Settings = NULL; + + MidiSynth_Destruct(STATIC_CAST(MidiSynth, self)); +} + +static ALboolean FSynth_init(FSynth *self, ALCdevice *device) +{ + ALfloat vol; + + if(ConfigValueFloat("midi", "volume", &vol)) + { + if(!(vol <= 0.0f)) + { + ERR("MIDI volume %f clamped to 0\n", vol); + vol = 0.0f; + } + self->GainScale = powf(10.0f, vol / 20.0f); + } + + self->Settings = new_fluid_settings(); + if(!self->Settings) + { + ERR("Failed to create FluidSettings\n"); + return AL_FALSE; + } + + fluid_settings_setint(self->Settings, "synth.polyphony", 256); + fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale); + fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency); + + self->Synth = new_fluid_synth(self->Settings); + if(!self->Synth) + { + ERR("Failed to create FluidSynth\n"); + return AL_FALSE; + } + + fluid_synth_add_sfloader(self->Synth, STATIC_CAST(fluid_sfloader_t, self)); + + return AL_TRUE; +} + + +static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename) +{ + FSynth *self = STATIC_UPCAST(FSynth, fluid_sfloader_t, loader); + FSfont *sfont; + int idx; + + if(!filename || sscanf(filename, "_al_internal %d", &idx) != 1) + return NULL; + if(idx < 0 || idx >= STATIC_CAST(MidiSynth, self)->NumSoundfonts) + { + ERR("Received invalid soundfont index %d (max: %d)\n", idx, STATIC_CAST(MidiSynth, self)->NumSoundfonts); + return NULL; + } + + sfont = calloc(1, sizeof(sfont[0])); + if(!sfont) return NULL; + + FSfont_Construct(sfont, STATIC_CAST(MidiSynth, self)->Soundfonts[idx]); + return STATIC_CAST(fluid_sfont_t, sfont); +} + +static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) +{ + int *fontid; + ALenum ret; + ALsizei i; + + ret = MidiSynth_selectSoundfonts(STATIC_CAST(MidiSynth, self), context, count, ids); + if(ret != AL_NO_ERROR) return ret; + + ALCdevice_Lock(context->Device); + for(i = 0;i < 16;i++) + fluid_synth_all_sounds_off(self->Synth, i); + ALCdevice_Unlock(context->Device); + + fontid = malloc(count * sizeof(fontid[0])); + if(fontid) + { + for(i = 0;i < STATIC_CAST(MidiSynth, self)->NumSoundfonts;i++) + { + char name[16]; + snprintf(name, sizeof(name), "_al_internal %d", i); + + fontid[i] = fluid_synth_sfload(self->Synth, name, 0); + if(fontid[i] == FLUID_FAILED) + ERR("Failed to load selected soundfont %d\n", i); + } + + fontid = ExchangePtr((XchgPtr*)&self->FontIDs, fontid); + count = ExchangeInt(&self->NumFontIDs, count); + } + else + { + ERR("Failed to allocate space for %d font IDs!\n", count); + fontid = ExchangePtr((XchgPtr*)&self->FontIDs, NULL); + count = ExchangeInt(&self->NumFontIDs, 0); + } + + for(i = 0;i < count;i++) + fluid_synth_sfunload(self->Synth, fontid[i], 0); + free(fontid); + + return ret; +} + + +static void FSynth_setGain(FSynth *self, ALfloat gain) +{ + fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale * gain); + fluid_synth_set_gain(self->Synth, self->GainScale * gain); + MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain); +} + + +static void FSynth_setState(FSynth *self, ALenum state) +{ + MidiSynth_setState(STATIC_CAST(MidiSynth, self), state); +} + +static void FSynth_stop(FSynth *self) +{ + MidiSynth *synth = STATIC_CAST(MidiSynth, self); + ALsizei chan; + + /* Make sure all pending events are processed. */ + while(!(synth->SamplesToNext >= 1.0)) + { + ALuint64 time = synth->NextEvtTime; + if(time == UINT64_MAX) + break; + + synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick; + synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0); + synth->LastEvtTime = time; + FSynth_processQueue(self, time); + + synth->NextEvtTime = MidiSynth_getNextEvtTime(synth); + if(synth->NextEvtTime != UINT64_MAX) + synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick; + } + + /* All notes off */ + for(chan = 0;chan < 16;chan++) + fluid_synth_cc(self->Synth, chan, CTRL_ALLNOTESOFF, 0); + + MidiSynth_stop(STATIC_CAST(MidiSynth, self)); +} + +static void FSynth_reset(FSynth *self) +{ + /* Reset to power-up status. */ + fluid_synth_system_reset(self->Synth); + + MidiSynth_reset(STATIC_CAST(MidiSynth, self)); +} + + +static void FSynth_update(FSynth *self, ALCdevice *device) +{ + fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency); + fluid_synth_set_sample_rate(self->Synth, device->Frequency); + MidiSynth_update(STATIC_CAST(MidiSynth, self), device); +} + + +static void FSynth_processQueue(FSynth *self, ALuint64 time) +{ + EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; + + while(queue->pos < queue->size && queue->events[queue->pos].time <= time) + { + const MidiEvent *evt = &queue->events[queue->pos]; + + if(evt->event == SYSEX_EVENT) + { + static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 }; + static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 }; + int handled = 0; + + fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0); + if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on)) + { + if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0) + self->ForceGM2BankSelect = AL_TRUE; + else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0) + self->ForceGM2BankSelect = AL_FALSE; + } + } + else switch((evt->event&0xF0)) + { + case AL_NOTEOFF_SOFT: + fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]); + break; + case AL_NOTEON_SOFT: + fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); + break; + case AL_KEYPRESSURE_SOFT: + break; + + case AL_CONTROLLERCHANGE_SOFT: + if(self->ForceGM2BankSelect) + { + int chan = (evt->event&0x0F); + if(evt->param.val[0] == CTRL_BANKSELECT_MSB) + { + if(evt->param.val[1] == 120 && (chan == 9 || chan == 10)) + fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM); + else if(evt->param.val[1] == 121) + fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC); + break; + } + if(evt->param.val[0] == CTRL_BANKSELECT_LSB) + { + fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]); + break; + } + } + fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); + break; + case AL_PROGRAMCHANGE_SOFT: + fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]); + break; + + case AL_CHANNELPRESSURE_SOFT: + fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]); + break; + + case AL_PITCHBEND_SOFT: + fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) | + ((evt->param.val[1]&0x7F)<<7)); + break; + } + + queue->pos++; + } +} + +static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]) +{ + MidiSynth *synth = STATIC_CAST(MidiSynth, self); + ALenum state = synth->State; + ALuint total = 0; + + if(state == AL_INITIAL) + return; + if(state != AL_PLAYING) + { + fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1, + DryBuffer[FrontRight], 0, 1); + return; + } + + while(total < SamplesToDo) + { + if(synth->SamplesToNext >= 1.0) + { + ALuint todo = minu(SamplesToDo - total, fastf2u(synth->SamplesToNext)); + + fluid_synth_write_float(self->Synth, todo, + &DryBuffer[FrontLeft][total], 0, 1, + &DryBuffer[FrontRight][total], 0, 1); + total += todo; + synth->SamplesSinceLast += todo; + synth->SamplesToNext -= todo; + } + else + { + ALuint64 time = synth->NextEvtTime; + if(time == UINT64_MAX) + { + synth->SamplesSinceLast += SamplesToDo-total; + fluid_synth_write_float(self->Synth, SamplesToDo-total, + &DryBuffer[FrontLeft][total], 0, 1, + &DryBuffer[FrontRight][total], 0, 1); + break; + } + + synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick; + synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0); + synth->LastEvtTime = time; + FSynth_processQueue(self, time); + + synth->NextEvtTime = MidiSynth_getNextEvtTime(synth); + if(synth->NextEvtTime != UINT64_MAX) + synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick; + } + } +} + + +static void FSynth_Delete(FSynth *self) +{ + free(self); +} + + +MidiSynth *FSynth_create(ALCdevice *device) +{ + FSynth *synth = calloc(1, sizeof(*synth)); + if(!synth) + { + ERR("Failed to allocate FSynth\n"); + return NULL; + } + FSynth_Construct(synth, device); + + if(FSynth_init(synth, device) == AL_FALSE) + { + DELETE_OBJ(STATIC_CAST(MidiSynth, synth)); + return NULL; + } + + return STATIC_CAST(MidiSynth, synth); +} + +#else + +MidiSynth *FSynth_create(ALCdevice* UNUSED(device)) +{ + return NULL; +} + +#endif diff --git a/jni/openal-soft-android/Alc/midi/sf2load.c b/jni/openal-soft-android/Alc/midi/sf2load.c new file mode 100644 index 00000000..5bba345f --- /dev/null +++ b/jni/openal-soft-android/Alc/midi/sf2load.c @@ -0,0 +1,1436 @@ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alu.h" + +#include "midi/base.h" + + +static ALuint read_le32(Reader *stream) +{ + ALubyte buf[4]; + if(READ(stream, buf, 4) != 4) + { + READERR(stream) = 1; + return 0; + } + return (buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0]; +} +static ALushort read_le16(Reader *stream) +{ + ALubyte buf[2]; + if(READ(stream, buf, 2) != 2) + { + READERR(stream) = 1; + return 0; + } + return (buf[1]<<8) | buf[0]; +} +static ALubyte read_8(Reader *stream) +{ + ALubyte buf[1]; + if(READ(stream, buf, 1) != 1) + { + READERR(stream) = 1; + return 0; + } + return buf[0]; +} +static void skip(Reader *stream, ALuint amt) +{ + while(amt > 0 && !READERR(stream)) + { + char buf[4096]; + size_t got; + + got = READ(stream, buf, minu(sizeof(buf), amt)); + if(got == 0) READERR(stream) = 1; + + amt -= got; + } +} + +typedef struct Generator { + ALushort mGenerator; + ALushort mAmount; +} Generator; +static void Generator_read(Generator *self, Reader *stream) +{ + self->mGenerator = read_le16(stream); + self->mAmount = read_le16(stream); +} + +static const ALint DefaultGenValue[60] = { + 0, /* 0 - startAddrOffset */ + 0, /* 1 - endAddrOffset */ + 0, /* 2 - startloopAddrOffset */ + 0, /* 3 - endloopAddrOffset */ + 0, /* 4 - startAddrCoarseOffset */ + 0, /* 5 - modLfoToPitch */ + 0, /* 6 - vibLfoToPitch */ + 0, /* 7 - modEnvToPitch */ + 13500, /* 8 - initialFilterFc */ + 0, /* 9 - initialFilterQ */ + 0, /* 10 - modLfoToFilterFc */ + 0, /* 11 - modEnvToFilterFc */ + 0, /* 12 - endAddrCoarseOffset */ + 0, /* 13 - modLfoToVolume */ + 0, /* 14 - */ + 0, /* 15 - chorusEffectsSend */ + 0, /* 16 - reverbEffectsSend */ + 0, /* 17 - pan */ + 0, /* 18 - */ + 0, /* 19 - */ + 0, /* 20 - */ + -12000, /* 21 - delayModLFO */ + 0, /* 22 - freqModLFO */ + -12000, /* 23 - delayVibLFO */ + 0, /* 24 - freqVibLFO */ + -12000, /* 25 - delayModEnv */ + -12000, /* 26 - attackModEnv */ + -12000, /* 27 - holdModEnv */ + -12000, /* 28 - decayModEnv */ + 0, /* 29 - sustainModEnv */ + -12000, /* 30 - releaseModEnv */ + 0, /* 31 - keynumToModEnvHold */ + 0, /* 32 - keynumToModEnvDecay */ + -12000, /* 33 - delayVolEnv */ + -12000, /* 34 - attackVolEnv */ + -12000, /* 35 - holdVolEnv */ + -12000, /* 36 - decayVolEnv */ + 0, /* 37 - sustainVolEnv */ + -12000, /* 38 - releaseVolEnv */ + 0, /* 39 - keynumToVolEnvHold */ + 0, /* 40 - keynumToVolEnvDecay */ + 0, /* 41 - */ + 0, /* 42 - */ + 0, /* 43 - keyRange */ + 0, /* 44 - velRange */ + 0, /* 45 - startloopAddrCoarseOffset */ + 0, /* 46 - keynum */ + 0, /* 47 - velocity */ + 0, /* 48 - initialAttenuation */ + 0, /* 49 - */ + 0, /* 50 - endloopAddrCoarseOffset */ + 0, /* 51 - corseTune */ + 0, /* 52 - fineTune */ + 0, /* 53 - */ + 0, /* 54 - sampleModes */ + 0, /* 55 - */ + 100, /* 56 - scaleTuning */ + 0, /* 57 - exclusiveClass */ + 0, /* 58 - overridingRootKey */ + 0, /* 59 - */ +}; + +typedef struct Modulator { + ALushort mSrcOp; + ALushort mDstOp; + ALshort mAmount; + ALushort mAmtSrcOp; + ALushort mTransOp; +} Modulator; +static void Modulator_read(Modulator *self, Reader *stream) +{ + self->mSrcOp = read_le16(stream); + self->mDstOp = read_le16(stream); + self->mAmount = read_le16(stream); + self->mAmtSrcOp = read_le16(stream); + self->mTransOp = read_le16(stream); +} + +typedef struct Zone { + ALushort mGenIdx; + ALushort mModIdx; +} Zone; +static void Zone_read(Zone *self, Reader *stream) +{ + self->mGenIdx = read_le16(stream); + self->mModIdx = read_le16(stream); +} + +typedef struct PresetHeader { + ALchar mName[20]; + ALushort mPreset; /* MIDI program number */ + ALushort mBank; + ALushort mZoneIdx; + ALuint mLibrary; + ALuint mGenre; + ALuint mMorphology; +} PresetHeader; +static void PresetHeader_read(PresetHeader *self, Reader *stream) +{ + if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName)) + READERR(stream) = 1; + self->mPreset = read_le16(stream); + self->mBank = read_le16(stream); + self->mZoneIdx = read_le16(stream); + self->mLibrary = read_le32(stream); + self->mGenre = read_le32(stream); + self->mMorphology = read_le32(stream); +} + +typedef struct InstrumentHeader { + ALchar mName[20]; + ALushort mZoneIdx; +} InstrumentHeader; +static void InstrumentHeader_read(InstrumentHeader *self, Reader *stream) +{ + if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName)) + READERR(stream) = 1; + self->mZoneIdx = read_le16(stream); +} + +typedef struct SampleHeader { + ALchar mName[20]; // 20 bytes + ALuint mStart; + ALuint mEnd; + ALuint mStartloop; + ALuint mEndloop; + ALuint mSampleRate; + ALubyte mOriginalKey; + ALbyte mCorrection; + ALushort mSampleLink; + ALushort mSampleType; +} SampleHeader; +static void SampleHeader_read(SampleHeader *self, Reader *stream) +{ + if(READ(stream, self->mName, sizeof(self->mName)) != sizeof(self->mName)) + READERR(stream) = 1; + self->mStart = read_le32(stream); + self->mEnd = read_le32(stream); + self->mStartloop = read_le32(stream); + self->mEndloop = read_le32(stream); + self->mSampleRate = read_le32(stream); + self->mOriginalKey = read_8(stream); + self->mCorrection = read_8(stream); + self->mSampleLink = read_le16(stream); + self->mSampleType = read_le16(stream); +} + + +typedef struct Soundfont { + ALuint ifil; + ALchar *irom; + + PresetHeader *phdr; + ALsizei phdr_size; + + Zone *pbag; + ALsizei pbag_size; + Modulator *pmod; + ALsizei pmod_size; + Generator *pgen; + ALsizei pgen_size; + + InstrumentHeader *inst; + ALsizei inst_size; + + Zone *ibag; + ALsizei ibag_size; + Modulator *imod; + ALsizei imod_size; + Generator *igen; + ALsizei igen_size; + + SampleHeader *shdr; + ALsizei shdr_size; +} Soundfont; + +static void Soundfont_Construct(Soundfont *self) +{ + self->ifil = 0; + self->irom = NULL; + + self->phdr = NULL; + self->phdr_size = 0; + + self->pbag = NULL; + self->pbag_size = 0; + self->pmod = NULL; + self->pmod_size = 0; + self->pgen = NULL; + self->pgen_size = 0; + + self->inst = NULL; + self->inst_size = 0; + + self->ibag = NULL; + self->ibag_size = 0; + self->imod = NULL; + self->imod_size = 0; + self->igen = NULL; + self->igen_size = 0; + + self->shdr = NULL; + self->shdr_size = 0; +} + +static void Soundfont_Destruct(Soundfont *self) +{ + free(self->irom); + self->irom = NULL; + + free(self->phdr); + self->phdr = NULL; + self->phdr_size = 0; + + free(self->pbag); + self->pbag = NULL; + self->pbag_size = 0; + free(self->pmod); + self->pmod = NULL; + self->pmod_size = 0; + free(self->pgen); + self->pgen = NULL; + self->pgen_size = 0; + + free(self->inst); + self->inst = NULL; + self->inst_size = 0; + + free(self->ibag); + self->ibag = NULL; + self->ibag_size = 0; + free(self->imod); + self->imod = NULL; + self->imod_size = 0; + free(self->igen); + self->igen = NULL; + self->igen_size = 0; + + free(self->shdr); + self->shdr = NULL; + self->shdr_size = 0; +} + + +#define FOURCC(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) +#define FOURCCARGS(x) (char)((x)&0xff), (char)(((x)>>8)&0xff), (char)(((x)>>16)&0xff), (char)(((x)>>24)&0xff) +typedef struct RiffHdr { + ALuint mCode; + ALuint mSize; +} RiffHdr; +static void RiffHdr_read(RiffHdr *self, Reader *stream) +{ + self->mCode = read_le32(stream); + self->mSize = read_le32(stream); +} + + +typedef struct GenModList { + Generator *gens; + ALsizei gens_size; + ALsizei gens_max; + + Modulator *mods; + ALsizei mods_size; + ALsizei mods_max; +} GenModList; + +static void GenModList_Construct(GenModList *self) +{ + self->gens = NULL; + self->gens_size = 0; + self->gens_max = 0; + + self->mods = NULL; + self->mods_size = 0; + self->mods_max = 0; +} + +static void GenModList_Destruct(GenModList *self) +{ + free(self->gens); + self->gens = NULL; + self->gens_size = 0; + self->gens_max = 0; + + free(self->mods); + self->mods = NULL; + self->mods_size = 0; + self->mods_max = 0; +} + +static GenModList GenModList_clone(const GenModList *self) +{ + GenModList ret; + + ret.gens = malloc(self->gens_max * sizeof(ret.gens[0])); + memcpy(ret.gens, self->gens, self->gens_size * sizeof(ret.gens[0])); + ret.gens_size = self->gens_size; + ret.gens_max = self->gens_max; + + ret.mods = malloc(self->mods_max * sizeof(ret.mods[0])); + memcpy(ret.mods, self->mods, self->mods_size * sizeof(ret.mods[0])); + ret.mods_size = self->mods_size; + ret.mods_max = self->mods_max; + + return ret; +} + +static void GenModList_insertGen(GenModList *self, const Generator *gen, ALboolean ispreset) +{ + Generator *i = self->gens; + Generator *end = i + self->gens_size; + for(;i != end;i++) + { + if(i->mGenerator == gen->mGenerator) + { + i->mAmount = gen->mAmount; + return; + } + } + + if(ispreset && + (gen->mGenerator == 0 || gen->mGenerator == 1 || gen->mGenerator == 2 || + gen->mGenerator == 3 || gen->mGenerator == 4 || gen->mGenerator == 12 || + gen->mGenerator == 45 || gen->mGenerator == 46 || gen->mGenerator == 47 || + gen->mGenerator == 50 || gen->mGenerator == 54 || gen->mGenerator == 57 || + gen->mGenerator == 58)) + return; + + if(self->gens_size == self->gens_max) + { + void *temp = NULL; + ALsizei newsize; + + newsize = (self->gens_max ? self->gens_max<<1 : 1); + if(newsize > self->gens_max) + temp = realloc(self->gens, newsize * sizeof(self->gens[0])); + if(!temp) + { + ERR("Failed to increase generator storage to %d elements (from %d)\n", + newsize, self->gens_max); + return; + } + + self->gens = temp; + self->gens_max = newsize; + } + + self->gens[self->gens_size] = *gen; + self->gens_size++; +} +static void GenModList_accumGen(GenModList *self, const Generator *gen) +{ + Generator *i = self->gens; + Generator *end = i + self->gens_size; + for(;i != end;i++) + { + if(i->mGenerator == gen->mGenerator) + { + if(gen->mGenerator == 43 || gen->mGenerator == 44) + { + /* Range generators accumulate by taking the intersection of + * the two ranges. + */ + ALushort low = maxu(i->mAmount&0x00ff, gen->mAmount&0x00ff); + ALushort high = minu(i->mAmount&0xff00, gen->mAmount&0xff00); + i->mAmount = low | high; + } + else + i->mAmount += gen->mAmount; + return; + } + } + + if(self->gens_size == self->gens_max) + { + void *temp = NULL; + ALsizei newsize; + + newsize = (self->gens_max ? self->gens_max<<1 : 1); + if(newsize > self->gens_max) + temp = realloc(self->gens, newsize * sizeof(self->gens[0])); + if(!temp) + { + ERR("Failed to increase generator storage to %d elements (from %d)\n", + newsize, self->gens_max); + return; + } + + self->gens = temp; + self->gens_max = newsize; + } + + self->gens[self->gens_size] = *gen; + if(gen->mGenerator < 60) + self->gens[self->gens_size].mAmount += DefaultGenValue[gen->mGenerator]; + self->gens_size++; +} + +static void GenModList_insertMod(GenModList *self, const Modulator *mod) +{ + Modulator *i = self->mods; + Modulator *end = i + self->mods_size; + for(;i != end;i++) + { + if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp && + i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp) + { + i->mAmount = mod->mAmount; + return; + } + } + + if(self->mods_size == self->mods_max) + { + void *temp = NULL; + ALsizei newsize; + + newsize = (self->mods_max ? self->mods_max<<1 : 1); + if(newsize > self->mods_max) + temp = realloc(self->mods, newsize * sizeof(self->mods[0])); + if(!temp) + { + ERR("Failed to increase modulator storage to %d elements (from %d)\n", + newsize, self->mods_max); + return; + } + + self->mods = temp; + self->mods_max = newsize; + } + + self->mods[self->mods_size] = *mod; + self->mods_size++; +} +static void GenModList_accumMod(GenModList *self, const Modulator *mod) +{ + Modulator *i = self->mods; + Modulator *end = i + self->mods_size; + for(;i != end;i++) + { + if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp && + i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp) + { + i->mAmount += mod->mAmount; + return; + } + } + + if(self->mods_size == self->mods_max) + { + void *temp = NULL; + ALsizei newsize; + + newsize = (self->mods_max ? self->mods_max<<1 : 1); + if(newsize > self->mods_max) + temp = realloc(self->mods, newsize * sizeof(self->mods[0])); + if(!temp) + { + ERR("Failed to increase modulator storage to %d elements (from %d)\n", + newsize, self->mods_max); + return; + } + + self->mods = temp; + self->mods_max = newsize; + } + + self->mods[self->mods_size] = *mod; + if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 960; + else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += -2400; + else if(mod->mSrcOp == 0x000D && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 50; + else if(mod->mSrcOp == 0x0081 && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 50; + else if(mod->mSrcOp == 0x0582 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 960; + else if(mod->mSrcOp == 0x028A && mod->mDstOp == 17 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 1000; + else if(mod->mSrcOp == 0x058B && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 960; + else if(mod->mSrcOp == 0x00DB && mod->mDstOp == 16 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 200; + else if(mod->mSrcOp == 0x00DD && mod->mDstOp == 15 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 200; + /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0) + self->mods[self->mods_size].mAmount += 12700;*/ + self->mods_size++; +} + + +#define ERROR_GOTO(lbl_, ...) do { \ + ERR(__VA_ARGS__); \ + goto lbl_; \ +} while(0) + +static ALboolean ensureFontSanity(const Soundfont *sfont) +{ + ALsizei i; + + for(i = 0;i < sfont->phdr_size-1;i++) + { + if(sfont->phdr[i].mZoneIdx >= sfont->pbag_size) + { + WARN("Preset %d has invalid zone index %d (max: %d)\n", i, + sfont->phdr[i].mZoneIdx, sfont->pbag_size); + return AL_FALSE; + } + if(sfont->phdr[i+1].mZoneIdx < sfont->phdr[i].mZoneIdx) + { + WARN("Preset %d has invalid zone index (%d does not follow %d)\n", i+1, + sfont->phdr[i+1].mZoneIdx, sfont->phdr[i].mZoneIdx); + return AL_FALSE; + } + } + if(sfont->phdr[i].mZoneIdx >= sfont->pbag_size) + { + WARN("Preset %d has invalid zone index %d (max: %d)\n", i, + sfont->phdr[i].mZoneIdx, sfont->pbag_size); + return AL_FALSE; + } + + for(i = 0;i < sfont->pbag_size-1;i++) + { + if(sfont->pbag[i].mGenIdx >= sfont->pgen_size) + { + WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i, + sfont->pbag[i].mGenIdx, sfont->pgen_size); + return AL_FALSE; + } + if(sfont->pbag[i+1].mGenIdx < sfont->pbag[i].mGenIdx) + { + WARN("Preset zone %d has invalid generator index (%d does not follow %d)\n", i+1, + sfont->pbag[i+1].mGenIdx, sfont->pbag[i].mGenIdx); + return AL_FALSE; + } + if(sfont->pbag[i].mModIdx >= sfont->pmod_size) + { + WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i, + sfont->pbag[i].mModIdx, sfont->pmod_size); + return AL_FALSE; + } + if(sfont->pbag[i+1].mModIdx < sfont->pbag[i].mModIdx) + { + WARN("Preset zone %d has invalid modulator index (%d does not follow %d)\n", i+1, + sfont->pbag[i+1].mModIdx, sfont->pbag[i].mModIdx); + return AL_FALSE; + } + } + if(sfont->pbag[i].mGenIdx >= sfont->pgen_size) + { + WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i, + sfont->pbag[i].mGenIdx, sfont->pgen_size); + return AL_FALSE; + } + if(sfont->pbag[i].mModIdx >= sfont->pmod_size) + { + WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i, + sfont->pbag[i].mModIdx, sfont->pmod_size); + return AL_FALSE; + } + + + for(i = 0;i < sfont->inst_size-1;i++) + { + if(sfont->inst[i].mZoneIdx >= sfont->ibag_size) + { + WARN("Instrument %d has invalid zone index %d (max: %d)\n", i, + sfont->inst[i].mZoneIdx, sfont->ibag_size); + return AL_FALSE; + } + if(sfont->inst[i+1].mZoneIdx < sfont->inst[i].mZoneIdx) + { + WARN("Instrument %d has invalid zone index (%d does not follow %d)\n", i+1, + sfont->inst[i+1].mZoneIdx, sfont->inst[i].mZoneIdx); + return AL_FALSE; + } + } + if(sfont->inst[i].mZoneIdx >= sfont->ibag_size) + { + WARN("Instrument %d has invalid zone index %d (max: %d)\n", i, + sfont->inst[i].mZoneIdx, sfont->ibag_size); + return AL_FALSE; + } + + for(i = 0;i < sfont->ibag_size-1;i++) + { + if(sfont->ibag[i].mGenIdx >= sfont->igen_size) + { + WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i, + sfont->ibag[i].mGenIdx, sfont->igen_size); + return AL_FALSE; + } + if(sfont->ibag[i+1].mGenIdx < sfont->ibag[i].mGenIdx) + { + WARN("Instrument zone %d has invalid generator index (%d does not follow %d)\n", i+1, + sfont->ibag[i+1].mGenIdx, sfont->ibag[i].mGenIdx); + return AL_FALSE; + } + if(sfont->ibag[i].mModIdx >= sfont->imod_size) + { + WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i, + sfont->ibag[i].mModIdx, sfont->imod_size); + return AL_FALSE; + } + if(sfont->ibag[i+1].mModIdx < sfont->ibag[i].mModIdx) + { + WARN("Instrument zone %d has invalid modulator index (%d does not follow %d)\n", i+1, + sfont->ibag[i+1].mModIdx, sfont->ibag[i].mModIdx); + return AL_FALSE; + } + } + if(sfont->ibag[i].mGenIdx >= sfont->igen_size) + { + WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i, + sfont->ibag[i].mGenIdx, sfont->igen_size); + return AL_FALSE; + } + if(sfont->ibag[i].mModIdx >= sfont->imod_size) + { + WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i, + sfont->ibag[i].mModIdx, sfont->imod_size); + return AL_FALSE; + } + + + for(i = 0;i < sfont->shdr_size-1;i++) + { + if((sfont->shdr[i].mSampleType&0x8000) && sfont->irom == NULL) + { + WARN("Sample header %d has ROM sample type without an irom sub-chunk\n", i); + return AL_FALSE; + } + } + + + return AL_TRUE; +} + +static ALboolean checkZone(const GenModList *zone, const PresetHeader *preset, const InstrumentHeader *inst, const SampleHeader *samp) +{ + ALsizei i; + + for(i = 0;i < zone->gens_size;i++) + { + if(zone->gens[i].mGenerator == 43 || zone->gens[i].mGenerator == 44) + { + int high = zone->gens[i].mAmount>>8; + int low = zone->gens[i].mAmount&0xff; + + if(!(low >= 0 && high <= 127 && high >= low)) + { + TRACE("Preset \"%s\", inst \"%s\", sample \"%s\": invalid %s range %d...%d\n", + preset->mName, inst->mName, samp->mName, + (zone->gens[i].mGenerator == 43) ? "key" : + (zone->gens[i].mGenerator == 44) ? "velocity" : "(unknown)", + low, high); + return AL_FALSE; + } + } + } + + return AL_TRUE; +} + +static ALenum getModSrcInput(int input) +{ + if(input == 0) return AL_ONE_SOFT; + if(input == 2) return AL_NOTEON_VELOCITY_SOFT; + if(input == 3) return AL_NOTEON_KEY_SOFT; + if(input == 10) return AL_KEYPRESSURE_SOFT; + if(input == 13) return AL_CHANNELPRESSURE_SOFT; + if(input == 14) return AL_PITCHBEND_SOFT; + if(input == 16) return AL_PITCHBEND_SENSITIVITY_SOFT; + if((input&0x80)) + { + input ^= 0x80; + if(input > 0 && input < 120 && !(input == 6 || (input >= 32 && input <= 63) || + (input >= 98 && input <= 101))) + return input; + input ^= 0x80; + } + ERR("Unhandled modulator source input: 0x%02x\n", input); + return AL_INVALID; +} + +static ALenum getModSrcType(int type) +{ + if(type == 0x0000) return AL_UNORM_SOFT; + if(type == 0x0100) return AL_UNORM_REV_SOFT; + if(type == 0x0200) return AL_SNORM_SOFT; + if(type == 0x0300) return AL_SNORM_REV_SOFT; + ERR("Unhandled modulator source type: 0x%04x\n", type); + return AL_INVALID; +} + +static ALenum getModSrcForm(int form) +{ + if(form == 0x0000) return AL_LINEAR_SOFT; + if(form == 0x0400) return AL_CONCAVE_SOFT; + if(form == 0x0800) return AL_CONVEX_SOFT; + if(form == 0x0C00) return AL_SWITCH_SOFT; + ERR("Unhandled modulator source form: 0x%04x\n", form); + return AL_INVALID; +} + +static ALenum getModTransOp(int op) +{ + if(op == 0) return AL_LINEAR_SOFT; + if(op == 2) return AL_ABSOLUTE_SOFT; + ERR("Unhandled modulator transform op: 0x%04x\n", op); + return AL_INVALID; +} + +static ALenum getLoopMode(int mode) +{ + if(mode == 0) return AL_NONE; + if(mode == 1) return AL_LOOP_CONTINUOUS_SOFT; + if(mode == 3) return AL_LOOP_UNTIL_RELEASE_SOFT; + ERR("Unhandled loop mode: %d\n", mode); + return AL_NONE; +} + +static ALenum getSampleType(int type) +{ + if(type == 1) return AL_MONO_SOFT; + if(type == 2) return AL_RIGHT_SOFT; + if(type == 4) return AL_LEFT_SOFT; + if(type == 8) + { + WARN("Sample type \"linked\" ignored; pretending mono\n"); + return AL_MONO_SOFT; + } + ERR("Unhandled sample type: 0x%04x\n", type); + return AL_MONO_SOFT; +} + +static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *zone) +{ + static const ALenum Gen2Param[60] = { + 0, /* 0 - startAddrOffset */ + 0, /* 1 - endAddrOffset */ + 0, /* 2 - startloopAddrOffset */ + 0, /* 3 - endloopAddrOffset */ + 0, /* 4 - startAddrCoarseOffset */ + AL_MOD_LFO_TO_PITCH_SOFT, /* 5 - modLfoToPitch */ + AL_VIBRATO_LFO_TO_PITCH_SOFT, /* 6 - vibLfoToPitch */ + AL_MOD_ENV_TO_PITCH_SOFT, /* 7 - modEnvToPitch */ + AL_FILTER_CUTOFF_SOFT, /* 8 - initialFilterFc */ + AL_FILTER_RESONANCE_SOFT, /* 9 - initialFilterQ */ + AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT, /* 10 - modLfoToFilterFc */ + AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT, /* 11 - modEnvToFilterFc */ + 0, /* 12 - endAddrCoarseOffset */ + AL_MOD_LFO_TO_VOLUME_SOFT, /* 13 - modLfoToVolume */ + 0, /* 14 - */ + AL_CHORUS_SEND_SOFT, /* 15 - chorusEffectsSend */ + AL_REVERB_SEND_SOFT, /* 16 - reverbEffectsSend */ + AL_PAN_SOFT, /* 17 - pan */ + 0, /* 18 - */ + 0, /* 19 - */ + 0, /* 20 - */ + AL_MOD_LFO_DELAY_SOFT, /* 21 - delayModLFO */ + AL_MOD_LFO_FREQUENCY_SOFT, /* 22 - freqModLFO */ + AL_VIBRATO_LFO_DELAY_SOFT, /* 23 - delayVibLFO */ + AL_VIBRATO_LFO_FREQUENCY_SOFT, /* 24 - freqVibLFO */ + AL_MOD_ENV_DELAYTIME_SOFT, /* 25 - delayModEnv */ + AL_MOD_ENV_ATTACKTIME_SOFT, /* 26 - attackModEnv */ + AL_MOD_ENV_HOLDTIME_SOFT, /* 27 - holdModEnv */ + AL_MOD_ENV_DECAYTIME_SOFT, /* 28 - decayModEnv */ + AL_MOD_ENV_SUSTAINVOLUME_SOFT, /* 29 - sustainModEnv */ + AL_MOD_ENV_RELEASETIME_SOFT, /* 30 - releaseModEnv */ + AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT, /* 31 - keynumToModEnvHold */ + AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT, /* 32 - keynumToModEnvDecay */ + AL_VOLUME_ENV_DELAYTIME_SOFT, /* 33 - delayVolEnv */ + AL_VOLUME_ENV_ATTACKTIME_SOFT, /* 34 - attackVolEnv */ + AL_VOLUME_ENV_HOLDTIME_SOFT, /* 35 - holdVolEnv */ + AL_VOLUME_ENV_DECAYTIME_SOFT, /* 36 - decayVolEnv */ + AL_VOLUME_ENV_SUSTAINVOLUME_SOFT, /* 37 - sustainVolEnv */ + AL_VOLUME_ENV_RELEASETIME_SOFT, /* 38 - releaseVolEnv */ + AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT, /* 39 - keynumToVolEnvHold */ + AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT, /* 40 - keynumToVolEnvDecay */ + 0, /* 41 - */ + 0, /* 42 - */ + AL_KEY_RANGE_SOFT, /* 43 - keyRange */ + AL_VELOCITY_RANGE_SOFT, /* 44 - velRange */ + 0, /* 45 - startloopAddrCoarseOffset */ + 0, /* 46 - keynum */ + 0, /* 47 - velocity */ + AL_ATTENUATION_SOFT, /* 48 - initialAttenuation */ + 0, /* 49 - */ + 0, /* 50 - endloopAddrCoarseOffset */ + AL_TUNING_COARSE_SOFT, /* 51 - corseTune */ + AL_TUNING_FINE_SOFT, /* 52 - fineTune */ + 0, /* 53 - */ + AL_LOOP_MODE_SOFT, /* 54 - sampleModes */ + 0, /* 55 - */ + AL_TUNING_SCALE_SOFT, /* 56 - scaleTuning */ + AL_EXCLUSIVE_CLASS_SOFT, /* 57 - exclusiveClass */ + AL_BASE_KEY_SOFT, /* 58 - overridingRootKey */ + 0, /* 59 - */ + }; + const Generator *gen, *gen_end; + + if(zone->mods) + { + ALsizei i; + for(i = 0;i < zone->mods_size;i++) + { + ALenum src0in = getModSrcInput(zone->mods[i].mSrcOp&0xFF); + ALenum src0type = getModSrcType(zone->mods[i].mSrcOp&0x0300); + ALenum src0form = getModSrcForm(zone->mods[i].mSrcOp&0xFC00); + ALenum src1in = getModSrcInput(zone->mods[i].mAmtSrcOp&0xFF); + ALenum src1type = getModSrcType(zone->mods[i].mAmtSrcOp&0x0300); + ALenum src1form = getModSrcForm(zone->mods[i].mAmtSrcOp&0xFC00); + ALenum trans = getModTransOp(zone->mods[i].mTransOp); + ALenum dst = (zone->mods[i].mDstOp < 60) ? Gen2Param[zone->mods[i].mDstOp] : 0; + if(!dst || dst == AL_KEY_RANGE_SOFT || dst == AL_VELOCITY_RANGE_SOFT || + dst == AL_LOOP_MODE_SOFT || dst == AL_EXCLUSIVE_CLASS_SOFT || + dst == AL_BASE_KEY_SOFT) + ERR("Unhandled modulator destination: %d\n", zone->mods[i].mDstOp); + else if(src0in != AL_INVALID && src0form != AL_INVALID && src0type != AL_INVALID && + src1in != AL_INVALID && src1form != AL_INVALID && src0type != AL_INVALID && + trans != AL_INVALID) + { + ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_INPUT_SOFT, src0in); + ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_TYPE_SOFT, src0type); + ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_FORM_SOFT, src0form); + ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_INPUT_SOFT, src1in); + ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_TYPE_SOFT, src1type); + ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_FORM_SOFT, src1form); + ALfontsound_setModStagei(sound, context, i, AL_AMOUNT_SOFT, zone->mods[i].mAmount); + ALfontsound_setModStagei(sound, context, i, AL_TRANSFORM_OP_SOFT, trans); + ALfontsound_setModStagei(sound, context, i, AL_DESTINATION_SOFT, dst); + } + } + } + + gen = zone->gens; + gen_end = gen + zone->gens_size; + for(;gen != gen_end;gen++) + { + ALint value = (ALshort)gen->mAmount; + if(gen->mGenerator == 0) + sound->Start += value; + else if(gen->mGenerator == 1) + sound->End += value; + else if(gen->mGenerator == 2) + sound->LoopStart += value; + else if(gen->mGenerator == 3) + sound->LoopEnd += value; + else if(gen->mGenerator == 4) + sound->Start += value<<15; + else if(gen->mGenerator == 12) + sound->End += value<<15; + else if(gen->mGenerator == 45) + sound->LoopStart += value<<15; + else if(gen->mGenerator == 50) + sound->LoopEnd += value<<15; + else if(gen->mGenerator == 43) + { + sound->MinKey = mini((value&0xff), 127); + sound->MaxKey = mini(((value>>8)&0xff), 127); + } + else if(gen->mGenerator == 44) + { + sound->MinVelocity = mini((value&0xff), 127); + sound->MaxVelocity = mini(((value>>8)&0xff), 127); + } + else + { + ALenum param = 0; + if(gen->mGenerator < 60) + param = Gen2Param[gen->mGenerator]; + if(param) + { + if(param == AL_BASE_KEY_SOFT) + { + if(!(value >= 0 && value <= 127)) + { + if(value != -1) + WARN("Invalid overridingRootKey generator value %d\n", value); + continue; + } + } + if(param == AL_FILTER_RESONANCE_SOFT || param == AL_ATTENUATION_SOFT) + value = maxi(0, value); + else if(param == AL_CHORUS_SEND_SOFT || param == AL_REVERB_SEND_SOFT) + value = clampi(value, 0, 1000); + else if(param == AL_LOOP_MODE_SOFT) + value = getLoopMode(value); + ALfontsound_setPropi(sound, context, param, value); + } + else if(gen->mGenerator < 256) + { + static ALboolean warned[256]; + if(!warned[gen->mGenerator]) + { + warned[gen->mGenerator] = AL_TRUE; + ERR("Unhandled generator %d\n", gen->mGenerator); + } + } + } + } +} + +static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCcontext *context, InstrumentHeader *inst, const PresetHeader *preset, const Soundfont *sfont, const GenModList *pzone) +{ + const Generator *gen, *gen_end; + const Modulator *mod, *mod_end; + const Zone *zone, *zone_end; + GenModList gzone; + ALvoid *temp; + + if((inst+1)->mZoneIdx == inst->mZoneIdx) + ERR("Instrument with no zones!"); + + GenModList_Construct(&gzone); + zone = sfont->ibag + inst->mZoneIdx; + zone_end = sfont->ibag + (inst+1)->mZoneIdx; + if(zone_end-zone > 1) + { + gen = sfont->igen + zone->mGenIdx; + gen_end = sfont->igen + (zone+1)->mGenIdx; + + // If no generators, or last generator is not a sample, this is a global zone + for(;gen != gen_end;gen++) + { + if(gen->mGenerator == 53) + break; + } + + if(gen == gen_end) + { + gen = sfont->igen + zone->mGenIdx; + gen_end = sfont->igen + (zone+1)->mGenIdx; + for(;gen != gen_end;gen++) + GenModList_insertGen(&gzone, gen, AL_FALSE); + + mod = sfont->imod + zone->mModIdx; + mod_end = sfont->imod + (zone+1)->mModIdx; + for(;mod != mod_end;mod++) + GenModList_insertMod(&gzone, mod); + + zone++; + } + } + + temp = realloc(*sounds, (zone_end-zone + *sounds_size)*sizeof((*sounds)[0])); + if(!temp) + { + ERR("Failed reallocating fontsound storage to %ld elements (from %d)\n", + (zone_end-zone + *sounds_size), *sounds_size); + return; + } + *sounds = temp; + for(;zone != zone_end;zone++) + { + GenModList lzone = GenModList_clone(&gzone); + mod = sfont->imod + zone->mModIdx; + mod_end = sfont->imod + (zone+1)->mModIdx; + for(;mod != mod_end;mod++) + GenModList_insertMod(&lzone, mod); + + gen = sfont->igen + zone->mGenIdx; + gen_end = sfont->igen + (zone+1)->mGenIdx; + for(;gen != gen_end;gen++) + { + if(gen->mGenerator == 53) + { + const SampleHeader *samp; + ALfontsound *sound; + + if(gen->mAmount >= sfont->shdr_size-1) + { + ERR("Generator %ld has invalid sample ID (%d of %d)\n", + (long)(gen-sfont->igen), gen->mAmount, sfont->shdr_size-1); + break; + } + samp = &sfont->shdr[gen->mAmount]; + + gen = pzone->gens; + gen_end = gen + pzone->gens_size; + for(;gen != gen_end;gen++) + GenModList_accumGen(&lzone, gen); + + mod = pzone->mods; + mod_end = mod + pzone->mods_size; + for(;mod != mod_end;mod++) + GenModList_accumMod(&lzone, mod); + + if(!checkZone(&lzone, preset, inst, samp)) + break; + /* Ignore ROM samples for now. */ + if((samp->mSampleType&0x8000)) + break; + + sound = NewFontsound(context); + (*sounds)[(*sounds_size)++] = sound; + ALfontsound_setPropi(sound, context, AL_SAMPLE_START_SOFT, samp->mStart); + ALfontsound_setPropi(sound, context, AL_SAMPLE_END_SOFT, samp->mEnd); + ALfontsound_setPropi(sound, context, AL_SAMPLE_LOOP_START_SOFT, samp->mStartloop); + ALfontsound_setPropi(sound, context, AL_SAMPLE_LOOP_END_SOFT, samp->mEndloop); + ALfontsound_setPropi(sound, context, AL_SAMPLE_RATE_SOFT, samp->mSampleRate); + ALfontsound_setPropi(sound, context, AL_BASE_KEY_SOFT, (samp->mOriginalKey <= 127) ? samp->mOriginalKey : 60); + ALfontsound_setPropi(sound, context, AL_KEY_CORRECTION_SOFT, samp->mCorrection); + ALfontsound_setPropi(sound, context, AL_SAMPLE_TYPE_SOFT, getSampleType(samp->mSampleType&0x7fff)); + fillZone(sound, context, &lzone); + + break; + } + GenModList_insertGen(&lzone, gen, AL_FALSE); + } + + GenModList_Destruct(&lzone); + } + + GenModList_Destruct(&gzone); +} + +ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context) +{ + ALsfpreset **presets = NULL; + ALsizei presets_size = 0; + ALuint ltype; + Soundfont sfont; + RiffHdr riff; + RiffHdr list; + ALsizei i; + + Soundfont_Construct(&sfont); + + RiffHdr_read(&riff, stream); + if(riff.mCode != FOURCC('R','I','F','F')) + ERROR_GOTO(error, "Invalid Format, expected RIFF got '%c%c%c%c'\n", FOURCCARGS(riff.mCode)); + if((ltype=read_le32(stream)) != FOURCC('s','f','b','k')) + ERROR_GOTO(error, "Invalid Format, expected sfbk got '%c%c%c%c'\n", FOURCCARGS(ltype)); + + if(READERR(stream) != 0) + ERROR_GOTO(error, "Error reading file header\n"); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('L','I','S','T')) + ERROR_GOTO(error, "Invalid Format, expected LIST (INFO) got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((ltype=read_le32(stream)) != FOURCC('I','N','F','O')) + ERROR_GOTO(error, "Invalid Format, expected INFO got '%c%c%c%c'\n", FOURCCARGS(ltype)); + list.mSize -= 4; + while(list.mSize > 0 && !READERR(stream)) + { + RiffHdr info; + + RiffHdr_read(&info, stream); + list.mSize -= 8; + if(info.mCode == FOURCC('i','f','i','l')) + { + if(info.mSize != 4) + ERR("Invalid ifil chunk size: %d\n", info.mSize); + else + { + ALushort major = read_le16(stream); + ALushort minor = read_le16(stream); + + list.mSize -= 4; + info.mSize -= 4; + + if(major != 2) + ERROR_GOTO(error, "Unsupported SF2 format version: %d.%02d\n", major, minor); + TRACE("SF2 format version: %d.%02d\n", major, minor); + + sfont.ifil = (major<<16) | minor; + } + } + else if(info.mCode == FOURCC('i','r','o','m')) + { + if(info.mSize == 0 || (info.mSize&1)) + ERR("Invalid irom size: %d\n", info.mSize); + else + { + free(sfont.irom); + sfont.irom = calloc(1, info.mSize+1); + READ(stream, sfont.irom, info.mSize); + + list.mSize -= info.mSize; + info.mSize -= info.mSize; + + TRACE("SF2 ROM ID: %s\n", sfont.irom); + } + } + list.mSize -= info.mSize; + skip(stream, info.mSize); + } + + if(READERR(stream) != 0) + ERROR_GOTO(error, "Error reading INFO chunk\n"); + if(sfont.ifil == 0) + ERROR_GOTO(error, "Missing ifil sub-chunk\n"); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('L','I','S','T')) + ERROR_GOTO(error, "Invalid Format, expected LIST (sdta) got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((ltype=read_le32(stream)) != FOURCC('s','d','t','a')) + ERROR_GOTO(error, "Invalid Format, expected sdta got '%c%c%c%c'\n", FOURCCARGS(ltype)); + list.mSize -= 4; + { + ALbyte *ptr; + RiffHdr smpl; + + RiffHdr_read(&smpl, stream); + if(smpl.mCode != FOURCC('s','m','p','l')) + ERROR_GOTO(error, "Invalid Format, expected smpl got '%c%c%c%c'\n", FOURCCARGS(smpl.mCode)); + list.mSize -= 8; + + if(smpl.mSize > list.mSize) + ERROR_GOTO(error, "Invalid Format, sample chunk size mismatch\n"); + + if(!(ptr=realloc(soundfont->Samples, smpl.mSize))) + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, error); + soundfont->Samples = (ALshort*)ptr; + soundfont->NumSamples = smpl.mSize/2; + + if(IS_LITTLE_ENDIAN) + READ(stream, ptr, smpl.mSize); + else + { + while(smpl.mSize > 0) + { + ALbyte buf[4096]; + ALuint todo = minu(smpl.mSize, sizeof(buf)); + ALuint i; + + READ(stream, buf, todo); + for(i = 0;i < todo;i++) + ptr[i] = buf[i^1]; + } + } + list.mSize -= smpl.mSize; + + skip(stream, list.mSize); + } + + if(READERR(stream) != 0) + ERROR_GOTO(error, "Error reading sdta chunk\n"); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('L','I','S','T')) + ERROR_GOTO(error, "Invalid Format, expected LIST (pdta) got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((ltype=read_le32(stream)) != FOURCC('p','d','t','a')) + ERROR_GOTO(error, "Invalid Format, expected pdta got '%c%c%c%c'\n", FOURCCARGS(ltype)); + + // + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('p','h','d','r')) + ERROR_GOTO(error, "Invalid Format, expected phdr got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%38) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad phdr size: %u\n", list.mSize); + sfont.phdr_size = list.mSize/38; + sfont.phdr = calloc(sfont.phdr_size, sizeof(sfont.phdr[0])); + for(i = 0;i < sfont.phdr_size;i++) + PresetHeader_read(&sfont.phdr[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('p','b','a','g')) + ERROR_GOTO(error, "Invalid Format, expected pbag got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%4) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad pbag size: %u\n", list.mSize); + sfont.pbag_size = list.mSize/4; + sfont.pbag = calloc(sfont.pbag_size, sizeof(sfont.pbag[0])); + for(i = 0;i < sfont.pbag_size;i++) + Zone_read(&sfont.pbag[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('p','m','o','d')) + ERROR_GOTO(error, "Invalid Format, expected pmod got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%10) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad pmod size: %u\n", list.mSize); + sfont.pmod_size = list.mSize/10; + sfont.pmod = calloc(sfont.pmod_size, sizeof(sfont.pmod[0])); + for(i = 0;i < sfont.pmod_size;i++) + Modulator_read(&sfont.pmod[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('p','g','e','n')) + ERROR_GOTO(error, "Invalid Format, expected pgen got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%4) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad pgen size: %u\n", list.mSize); + sfont.pgen_size = list.mSize/4; + sfont.pgen = calloc(sfont.pgen_size, sizeof(sfont.pgen[0])); + for(i = 0;i < sfont.pgen_size;i++) + Generator_read(&sfont.pgen[i], stream); + + // + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('i','n','s','t')) + ERROR_GOTO(error, "Invalid Format, expected inst got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%22) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad inst size: %u\n", list.mSize); + sfont.inst_size = list.mSize/22; + sfont.inst = calloc(sfont.inst_size, sizeof(sfont.inst[0])); + for(i = 0;i < sfont.inst_size;i++) + InstrumentHeader_read(&sfont.inst[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('i','b','a','g')) + ERROR_GOTO(error, "Invalid Format, expected ibag got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%4) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad ibag size: %u\n", list.mSize); + sfont.ibag_size = list.mSize/4; + sfont.ibag = calloc(sfont.ibag_size, sizeof(sfont.ibag[0])); + for(i = 0;i < sfont.ibag_size;i++) + Zone_read(&sfont.ibag[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('i','m','o','d')) + ERROR_GOTO(error, "Invalid Format, expected imod got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%10) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad imod size: %u\n", list.mSize); + sfont.imod_size = list.mSize/10; + sfont.imod = calloc(sfont.imod_size, sizeof(sfont.imod[0])); + for(i = 0;i < sfont.imod_size;i++) + Modulator_read(&sfont.imod[i], stream); + + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('i','g','e','n')) + ERROR_GOTO(error, "Invalid Format, expected igen got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%4) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad igen size: %u\n", list.mSize); + sfont.igen_size = list.mSize/4; + sfont.igen = calloc(sfont.igen_size, sizeof(sfont.igen[0])); + for(i = 0;i < sfont.igen_size;i++) + Generator_read(&sfont.igen[i], stream); + + // + RiffHdr_read(&list, stream); + if(list.mCode != FOURCC('s','h','d','r')) + ERROR_GOTO(error, "Invalid Format, expected shdr got '%c%c%c%c'\n", FOURCCARGS(list.mCode)); + if((list.mSize%46) != 0 || list.mSize == 0) + ERROR_GOTO(error, "Invalid Format, bad shdr size: %u\n", list.mSize); + sfont.shdr_size = list.mSize/46; + sfont.shdr = calloc(sfont.shdr_size, sizeof(sfont.shdr[0])); + for(i = 0;i < sfont.shdr_size;i++) + SampleHeader_read(&sfont.shdr[i], stream); + + if(READERR(stream) != 0) + ERROR_GOTO(error, "Error reading pdta chunk\n"); + + if(!ensureFontSanity(&sfont)) + goto error; + + presets = calloc(1, (sfont.phdr_size-1)*sizeof(presets[0])); + if(!presets) + ERROR_GOTO(error, "Error allocating presets\n"); + + for(i = 0;i < sfont.phdr_size-1;i++) + { + const Generator *gen, *gen_end; + const Modulator *mod, *mod_end; + const Zone *zone, *zone_end; + ALfontsound **sounds = NULL; + ALsizei sounds_size = 0; + GenModList gzone; + + if(sfont.phdr[i+1].mZoneIdx == sfont.phdr[i].mZoneIdx) + continue; + + GenModList_Construct(&gzone); + zone = sfont.pbag + sfont.phdr[i].mZoneIdx; + zone_end = sfont.pbag + sfont.phdr[i+1].mZoneIdx; + if(zone_end-zone > 1) + { + gen = sfont.pgen + zone->mGenIdx; + gen_end = sfont.pgen + (zone+1)->mGenIdx; + + // If no generators, or last generator is not an instrument, this is a global zone + for(;gen != gen_end;gen++) + { + if(gen->mGenerator == 41) + break; + } + + if(gen == gen_end) + { + gen = sfont.pgen + zone->mGenIdx; + gen_end = sfont.pgen + (zone+1)->mGenIdx; + for(;gen != gen_end;gen++) + GenModList_insertGen(&gzone, gen, AL_TRUE); + + mod = sfont.pmod + zone->mModIdx; + mod_end = sfont.pmod + (zone+1)->mModIdx; + for(;mod != mod_end;mod++) + GenModList_insertMod(&gzone, mod); + + zone++; + } + } + + for(;zone != zone_end;zone++) + { + GenModList lzone = GenModList_clone(&gzone); + + mod = sfont.pmod + zone->mModIdx; + mod_end = sfont.pmod + (zone+1)->mModIdx; + for(;mod != mod_end;mod++) + GenModList_insertMod(&lzone, mod); + + gen = sfont.pgen + zone->mGenIdx; + gen_end = sfont.pgen + (zone+1)->mGenIdx; + for(;gen != gen_end;gen++) + { + if(gen->mGenerator == 41) + { + if(gen->mAmount >= sfont.inst_size-1) + ERR("Generator %ld has invalid instrument ID (%d of %d)\n", + (long)(gen-sfont.pgen), gen->mAmount, sfont.inst_size-1); + else + processInstrument(&sounds, &sounds_size, context, + &sfont.inst[gen->mAmount], &sfont.phdr[i], &sfont, &lzone); + break; + } + GenModList_insertGen(&lzone, gen, AL_TRUE); + } + GenModList_Destruct(&lzone); + } + + if(sounds_size > 0) + { + ALsizei j; + + presets[presets_size] = NewPreset(context); + presets[presets_size]->Preset = sfont.phdr[i].mPreset; + presets[presets_size]->Bank = sfont.phdr[i].mBank; + + for(j = 0;j < sounds_size;j++) + IncrementRef(&sounds[j]->ref); + sounds = ExchangePtr((XchgPtr*)&presets[presets_size]->Sounds, sounds); + ExchangeInt(&presets[presets_size]->NumSounds, sounds_size); + presets_size++; + } + free(sounds); + + GenModList_Destruct(&gzone); + } + + for(i = 0;i < presets_size;i++) + IncrementRef(&presets[i]->ref); + presets = ExchangePtr((XchgPtr*)&soundfont->Presets, presets); + ExchangeInt(&soundfont->NumPresets, presets_size); + + free(presets); + + Soundfont_Destruct(&sfont); + + return AL_TRUE; + +error: + if(presets) + { + ALCdevice *device = context->Device; + for(i = 0;i < presets_size;i++) + DeletePreset(presets[i], device); + free(presets); + } + + Soundfont_Destruct(&sfont); + + return AL_FALSE; +} diff --git a/jni/openal-soft-android/Alc/mixer.c b/jni/openal-soft-android/Alc/mixer.c index 0181a31a..acd6c610 100644 --- a/jni/openal-soft-android/Alc/mixer.c +++ b/jni/openal-soft-android/Alc/mixer.c @@ -37,454 +37,21 @@ #include "bs2b.h" -static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac) -{ return vals[0]; (void)step; (void)frac; } -static __inline ALfloat lerp32(const ALfloat *vals, ALint step, ALint frac) -{ return lerp(vals[0], vals[step], frac * (1.0f/FRACTIONONE)); } -static __inline ALfloat cubic32(const ALfloat *vals, ALint step, ALint frac) -{ return cubic(vals[-step], vals[0], vals[step], vals[step+step], - frac * (1.0f/FRACTIONONE)); } - -#ifdef __GNUC__ -#define LIKELY(x) __builtin_expect(!!(x), 1) -#define UNLIKELY(x) __builtin_expect(!!(x), 0) -#else -#define LIKELY(x) (x) -#define UNLIKELY(x) (x) -#endif - -#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_H) -#include - -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], - ALfloat (*RESTRICT Coeffs)[2], - ALfloat left, ALfloat right) -{ - ALuint c; - float32x4_t leftright4; - { - float32x2_t leftright2 = vdup_n_f32(0.0); - leftright2 = vset_lane_f32(left, leftright2, 0); - leftright2 = vset_lane_f32(right, leftright2, 1); - leftright4 = vcombine_f32(leftright2, leftright2); - } - for(c = 0;c < HRIR_LENGTH;c += 2) - { - const ALuint o0 = (Offset+c)&HRIR_MASK; - const ALuint o1 = (o0+1)&HRIR_MASK; - float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]), - vld1_f32((float32_t*)&Values[o1][0])); - float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]); - - vals = vmlaq_f32(vals, coefs, leftright4); - - vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals)); - vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals)); - } -} - -#else - -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], - ALfloat (*RESTRICT Coeffs)[2], - ALfloat left, ALfloat right) -{ - ALuint c; - for(c = 0;c < HRIR_LENGTH;c++) - { - const ALuint off = (Offset+c)&HRIR_MASK; - Values[off][0] += Coeffs[c][0] * left; - Values[off][1] += Coeffs[c][1] * right; - } -} - -#endif - -#define DECL_TEMPLATE(T, sampler) \ -static void Mix_Hrtf_##T##_##sampler(ALsource *Source, ALCdevice *Device, \ - const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \ - ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \ -{ \ - const ALuint NumChannels = Source->NumChannels; \ - const T *RESTRICT data = srcdata; \ - const ALint *RESTRICT DelayStep = Source->Params.HrtfDelayStep; \ - ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \ - ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \ - ALfloat (*RESTRICT CoeffStep)[2] = Source->Params.HrtfCoeffStep; \ - ALuint pos, frac; \ - FILTER *DryFilter; \ - ALuint BufferIdx; \ - ALuint increment; \ - ALuint i, out, c; \ - ALfloat value; \ - \ - increment = Source->Params.Step; \ - \ - DryBuffer = Device->DryBuffer; \ - ClickRemoval = Device->ClickRemoval; \ - PendingClicks = Device->PendingClicks; \ - DryFilter = &Source->Params.iirFilter; \ - \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - ALfloat (*RESTRICT TargetCoeffs)[2] = Source->Params.HrtfCoeffs[i]; \ - ALuint *RESTRICT TargetDelay = Source->Params.HrtfDelay[i]; \ - ALfloat *RESTRICT History = Source->HrtfHistory[i]; \ - ALfloat (*RESTRICT Values)[2] = Source->HrtfValues[i]; \ - ALint Counter = maxu(Source->HrtfCounter, OutPos) - OutPos; \ - ALuint Offset = Source->HrtfOffset + OutPos; \ - ALfloat Coeffs[HRIR_LENGTH][2]; \ - ALuint Delay[2]; \ - ALfloat left, right; \ - \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - for(c = 0;c < HRIR_LENGTH;c++) \ - { \ - Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter); \ - Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter); \ - } \ - \ - Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter) + 32768; \ - Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter) + 32768; \ - \ - if(LIKELY(OutPos == 0)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - value = lpFilter2PC(DryFilter, i, value); \ - \ - History[Offset&SRC_HISTORY_MASK] = value; \ - left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \ - right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \ - \ - ClickRemoval[FRONT_LEFT] -= Values[(Offset+1)&HRIR_MASK][0] + \ - Coeffs[0][0] * left; \ - ClickRemoval[FRONT_RIGHT] -= Values[(Offset+1)&HRIR_MASK][1] + \ - Coeffs[0][1] * right; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize && Counter > 0;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - value = lpFilter2P(DryFilter, i, value); \ - \ - History[Offset&SRC_HISTORY_MASK] = value; \ - left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \ - right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \ - \ - Delay[0] += DelayStep[0]; \ - Delay[1] += DelayStep[1]; \ - \ - Values[Offset&HRIR_MASK][0] = 0.0f; \ - Values[Offset&HRIR_MASK][1] = 0.0f; \ - Offset++; \ - \ - for(c = 0;c < HRIR_LENGTH;c++) \ - { \ - const ALuint off = (Offset+c)&HRIR_MASK; \ - Values[off][0] += Coeffs[c][0] * left; \ - Values[off][1] += Coeffs[c][1] * right; \ - Coeffs[c][0] += CoeffStep[c][0]; \ - Coeffs[c][1] += CoeffStep[c][1]; \ - } \ - \ - DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \ - DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - Counter--; \ - } \ - \ - Delay[0] >>= 16; \ - Delay[1] >>= 16; \ - for(;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - value = lpFilter2P(DryFilter, i, value); \ - \ - History[Offset&SRC_HISTORY_MASK] = value; \ - left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \ - right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \ - \ - Values[Offset&HRIR_MASK][0] = 0.0f; \ - Values[Offset&HRIR_MASK][1] = 0.0f; \ - Offset++; \ - \ - ApplyCoeffs(Offset, Values, Coeffs, left, right); \ - DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \ - DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(LIKELY(OutPos == SamplesToDo)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - value = lpFilter2PC(DryFilter, i, value); \ - \ - History[Offset&SRC_HISTORY_MASK] = value; \ - left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \ - right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \ - \ - PendingClicks[FRONT_LEFT] += Values[(Offset+1)&HRIR_MASK][0] + \ - Coeffs[0][0] * left; \ - PendingClicks[FRONT_RIGHT] += Values[(Offset+1)&HRIR_MASK][1] + \ - Coeffs[0][1] * right; \ - } \ - OutPos -= BufferSize; \ - } \ - \ - for(out = 0;out < Device->NumAuxSends;out++) \ - { \ - ALeffectslot *Slot = Source->Params.Send[out].Slot; \ - ALfloat WetSend; \ - ALfloat *RESTRICT WetBuffer; \ - ALfloat *RESTRICT WetClickRemoval; \ - ALfloat *RESTRICT WetPendingClicks; \ - FILTER *WetFilter; \ - \ - if(!Slot || Slot->effect.type == AL_EFFECT_NULL) \ - continue; \ - \ - WetBuffer = Slot->WetBuffer; \ - WetClickRemoval = Slot->ClickRemoval; \ - WetPendingClicks = Slot->PendingClicks; \ - WetFilter = &Source->Params.Send[out].iirFilter; \ - WetSend = Source->Params.Send[out].WetGain; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - if(LIKELY(OutPos == 0)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1PC(WetFilter, i, value); \ - \ - WetClickRemoval[0] -= value * WetSend; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1P(WetFilter, i, value); \ - \ - WetBuffer[OutPos] += value * WetSend; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(LIKELY(OutPos == SamplesToDo)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1PC(WetFilter, i, value); \ - \ - WetPendingClicks[0] += value * WetSend; \ - } \ - OutPos -= BufferSize; \ - } \ - } \ - *DataPosInt += pos; \ - *DataPosFrac = frac; \ -} - -DECL_TEMPLATE(ALfloat, point32) -DECL_TEMPLATE(ALfloat, lerp32) -DECL_TEMPLATE(ALfloat, cubic32) - -#undef DECL_TEMPLATE - - -#define DECL_TEMPLATE(T, sampler) \ -static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \ - const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \ - ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \ -{ \ - const ALuint NumChannels = Source->NumChannels; \ - const T *RESTRICT data = srcdata; \ - ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \ - ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \ - ALfloat DrySend[MAXCHANNELS]; \ - FILTER *DryFilter; \ - ALuint pos, frac; \ - ALuint BufferIdx; \ - ALuint increment; \ - ALuint i, out, c; \ - ALfloat value; \ - \ - increment = Source->Params.Step; \ - \ - DryBuffer = Device->DryBuffer; \ - ClickRemoval = Device->ClickRemoval; \ - PendingClicks = Device->PendingClicks; \ - DryFilter = &Source->Params.iirFilter; \ - \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - for(c = 0;c < MAXCHANNELS;c++) \ - DrySend[c] = Source->Params.DryGains[i][c]; \ - \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - if(OutPos == 0) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - \ - value = lpFilter2PC(DryFilter, i, value); \ - for(c = 0;c < MAXCHANNELS;c++) \ - ClickRemoval[c] -= value*DrySend[c]; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - \ - value = lpFilter2P(DryFilter, i, value); \ - for(c = 0;c < MAXCHANNELS;c++) \ - DryBuffer[OutPos][c] += value*DrySend[c]; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(OutPos == SamplesToDo) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels, frac); \ - \ - value = lpFilter2PC(DryFilter, i, value); \ - for(c = 0;c < MAXCHANNELS;c++) \ - PendingClicks[c] += value*DrySend[c]; \ - } \ - OutPos -= BufferSize; \ - } \ - \ - for(out = 0;out < Device->NumAuxSends;out++) \ - { \ - ALeffectslot *Slot = Source->Params.Send[out].Slot; \ - ALfloat WetSend; \ - ALfloat *WetBuffer; \ - ALfloat *WetClickRemoval; \ - ALfloat *WetPendingClicks; \ - FILTER *WetFilter; \ - \ - if(!Slot || Slot->effect.type == AL_EFFECT_NULL) \ - continue; \ - \ - WetBuffer = Slot->WetBuffer; \ - WetClickRemoval = Slot->ClickRemoval; \ - WetPendingClicks = Slot->PendingClicks; \ - WetFilter = &Source->Params.Send[out].iirFilter; \ - WetSend = Source->Params.Send[out].WetGain; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - pos = 0; \ - frac = *DataPosFrac; \ - \ - if(OutPos == 0) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - \ - value = lpFilter1PC(WetFilter, i, value); \ - WetClickRemoval[0] -= value * WetSend; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - \ - value = lpFilter1P(WetFilter, i, value); \ - WetBuffer[OutPos] += value * WetSend; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(OutPos == SamplesToDo) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - \ - value = lpFilter1PC(WetFilter, i, value); \ - WetPendingClicks[0] += value * WetSend; \ - } \ - OutPos -= BufferSize; \ - } \ - } \ - *DataPosInt += pos; \ - *DataPosFrac = frac; \ -} - -DECL_TEMPLATE(ALfloat, point32) -DECL_TEMPLATE(ALfloat, lerp32) -DECL_TEMPLATE(ALfloat, cubic32) - -#undef DECL_TEMPLATE - - -MixerFunc SelectMixer(enum Resampler Resampler) -{ - switch(Resampler) - { - case POINT_RESAMPLER: - return Mix_ALfloat_point32; - case LINEAR_RESAMPLER: - return Mix_ALfloat_lerp32; - case CUBIC_RESAMPLER: - return Mix_ALfloat_cubic32; - case RESAMPLER_MIN: - case RESAMPLER_MAX: - break; - } - return NULL; -} - -MixerFunc SelectHrtfMixer(enum Resampler Resampler) -{ - switch(Resampler) - { - case POINT_RESAMPLER: - return Mix_Hrtf_ALfloat_point32; - case LINEAR_RESAMPLER: - return Mix_Hrtf_ALfloat_lerp32; - case CUBIC_RESAMPLER: - return Mix_Hrtf_ALfloat_cubic32; - case RESAMPLER_MIN: - case RESAMPLER_MAX: - break; - } - return NULL; -} - - -static __inline ALfloat Sample_ALbyte(ALbyte val) +static inline ALfloat Sample_ALbyte(ALbyte val) { return val * (1.0f/127.0f); } -static __inline ALfloat Sample_ALshort(ALshort val) +static inline ALfloat Sample_ALshort(ALshort val) { return val * (1.0f/32767.0f); } -static __inline ALfloat Sample_ALfloat(ALfloat val) +static inline ALfloat Sample_ALfloat(ALfloat val) { return val; } #define DECL_TEMPLATE(T) \ -static void Load_##T(ALfloat *dst, const T *src, ALuint samples) \ +static void Load_##T(ALfloat *dst, const T *src, ALuint srcstep, ALuint samples)\ { \ ALuint i; \ for(i = 0;i < samples;i++) \ - dst[i] = Sample_##T(src[i]); \ + dst[i] = Sample_##T(src[i*srcstep]); \ } DECL_TEMPLATE(ALbyte) @@ -493,23 +60,23 @@ DECL_TEMPLATE(ALfloat) #undef DECL_TEMPLATE -static void LoadStack(ALfloat *dst, const ALvoid *src, enum FmtType srctype, ALuint samples) +static void LoadData(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples) { switch(srctype) { case FmtByte: - Load_ALbyte(dst, src, samples); + Load_ALbyte(dst, src, srcstep, samples); break; case FmtShort: - Load_ALshort(dst, src, samples); + Load_ALshort(dst, src, srcstep, samples); break; case FmtFloat: - Load_ALfloat(dst, src, samples); + Load_ALfloat(dst, src, srcstep, samples); break; } } -static void SilenceStack(ALfloat *dst, ALuint samples) +static void SilenceData(ALfloat *dst, ALuint samples) { ALuint i; for(i = 0;i < samples;i++) @@ -517,6 +84,16 @@ static void SilenceStack(ALfloat *dst, ALuint samples) } +static void DoFilter(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *restrict src, + ALuint numsamples) +{ + ALuint i; + for(i = 0;i < numsamples;i++) + dst[i] = ALfilterState_processSingle(filter, src[i]); + dst[i] = ALfilterState_processSingleC(filter, src[i]); +} + + ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) { ALbufferlistitem *BufferListItem; @@ -528,232 +105,255 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) ALenum State; ALuint OutPos; ALuint NumChannels; - ALuint FrameSize; + ALuint SampleSize; ALint64 DataSize64; - ALuint i; + ALuint chan, j; /* Get source info */ State = Source->state; BuffersPlayed = Source->BuffersPlayed; DataPosInt = Source->position; DataPosFrac = Source->position_fraction; - Looping = Source->bLooping; + Looping = Source->Looping; increment = Source->Params.Step; - Resampler = Source->Resampler; + Resampler = (increment==FRACTIONONE) ? PointResampler : Source->Resampler; NumChannels = Source->NumChannels; - FrameSize = NumChannels * Source->SampleSize; + SampleSize = Source->SampleSize; /* Get current buffer queue item */ BufferListItem = Source->queue; - for(i = 0;i < BuffersPlayed;i++) + for(j = 0;j < BuffersPlayed;j++) BufferListItem = BufferListItem->next; OutPos = 0; do { const ALuint BufferPrePadding = ResamplerPrePadding[Resampler]; const ALuint BufferPadding = ResamplerPadding[Resampler]; - ALfloat StackData[STACK_DATA_SIZE/sizeof(ALfloat)]; - ALfloat *SrcData = StackData; - ALuint SrcDataSize = 0; - ALuint BufferSize; + ALuint SrcBufferSize, DstBufferSize; - /* Figure out how many buffer bytes will be needed */ + /* Figure out how many buffer samples will be needed */ DataSize64 = SamplesToDo-OutPos+1; DataSize64 *= increment; DataSize64 += DataPosFrac+FRACTIONMASK; DataSize64 >>= FRACTIONBITS; DataSize64 += BufferPadding+BufferPrePadding; - DataSize64 *= NumChannels; - BufferSize = (ALuint)mini64(DataSize64, STACK_DATA_SIZE/sizeof(ALfloat)); - BufferSize /= NumChannels; + SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE); - if(Source->lSourceType == AL_STATIC) - { - const ALbuffer *ALBuffer = Source->queue->buffer; - const ALubyte *Data = ALBuffer->data; - ALuint DataSize; - ALuint pos; - - /* If current pos is beyond the loop range, do not loop */ - if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd) - { - Looping = AL_FALSE; - - if(DataPosInt >= BufferPrePadding) - pos = DataPosInt - BufferPrePadding; - else - { - DataSize = BufferPrePadding - DataPosInt; - DataSize = minu(BufferSize, DataSize); - - SilenceStack(&SrcData[SrcDataSize*NumChannels], - DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - - pos = 0; - } - - /* Copy what's left to play in the source buffer, and clear the - * rest of the temp buffer */ - DataSize = ALBuffer->SampleLen - pos; - DataSize = minu(BufferSize, DataSize); - - LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize], - ALBuffer->FmtType, DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - - SilenceStack(&SrcData[SrcDataSize*NumChannels], - BufferSize*NumChannels); - SrcDataSize += BufferSize; - BufferSize -= BufferSize; - } - else - { - ALuint LoopStart = ALBuffer->LoopStart; - ALuint LoopEnd = ALBuffer->LoopEnd; - - if(DataPosInt >= LoopStart) - { - pos = DataPosInt-LoopStart; - while(pos < BufferPrePadding) - pos += LoopEnd-LoopStart; - pos -= BufferPrePadding; - pos += LoopStart; - } - else if(DataPosInt >= BufferPrePadding) - pos = DataPosInt - BufferPrePadding; - else - { - DataSize = BufferPrePadding - DataPosInt; - DataSize = minu(BufferSize, DataSize); - - SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - - pos = 0; - } - - /* Copy what's left of this loop iteration, then copy repeats - * of the loop section */ - DataSize = LoopEnd - pos; - DataSize = minu(BufferSize, DataSize); - - LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize], - ALBuffer->FmtType, DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - - DataSize = LoopEnd-LoopStart; - while(BufferSize > 0) - { - DataSize = minu(BufferSize, DataSize); - - LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[LoopStart*FrameSize], - ALBuffer->FmtType, DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - } - } - } - else - { - /* Crawl the buffer queue to fill in the temp buffer */ - ALbufferlistitem *tmpiter = BufferListItem; - ALuint pos; - - if(DataPosInt >= BufferPrePadding) - pos = DataPosInt - BufferPrePadding; - else - { - pos = BufferPrePadding - DataPosInt; - while(pos > 0) - { - if(!tmpiter->prev && !Looping) - { - ALuint DataSize = minu(BufferSize, pos); - - SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - - pos = 0; - break; - } - - if(tmpiter->prev) - tmpiter = tmpiter->prev; - else - { - while(tmpiter->next) - tmpiter = tmpiter->next; - } - - if(tmpiter->buffer) - { - if((ALuint)tmpiter->buffer->SampleLen > pos) - { - pos = tmpiter->buffer->SampleLen - pos; - break; - } - pos -= tmpiter->buffer->SampleLen; - } - } - } - - while(tmpiter && BufferSize > 0) - { - const ALbuffer *ALBuffer; - if((ALBuffer=tmpiter->buffer) != NULL) - { - const ALubyte *Data = ALBuffer->data; - ALuint DataSize = ALBuffer->SampleLen; - - /* Skip the data already played */ - if(DataSize <= pos) - pos -= DataSize; - else - { - Data += pos*FrameSize; - DataSize -= pos; - pos -= pos; - - DataSize = minu(BufferSize, DataSize); - LoadStack(&SrcData[SrcDataSize*NumChannels], Data, - ALBuffer->FmtType, DataSize*NumChannels); - SrcDataSize += DataSize; - BufferSize -= DataSize; - } - } - tmpiter = tmpiter->next; - if(!tmpiter && Looping) - tmpiter = Source->queue; - else if(!tmpiter) - { - SilenceStack(&SrcData[SrcDataSize*NumChannels], BufferSize*NumChannels); - SrcDataSize += BufferSize; - BufferSize -= BufferSize; - } - } - } - - /* Figure out how many samples we can mix. */ - DataSize64 = SrcDataSize; + /* Figure out how many samples we can actually mix from this. */ + DataSize64 = SrcBufferSize; DataSize64 -= BufferPadding+BufferPrePadding; DataSize64 <<= FRACTIONBITS; DataSize64 -= increment; DataSize64 -= DataPosFrac; - BufferSize = (ALuint)((DataSize64+(increment-1)) / increment); - BufferSize = minu(BufferSize, (SamplesToDo-OutPos)); + DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment); + DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos)); - SrcData += BufferPrePadding*NumChannels; - Source->Params.DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac, - OutPos, SamplesToDo, BufferSize); - OutPos += BufferSize; + /* Some mixers like having a multiple of 4, so try to give that unless + * this is the last update. */ + if(OutPos+DstBufferSize < SamplesToDo) + DstBufferSize &= ~3; + + for(chan = 0;chan < NumChannels;chan++) + { + ALfloat *SrcData = Device->SampleData1; + ALfloat *ResampledData = Device->SampleData2; + ALuint SrcDataSize = 0; + + if(Source->SourceType == AL_STATIC) + { + const ALbuffer *ALBuffer = Source->queue->buffer; + const ALubyte *Data = ALBuffer->data; + ALuint DataSize; + ALuint pos; + + /* If current pos is beyond the loop range, do not loop */ + if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd) + { + Looping = AL_FALSE; + + if(DataPosInt >= BufferPrePadding) + pos = DataPosInt - BufferPrePadding; + else + { + DataSize = BufferPrePadding - DataPosInt; + DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + + SilenceData(&SrcData[SrcDataSize], DataSize); + SrcDataSize += DataSize; + + pos = 0; + } + + /* Copy what's left to play in the source buffer, and clear the + * rest of the temp buffer */ + DataSize = minu(SrcBufferSize - SrcDataSize, ALBuffer->SampleLen - pos); + + LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize], + NumChannels, ALBuffer->FmtType, DataSize); + SrcDataSize += DataSize; + + SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); + SrcDataSize += SrcBufferSize - SrcDataSize; + } + else + { + ALuint LoopStart = ALBuffer->LoopStart; + ALuint LoopEnd = ALBuffer->LoopEnd; + + if(DataPosInt >= LoopStart) + { + pos = DataPosInt-LoopStart; + while(pos < BufferPrePadding) + pos += LoopEnd-LoopStart; + pos -= BufferPrePadding; + pos += LoopStart; + } + else if(DataPosInt >= BufferPrePadding) + pos = DataPosInt - BufferPrePadding; + else + { + DataSize = BufferPrePadding - DataPosInt; + DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + + SilenceData(&SrcData[SrcDataSize], DataSize); + SrcDataSize += DataSize; + + pos = 0; + } + + /* Copy what's left of this loop iteration, then copy repeats + * of the loop section */ + DataSize = LoopEnd - pos; + DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + + LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize], + NumChannels, ALBuffer->FmtType, DataSize); + SrcDataSize += DataSize; + + DataSize = LoopEnd-LoopStart; + while(SrcBufferSize > SrcDataSize) + { + DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + + LoadData(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize], + NumChannels, ALBuffer->FmtType, DataSize); + SrcDataSize += DataSize; + } + } + } + else + { + /* Crawl the buffer queue to fill in the temp buffer */ + ALbufferlistitem *tmpiter = BufferListItem; + ALuint pos; + + if(DataPosInt >= BufferPrePadding) + pos = DataPosInt - BufferPrePadding; + else + { + pos = BufferPrePadding - DataPosInt; + while(pos > 0) + { + if(!tmpiter->prev && !Looping) + { + ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos); + + SilenceData(&SrcData[SrcDataSize], DataSize); + SrcDataSize += DataSize; + + pos = 0; + break; + } + + if(tmpiter->prev) + tmpiter = tmpiter->prev; + else + { + while(tmpiter->next) + tmpiter = tmpiter->next; + } + + if(tmpiter->buffer) + { + if((ALuint)tmpiter->buffer->SampleLen > pos) + { + pos = tmpiter->buffer->SampleLen - pos; + break; + } + pos -= tmpiter->buffer->SampleLen; + } + } + } + + while(tmpiter && SrcBufferSize > SrcDataSize) + { + const ALbuffer *ALBuffer; + if((ALBuffer=tmpiter->buffer) != NULL) + { + const ALubyte *Data = ALBuffer->data; + ALuint DataSize = ALBuffer->SampleLen; + + /* Skip the data already played */ + if(DataSize <= pos) + pos -= DataSize; + else + { + Data += (pos*NumChannels + chan)*SampleSize; + DataSize -= pos; + pos -= pos; + + DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + LoadData(&SrcData[SrcDataSize], Data, NumChannels, + ALBuffer->FmtType, DataSize); + SrcDataSize += DataSize; + } + } + tmpiter = tmpiter->next; + if(!tmpiter && Looping) + tmpiter = Source->queue; + else if(!tmpiter) + { + SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); + SrcDataSize += SrcBufferSize - SrcDataSize; + } + } + } + + /* Now resample, then filter and mix to the appropriate outputs. */ + Source->Params.Resample(&SrcData[BufferPrePadding], DataPosFrac, + increment, ResampledData, DstBufferSize); + + { + DirectParams *directparms = &Source->Params.Direct; + + DoFilter(&directparms->LpFilter[chan], SrcData, ResampledData, + DstBufferSize); + Source->Params.DryMix(directparms, SrcData, chan, OutPos, + SamplesToDo, DstBufferSize); + } + + for(j = 0;j < Device->NumAuxSends;j++) + { + SendParams *sendparms = &Source->Params.Send[j]; + if(!sendparms->OutBuffer) + continue; + + DoFilter(&sendparms->LpFilter[chan], SrcData, ResampledData, + DstBufferSize); + Source->Params.WetMix(sendparms, SrcData, OutPos, + SamplesToDo, DstBufferSize); + } + } + /* Update positions */ + for(j = 0;j < DstBufferSize;j++) + { + DataPosFrac += increment; + DataPosInt += DataPosFrac>>FRACTIONBITS; + DataPosFrac &= FRACTIONMASK; + } + OutPos += DstBufferSize; /* Handle looping sources */ while(1) @@ -772,7 +372,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) break; } - if(Looping && Source->lSourceType == AL_STATIC) + if(Looping && Source->SourceType == AL_STATIC) { DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart; break; @@ -810,15 +410,12 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) Source->BuffersPlayed = BuffersPlayed; Source->position = DataPosInt; Source->position_fraction = DataPosFrac; - Source->HrtfOffset += OutPos; + Source->Hrtf.Offset += OutPos; if(State == AL_PLAYING) - { - Source->HrtfCounter = maxu(Source->HrtfCounter, OutPos) - OutPos; - Source->HrtfMoving = AL_TRUE; - } + Source->Hrtf.Counter = maxu(Source->Hrtf.Counter, OutPos) - OutPos; else { - Source->HrtfCounter = 0; - Source->HrtfMoving = AL_FALSE; + Source->Hrtf.Counter = 0; + Source->Hrtf.Moving = AL_FALSE; } } diff --git a/jni/openal-soft-android/Alc/mixer_c.c b/jni/openal-soft-android/Alc/mixer_c.c new file mode 100644 index 00000000..36d8bf5a --- /dev/null +++ b/jni/openal-soft-android/Alc/mixer_c.c @@ -0,0 +1,125 @@ +#include "config.h" + +#include + +#include "alMain.h" +#include "alu.h" +#include "alSource.h" +#include "alAuxEffectSlot.h" + + +static inline ALfloat point32(const ALfloat *vals, ALuint UNUSED(frac)) +{ return vals[0]; } +static inline ALfloat lerp32(const ALfloat *vals, ALuint frac) +{ return lerp(vals[0], vals[1], frac * (1.0f/FRACTIONONE)); } +static inline ALfloat cubic32(const ALfloat *vals, ALuint frac) +{ return cubic(vals[-1], vals[0], vals[1], vals[2], frac * (1.0f/FRACTIONONE)); } + +void Resample_copy32_C(const ALfloat *data, ALuint UNUSED(frac), + ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize) +{ + assert(increment==FRACTIONONE); + memcpy(OutBuffer, data, (BufferSize+1)*sizeof(ALfloat)); +} + +#define DECL_TEMPLATE(Sampler) \ +void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \ + ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize) \ +{ \ + ALuint pos = 0; \ + ALuint i; \ + \ + for(i = 0;i < BufferSize+1;i++) \ + { \ + OutBuffer[i] = Sampler(data + pos, frac); \ + \ + frac += increment; \ + pos += frac>>FRACTIONBITS; \ + frac &= FRACTIONMASK; \ + } \ +} + +DECL_TEMPLATE(point32) +DECL_TEMPLATE(lerp32) +DECL_TEMPLATE(cubic32) + +#undef DECL_TEMPLATE + + +static inline void ApplyCoeffsStep(const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2]) +{ + ALuint c; + for(c = 0;c < IrSize;c++) + { + Coeffs[c][0] += CoeffStep[c][0]; + Coeffs[c][1] += CoeffStep[c][1]; + } +} + +static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], + const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + ALfloat left, ALfloat right) +{ + ALuint c; + for(c = 0;c < IrSize;c++) + { + const ALuint off = (Offset+c)&HRIR_MASK; + Values[off][0] += Coeffs[c][0] * left; + Values[off][1] += Coeffs[c][1] * right; + } +} + +#define SUFFIX C +#include "mixer_inc.c" +#undef SUFFIX + + +void MixDirect_C(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat DrySend; + ALuint pos; + ALuint c; + + for(c = 0;c < MaxChannels;c++) + { + DrySend = params->Gains[srcchan][c]; + if(!(DrySend > GAIN_SILENCE_THRESHOLD)) + continue; + + if(OutPos == 0) + ClickRemoval[c] -= data[0]*DrySend; + for(pos = 0;pos < BufferSize;pos++) + OutBuffer[c][OutPos+pos] += data[pos]*DrySend; + if(OutPos+pos == SamplesToDo) + PendingClicks[c] += data[pos]*DrySend; + } +} + + +void MixSend_C(const SendParams *params, const ALfloat *restrict data, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat WetSend; + ALuint pos; + + WetSend = params->Gain; + if(!(WetSend > GAIN_SILENCE_THRESHOLD)) + return; + + if(OutPos == 0) + ClickRemoval[0] -= data[0] * WetSend; + for(pos = 0;pos < BufferSize;pos++) + OutBuffer[0][OutPos+pos] += data[pos] * WetSend; + if(OutPos+pos == SamplesToDo) + PendingClicks[0] += data[pos] * WetSend; +} diff --git a/jni/openal-soft-android/Alc/mixer_defs.h b/jni/openal-soft-android/Alc/mixer_defs.h new file mode 100644 index 00000000..f8968a0a --- /dev/null +++ b/jni/openal-soft-android/Alc/mixer_defs.h @@ -0,0 +1,33 @@ +#ifndef MIXER_DEFS_H +#define MIXER_DEFS_H + +#include "AL/alc.h" +#include "AL/al.h" +#include "alMain.h" + +struct DirectParams; +struct SendParams; + +/* C resamplers */ +void Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); + + +/* C mixers */ +void MixDirect_Hrtf_C(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixDirect_C(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixSend_C(const struct SendParams*,const ALfloat*restrict,ALuint,ALuint,ALuint); + +/* SSE mixers */ +void MixDirect_Hrtf_SSE(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixDirect_SSE(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixSend_SSE(const struct SendParams*,const ALfloat*restrict,ALuint,ALuint,ALuint); + +/* Neon mixers */ +void MixDirect_Hrtf_Neon(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixDirect_Neon(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixSend_Neon(const struct SendParams*,const ALfloat*restrict,ALuint,ALuint,ALuint); + +#endif /* MIXER_DEFS_H */ diff --git a/jni/openal-soft-android/Alc/mixer_inc.c b/jni/openal-soft-android/Alc/mixer_inc.c new file mode 100644 index 00000000..17be5cde --- /dev/null +++ b/jni/openal-soft-android/Alc/mixer_inc.c @@ -0,0 +1,140 @@ +#include "config.h" + +#include "alMain.h" +#include "alSource.h" +#include "mixer_defs.h" + +#ifdef __GNUC__ +#define LIKELY(x) __builtin_expect(!!(x), 1) +#define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#define REAL_MERGE2(a,b) a##b +#define MERGE2(a,b) REAL_MERGE2(a,b) + +#define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX) + + +static inline void ApplyCoeffsStep(const ALuint irSize, + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2]); +static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], + const ALuint irSize, + ALfloat (*restrict Coeffs)[2], + ALfloat left, ALfloat right); + + +void MixDirect_Hrtf(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + const ALuint IrSize = params->Hrtf.Params.IrSize; + const ALint *restrict DelayStep = params->Hrtf.Params.DelayStep; + const ALfloat (*restrict CoeffStep)[2] = params->Hrtf.Params.CoeffStep; + const ALfloat (*restrict TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan]; + const ALuint *restrict TargetDelay = params->Hrtf.Params.Delay[srcchan]; + ALfloat *restrict History = params->Hrtf.State->History[srcchan]; + ALfloat (*restrict Values)[2] = params->Hrtf.State->Values[srcchan]; + ALint Counter = maxu(params->Hrtf.State->Counter, OutPos) - OutPos; + ALuint Offset = params->Hrtf.State->Offset + OutPos; + ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2]; + ALuint Delay[2]; + ALfloat left, right; + ALuint pos; + ALuint c; + + pos = 0; + for(c = 0;c < IrSize;c++) + { + Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter); + Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter); + } + + Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter); + Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter); + + if(LIKELY(OutPos == 0)) + { + History[Offset&SRC_HISTORY_MASK] = data[pos]; + left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], + History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], + (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], + History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], + (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + + ClickRemoval[FrontLeft] -= Values[(Offset+1)&HRIR_MASK][0] + + Coeffs[0][0] * left; + ClickRemoval[FrontRight] -= Values[(Offset+1)&HRIR_MASK][1] + + Coeffs[0][1] * right; + } + for(pos = 0;pos < BufferSize && Counter > 0;pos++) + { + History[Offset&SRC_HISTORY_MASK] = data[pos]; + left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], + History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], + (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], + History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], + (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + + Delay[0] += DelayStep[0]; + Delay[1] += DelayStep[1]; + + Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; + Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; + Offset++; + + ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right); + DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0]; + DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1]; + ApplyCoeffsStep(IrSize, Coeffs, CoeffStep); + + OutPos++; + Counter--; + } + + Delay[0] >>= HRTFDELAY_BITS; + Delay[1] >>= HRTFDELAY_BITS; + for(;pos < BufferSize;pos++) + { + History[Offset&SRC_HISTORY_MASK] = data[pos]; + left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; + right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; + + Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; + Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; + Offset++; + + ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right); + DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0]; + DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1]; + + OutPos++; + } + if(LIKELY(OutPos == SamplesToDo)) + { + History[Offset&SRC_HISTORY_MASK] = data[pos]; + left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; + right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; + + PendingClicks[FrontLeft] += Values[(Offset+1)&HRIR_MASK][0] + + Coeffs[0][0] * left; + PendingClicks[FrontRight] += Values[(Offset+1)&HRIR_MASK][1] + + Coeffs[0][1] * right; + } +} + + +#undef MixDirect_Hrtf + +#undef MERGE2 +#undef REAL_MERGE2 + +#undef UNLIKELY +#undef LIKELY diff --git a/jni/openal-soft-android/Alc/mixer_neon.c b/jni/openal-soft-android/Alc/mixer_neon.c new file mode 100644 index 00000000..0aa450ad --- /dev/null +++ b/jni/openal-soft-android/Alc/mixer_neon.c @@ -0,0 +1,130 @@ +#include "config.h" + +#ifdef HAVE_ARM_NEON_H +#include +#endif + +#include "AL/al.h" +#include "AL/alc.h" +#include "alMain.h" +#include "alu.h" + + +static inline void ApplyCoeffsStep(const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2]) +{ + float32x4_t coeffs, deltas; + ALuint c; + + for(c = 0;c < IrSize;c += 2) + { + coeffs = vld1q_f32(&Coeffs[c][0]); + deltas = vld1q_f32(&CoeffStep[c][0]); + coeffs = vaddq_f32(coeffs, deltas); + vst1q_f32(&Coeffs[c][0], coeffs); + } +} + +static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], + const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + ALfloat left, ALfloat right) +{ + ALuint c; + float32x4_t leftright4; + { + float32x2_t leftright2 = vdup_n_f32(0.0); + leftright2 = vset_lane_f32(left, leftright2, 0); + leftright2 = vset_lane_f32(right, leftright2, 1); + leftright4 = vcombine_f32(leftright2, leftright2); + } + for(c = 0;c < IrSize;c += 2) + { + const ALuint o0 = (Offset+c)&HRIR_MASK; + const ALuint o1 = (o0+1)&HRIR_MASK; + float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]), + vld1_f32((float32_t*)&Values[o1][0])); + float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]); + + vals = vmlaq_f32(vals, coefs, leftright4); + + vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals)); + vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals)); + } +} + + +#define SUFFIX Neon +#include "mixer_inc.c" +#undef SUFFIX + + +void MixDirect_Neon(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat DrySend; + float32x4_t gain; + ALuint pos; + ALuint c; + + for(c = 0;c < MaxChannels;c++) + { + DrySend = params->Gains[srcchan][c]; + if(!(DrySend > GAIN_SILENCE_THRESHOLD)) + continue; + + if(OutPos == 0) + ClickRemoval[c] -= data[0]*DrySend; + + gain = vdupq_n_f32(DrySend); + for(pos = 0;BufferSize-pos > 3;pos += 4) + { + const float32x4_t val4 = vld1q_f32(&data[pos]); + float32x4_t dry4 = vld1q_f32(&OutBuffer[c][OutPos+pos]); + dry4 = vaddq_f32(dry4, vmulq_f32(val4, gain)); + vst1q_f32(&OutBuffer[c][OutPos+pos], dry4); + } + for(;pos < BufferSize;pos++) + OutBuffer[c][OutPos+pos] += data[pos]*DrySend; + + if(OutPos+pos == SamplesToDo) + PendingClicks[c] += data[pos]*DrySend; + } +} + + +void MixSend_Neon(const SendParams *params, const ALfloat *restrict data, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat WetGain; + float32x4_t gain; + ALuint pos; + + WetGain = params->Gain; + if(!(WetGain > GAIN_SILENCE_THRESHOLD)) + return; + + if(OutPos == 0) + ClickRemoval[0] -= data[0] * WetGain; + + gain = vdupq_n_f32(WetGain); + for(pos = 0;BufferSize-pos > 3;pos += 4) + { + const float32x4_t val4 = vld1q_f32(&data[pos]); + float32x4_t wet4 = vld1q_f32(&OutBuffer[0][OutPos+pos]); + wet4 = vaddq_f32(wet4, vmulq_f32(val4, gain)); + vst1q_f32(&OutBuffer[0][OutPos+pos], wet4); + } + for(;pos < BufferSize;pos++) + OutBuffer[0][OutPos+pos] += data[pos] * WetGain; + + if(OutPos+pos == SamplesToDo) + PendingClicks[0] += data[pos] * WetGain; +} diff --git a/jni/openal-soft-android/Alc/mixer_sse.c b/jni/openal-soft-android/Alc/mixer_sse.c new file mode 100644 index 00000000..719ebd23 --- /dev/null +++ b/jni/openal-soft-android/Alc/mixer_sse.c @@ -0,0 +1,164 @@ +#include "config.h" + +#ifdef HAVE_XMMINTRIN_H +#ifdef IN_IDE_PARSER +/* KDevelop's parser won't recognize these defines that get added by the -msse + * switch used to compile this source. Without them, xmmintrin.h fails to + * declare anything. */ +#define __MMX__ +#define __SSE__ +#endif +#include +#endif + +#include "AL/al.h" +#include "AL/alc.h" +#include "alMain.h" +#include "alu.h" + +#include "alSource.h" +#include "alAuxEffectSlot.h" +#include "mixer_defs.h" + + +static inline void ApplyCoeffsStep(const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2]) +{ + __m128 coeffs, deltas; + ALuint i; + + for(i = 0;i < IrSize;i += 2) + { + coeffs = _mm_load_ps(&Coeffs[i][0]); + deltas = _mm_load_ps(&CoeffStep[i][0]); + coeffs = _mm_add_ps(coeffs, deltas); + _mm_store_ps(&Coeffs[i][0], coeffs); + } +} + +static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], + const ALuint IrSize, + ALfloat (*restrict Coeffs)[2], + ALfloat left, ALfloat right) +{ + const __m128 lrlr = { left, right, left, right }; + __m128 vals = _mm_setzero_ps(); + __m128 coeffs; + ALuint i; + + if((Offset&1)) + { + const ALuint o0 = Offset&HRIR_MASK; + const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK; + __m128 imp0, imp1; + + coeffs = _mm_load_ps(&Coeffs[0][0]); + vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]); + imp0 = _mm_mul_ps(lrlr, coeffs); + vals = _mm_add_ps(imp0, vals); + _mm_storel_pi((__m64*)&Values[o0][0], vals); + for(i = 1;i < IrSize-1;i += 2) + { + const ALuint o2 = (Offset+i)&HRIR_MASK; + + coeffs = _mm_load_ps(&Coeffs[i+1][0]); + vals = _mm_load_ps(&Values[o2][0]); + imp1 = _mm_mul_ps(lrlr, coeffs); + imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2)); + vals = _mm_add_ps(imp0, vals); + _mm_store_ps(&Values[o2][0], vals); + imp0 = imp1; + } + vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]); + imp0 = _mm_movehl_ps(imp0, imp0); + vals = _mm_add_ps(imp0, vals); + _mm_storel_pi((__m64*)&Values[o1][0], vals); + } + else + { + for(i = 0;i < IrSize;i += 2) + { + const ALuint o = (Offset + i)&HRIR_MASK; + + coeffs = _mm_load_ps(&Coeffs[i][0]); + vals = _mm_load_ps(&Values[o][0]); + vals = _mm_add_ps(vals, _mm_mul_ps(lrlr, coeffs)); + _mm_store_ps(&Values[o][0], vals); + } + } +} + +#define SUFFIX SSE +#include "mixer_inc.c" +#undef SUFFIX + + +void MixDirect_SSE(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat DrySend; + __m128 gain; + ALuint pos; + ALuint c; + + for(c = 0;c < MaxChannels;c++) + { + DrySend = params->Gains[srcchan][c]; + if(!(DrySend > GAIN_SILENCE_THRESHOLD)) + continue; + + if(OutPos == 0) + ClickRemoval[c] -= data[0]*DrySend; + + gain = _mm_set1_ps(DrySend); + for(pos = 0;BufferSize-pos > 3;pos += 4) + { + const __m128 val4 = _mm_load_ps(&data[pos]); + __m128 dry4 = _mm_load_ps(&OutBuffer[c][OutPos+pos]); + dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain)); + _mm_store_ps(&OutBuffer[c][OutPos+pos], dry4); + } + for(;pos < BufferSize;pos++) + OutBuffer[c][OutPos+pos] += data[pos]*DrySend; + + if(OutPos+pos == SamplesToDo) + PendingClicks[c] += data[pos]*DrySend; + } +} + + +void MixSend_SSE(const SendParams *params, const ALfloat *restrict data, + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) +{ + ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; + ALfloat WetGain; + __m128 gain; + ALuint pos; + + WetGain = params->Gain; + if(!(WetGain > GAIN_SILENCE_THRESHOLD)) + return; + + if(OutPos == 0) + ClickRemoval[0] -= data[0] * WetGain; + + gain = _mm_set1_ps(WetGain); + for(pos = 0;BufferSize-pos > 3;pos += 4) + { + const __m128 val4 = _mm_load_ps(&data[pos]); + __m128 wet4 = _mm_load_ps(&OutBuffer[0][OutPos+pos]); + wet4 = _mm_add_ps(wet4, _mm_mul_ps(val4, gain)); + _mm_store_ps(&OutBuffer[0][OutPos+pos], wet4); + } + for(;pos < BufferSize;pos++) + OutBuffer[0][OutPos+pos] += data[pos] * WetGain; + + if(OutPos+pos == SamplesToDo) + PendingClicks[0] += data[pos] * WetGain; +} diff --git a/jni/openal-soft-android/Alc/panning.c b/jni/openal-soft-android/Alc/panning.c index 0d83ea30..30a1e571 100644 --- a/jni/openal-soft-android/Alc/panning.c +++ b/jni/openal-soft-android/Alc/panning.c @@ -31,8 +31,10 @@ #include "AL/alc.h" #include "alu.h" -static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHANNELS], - enum Channel Speaker2Chan[MAXCHANNELS], ALint chans) +extern inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxChannels]); + +static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MaxChannels], + enum Channel Speaker2Chan[MaxChannels], ALint chans) { char *confkey, *next; char *layout_str; @@ -71,21 +73,21 @@ static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHAN *(++end) = 0; if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0) - val = FRONT_LEFT; + val = FrontLeft; else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0) - val = FRONT_RIGHT; + val = FrontRight; else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0) - val = FRONT_CENTER; + val = FrontCenter; else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0) - val = BACK_LEFT; + val = BackLeft; else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0) - val = BACK_RIGHT; + val = BackRight; else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0) - val = BACK_CENTER; + val = BackCenter; else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0) - val = SIDE_LEFT; + val = SideLeft; else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0) - val = SIDE_RIGHT; + val = SideRight; else { ERR("Unknown speaker for %s: \"%s\"\n", name, confkey); @@ -102,7 +104,7 @@ static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHAN { long angle = strtol(sep, NULL, 10); if(angle >= -180 && angle <= 180) - SpeakerAngle[i] = angle * F_PI/180.0f; + SpeakerAngle[i] = DEG2RAD(angle); else ERR("Invalid angle for speaker \"%s\": %ld\n", confkey, angle); break; @@ -139,176 +141,310 @@ static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHAN } } -static ALfloat aluLUTpos2Angle(ALint pos) + +void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]) { - if(pos < QUADRANT_NUM) - return aluAtan((ALfloat)pos / (ALfloat)(QUADRANT_NUM - pos)); - if(pos < 2 * QUADRANT_NUM) - return F_PI_2 + aluAtan((ALfloat)(pos - QUADRANT_NUM) / (ALfloat)(2 * QUADRANT_NUM - pos)); - if(pos < 3 * QUADRANT_NUM) - return aluAtan((ALfloat)(pos - 2 * QUADRANT_NUM) / (ALfloat)(3 * QUADRANT_NUM - pos)) - F_PI; - return aluAtan((ALfloat)(pos - 3 * QUADRANT_NUM) / (ALfloat)(4 * QUADRANT_NUM - pos)) - F_PI_2; + ALfloat tmpgains[MaxChannels] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + enum Channel Speaker2Chan[MaxChannels]; + ALfloat SpeakerAngle[MaxChannels]; + ALfloat langle, rangle; + ALfloat a; + ALuint i; + + for(i = 0;i < device->NumChan;i++) + Speaker2Chan[i] = device->Speaker2Chan[i]; + for(i = 0;i < device->NumChan;i++) + SpeakerAngle[i] = device->SpeakerAngle[i]; + + /* Some easy special-cases first... */ + if(device->NumChan <= 1 || hwidth >= F_PI) + { + /* Full coverage for all speakers. */ + for(i = 0;i < MaxChannels;i++) + gains[i] = 0.0f; + for(i = 0;i < device->NumChan;i++) + { + enum Channel chan = Speaker2Chan[i]; + gains[chan] = ingain; + } + return; + } + if(hwidth <= 0.0f) + { + /* Infinitely small sound point. */ + for(i = 0;i < MaxChannels;i++) + gains[i] = 0.0f; + for(i = 0;i < device->NumChan-1;i++) + { + if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1]) + { + /* Sound is between speakers i and i+1 */ + a = (angle-SpeakerAngle[i]) / + (SpeakerAngle[i+1]-SpeakerAngle[i]); + gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain; + gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain; + return; + } + } + /* Sound is between last and first speakers */ + if(angle < SpeakerAngle[0]) + angle += F_2PI; + a = (angle-SpeakerAngle[i]) / + (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); + gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain; + gains[Speaker2Chan[0]] = sqrtf( a) * ingain; + return; + } + + if(fabsf(angle)+hwidth > F_PI) + { + /* The coverage area would go outside of -pi...+pi. Instead, rotate the + * speaker angles so it would be as if angle=0, and keep them wrapped + * within -pi...+pi. */ + if(angle > 0.0f) + { + ALuint done; + ALuint i = 0; + while(i < device->NumChan && device->SpeakerAngle[i]-angle < -F_PI) + i++; + for(done = 0;i < device->NumChan;done++) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle; + Speaker2Chan[done] = device->Speaker2Chan[i]; + i++; + } + for(i = 0;done < device->NumChan;i++) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle + F_2PI; + Speaker2Chan[done] = device->Speaker2Chan[i]; + done++; + } + } + else + { + /* NOTE: '< device->NumChan' on the iterators is correct here since + * we need to handle index 0. Because the iterators are unsigned, + * they'll underflow and wrap to become 0xFFFFFFFF, which will + * break as expected. */ + ALuint done; + ALuint i = device->NumChan-1; + while(i < device->NumChan && device->SpeakerAngle[i]-angle > F_PI) + i--; + for(done = device->NumChan-1;i < device->NumChan;done--) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle; + Speaker2Chan[done] = device->Speaker2Chan[i]; + i--; + } + for(i = device->NumChan-1;done < device->NumChan;i--) + { + SpeakerAngle[done] = device->SpeakerAngle[i]-angle - F_2PI; + Speaker2Chan[done] = device->Speaker2Chan[i]; + done--; + } + } + angle = 0.0f; + } + langle = angle - hwidth; + rangle = angle + hwidth; + + /* First speaker */ + i = 0; + do { + ALuint last = device->NumChan-1; + enum Channel chan = Speaker2Chan[i]; + + if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) + { + tmpgains[chan] = 1.0f; + continue; + } + + if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle) + { + a = (langle-SpeakerAngle[i]) / + (SpeakerAngle[i+1]-SpeakerAngle[i]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); + } + if(SpeakerAngle[i] > rangle) + { + a = (F_2PI + rangle-SpeakerAngle[last]) / + (F_2PI + SpeakerAngle[i]-SpeakerAngle[last]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); + } + else if(SpeakerAngle[last] < rangle) + { + a = (rangle-SpeakerAngle[last]) / + (F_2PI + SpeakerAngle[i]-SpeakerAngle[last]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); + } + } while(0); + + for(i = 1;i < device->NumChan-1;i++) + { + enum Channel chan = Speaker2Chan[i]; + if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) + { + tmpgains[chan] = 1.0f; + continue; + } + + if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle) + { + a = (langle-SpeakerAngle[i]) / + (SpeakerAngle[i+1]-SpeakerAngle[i]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); + } + if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle) + { + a = (rangle-SpeakerAngle[i-1]) / + (SpeakerAngle[i]-SpeakerAngle[i-1]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); + } + } + + /* Last speaker */ + i = device->NumChan-1; + do { + enum Channel chan = Speaker2Chan[i]; + if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle) + { + tmpgains[Speaker2Chan[i]] = 1.0f; + continue; + } + if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle) + { + a = (rangle-SpeakerAngle[i-1]) / + (SpeakerAngle[i]-SpeakerAngle[i-1]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); + } + if(SpeakerAngle[i] < langle) + { + a = (langle-SpeakerAngle[i]) / + (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); + } + else if(SpeakerAngle[0] > langle) + { + a = (F_2PI + langle-SpeakerAngle[i]) / + (F_2PI + SpeakerAngle[0]-SpeakerAngle[i]); + tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); + } + } while(0); + + for(i = 0;i < device->NumChan;i++) + { + enum Channel chan = device->Speaker2Chan[i]; + gains[chan] = sqrtf(tmpgains[chan]) * ingain; + } } -ALint aluCart2LUTpos(ALfloat re, ALfloat im) -{ - ALint pos = 0; - ALfloat denom = aluFabs(re) + aluFabs(im); - if(denom > 0.0f) - pos = (ALint)(QUADRANT_NUM*aluFabs(im) / denom + 0.5); - - if(re < 0.0f) - pos = 2 * QUADRANT_NUM - pos; - if(im < 0.0f) - pos = LUT_NUM - pos; - return pos%LUT_NUM; -} ALvoid aluInitPanning(ALCdevice *Device) { - ALfloat SpeakerAngle[MAXCHANNELS]; + const char *layoutname = NULL; enum Channel *Speaker2Chan; - ALfloat Alpha, Theta; - ALint pos; - ALuint s; + ALfloat *SpeakerAngle; Speaker2Chan = Device->Speaker2Chan; + SpeakerAngle = Device->SpeakerAngle; switch(Device->FmtChans) { case DevFmtMono: Device->NumChan = 1; - Speaker2Chan[0] = FRONT_CENTER; - SpeakerAngle[0] = F_PI/180.0f * 0.0f; + Speaker2Chan[0] = FrontCenter; + SpeakerAngle[0] = DEG2RAD(0.0f); + layoutname = NULL; break; case DevFmtStereo: Device->NumChan = 2; - Speaker2Chan[0] = FRONT_LEFT; - Speaker2Chan[1] = FRONT_RIGHT; - SpeakerAngle[0] = F_PI/180.0f * -90.0f; - SpeakerAngle[1] = F_PI/180.0f * 90.0f; - SetSpeakerArrangement("layout_STEREO", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = FrontLeft; + Speaker2Chan[1] = FrontRight; + SpeakerAngle[0] = DEG2RAD(-90.0f); + SpeakerAngle[1] = DEG2RAD( 90.0f); + layoutname = "layout_stereo"; break; case DevFmtQuad: Device->NumChan = 4; - Speaker2Chan[0] = BACK_LEFT; - Speaker2Chan[1] = FRONT_LEFT; - Speaker2Chan[2] = FRONT_RIGHT; - Speaker2Chan[3] = BACK_RIGHT; - SpeakerAngle[0] = F_PI/180.0f * -135.0f; - SpeakerAngle[1] = F_PI/180.0f * -45.0f; - SpeakerAngle[2] = F_PI/180.0f * 45.0f; - SpeakerAngle[3] = F_PI/180.0f * 135.0f; - SetSpeakerArrangement("layout_QUAD", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = BackLeft; + Speaker2Chan[1] = FrontLeft; + Speaker2Chan[2] = FrontRight; + Speaker2Chan[3] = BackRight; + SpeakerAngle[0] = DEG2RAD(-135.0f); + SpeakerAngle[1] = DEG2RAD( -45.0f); + SpeakerAngle[2] = DEG2RAD( 45.0f); + SpeakerAngle[3] = DEG2RAD( 135.0f); + layoutname = "layout_quad"; break; case DevFmtX51: Device->NumChan = 5; - Speaker2Chan[0] = BACK_LEFT; - Speaker2Chan[1] = FRONT_LEFT; - Speaker2Chan[2] = FRONT_CENTER; - Speaker2Chan[3] = FRONT_RIGHT; - Speaker2Chan[4] = BACK_RIGHT; - SpeakerAngle[0] = F_PI/180.0f * -110.0f; - SpeakerAngle[1] = F_PI/180.0f * -30.0f; - SpeakerAngle[2] = F_PI/180.0f * 0.0f; - SpeakerAngle[3] = F_PI/180.0f * 30.0f; - SpeakerAngle[4] = F_PI/180.0f * 110.0f; - SetSpeakerArrangement("layout_51CHN", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = BackLeft; + Speaker2Chan[1] = FrontLeft; + Speaker2Chan[2] = FrontCenter; + Speaker2Chan[3] = FrontRight; + Speaker2Chan[4] = BackRight; + SpeakerAngle[0] = DEG2RAD(-110.0f); + SpeakerAngle[1] = DEG2RAD( -30.0f); + SpeakerAngle[2] = DEG2RAD( 0.0f); + SpeakerAngle[3] = DEG2RAD( 30.0f); + SpeakerAngle[4] = DEG2RAD( 110.0f); + layoutname = "layout_surround51"; break; case DevFmtX51Side: Device->NumChan = 5; - Speaker2Chan[0] = SIDE_LEFT; - Speaker2Chan[1] = FRONT_LEFT; - Speaker2Chan[2] = FRONT_CENTER; - Speaker2Chan[3] = FRONT_RIGHT; - Speaker2Chan[4] = SIDE_RIGHT; - SpeakerAngle[0] = F_PI/180.0f * -90.0f; - SpeakerAngle[1] = F_PI/180.0f * -30.0f; - SpeakerAngle[2] = F_PI/180.0f * 0.0f; - SpeakerAngle[3] = F_PI/180.0f * 30.0f; - SpeakerAngle[4] = F_PI/180.0f * 90.0f; - SetSpeakerArrangement("layout_51SIDECHN", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = SideLeft; + Speaker2Chan[1] = FrontLeft; + Speaker2Chan[2] = FrontCenter; + Speaker2Chan[3] = FrontRight; + Speaker2Chan[4] = SideRight; + SpeakerAngle[0] = DEG2RAD(-90.0f); + SpeakerAngle[1] = DEG2RAD(-30.0f); + SpeakerAngle[2] = DEG2RAD( 0.0f); + SpeakerAngle[3] = DEG2RAD( 30.0f); + SpeakerAngle[4] = DEG2RAD( 90.0f); + layoutname = "layout_side51"; break; case DevFmtX61: Device->NumChan = 6; - Speaker2Chan[0] = SIDE_LEFT; - Speaker2Chan[1] = FRONT_LEFT; - Speaker2Chan[2] = FRONT_CENTER; - Speaker2Chan[3] = FRONT_RIGHT; - Speaker2Chan[4] = SIDE_RIGHT; - Speaker2Chan[5] = BACK_CENTER; - SpeakerAngle[0] = F_PI/180.0f * -90.0f; - SpeakerAngle[1] = F_PI/180.0f * -30.0f; - SpeakerAngle[2] = F_PI/180.0f * 0.0f; - SpeakerAngle[3] = F_PI/180.0f * 30.0f; - SpeakerAngle[4] = F_PI/180.0f * 90.0f; - SpeakerAngle[5] = F_PI/180.0f * 180.0f; - SetSpeakerArrangement("layout_61CHN", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = SideLeft; + Speaker2Chan[1] = FrontLeft; + Speaker2Chan[2] = FrontCenter; + Speaker2Chan[3] = FrontRight; + Speaker2Chan[4] = SideRight; + Speaker2Chan[5] = BackCenter; + SpeakerAngle[0] = DEG2RAD(-90.0f); + SpeakerAngle[1] = DEG2RAD(-30.0f); + SpeakerAngle[2] = DEG2RAD( 0.0f); + SpeakerAngle[3] = DEG2RAD( 30.0f); + SpeakerAngle[4] = DEG2RAD( 90.0f); + SpeakerAngle[5] = DEG2RAD(180.0f); + layoutname = "layout_surround61"; break; case DevFmtX71: Device->NumChan = 7; - Speaker2Chan[0] = BACK_LEFT; - Speaker2Chan[1] = SIDE_LEFT; - Speaker2Chan[2] = FRONT_LEFT; - Speaker2Chan[3] = FRONT_CENTER; - Speaker2Chan[4] = FRONT_RIGHT; - Speaker2Chan[5] = SIDE_RIGHT; - Speaker2Chan[6] = BACK_RIGHT; - SpeakerAngle[0] = F_PI/180.0f * -150.0f; - SpeakerAngle[1] = F_PI/180.0f * -90.0f; - SpeakerAngle[2] = F_PI/180.0f * -30.0f; - SpeakerAngle[3] = F_PI/180.0f * 0.0f; - SpeakerAngle[4] = F_PI/180.0f * 30.0f; - SpeakerAngle[5] = F_PI/180.0f * 90.0f; - SpeakerAngle[6] = F_PI/180.0f * 150.0f; - SetSpeakerArrangement("layout_71CHN", SpeakerAngle, Speaker2Chan, Device->NumChan); + Speaker2Chan[0] = BackLeft; + Speaker2Chan[1] = SideLeft; + Speaker2Chan[2] = FrontLeft; + Speaker2Chan[3] = FrontCenter; + Speaker2Chan[4] = FrontRight; + Speaker2Chan[5] = SideRight; + Speaker2Chan[6] = BackRight; + SpeakerAngle[0] = DEG2RAD(-150.0f); + SpeakerAngle[1] = DEG2RAD( -90.0f); + SpeakerAngle[2] = DEG2RAD( -30.0f); + SpeakerAngle[3] = DEG2RAD( 0.0f); + SpeakerAngle[4] = DEG2RAD( 30.0f); + SpeakerAngle[5] = DEG2RAD( 90.0f); + SpeakerAngle[6] = DEG2RAD( 150.0f); + layoutname = "layout_surround71"; break; } - - for(pos = 0; pos < LUT_NUM; pos++) - { - ALfloat *PanningLUT = Device->PanningLUT[pos]; - - /* clear all values */ - for(s = 0; s < MAXCHANNELS; s++) - PanningLUT[s] = 0.0f; - - if(Device->NumChan == 1) - { - PanningLUT[Speaker2Chan[0]] = 1.0f; - continue; - } - - /* source angle */ - Theta = aluLUTpos2Angle(pos); - - /* set panning values */ - for(s = 0; s < Device->NumChan - 1; s++) - { - if(Theta >= SpeakerAngle[s] && Theta < SpeakerAngle[s+1]) - { - /* source between speaker s and speaker s+1 */ - Alpha = (Theta-SpeakerAngle[s]) / - (SpeakerAngle[s+1]-SpeakerAngle[s]); - PanningLUT[Speaker2Chan[s]] = aluSqrt(1.0f-Alpha); - PanningLUT[Speaker2Chan[s+1]] = aluSqrt( Alpha); - break; - } - } - if(s == Device->NumChan - 1) - { - /* source between last and first speaker */ - if(Theta < SpeakerAngle[0]) - Theta += F_PI*2.0f; - Alpha = (Theta-SpeakerAngle[s]) / - (F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[s]); - PanningLUT[Speaker2Chan[s]] = aluSqrt(1.0f-Alpha); - PanningLUT[Speaker2Chan[0]] = aluSqrt( Alpha); - } - } + if(layoutname && Device->Type != Loopback) + SetSpeakerArrangement(layoutname, SpeakerAngle, Speaker2Chan, Device->NumChan); } diff --git a/jni/openal-soft-android/Alc/rwlock.h b/jni/openal-soft-android/Alc/rwlock.h new file mode 100644 index 00000000..efbab4e8 --- /dev/null +++ b/jni/openal-soft-android/Alc/rwlock.h @@ -0,0 +1,21 @@ +#ifndef AL_RWLOCK_H +#define AL_RWLOCK_H + +#include "AL/al.h" +#include "atomic.h" + +typedef struct { + volatile RefCount read_count; + volatile RefCount write_count; + volatile ALenum read_lock; + volatile ALenum read_entry_lock; + volatile ALenum write_lock; +} RWLock; + +void RWLockInit(RWLock *lock); +void ReadLock(RWLock *lock); +void ReadUnlock(RWLock *lock); +void WriteLock(RWLock *lock); +void WriteUnlock(RWLock *lock); + +#endif /* AL_RWLOCK_H */ diff --git a/jni/openal-soft-android/Alc/threads.c b/jni/openal-soft-android/Alc/threads.c new file mode 100644 index 00000000..64586ae9 --- /dev/null +++ b/jni/openal-soft-android/Alc/threads.c @@ -0,0 +1,200 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include "threads.h" + +#include +#include + +#include "alMain.h" +#include "alThunk.h" + +#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct althread_info { + ALuint (*func)(ALvoid*); + ALvoid *ptr; + HANDLE hdl; +} althread_info; + +static DWORD CALLBACK StarterFunc(void *ptr) +{ + althread_info *inf = (althread_info*)ptr; + ALuint ret; + + ret = inf->func(inf->ptr); + ExitThread((DWORD)ret); + + return (DWORD)ret; +} + + +ALboolean StartThread(althread_t *thread, ALuint (*func)(ALvoid*), ALvoid *ptr) +{ + althread_info *info; + DWORD dummy; + + info = malloc(sizeof(*info)); + if(!info) return AL_FALSE; + + info->func = func; + info->ptr = ptr; + + info->hdl = CreateThread(NULL, THREAD_STACK_SIZE, StarterFunc, info, 0, &dummy); + if(!info->hdl) + { + free(info); + return AL_FALSE; + } + + *thread = info; + return AL_TRUE; +} + +ALuint StopThread(althread_t thread) +{ + DWORD ret = 0; + + WaitForSingleObject(thread->hdl, INFINITE); + GetExitCodeThread(thread->hdl, &ret); + CloseHandle(thread->hdl); + + free(thread); + + return (ALuint)ret; +} + + +void SetThreadName(const char *name) +{ +#if defined(_MSC_VER) +#define MS_VC_EXCEPTION 0x406D1388 + struct { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. + } info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = -1; + info.dwFlags = 0; + + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info); + } + __except(EXCEPTION_CONTINUE_EXECUTION) { + } +#undef MS_VC_EXCEPTION +#else + TRACE("Can't set thread %04lx name to \"%s\"\n", GetCurrentThreadId(), name); +#endif +} + +#else + +#include + +typedef struct althread_info { + ALuint (*func)(ALvoid*); + ALvoid *ptr; + ALuint ret; + pthread_t hdl; +} althread_info; + +static void *StarterFunc(void *ptr) +{ + althread_info *inf = (althread_info*)ptr; + inf->ret = inf->func(inf->ptr); + return NULL; +} + + +ALboolean StartThread(althread_t *thread, ALuint (*func)(ALvoid*), ALvoid *ptr) +{ + pthread_attr_t attr; + althread_info *info; + + info = malloc(sizeof(*info)); + if(!info) return AL_FALSE; + + if(pthread_attr_init(&attr) != 0) + { + free(info); + return AL_FALSE; + } + if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0) + { + pthread_attr_destroy(&attr); + free(info); + return AL_FALSE; + } + + info->func = func; + info->ptr = ptr; + if(pthread_create(&info->hdl, &attr, StarterFunc, info) != 0) + { + pthread_attr_destroy(&attr); + free(info); + return AL_FALSE; + } + pthread_attr_destroy(&attr); + + *thread = info; + return AL_TRUE; +} + +ALuint StopThread(althread_t thread) +{ + ALuint ret; + + pthread_join(thread->hdl, NULL); + ret = thread->ret; + + free(thread); + + return ret; +} + + +void SetThreadName(const char *name) +{ +#if defined(HAVE_PTHREAD_SETNAME_NP) +#if defined(__GNUC__) + if(pthread_setname_np(pthread_self(), name) != 0) +#elif defined(__APPLE__) + if(pthread_setname_np(name) != 0) +#endif + WARN("Failed to set thread name to \"%s\": %s\n", name, strerror(errno)); +#elif defined(HAVE_PTHREAD_SET_NAME_NP) + pthread_set_name_np(pthread_self(), name); +#else + TRACE("Can't set thread name to \"%s\"\n", name); +#endif +} + +#endif diff --git a/jni/openal-soft-android/Alc/uintmap.h b/jni/openal-soft-android/Alc/uintmap.h new file mode 100644 index 00000000..2c70f161 --- /dev/null +++ b/jni/openal-soft-android/Alc/uintmap.h @@ -0,0 +1,34 @@ +#ifndef AL_UINTMAP_H +#define AL_UINTMAP_H + +#include "AL/al.h" +#include "rwlock.h" + +typedef struct UIntMap { + struct { + ALuint key; + ALvoid *value; + } *array; + ALsizei size; + ALsizei maxsize; + ALsizei limit; + RWLock lock; +} UIntMap; +extern UIntMap TlsDestructor; + +void InitUIntMap(UIntMap *map, ALsizei limit); +void ResetUIntMap(UIntMap *map); +ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); +ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); +ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key); + +inline void LockUIntMapRead(UIntMap *map) +{ ReadLock(&map->lock); } +inline void UnlockUIntMapRead(UIntMap *map) +{ ReadUnlock(&map->lock); } +inline void LockUIntMapWrite(UIntMap *map) +{ WriteLock(&map->lock); } +inline void UnlockUIntMapWrite(UIntMap *map) +{ WriteUnlock(&map->lock); } + +#endif /* AL_UINTMAP_H */ diff --git a/jni/openal-soft-android/Android.mk b/jni/openal-soft-android/Android.mk index 21fe40dd..dbf91063 100644 --- a/jni/openal-soft-android/Android.mk +++ b/jni/openal-soft-android/Android.mk @@ -4,24 +4,34 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libopenal -LOCAL_CFLAGS := -fexceptions -g -Dlinux -DAL_ALEXT_PROTOTYPES=1 -DHAVE_GCC_DESTRUCTOR=1 -DOPT_GENERIC -DREAL_IS_FLOAT +LOCAL_CFLAGS := -DAL_ALEXT_PROTOTYPES -DAL_BUILD_LIBRARY -DAL_LIBTYPE_STATIC -D_GNU_SOURCE=1 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -std=c99 -Drestrict=__restrict + LOCAL_CPPFLAGS := ${LOCAL_CFLAGS} LOCAL_C_INCLUDES := \ ${LOCAL_PATH}/include \ + ${LOCAL_PATH}/Alc \ ${LOCAL_PATH}/OpenAL32/Include LOCAL_SRC_FILES := \ - $(filter-out , $(subst $(LOCAL_PATH)/,,\ - ${LOCAL_PATH}/Alc/backends/loopback.c \ - ${LOCAL_PATH}/Alc/backends/null.c \ - ${LOCAL_PATH}/Alc/backends/android.c \ - ${LOCAL_PATH}/Alc/backends/wave.c \ - $(wildcard ${LOCAL_PATH}/Alc/*.c) \ - $(wildcard ${LOCAL_PATH}/OpenAL32/*.c) \ + $(filter-out \ + Alc/mixer_neon.c \ + Alc/mixer_sse.c \ + , $(subst $(LOCAL_PATH)/,,\ + ${LOCAL_PATH}/Alc/backends/base.c \ + ${LOCAL_PATH}/Alc/backends/loopback.c \ + ${LOCAL_PATH}/Alc/backends/null.c \ + ${LOCAL_PATH}/Alc/backends/opensl.c \ + ${LOCAL_PATH}/Alc/backends/wave.c \ + $(wildcard ${LOCAL_PATH}/Alc/midi/*.c) \ + $(wildcard ${LOCAL_PATH}/Alc/effects/*.c) \ + $(wildcard ${LOCAL_PATH}/Alc/*.c) \ + $(wildcard ${LOCAL_PATH}/OpenAL32/*.c) \ )) # $(info libopenal: include dirs $(LOCAL_C_INCLUDES)) # $(info libopenal: src files $(LOCAL_SRC_FILES)) +LOCAL_LDLIBS := -llog -lOpenSLES + include $(BUILD_STATIC_LIBRARY) diff --git a/jni/openal-soft-android/CMakeCache.txt b/jni/openal-soft-android/CMakeCache.txt deleted file mode 100644 index b579b007..00000000 --- a/jni/openal-soft-android/CMakeCache.txt +++ /dev/null @@ -1,498 +0,0 @@ -# This is the CMakeCache file. -# For build in directory: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android -# It was generated by CMake: /usr/bin/cmake -# You can edit this file to change values found and used by cmake. -# If you do not want to change any of the values, simply exit the editor. -# If you do want to change a value, simply edit, save, and exit the editor. -# The syntax for the file is as follows: -# KEY:TYPE=VALUE -# KEY is the name of a variable in the cache. -# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!. -# VALUE is the current value for the KEY. - -######################## -# EXTERNAL cache entries -######################## - -//Check for ALSA backend -ALSA:BOOL=ON - -//Install alsoft.conf configuration file -ALSOFT_CONFIG:BOOL=OFF - -//Check for Android backend -ANDROID:BOOL=ON - -//android API level -ANDROID_API_LEVEL:STRING=5 - -//Enable Android low-latency backend -ANDROID_LOW_LATENCY:BOOL=OFF - -//archive -CMAKE_AR:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar - -//For backwards compatibility, what version of CMake commands and -// syntax should this version of CMake try to support. -CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4 - -//Choose the type of build, options are: Debug Release RelWithDebInfo -// MinSizeRel. -CMAKE_BUILD_TYPE:STRING=RelWithDebInfo - -//Enable/Disable color output during build. -CMAKE_COLOR_MAKEFILE:BOOL=ON - -//g++ -CMAKE_CXX_COMPILER:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ - -//c++ flags -CMAKE_CXX_FLAGS:STRING=--sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb - -//C compiler. -CMAKE_C_COMPILER:FILEPATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc - -//c flags -CMAKE_C_FLAGS:STRING=--sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb - -//Flags used by the compiler during debug builds. -CMAKE_C_FLAGS_DEBUG:STRING=-g3 -D_DEBUG - -//Flags used by the compiler during release minsize builds. -CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG - -//Flags used by the compiler during release builds -CMAKE_C_FLAGS_RELEASE:STRING=-O2 -fomit-frame-pointer -DNDEBUG - -//Flags used by the compiler during Release with Debug Info builds. -CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-g -O2 -D_DEBUG - -//Library postfix for debug builds. Normally left blank. -CMAKE_DEBUG_POSTFIX:STRING= - -//linker flags -CMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ - -//Flags used by the linker during debug builds. -CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during release minsize builds. -CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during release builds. -CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during Release with Debug Info builds. -CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//Install path prefix, prepended onto install directories. -CMAKE_INSTALL_PREFIX:PATH=/usr/local - -//linker -CMAKE_LINKER:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ld - -//Path to a program. -CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make - -//linker flags -CMAKE_MODULE_LINKER_FLAGS:STRING=-Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ - -//Flags used by the linker during debug builds. -CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during release minsize builds. -CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during release builds. -CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during Release with Debug Info builds. -CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//nm -CMAKE_NM:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-nm - -//objcopy -CMAKE_OBJCOPY:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-objcopy - -//objdump -CMAKE_OBJDUMP:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-objdump - -//Value Computed by CMake -CMAKE_PROJECT_NAME:STATIC=OpenAL - -//ranlib -CMAKE_RANLIB:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ranlib - -//linker flags -CMAKE_SHARED_LINKER_FLAGS:STRING=-Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ - -//Flags used by the linker during debug builds. -CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= - -//Flags used by the linker during release minsize builds. -CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= - -//Flags used by the linker during release builds. -CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= - -//Flags used by the linker during Release with Debug Info builds. -CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= - -//If set, runtime paths are not added when using shared libraries. -CMAKE_SKIP_RPATH:BOOL=OFF - -//strip -CMAKE_STRIP:PATH=/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip - -//The CMake toolchain file -CMAKE_TOOLCHAIN_FILE:FILEPATH=/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/toolchain.android.cmake - -//If true, cmake will use relative paths in makefiles and projects. -CMAKE_USE_RELATIVE_PATHS:BOOL=OFF - -//If this value is on, makefiles will be generated without the -// .SILENT directive, and all commands will be echoed to the console -// during the make. This is useful for debugging only. With Visual -// Studio IDE projects all commands are done without /nologo. -CMAKE_VERBOSE_MAKEFILE:BOOL=OFF - -//Check for CoreAudio backend -COREAUDIO:BOOL=ON - -//Check for the dlopen API for loading optional libs -DLOPEN:BOOL=ON - -//Check for DirectSound backend -DSOUND:BOOL=ON - -//Single output directory for building all executables. -EXECUTABLE_OUTPUT_PATH:PATH= - -//Use 32-bit ARM instructions instead of Thumb-1 -FORCE_ARM:BOOL=OFF - -//Single output directory for building all libraries. -LIBRARY_OUTPUT_PATH:PATH= - -//Check for MMDevApi -MMDEVAPI:BOOL=ON - -NDK_CPU_ARM:BOOL=ON - -//Check for OpenSL backend -OPENSL:BOOL=ON - -//Check for OSS backend -OSS:BOOL=ON - -//Value Computed by CMake -OpenAL_BINARY_DIR:STATIC=/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -//Value Computed by CMake -OpenAL_SOURCE_DIR:STATIC=/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -//Check for PortAudio backend -PORTAUDIO:BOOL=ON - -//Check for PulseAudio backend -PULSEAUDIO:BOOL=ON - -//Require ALSA backend -REQUIRE_ALSA:BOOL=OFF - -//Require Android backend -REQUIRE_ANDROID:BOOL=OFF - -//Require CoreAudio backend -REQUIRE_COREAUDIO:BOOL=OFF - -//Require DirectSound backend -REQUIRE_DSOUND:BOOL=OFF - -//Require MMDevApi -REQUIRE_MMDEVAPI:BOOL=OFF - -//Require OpenSL backend -REQUIRE_OPENSL:BOOL=OFF - -//Require OSS backend -REQUIRE_OSS:BOOL=OFF - -//Require PortAudio backend -REQUIRE_PORTAUDIO:BOOL=OFF - -//Require PulseAudio backend -REQUIRE_PULSEAUDIO:BOOL=OFF - -//Require SndIO backend -REQUIRE_SNDIO:BOOL=OFF - -//Require Solaris backend -REQUIRE_SOLARIS:BOOL=OFF - -//Require Windows Multimedia backend -REQUIRE_WINMM:BOOL=OFF - -//Check for SndIO backend -SNDIO:BOOL=ON - -//Check for Solaris backend -SOLARIS:BOOL=ON - -//Build and install utility programs -UTILS:BOOL=ON - -//Enable Wave Writer backend -WAVE:BOOL=ON - -//Treat compile warnings as errors -WERROR:BOOL=OFF - -//Check for Windows Multimedia backend -WINMM:BOOL=ON - -//Dependencies for the target -openal_LIB_DEPENDS:STATIC=general;dl;general;m; - - -######################## -# INTERNAL cache entries -######################## - -//ADVANCED property for variable: CMAKE_AR -CMAKE_AR-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_BUILD_TOOL -CMAKE_BUILD_TOOL-ADVANCED:INTERNAL=1 -//What is the target build tool cmake is generating for. -CMAKE_BUILD_TOOL:INTERNAL=/usr/bin/make -//This is the directory where this CMakeCache.txt was created -CMAKE_CACHEFILE_DIR:INTERNAL=/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android -//Major version of cmake used to create the current loaded cache -CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2 -//Minor version of cmake used to create the current loaded cache -CMAKE_CACHE_MINOR_VERSION:INTERNAL=8 -//Patch version of cmake used to create the current loaded cache -CMAKE_CACHE_PATCH_VERSION:INTERNAL=3 -//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE -CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 -//Path to CMake executable. -CMAKE_COMMAND:INTERNAL=/usr/bin/cmake -//Path to cpack program executable. -CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack -//Path to ctest program executable. -CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest -//ADVANCED property for variable: CMAKE_C_COMPILER -CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 -CMAKE_C_COMPILER_WORKS:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS -CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG -CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL -CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE -CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO -CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//Path to cache edit program executable. -CMAKE_EDIT_COMMAND:INTERNAL=/usr/bin/cmake-gui -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS -CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG -CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL -CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE -CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//Name of generator. -CMAKE_GENERATOR:INTERNAL=Unix Makefiles -//Start directory with the top level CMakeLists.txt file for this -// project -CMAKE_HOME_DIRECTORY:INTERNAL=/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android -//Install .so files without execute permission. -CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 -//ADVANCED property for variable: CMAKE_LINKER -CMAKE_LINKER-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MAKE_PROGRAM -CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS -CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG -CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL -CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE -CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_NM -CMAKE_NM-ADVANCED:INTERNAL=1 -//number of local generators -CMAKE_NUMBER_OF_LOCAL_GENERATORS:INTERNAL=1 -//ADVANCED property for variable: CMAKE_OBJCOPY -CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_OBJDUMP -CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_RANLIB -CMAKE_RANLIB-ADVANCED:INTERNAL=1 -//Path to CMake installation. -CMAKE_ROOT:INTERNAL=/usr/share/cmake-2.8 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS -CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG -CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL -CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE -CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO -CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_SKIP_RPATH -CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_STRIP -CMAKE_STRIP-ADVANCED:INTERNAL=1 -//Suppress Warnings that are meant for the author of the CMakeLists.txt -// files. -CMAKE_SUPPRESS_DEVELOPER_WARNINGS:INTERNAL=FALSE -//uname command -CMAKE_UNAME:INTERNAL=/bin/uname -//ADVANCED property for variable: CMAKE_USE_RELATIVE_PATHS -CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE -CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 -//ADVANCED property for variable: FORCE_ARM -FORCE_ARM-ADVANCED:INTERNAL=1 -//Have symbol acosf -HAVE_ACOSF:INTERNAL=1 -//Have include alsa/asoundlib.h -HAVE_ALSA_ASOUNDLIB_H:INTERNAL= -//Have include android/api-level.h -HAVE_ANDROID_API_LEVEL_H:INTERNAL=1 -//Have symbol __ANDROID_API__ -HAVE_ANDROID_INTERNAL:INTERNAL=1 -//Have include arm_neon.h -HAVE_ARM_NEON_H:INTERNAL= -//Have symbol asinf -HAVE_ASINF:INTERNAL=1 -//Have symbol atan2f -HAVE_ATAN2F:INTERNAL=1 -//Have symbol atanf -HAVE_ATANF:INTERNAL=1 -//Have include /System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h -HAVE_COREAUDIO_FRAMEWORK:INTERNAL= -//Have symbol cosf -HAVE_COSF:INTERNAL=1 -//Have include dlfcn.h -HAVE_DLFCN_H:INTERNAL=1 -//Have include dsound.h -HAVE_DSOUND_H:INTERNAL= -//Have symbol fabsf -HAVE_FABSF:INTERNAL=1 -//Have include fenv.h -HAVE_FENV_H:INTERNAL= -//Have include float.h -HAVE_FLOAT_H:INTERNAL=1 -//Have symbol floorf -HAVE_FLOORF:INTERNAL=1 -//Have include fpu_control.h -HAVE_FPU_CONTROL_H:INTERNAL= -//Test HAVE_GCC_DESTRUCTOR -HAVE_GCC_DESTRUCTOR:INTERNAL=1 -//Test HAVE_GCC_FORMAT -HAVE_GCC_FORMAT:INTERNAL=1 -//Test HAVE_GCC_PROTECTED_VISIBILITY -HAVE_GCC_PROTECTED_VISIBILITY:INTERNAL=1 -//Have function gettimeofday -HAVE_GETTIMEOFDAY:INTERNAL=1 -//Have include guiddef.h -HAVE_GUIDDEF_H:INTERNAL= -//Have include ieeefp.h -HAVE_IEEEFP_H:INTERNAL= -//Have include initguid.h -HAVE_INITGUID_H:INTERNAL= -//Have symbol isfinite -HAVE_ISFINITE:INTERNAL=1 -//Have symbol isnan -HAVE_ISNAN:INTERNAL=1 -//Have library dl -HAVE_LIBDL:INTERNAL=1 -//Have library m -HAVE_LIBM:INTERNAL=1 -//Have library pthread -HAVE_LIBPTHREAD:INTERNAL= -//Have library rt -HAVE_LIBRT:INTERNAL= -//Have symbol timeGetTime in winmm -HAVE_LIBWINMM:INTERNAL= -//Have symbol log10f -HAVE_LOG10F:INTERNAL=1 -//Have function nanosleep -HAVE_NANOSLEEP:INTERNAL=1 -//Have include portaudio.h -HAVE_PORTAUDIO_H:INTERNAL= -//Have symbol powf -HAVE_POWF:INTERNAL=1 -//Test HAVE_PTHREAD -HAVE_PTHREAD:INTERNAL= -//Have include pthread.h -HAVE_PTHREAD_H:INTERNAL=1 -//Have includes HAVE_PTHREAD_NP_H -HAVE_PTHREAD_NP_H:INTERNAL= -//Have library pthread -HAVE_PTHREAD_SETSCHEDPARAM:INTERNAL= -//Have include pulse/pulseaudio.h -HAVE_PULSE_PULSEAUDIO_H:INTERNAL= -//Test HAVE_RESTRICT -HAVE_RESTRICT:INTERNAL= -//Have symbol sinf -HAVE_SINF:INTERNAL=1 -//Result of TRY_COMPILE -HAVE_SIZEOF_LONG:INTERNAL=TRUE -//Result of TRY_COMPILE -HAVE_SIZEOF_LONG_LONG:INTERNAL=TRUE -//Have includes HAVE_SLES_OPENSLES_ANDROID_H -HAVE_SLES_OPENSLES_ANDROID_H:INTERNAL= -//Have include sndio.h -HAVE_SNDIO_H:INTERNAL= -//Have function snprintf -HAVE_SNPRINTF:INTERNAL=1 -//Have symbol sqrtf -HAVE_SQRTF:INTERNAL=1 -//Have function stat -HAVE_STAT:INTERNAL=1 -//Have include stddef.h -HAVE_STDDEF_H:INTERNAL=1 -//Have include stdint.h -HAVE_STDINT_H:INTERNAL=1 -//Have function strcasecmp -HAVE_STRCASECMP:INTERNAL=1 -//Have function strncasecmp -HAVE_STRNCASECMP:INTERNAL=1 -//Have function strtof -HAVE_STRTOF:INTERNAL= -//Have include sys/audioio.h -HAVE_SYS_AUDIOIO_H:INTERNAL= -//Have include sys/soundcard.h -HAVE_SYS_SOUNDCARD_H:INTERNAL= -//Have include sys/types.h -HAVE_SYS_TYPES_H:INTERNAL=1 -//Test HAVE_VISIBILITY_INTERNAL_SWITCH -HAVE_VISIBILITY_INTERNAL_SWITCH:INTERNAL=1 -//Have function vsnprintf -HAVE_VSNPRINTF:INTERNAL=1 -//Have include windows.h -HAVE_WINDOWS_H:INTERNAL= -//Test HAVE_W_EXTRA -HAVE_W_EXTRA:INTERNAL=1 -//Have function _controlfp -HAVE__CONTROLFP:INTERNAL= -//Test HAVE___RESTRICT -HAVE___RESTRICT:INTERNAL=1 -//CHECK_TYPE_SIZE: sizeof(long) -SIZEOF_LONG:INTERNAL=4 -//CHECK_TYPE_SIZE: sizeof(long long) -SIZEOF_LONG_LONG:INTERNAL=8 - diff --git a/jni/openal-soft-android/CMakeFiles/CMakeCCompiler.cmake b/jni/openal-soft-android/CMakeFiles/CMakeCCompiler.cmake deleted file mode 100644 index 4e09da91..00000000 --- a/jni/openal-soft-android/CMakeFiles/CMakeCCompiler.cmake +++ /dev/null @@ -1,44 +0,0 @@ -SET(CMAKE_C_COMPILER "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc") -SET(CMAKE_C_COMPILER_ARG1 "") -SET(CMAKE_C_COMPILER_ID "GNU") -SET(CMAKE_C_PLATFORM_ID "") - -SET(CMAKE_AR "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar") -SET(CMAKE_RANLIB "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ranlib") -SET(CMAKE_LINKER "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ld") -SET(CMAKE_COMPILER_IS_GNUCC 1) -SET(CMAKE_C_COMPILER_LOADED 1) -SET(CMAKE_COMPILER_IS_MINGW ) -SET(CMAKE_COMPILER_IS_CYGWIN ) -IF(CMAKE_COMPILER_IS_CYGWIN) - SET(CYGWIN 1) - SET(UNIX 1) -ENDIF(CMAKE_COMPILER_IS_CYGWIN) - -SET(CMAKE_C_COMPILER_ENV_VAR "CC") - -IF(CMAKE_COMPILER_IS_MINGW) - SET(MINGW 1) -ENDIF(CMAKE_COMPILER_IS_MINGW) -SET(CMAKE_C_COMPILER_ID_RUN 1) -SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c) -SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) -SET(CMAKE_C_LINKER_PREFERENCE 10) - -# Save compiler ABI information. -SET(CMAKE_C_SIZEOF_DATA_PTR "") -SET(CMAKE_C_COMPILER_ABI "") - -IF(CMAKE_C_SIZEOF_DATA_PTR) - SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") -ENDIF(CMAKE_C_SIZEOF_DATA_PTR) - -IF(CMAKE_C_COMPILER_ABI) - SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") -ENDIF(CMAKE_C_COMPILER_ABI) - -SET(CMAKE_C_HAS_ISYSROOT "") - - -SET(CMAKE_C_IMPLICIT_LINK_LIBRARIES "") -SET(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "") diff --git a/jni/openal-soft-android/CMakeFiles/CMakeDirectoryInformation.cmake b/jni/openal-soft-android/CMakeFiles/CMakeDirectoryInformation.cmake deleted file mode 100644 index c90c9d7d..00000000 --- a/jni/openal-soft-android/CMakeFiles/CMakeDirectoryInformation.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# Relative path conversion top directories. -SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android") -SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android") - -# Force unix paths in dependencies. -SET(CMAKE_FORCE_UNIX_PATHS 1) - -# The C and CXX include file search paths: -SET(CMAKE_C_INCLUDE_PATH - "/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include" - "/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include" - "OpenAL32/Include" - "include" - "." - ) -SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) -SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) - -# The C and CXX include file regular expressions for this directory. -SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") -SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") -SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) -SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/jni/openal-soft-android/CMakeFiles/CMakeError.log b/jni/openal-soft-android/CMakeFiles/CMakeError.log deleted file mode 100644 index 6a3d66e9..00000000 --- a/jni/openal-soft-android/CMakeFiles/CMakeError.log +++ /dev/null @@ -1,437 +0,0 @@ -Performing C SOURCE FILE Test HAVE_RESTRICT failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_RESTRICT -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'foo' -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/src.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - -Source file was: -int *restrict foo; - int main() {return 0;} -Determining if the include file fenv.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -In file included from /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1: -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h:34:28: error: bits/c++config.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file fpu_control.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:25: error: fpu_control.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file ieeefp.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:20: error: ieeefp.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file guiddef.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:21: error: guiddef.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file initguid.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:22: error: initguid.h: No such file or directory -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file arm_neon.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -In file included from /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1: -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/include/arm_neon.h:32:2: error: #error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the function strtof exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strtof -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strtof -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o: In function `main': -CheckFunctionExists.c:(.text+0xa): undefined reference to `strtof' -collect2: ld returned 1 exit status -make[1]: *** [cmTryCompileExec] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the function _controlfp exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=_controlfp -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=_controlfp -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o: In function `main': -CheckFunctionExists.c:(.text+0xa): undefined reference to `_controlfp' -collect2: ld returned 1 exit status -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make[1]: *** [cmTryCompileExec] Error 1 -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file windows.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -D_WIN32_WINNT=0x0500 -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:21: error: windows.h: No such file or directory -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make: *** [cmTryCompileExec/fast] Error 2 - - -Performing C SOURCE FILE Test HAVE_PTHREAD failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -pthread -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -pthread -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lpthread -collect2: ld returned 1 exit status -make[1]: *** [cmTryCompileExec] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - -Source file was: - -Determining if files pthread.h;pthread_np.h exist failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c:3:24: error: pthread_np.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - -Source: -/* */ -#include -#include - - -int main(){return 0;} - -Determining if the function pthread_create exists in the pthread failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pthread_create -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pthread_create -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lpthread -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lpthread -collect2: ld returned 1 exit status -make[1]: *** [cmTryCompileExec] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the function pthread_setschedparam exists in the pthread failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pthread_setschedparam -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pthread_setschedparam -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lpthread -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lpthread -collect2: ld returned 1 exit status -make[1]: *** [cmTryCompileExec] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the function clock_gettime exists in the rt failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=clock_gettime -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=clock_gettime -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lrt -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lrt -collect2: ld returned 1 exit status -make[1]: *** [cmTryCompileExec] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the timeGetTime exist in winmm failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c:2:21: error: windows.h: No such file or directory -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c:3:22: error: mmsystem.h: No such file or directory -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: In function 'main': -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c:8: error: 'timeGetTime' undeclared (first use in this function) -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c:8: error: (Each undeclared identifier is reported only once -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c:8: error: for each function it appears in.) -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ - cmakeRequireSymbol(0,&timeGetTime); - return 0; -} - -Determining if the include file alsa/asoundlib.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:28: error: alsa/asoundlib.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file sys/soundcard.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:27: error: sys/soundcard.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file sys/audioio.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:25: error: sys/audioio.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file sndio.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:19: error: sndio.h: No such file or directory -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file dsound.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:20: error: dsound.h: No such file or directory -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file portaudio.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:23: error: portaudio.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file pulse/pulseaudio.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:30: error: pulse/pulseaudio.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if the include file /System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h exists failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c:1:78: error: /System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - - -Determining if files SLES/OpenSLES.h;SLES/OpenSLES_Android.h exist failed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c:2:27: error: SLES/OpenSLES.h: No such file or directory -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFiles.c:3:35: error: SLES/OpenSLES_Android.h: No such file or directory -make[1]: *** [CMakeFiles/cmTryCompileExec.dir/CheckIncludeFiles.c.o] Error 1 -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -make: *** [cmTryCompileExec/fast] Error 2 - -Source: -/* */ -#include -#include - - -int main(){return 0;} - diff --git a/jni/openal-soft-android/CMakeFiles/CMakeOutput.log b/jni/openal-soft-android/CMakeFiles/CMakeOutput.log deleted file mode 100644 index a2f8fc63..00000000 --- a/jni/openal-soft-android/CMakeFiles/CMakeOutput.log +++ /dev/null @@ -1,755 +0,0 @@ -The target system is: Linux - 1 - -The host system is: Linux - 2.6.38-12-generic-pae - i686 -Determining if the include file sys/types.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the include file stdint.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the include file stddef.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining size of long passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining size of long long passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG_LONG.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG_LONG.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/SIZEOF_LONG_LONG.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Performing C SOURCE FILE Test HAVE___RESTRICT succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE___RESTRICT -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE___RESTRICT -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: -int *__restrict foo; - int main() {return 0;} -Performing C SOURCE FILE Test HAVE_W_EXTRA succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wextra -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wextra -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: - -Performing C SOURCE FILE Test HAVE_GCC_DESTRUCTOR succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_DESTRUCTOR -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_DESTRUCTOR -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: -int foo() __attribute__((destructor)); - int main() {return 0;} -Performing C SOURCE FILE Test HAVE_GCC_PROTECTED_VISIBILITY succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_PROTECTED_VISIBILITY -Wattributes -Werror -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_PROTECTED_VISIBILITY -Wattributes -Werror -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: -int foo() __attribute__((visibility("protected"))); - int main() {return 0;} -Performing C SOURCE FILE Test HAVE_VISIBILITY_INTERNAL_SWITCH succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -fvisibility=internal -Wattributes -Werror -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -fvisibility=internal -Wattributes -Werror -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: - -Performing C SOURCE FILE Test HAVE_GCC_FORMAT succeded with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/src.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_FORMAT -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/src.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/src.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DHAVE_GCC_FORMAT -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/src.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -Source file was: -int foo(const char *str, ...) __attribute__((format(printf, 1, 2))); - int main() {return 0;} -Determining if the include file float.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function pow exists in the m passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pow -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -/usr/share/cmake-2.8/Modules/CheckFunctionExists.c:3: warning: conflicting types for built-in function 'pow' -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=pow -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the powf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef powf - cmakeRequireSymbol(0,&powf); -#endif - return 0; -} - -Determining if the sqrtf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef sqrtf - cmakeRequireSymbol(0,&sqrtf); -#endif - return 0; -} - -Determining if the cosf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef cosf - cmakeRequireSymbol(0,&cosf); -#endif - return 0; -} - -Determining if the sinf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef sinf - cmakeRequireSymbol(0,&sinf); -#endif - return 0; -} - -Determining if the acosf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef acosf - cmakeRequireSymbol(0,&acosf); -#endif - return 0; -} - -Determining if the asinf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef asinf - cmakeRequireSymbol(0,&asinf); -#endif - return 0; -} - -Determining if the atanf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef atanf - cmakeRequireSymbol(0,&atanf); -#endif - return 0; -} - -Determining if the atan2f exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef atan2f - cmakeRequireSymbol(0,&atan2f); -#endif - return 0; -} - -Determining if the fabsf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef fabsf - cmakeRequireSymbol(0,&fabsf); -#endif - return 0; -} - -Determining if the log10f exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef log10f - cmakeRequireSymbol(0,&log10f); -#endif - return 0; -} - -Determining if the floorf exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef floorf - cmakeRequireSymbol(0,&floorf); -#endif - return 0; -} - -Determining if the function stat exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=stat -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=stat -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function strcasecmp exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strcasecmp -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -/usr/share/cmake-2.8/Modules/CheckFunctionExists.c:3: warning: conflicting types for built-in function 'strcasecmp' -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strcasecmp -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function strncasecmp exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strncasecmp -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -/usr/share/cmake-2.8/Modules/CheckFunctionExists.c:3: warning: conflicting types for built-in function 'strncasecmp' -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=strncasecmp -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function snprintf exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=snprintf -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -/usr/share/cmake-2.8/Modules/CheckFunctionExists.c:3: warning: conflicting types for built-in function 'snprintf' -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=snprintf -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function vsnprintf exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=vsnprintf -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -/usr/share/cmake-2.8/Modules/CheckFunctionExists.c:3: warning: conflicting types for built-in function 'vsnprintf' -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=vsnprintf -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the isfinite exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef isfinite - cmakeRequireSymbol(0,&isfinite); -#endif - return 0; -} - -Determining if the isnan exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef isnan - cmakeRequireSymbol(0,&isnan); -#endif - return 0; -} - -Determining if the include file dlfcn.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function dlopen exists in the dl passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=dlopen -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=dlopen -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -ldl -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function gettimeofday exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=gettimeofday -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=gettimeofday -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the function nanosleep exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=nanosleep -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -c /usr/share/cmake-2.8/Modules/CheckFunctionExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -DCHECK_FUNCTION_EXISTS=nanosleep -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckFunctionExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the include file pthread.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the include file android/api-level.h exists passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckIncludeFile.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckIncludeFile.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - - -Determining if the __ANDROID_API__ exist passed with the following output: -Change Dir: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp - -Run Build Command:/usr/bin/make "cmTryCompileExec/fast" -/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build -make[1]: Entering directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' -/usr/bin/cmake -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CMakeFiles 1 -Building C object CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/include -o CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c -Linking C executable cmTryCompileExec -/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTryCompileExec.dir/link.txt --verbose=1 -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/" -L"/libs/" -lstdc++ -lsupc++ CMakeFiles/cmTryCompileExec.dir/CheckSymbolExists.c.o -o cmTryCompileExec -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -make[1]: Leaving directory `/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp' - -File /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeTmp/CheckSymbolExists.c: -/* */ -#include - -void cmakeRequireSymbol(int dummy,...){(void)dummy;} -int main() -{ -#ifndef __ANDROID_API__ - cmakeRequireSymbol(0,&__ANDROID_API__); -#endif - return 0; -} - diff --git a/jni/openal-soft-android/CMakeFiles/CMakeSystem.cmake b/jni/openal-soft-android/CMakeFiles/CMakeSystem.cmake deleted file mode 100644 index 31e08bf6..00000000 --- a/jni/openal-soft-android/CMakeFiles/CMakeSystem.cmake +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDE("/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/toolchain.android.cmake") - -SET(CMAKE_SYSTEM "Linux-1") -SET(CMAKE_SYSTEM_NAME "Linux") -SET(CMAKE_SYSTEM_VERSION "1") -SET(CMAKE_SYSTEM_PROCESSOR "") - -SET(CMAKE_HOST_SYSTEM "Linux-2.6.38-12-generic-pae") -SET(CMAKE_HOST_SYSTEM_NAME "Linux") -SET(CMAKE_HOST_SYSTEM_VERSION "2.6.38-12-generic-pae") -SET(CMAKE_HOST_SYSTEM_PROCESSOR "i686") - -SET(CMAKE_CROSSCOMPILING "TRUE") - -SET(CMAKE_SYSTEM_LOADED 1) diff --git a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.bin b/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.bin deleted file mode 100755 index 4852a91107a22d5ae6864730c557976a19d6a5dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32731 zcmdsg3w%|@x$msCcCvRKgdJW6*udV|0Rn-Yga9J)$cylXkOU0i=_Vu_5(!C6!c)P3 z^b}jFKq&H(Qmr0Tq|u7Uo@$HFTHBr`z7E>z*}hS!O+8wyQgZ+QnYH#_3DBN%&%O6| z@111!H{X2UeDlpWk2P!7tXa3rm{+7}ny{QM(gm^3T|$fpJW?ZsE=0_D;T2BMQpGUR z8%_@v;`CwV&w!8KVft7=rXAm+d>CQ+7MS14+Ezsop~&JzqtzF66Zt=>6uNNnwmpvGgsEs zW!BcztqC;>QGobD_$lyoD885q9}mxTec*?{`{DE9r@>opBmxuQv*8C>k$|+rB=`V) zGW^x>>G0RUGe0^n{B#CPH`;`>7u^_m>O2Y{Cauv@h`@-ylCkk2+n{2@Sl`mt;nC*k3k{>P}e zGMhfXR3!Q9#qXQ&Z4gR(Qr@2c&)M|r!-_YZ7cd?8Q{PqXkNj5yKe0@B zfgg+T_Y&n0q#YFE20+r+0={C?XD2fl5H#0Jqw2JO@P6r2_styuCf9g1#H|K}Y$Mfj^A) z%)Uu{5%8ygrQezPt8P0)|m4>~tS$s?ezMf>0wOnD0d?fo|a{PyyW zVM1Gd{0QkM+2sEM`1fq>@h#v#vFUpeINJ-I8##*Fnw3q>Rh1bTfu?#93|53HR@Ma9 z)orM$s|r>&Gz1$Ovk)EHSW~qz7^ZZ$Q7%U8CPYgEK z2XnGbL6sG?wJ<|yV?(I2IfP=H1%pNfMR{UvXl-S~rbz6PlG0#lsJXlF{EEso&5ae6 zAw*X-)d#C9>Z)pq*sNidI9S+CR&hO*zf4_>L$sxeUA`4}iFG3cX|V2@!-*Ug__ zj{JkH#$ZidO^r`t9Z46bei$t2NHnA+dtiI+= z4WZ!Liss7dOEg7wUlJ#^hg#jM&t~4g(F`xsfb0p`{AHu>o~f)a+N&T^UuY3!p^a## zwfPlI&@tLj=2g_KURSX?REjoKv#O@Du%fvlLT8gf((d9do0vJsmSWm)Rbxd@3q+Km z`7YB~(3YdhFmp>sRCHCX>abOa4ywK!3=x5-l}$}nR5Tn6niLEIGHk)3*$ZX|^GZtc zmLj^QZdHA-sb(|ls-SFPNpRlm(lW^ouCfT*+KL)>{o;}t-J&rjJ%O>QKPFA52{Fh% zONdFx3xp|{yAWdVZYT8O+Cn%U_X31@xV8cgz(nsjAue(!2r&U|BgDk)Q9?|>9w$UP zM|kY}j_~*2PYT}=c6I*j{R@yOp1j1BvoS&#`F8ILPa%xAL_)+}an+i9sxMqb& z{c6SLYUk|b<%h2y96NZxSJf}4e7)l9>J-nDMUJ+XCr=mELgz`$Yn0Khc^#t?Uyl!q z3|B|*(XnUtik1{{IKO((3gH!D-P^#-l=4>6{aruo@BlkD8?%dej&I5^_gjW4G zy&n9B6(Zfy5vTXsQ{FhJ(G`x@`y|CVmNo7bz4knmqWcCm#vas1iH>{M_}7Y5*WNQu z@ygloXJIE|9UV7R8?BDLt_hBC#!jQPdZ%N8W4GhbJ++$e+XXMD#I*KK75*#_rrCFP zoxiEeeJJLD@bAu#J!2f!eBUW}Cgo86;k@PfjzgL+KG!&?c}s+r8(*M}9?~vG8}0gN z(f)3DPIz#v$mr7^dr*w(-Jb60I={8cG2z}yr^k!%=bz#t-O(O)Kj^+wv_2blOgI*f zJtRgC?hqLn?Q5#jJ&qR+dPK+1!*K_b_bl}!v_qQ=(f(BVOTE3G_`_Z2&q)c%yOR$y zmy_Yt8;re5>t3nUdsvtIuyNo(zN6!w8}7>2I?_G!!>$Qy!=tNX50;1$7q~|aM{Z@% zS#M83-U~Z2h6t~tHD-6eu;W0?A)`9(pf)afPt0B`@A$)Bk4Wu0fAUkuVMmUmRisbo zh&f;!+?oGD$69FM=%&G27u|;)(7-P>@OB9QyDJ@jf2DCSW5^FyR#s+Ii;TX%b9uC^ z7LlIPb^gZ0AGynWj`pL9PcNbw6_FO>gAl+3>}`EcdRdsoJKKmBk$ zZk*kxbfo#=MK}78`;><8Q8P?g2V}VORNnl&xmyZ9DZi~vzsBJad(gAmT^{HCUFYLJ z)pv{ZxDIc{)bKTPKQ6y!?kDAX>q~=Pay$1rQO8;B+O@)mcH64$LCZT>n(|ifKd0!2 z*1OM(e;YUn_F8b!I2^P4XujT|d2{n)!}`Gn&uQU;W%Dj-lf^x3-G}1P_I&+yZKAgS)el9cfg18x#CgYtDQ)D%V^ud*YZ)pw#+w?RG(=?RZ-lEf zzY*>_e-$hkt_s)sLk4Q4_Zx$?!M)LYI}+!{hBd&1xq4X7c(o%Q_7IyZi-g+*uG$NuVNPU97? zr#(w_t_L>A>3HRgf4K;!DEy6B$1A)1hb8{V$E=6WQ$y#yyyo7*zE%1jrzd$x%<){* z-jqLRe)Qhf2f@3haNh~XLq_YUTK3A!E;Pgr5A-J>6Te5Oc` z@9@{Sygtup&w-h-p15?QJtqC_4z!UGj^kbD@9ugC67MR^@^m8ad4KKd>O3`i-ZRzr z7RI#3cy6s3;BjQ%2@M>r`%iS8|LUCZ?{76)eYG4LKD)Rfe?wmUi1UNl3fvw3+Srr3 zQ`c1ZJbMNE!aL_OY9@I`dB!2tVNlSiwDO97ijwG_ST_?7Ie9Wq4wawn5M2 z4jnDV-LX5>>xsR8ujo4e^f{Djge&70?amCn-3aM|^*Iivl zaDU)F_0)>(6>qE=R5eic^}D*Y}dm7cRz*F*>qP;;!?jyY@)C#(Amd6R@lM)H7&vdPmp!Uw1jezgm+} z#ZhS%G(BC^aH^mtq3Rj5pODp?R8JvnSWbeQf`(fZ|KfE1MNb` zSS{LL4fh_~?@Venu0Hwh_HP$>J*g{ZWyNH~bm;y;1*t1U=X+-zVcma7hF?1?0&#Ep zs~xF*^JCgu!R=qc9`wdp^!RoMTEequ;~`N$!|?NG4P39B?L`Q`fRy^1Zg1{jTKYqz`!WW1;VLJg~1wKa?x>6&ky>Ju%^xMUHW^wW-p>&Vv+;R5qHCS>J{%;n#dF&w<>me7*gEXn8TS7_9(p;O@#* zkkoKi!z>9)x85}v^-dQ}#zO0Ocgs7I#GbR0#MqCzdhb3f!grnZCG0*ov@7#%UqXw7 zUK965@OCr)w1m3Wc}`D;_rYhw=fN+6uYkW1ejEHA_#ePO4F42-2mIUcf9f=4gdqdo z2cHd}2fqlu0{%w$ZSZ^Ge*ph5{8R89@NdKaDJ*4Z+uAN@d*FWn|8Uy{mO#^i>pEZX6|UlKzpFj7Y0wbP zjNB>WNs9;bFn=P(vuw$8pjMzwb)NcGTaqURvle3yN7R4ra(LR(`*#?JFh|E|;d?s< zGat-z{AmBUn)Uq(P|dS|dA|}~_uDQ0l>ELO-x6K^VYxBT1svu~=fYncSH~Q#h}B;G zcZ>r6J}~Cao5GzV4bQc?Eg1tl96EE{+SM|0y6z}=B42cT6i$mtOJokIkkNI%{I9sU zx4#vhlHZ1r*x38fhr2Tdbo5Tub9;{#9WRA@;rF-Um=jEaJfYDue-ZnLVHS(@?SI+# z;jxTf9bNvxnlp8K!9Y)PUc6^euHkgQ+T#D6HmD#m+?G+^@o;(qt`=SACw1vVMaO;N z$@!xFo-pN9g&#>z>tLyrOkQpG{Dr)!U3!`;e2dSOdn|WwN|q<4)j1yXny!}An8WV; z&pNjGZb`jOxO11MkdA9OWIX)gk1dhRkDrOQzv7{3F6InCVVk>`d+L*K^(DQgZtkT9#hWKm5z| z!BX#kLSCJa;m#cl&0SJnJ1pE&#~4_D6K2q&+JqjT8%Tuc4eFT1)fz`qE;@~f_{$KdaK1S3b= zgBtk`{Hg1fwzjsG$4z(!kc6`){+55_UCdy|5NU9=xDiJkasz6(XRw&FDP0#nF~P6v*5=6gXEi8P%zn> zK6An1QQq-^@qrv6{xdPsUM#bE8iQx9Xq)BMLomeBp1SxP#id2ny8XYhf=s9A9Wa-o zw_qK-AB}0cCh#ixlyNhz^wxTrwK(@#k2tRJo`h*FK65qrcebd=3aAcEExw-1rSBwy zcDW_HaU#3d6-e2lGvt>{>VI@6*;g=qs8L(0%dWJZ?9O9sqarlzi0 z#01xE5PCX?2YoD>iax5CJTB)GjQI_O>Z4aOMt5eQ$oh2g33c30w5RiKE2V@um{e*Kr=$i9( z1a+ql8HTeDWVoC^MA$9#LI~0Ge?s#6RAxpFgExakpYKFc7lY;cd~SY-yPX_MHj?NU zaW|9my89&NiW@`)Dt3TP_b0~vgs}Q$iFxDrlu@tavrOGTDUQ$l^bOe(nz4#=T1{s4%xk zNYSg#LtJ80gU~}NR>X0H(N{5E_d7%{MmwQf5`P?`x5Js>*4OxeD9&02p@rgPDI}*M zz;kt!zIHueEmP*%}&2;Bvj5=zWVgzk`j0BpZnfl#bgY0#`EAAArA1W*kg_CKfu=m_I1qu3UEctPS z`h0+ZG(jJtU}e+P7gNqJeu5ac;#XztK}cq&(io1IHn5}HKgDccfE>-s4jg|SqBYn1V9(X2mH{L-3T+w# zktS0GMAmI@;kp1T?$io*k+Di>GZ+A4VnYS6BHF<4w`ii*41~D!W2LKs#apyFG#b;* zH`58%N(fBU7P0OVHwdjnHUhudSl_ZF=)(0~D7r#ha-NK$te%nJ&{nTNY}^gdMytLK%0qPABGjfgiX9Ydct6!{27a{h9iHlSKuJ{_;L+^B<{Y zLZQ~06VYQ|H$A>*>LK)0X0|^Ge6IP(!lfNq%`^*H@Vl%uGeFVIK7l;QsC|DL_y(Lt zQ2#>nvD)uN#8q#y{eN*B&FiX9p{f1_n{vwfidvzcr#LaN1Uc#sO*77be~{#NXiP9j zCU9s>F<7Q>NWo&j!=UPKsayn-dm5S>5y4zjn%81v3^OQ(yu!kd(6t*`DEis-CJltC(a?I@D%Wacm?m@8rD;P*F&tiKhNkjOlleL{ zX3Q&Xn#?#xW6qpp50^Q|YG&5MWY#WC<~`zTO6sf2#K)22&s47WAlH#-$$fQ(UIbIR z>>K^1J>LWlweJVX%Upd}(1-3X%W6Fh3C}7ioT@6_JqAt2%)}_|H?+Yk8kwF~jGVp> z{{TeoE`uYaRxCzqegyPawHLs020jT{i~--s&_;CklaeohIFZo|D{6l>vN!E)@?vNeQn$-tF0`Z zmlW-S!K(;+?^tP+zZx`xzQsMJHiVXT(L@u+KFJo)6+ugxSU4zK-{MWb5%M)nqFI!+ zpG{LY$zuZG5+Rfz{d!9A%4^bL^2u8FscY1hewh#4flX}id*X4!R*O12E=ecBn$3Rv zYtZm4TWJ66SPPbMze1e8XGPA>0dszgA2FV6Z-MPBy!N=`GAv?3BY18H{RnyPbvy%6 zIk!{9t@xQ}QLa7+j8}4O`pm-5BHUh%sS(67Hk(7q z667%pskOb1R0zoV2yv6D5pnhB41oGkm15r<6~D^@BqS8|KYbjTb7UrUW> zrVUaDv@}_?M34r-Yt4?M%raUuiz20cLrM$mgaUs7n<`D2l=MB2h8936ZLwoCs#29~ zi7Xi#|9F<{EIMc>yjJ0mrJ86(T*H#VW!?ws^YD{V^|CsrNa^PwVKVFKXP_MiqlPtc zR%JZ0vel)SOuLkU=`@+LZFZS-1~IY}*B}j?EOAf2L}!N6mT(B`z5s0-c{oELDW(BS3u&8tP=OG6!&>V+;GQu&XNht? z@Lz+py*CQFUJ?I{N=!$RG~A_=nPWi_@kfaN)FAIt;A2Oj^xBh#f%L|n7dEHwML_$R zaT08`ppRKsxl(AS4c?jxOK?#+DN? z_V(#^aK@Ff6qTYqttyVX7q<#=40&;(Lsk3Jvf_Rd(f4Vc`hG%uDfN3sR@6n{V?Us< z=k$|M1*RWcO!D)(ye@BXkBws+`GwBX=vxw1VPDi$VUOQ5Hiu*jKf8X?EGVDO`(N!< zodq2U`q&s`qrGOzaHW5jIsBVMXMoHKNo1MJRfVuHRq&Od{d1&1<GFd@S02g^Ii}p{tMydPZe~VbI`Y2QVlQh*I5jRpclz)<@>V=DX zx-9(tQqv6JP?R%!EnO*k0HQvJF9V5-L`qz`RCF8Slp>>~BHstDjF(}yl;bxk@nd95 zc~Xi0nl1PaC7z;__6hMPkhs94#NQ#sC*wk=#P62kGl4@pt_f*1Dmk{Hhz0QTLE<`; zN?s$A^OCEQ*U04G0j{)JBel7o;_|h-QBnGj<=n3rlDNwA5-6|tMQS-iNtKhoE=ofJ zq50+HZ#J$$X*aTx)8q`Uk+_`x4VTluCxEN@-bgv$%dCU&Bk-+#(5*T3*2Zd_%*^6M zV+9*eKnhyLs}HW*nQ{uh1DMEUIvtA5fKurP*zgJ^@7>mH75b-+5y0{y);m}fG05*cHSVhi+F*EC`){L#HSzXhd+0xpG}iZB=F< zkh!|Dl76gQ>BhS}D;Z(NSJv09s#%>`(YTfbwe}b&?I}))YOb%Zt*pjI$+2J`i+6(7 zZ5)do#EtbeRotU(%8%xBS+30H>UC>Znpy~~z;rB`zmG)cxCCD@w!(4*2#1}JB6A95JNJX=jAQi?XNZv;FnhaKYDb}_G zS%SDetkXUWf%~NV%>%+E$ZrDvoh3-H?RWzXv*da zqg7J1!bn1Nh4CB6D7wO^Fs?AlG-`#BnYbNnUws|j*Y^6^*JP?8w?D51`WM3(luImf zO=f^vlc7j))o;L|RcIP*WPA&ZDf0SJp)rvd_!!B>8WmyhI|+}a4X#-ZlDE3W4E_j1 z)nH7eO33ybj$3X=Kg4^qIcNg{OPeM4K zZ=?vVmc$1@95Dxy8{s)! z7%A5=ZY6CnCNN^e2O#K&g!mPSa$azf#A`@Q9RWfE{K#LhF}+CnYe~TSa-22l|0XrB zh1MM0_k%R#15ma3(nL=amu+RfG~uhjRUIyrb$Ax|DAg7Z=(^ z(fGJt5uuYX(~9p4bPA>?34Lve6TxJPB~vd=o86Z}lYC-!-%L!ndMg#sX?jB~>X+PK z8<|L+J~7}yKPRqI^&<~@GjfQr)Ef|hRz%3;l^S0a6VVJkdVE9!v;vbkW@Msb#r>;H z9mAXk1EI1K@tBCzX-G7kmB~=ZWxkSmn3;)0yd$LEzJNA8F{&EtA~&ApN{yPB>wU6W{{(U(NWQoW2zvXIeZqD9o9$XHtz zKm!TdV#$`7fY#SXqo6EX3TTl%M9c150=Dvmr7@(BixJsfr-h0J9Rrs z{)tL7I`4QUgvd$E6&;N@E`#dnWmdUT>1k$>(T1dXWaMvS(?_^wi@}f41CdiM7mu)dhC@^gWNz)VAMR=FzjwOTP8tfYG>Wkw3|JG|& zSM3+ItkrSw4w32=>~eU~#~L4SIgVP@Vor%R|7h=xnpgHG_F;33VMPs&iX`f}QmqV$ ziYDKc`ZH->dsD=vP_@@ot3CRy24?kLv&jsP);pW|h-lXsX`?`X`sH*)zcow3p#bUe z%o9Vocn%?5`#Px??uj(CMFFq<_iuat*WBu;o2;6;%Gz~RAtBU#6mOFPcno3Tfoc>3 zE=K1ABjZC&>u>Z57){>k^Oue>dU=ibKz}1CU^IHCFIbvkBzcYVTA+Vw=DcjI zi1ZChbLhqkn^vuJXvR-sy(iDtPS0S}Gn-Z+=E+#E40{oNHa6f(n>NuiE;kc#-`W%y zHXgBG#(FpSjl?;K+Oa8sh_7Rt=jM<1`BR5Z%R=NE8~+87ZBEK*-$*$>a(baA(3dxQ zrHK2T-b2QKav4JjC!COwImSQ4pPG-zj*ZmhM^0wZAtgNE+-)QVruvNU-%>t&@NmTM z-$cpp$9jhwPu$`)9@OU4q#NMXjT0LKM$&c=f8}&}jsMshF!pGSzh@(}y2rU4wlRJy z=J=)>>jT!$r<(&tg4b9#$B6S98@%{U&03ZgpInOXCvW#(o3CS(pB;YpjGDV-5NXPVDAa`R^>@U+Zn*;D6DT{?BC@yD3JL}*71 zjfB85X!GReDbVJHm?;Q9zL}c65JN2=-^{YV9J31Hhc>f}uf+sbtT9%X8y@d8x5Zw*YRRWgdF8hrvr^LC$+IK?+>+GLi~h@XOX zX!Q2-H+jmw>Ur5y^QNLfPKQ|vG8be{pPIWSGy6KjpJ}+~7@GsW zoays3zp=pQ8|s6*cHDH>b^Zbr+?PMk=UX~C&u^UEI>*?l1@JPFSC7Fc@B&8!f$sLd zWnADp__KY(vNGppXQS;ss0Vy##Xe&VyTPru zup8W}HIFnlc}Mmhnwo7?2M~X|j6W}$jjy(p2XeCKW*fiNyvD;@z0-CWztWnGC$
  • *aHFJ7a<_+uCrRLn4S)83U^@hBh9aDX&^U#<^7vGwjJ#}f${LHbw zAbQf8EMi$xuU|Ny7zdek_NO9mhAv`AV{{fmz z{faBp*J<3gUan1*fuDUR0J$tDaW11^zSPa87LAK0SE6x=gyqdoa>zEqG*-IzKvU(4 z(#XsF+5(%|9+*Uer~7%VEun?EC1GNW|y{22nvv zRZXF0d2)yS1PA*GBsj+dCoPzzGB<4p7ef&AoVPHqOf=T4u5OO1DT2#No3D|lQSd|q zv0?4njg{*B5F9Vkh;tpH2R+P~RTi8Ts;I(=UD!-!9x~F?4lsI2+3W=~Rhe1Jl@*PR zHKE2}WkqE*g`sYW@@CIlTrxv6g(?~=tAjIeU_x`nN*o!|P>qu%vZc+guxp$OR*AaC zP$fi_28$M!6wEMdB2w<2o6uFB3vmX+%mu+2Fx%QTxQv z>YLEiDrCm;V2h?|Ts^(rnwr%lpaKq(SzRD|l3C;)C%^@m@BGqsEkm}C2FkF z?mQdn8>=D$)KG&?IkN=fWHv>`c_@ZDoTjcG=lMiW?@ud|o*u6~pe0TcG$HzdIW*x}T%+JX!iH!ns?KSldWca4DG60HLFEEe zZX~XZrvPyvZ47m5mW|ELHELWG4EDS^{-1fQs7h_#3$tk~nO#!0IB#CJVL77Mb*KnY z(}Yg8D%2RNs|*R*)6gbq|8;9?>Q-BWn!rZ7)y>tSs-~&3u?Cb1oW27as*|BqkClnp ztZBL$_B`xNwG6|?cExjzvLNXSC)gleAx8=f53KwWjwfMXs%AS|jS#tqrPS4FizXrIe*{ zJ{D?l?OGmX#lFDn>g)xJBZDume9@z&)bP1@_JXpUakOx#5sflC5{kyIrLKBn$ z3WH2PalB;?UNtcEKo3?KM;O~_T^L(}C^b&*!bO+kE7Hj}OmlR50|qsS!mp}RS5whk zjbJU(Jy!m?=1#h^Fcqj3#Ex;)49( zs>b@YFsz!C{P)+LGP~VBbt|~_>W{5-_Vb)DwFoxwsu~%m?C&9A1}3M2nkeS%k~1;{ zQvo=+LlD0a$NLgZl#t3>76c-YEe1ojtp2Suq(o-BQk0c z!Am-+W!&7Fh|~!3$s`3K2)cAkvkM-^BT$S>qKr!<7kfE zx=v8S1Efh3m_$QQW~&1`5ZvY5pXNr)RN zSr=JRl*A;cn`Z^nq#=z&7*NKJ7|a1WkE*ok>jf7%ZBZ2YB8tGA34bk%Q%dl+l-mpX z-IBGNa=Q=(NgD}I!b{y4pv{phfhl&Qt;`#(0xkocwX2EiqAiJUuSj=;NrlwYf^=4i zM0ms`>qa6LyJamF&6Zijz<*x?EjkXKeT0xFQz9JcY>eZ+Y+L_~Mnw!0jfxCLe7#D( z7zV+Fd?ard%(y~$o8V|vL~t}JB6t=O%~8T6EK%Wz#-tU)+XP3WB7&n)5y53hv_uJ$ zaD@u@Bi!ha+E20!Pre)AkqN;vkZpqisVgNllHU=aCuG!hCjnG~NVV@m)LwWP$U~^I zQ(G38B~!P-BfFmgJgtK50AH!#1%QhxXsP%B(6EeJ@*coB73>61nJ=*zxwZ4pl3F?* z<(MqXQaS}7Uj+*R=BS{Rh6-+mXR{%ET7@H(z_{)3P?+Gf43-g)(^fUl0(~Byf(U=D z!u<#fvATrj&P68W$nY9G(i2Pp0o}+><-TxDM6AvPToWBv-hUBSSenlq5JOgOQ<|)Fm=1q9mi1$*2;7W*J=a z3c!0RXi2V)P_NsFppqOZ{?8CaQz74X06tbhD=pRh3Z6wEOvLgN!jTGNTs-1zRl_KU zjEbnrD9%)D_KYTs49k?wx7C;zA>Tqn*lp>;xIXa6i-2TY@-C$=ic%xjS4Is`X|n(( zsUX2*6|}_U0?mh~5`?o?E5*f9KKv5(5u0T|k zq!trwmccTDn^i1{B;Ye*T?l?Rw^Z>x4DrjjNr7nt6BX#sRnEwTy zvI+V2q22n7djTG@3FOO((fLc1x+qGGl=Uqn_&}xo7=UlXVSD-@U}d3Cj9q7vwyEP4-3(<0O*q?$#tOgADzEsds)NL~VJnN(~s!4erPA)ub^Q!lT)=04R$riCQEw zkj#VdtupIKZ*2qmdl_|Iv~I6sp_Mfw!~3IP`am)+A-Euew)U_jnkJH8IKmjo?;S*4 zlxY{UBt5Du9Z^Nn;E|di5s8X4c@`QXSSCHPoI@4<1ODnGJ7 zpmgux_hWd>^UeW$s)G2HZaq?Lhlhqo0MzYTNiB44P2tR{|Y7RoVf7Mpcq<;=?t7k^3Tlh%l>qJznoN2ScN%tCldFN)` z<(tu>8F4%#g*V&(2yeNI(2@7?J^2|A?L;DcKX^R;7Q8*S+~1?$jP$&9<&$da!&}&s zw)8xep&H)0LAB&wKp+wE~S=a<=%0iVZ*yPXNCU?;aI?P zfSk%(j_*=`1O6p=PMuf5^Bqge<)tGe*M@~Q6v3DYWi#-0flG_i`Z)S&{k5x%6m6h3 zNEd;oO>6PM46wOT!D=gnCvKs}1`)u6v}zHk+EfQt1+lIfz*9uVsXzmkPy_N=XrQrP zJ~#^GmCO%d;h&;akZ)fGu$0fk^6{Xxv0{@5*u#8oW5riuoxDlrRk60FQUq4lL%x!W zgVsfWtH*r!5~vETT(=sj_;is8B-*fUWgQNFkKpogq{X^&B_8csoOnYhWQEl#tjPu& zSn+s3X9cZnSRgz%Zp8K*Jk_y`{&(SEaG>$9;i_*c0qJW?MH-zSo|Q?y^lk7Uqye!S z3L66bD0pnTmVEPW#RL!xxgd~6S%hx*Y!0M~*=U|b z$OCTA*9ANu-s0m~YS)90gE;vhTINf>B6!MD!89EVX6=|uB?@{nQ3O zk1*}X^6|_%e$&e0L6p>qke5TMO+KDwckBv$ynNw32+7AY?v7u9Z$EfgUdrQH_ib0; zy9;#Mn0!2sj^ES@BW&qUNPX{vx8(6`yaPipPeq*N$VdMmyv4`wp8Otsm$UQ3;GC<~2b zI@*|y`_;+EzC$+;9pM&sEYp!j?=ktT_+ORb<@00@52jBCn)K$#lq%67#2tb_% zg~4{!YAmsEi;r2@)E3u)Z-zw#%?c9Q%rDN>!Oj?%e27O-wkfs+7R@g2!X|t>=rVQ& z+a<2wHWg)P*mThTc(sD7+))r;6)6|O4Y z`W}%XPq0+|PtomH6y|U5xy1V`LFTU^cm74A40%GP9gocJWuzenMu`X+@)=w-%8(~` z+Hnj)Sd^iI410Mj0 zQ^X`c_gpHcaPGOZ^8}!eD1eYPRZvUOFPbem3Ewa zDJ^_H0uKRCLq%EgAKeqB(|+7jshmqJN1y}v96+ml+*hfbS)VqX>A9cMqTh(XUBDj& zwDOzPYLdqtDo!_rhPSHDUIMefcfp)s*KolpP-#=4M zrJrTPN$2B*vlIP~Gj&+^iK#FbO+=ZFm_-MW5o22A~r>@wMblYY#GzYU!AH5!oLulo|v z{=G@ATG+ogIU2bAdy$2}?cbX$25$e}8+Q^%f!pho&qA&1DdqF9LhE|z#`W?vaQpWrUj=Ue-Xx!zTF#4r z21DDwH`yQfdp7-f4wv0t#lY?LcRg^Pkv<8ss80oOyS_ER?cbZc75Enzj|Z9jcaz_A zseu0i+}g4@=WPGY&8GH^sPdzJ z_D?OAT(Yy(zQOOZ+a|G_GP+%@`&K=Ra2cum?4S8jKQnc7tN;HcU)SvRtwGy|3gs6D zZJYn?ivREa^rn3SY_#%w>?c;=Nwtw>rJ6f1O>3h{uJAcd`&SihrL+=U+FBy@f9alo zwT&^d!@TEb8f}e0?dc8Tl@Z&Q8!x|g(%yh=TKzBmuBT MC_Zi*{f6lO0Bn_2?f?J) diff --git a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.c b/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.c deleted file mode 100644 index 44d4458a..00000000 --- a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include - - -#undef KEY -#if defined(__i386) -# define KEY '_','_','i','3','8','6' -#elif defined(__x86_64) -# define KEY '_','_','x','8','6','_','6','4' -#elif defined(__ppc__) -# define KEY '_','_','p','p','c','_','_' -#elif defined(__ppc64__) -# define KEY '_','_','p','p','c','6','4','_','_' -#endif - -#define SIZE (sizeof(long)) -char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[', - ('0' + ((SIZE / 10000)%10)), - ('0' + ((SIZE / 1000)%10)), - ('0' + ((SIZE / 100)%10)), - ('0' + ((SIZE / 10)%10)), - ('0' + (SIZE % 10)), - ']', -#ifdef KEY - ' ','k','e','y','[', KEY, ']', -#endif - '\0'}; - -#ifdef __CLASSIC_C__ -int main(argc, argv) int argc; char *argv[]; -#else -int main(int argc, char *argv[]) -#endif -{ - int require = 0; - require += info_size[argc]; - (void)argv; - return require; -} diff --git a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.bin b/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.bin deleted file mode 100755 index 0facba76a72f3dc280817679dc0121067096790b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32736 zcmdsg3w%`7x$oM0PcoASVR#x~fSF8yKwy#(KtvvS5#A7zfB|iXkW5G-*NXzV)rgUVH7e*S>k?{9;YhgynRRA&7PE5@G`2kvbuCA>t+ouW*8vCWe#V zcxs3crw%KB8hrE))5ilc?SvNPBM8&S!IQ^;?++pUw<+HbI6Y~ImL5Qe7Ud6kgrH}7 z;Z}4RcO3EX6-ZPI&wNRTzTz?PKL#3o1UNnE%wzF;&D8)GIVWOB&uZG#)EruqwX&`u ztG=#bbto)EA>xbRr^3^r_+lD-B0SUeg&zv87j5&s-Kx!zpGn_?e6}g#4+7fLk7L6)0T0LYKSsrs z+w}RRBFSGbe&2v^gHYO&^8O5X)}~)yR=nxFfEmD_{EljW;J69048LhujWD?|%$@`r$v&SLbz2oVPU2b(_M0={^k5G&BI z$$tp=t)_j_fIkG>US9S;j#+fH$Frb+-)3+2v&U@uzX^J~js7R#pV{(HM8411_!mLZ zKR{phxas?*n^s>>~ezz~8m;|DuPz`Z9l%myY&a z58Ma+Cj)2t$-wRUc0k@@w12C8eGL3_;8y!h$*bya3&plPiL1}j6AE9-*m z8aC85R0pdX8-tDEY($4P)>Ur|h8n7);il%waI>gfxfZ{WQKgaxm#CD*Yr|EcYK0)l zs)ltIrL?lHDKv9qRj9GKZf!$%T3O}#P;hB+iLjVwg_=u4tH4(#a|;G7LTRXJ-I`Ev zZ8%sOYOW2h-2g#V8!Lk=!QBw7st;8*tZPJEIMmdk5iW3aBFu17g6HhaYsh3Z4i_G&cEQ@D0bBPnJ^>r`t9Z46bdi$`hg#jM&t~4g(+n@sfb0p`{AHu>o~f)a+N&^HUuY5Kp^a## z^#zqp&@t9f=2teXT35L$RE9QGS5sG2RM}h^rL)N(X?O9KP0So*OEGO&6RzxOfv7Sx z-z6Fg+Hy=8W^U<-imt9#9kv?LLDiRoAtDg9vZ=|6iiLwglY&7&hAmh;XW^V+eraj` zGDO!k)T|9Q)oo^76_zh54bGoaRxa7WRUTzqQ(4EZUs5`=TQtU`$1yeyz@+IEAqLrJ z2r&tHo-h@27eWl)?Sx)jTL>rMUVtzk*H*xRnCKlN#6|8nAts=0gqWB;LWl|2V}wZO zh>UyB5&7Z-4twU0omDV~CG<9pJT-^AmN=1s`}@PVQ(EKT4c;W6{PHSFI3f zU#{3(>zs3K#o_CQ#19$xW$jC;U#pGRn^m+A-vk2WMZ>iNhB2z=I2WGjS=sell=4>74aruojBkwo$?!5Tj&I8Gwq*nbm zy&m}53X$RHNYH!jsR$1ayCR8t-;@N$^6*~KYtMtJx^GZ8{-8cubo^koe~n0U?LF-j zFQ18g8gU}l(Q$pP(dyXin&^mR?lf9!cRD6Ib~_H;Q?L2HRrpeBTx;(%;m`J9nteyt zxf{FOhvE(h|L%hL)5c-V_wB-`Qx6p!&cC+6aY*we<{1YyZ>iAo5(~94L)*m|qg@{( z+TV%HjSPtwnSI;i4~o&f+cP{}=eBk^CjOwx>G2}`*(bP2ceF>`54i6Tt`|8>ZkK_4+9?|jhNW#HBdzN{U+M!LRXn(Te#ok^|;^D4yXQhNbyZanw zE+-;s*Bg74*1giG_wX+FVdKDo0!PO^*WX#7b!2!JL|hZsM8?#{A1oE6E^vD22-sRD< zTSP``*SSwF2p=sk?r`tUhK*jl;NBA?=KH+{qkm47{}8K@zDWrBBHgwjS`I9h#Ut(K``z#|RE57D?|6Ba|FFa#{)qL^d2-nNmsbCvs9&|d$LZ-aH11d) zYH#WvH9vZ9>jU6jU9|7G<3Xc!bUk}zRu>v#hjCc63SWjN8Li*}w2s^Umf_J4J~m5a zBzE}gTwb4NjOW0tcuzux(H@uaRtMV1NXN0Rb9Z+=2#I$VWqUf2_x!(gb#dGD*b3Yo{`&Y6 zyVF)z`aF9D`@-92GwUXMMtjC1=O3>&cIy$he|X_Ns~vY$Rcl^tzu0#bw953v-PHy? z`*i4NG477tXK%6+6P=HLm@rb`Z_LvV+*w3@tH0{% zI)eKH_sJ($Y_EKM_2BA3vajFS<$j{^WSl42qcpwqg0w^Z>PpRCS=xSWv1q-jp5vBBT z7ay4A@VGKQZLclvI(Pm;{8*zS8zt^KcdBcTv}=NwdOi-jx=%ihHm7%Vo%?l{Bl4@& zN!1*cW<%3c#f>Km>yoOUMjPsds|l`Qpj_SMju>@5kM3p7IWzQjSBA4gk7PjC$sc-U zF5l_uIydPo_5Qfc;Xz%E7O#2VYMpzl*j#jL#kW%LDAv3~-r^WM;H^oH?W;AHZp-m^{fbDOult z!yvbpF<$Ss0`b}(BNfAD70k--Je8_T&%SnQx$7 z=oqU-`zw*&La!%n#q8|3%(xESKe#Y$h3I_uj3c7^56SSWXG9?3 z4S%g8tzSW0dn>s8E7*fxKZ73M?m$a;=1d|a>Zcig?u>!!m9xDV;pdT3f5Yv~8-i>7 zf$yzO@`#LqZ+s;5y^j0$73+uc#J(b9x3(uPva;AQ-u26U#f~Yir!Y2OZM1&=qIS4N z3`rG%!Ef9k#(3Q0#Eb4U_mme!@v)ZF9mU3;RFBpg7pW@7b>#UY#g3~TPaB7{DaKx= zyj5JAibcM5NA5jUmX-}?u8nHh2+hjhppM})B@rWYe#e#4vi~v2omqU^sCA*N@hGdY zg5$#}j1N1{jC?S|BRY4SxqEe&STFi`{x~StqerwCw5zpeMdp_skBZv{-CH#hGE2^k z#Ed7c!yWKKmRri&HB#2MAWQf)pUZO~FS|f*KOkCO$SOfAKpVKb zss@r8&uEw>Vd>Vp8l&E+;we~Yo#1YHd$QPbX0jOfVOQ_nXGG-AGrpwVXNPrVz2!@4 zk=Li{UHbZ-CzhzX$$%@DIU13Eu(#7W|((O&Jl$ zfcL@Yz~{p+hOdOb0e&0&9{BIUKLr0IdwjD(r z{P*A=Ix6Et1Z5pQ?n9A%^qpjs+u{Ds+m2JWzpb6x^^ON=y3U>XoBMFzwp7k1{~>P* zuD<_S-j6OXH@l|}+b_@S?aBM%c}oXBSE`U}ff3|e8N ziHJ63aCmU7JEgBac!iqhcAe8d;v4~2M2wT-g);xKD5_Hab~moA5=En`53aR_sCj26DP z;xO~UJjajrkE>a~F9Fp&3z+vy;dQ^&;!iE;*YQo!SL&4}P#ab6`jBG(E5P7}4=!q!)gF8;Lv46vz`AJ^fd)j~HgLNZ@#^NW#^k>)hlneVFLD zH!`I_wBHkYe7ybLY)43OrK^`$f+Cjl4%P6FQ8v z{&~<$U+EcKhO0 zGGmC;`-jM@6EfU+L!h}!%4>&(d+Hbm>u;@Z$&;T)aA-{V^9zkSiwbsqi&_?2IFbv+7y@52~5 z+8)rzci_)mH@CI5wLE6R(|{zLG4Xdz7?JQ;i;RDuZ_Dn_nC@81J`)}=;Ss_ITrH1% zuIT3h9~k>^OY>j4Zr<6|b+h-JiXSWC{Vf%M54az0Ic~B3m-hkkc^IEp@xGqV>xgr$ znfLgZLQ5P|Hj%MSJsaBfO|_Oh{}%O(w;qA6Sex;7hb^4BEatir-6 z-i%obmyGsK2uuj%3h|$bk@jMl)zcU}b4A;%upWXTmiE-eXDBW$s@CoQjTK}%Mel&Q z6ukxO;QeV#(=~xt$)}8)aHY4_%dEw@PkY31jrRmhYw?+@!N0dfMOQ#|Xln8GTrPb( z8MI3+*^L)Dy)Hw_5iOS^Ws6^6iLBega%^$90!^tKsoSEchKAIQ+G7QI#YOas7EZr= zX%_JbHS7Wke;g;-oYmQw$tJITI+=|hd$QeAST^+b0b`-6l` ztT3ulo2#qV3iW$E32NDuYImZIn5|KJ9k})z@UltraS@$93B}RV$0BGroX-I`9C39G z%_1(iZiCP>I6Ua%&{Xu%CFF5AA7{*OAXFc-k}5kcZv+9Ur@T*wq0mn__k*rE zZ$nUb>X2bL`$C4x`F(`lLN9_4z2GM#zeiBy}-Zp)cU(hlJb6v2-Je zevxn!Ij^}_Vy=Y2RG@MP*mQq#!cPcmUy_(NflnFr20qKw{gV^;%unBtBeB^+&!d=y z?3{@VYWilTS~LaWr2hJH%1HPrwY-*5%=lSi*D1`A@LOVEQt1gn0pb(xV4G=HG?yyYI)x<*w__8O=*35-^ir&oZQ^>EwvToc zaedh=`Z5IW^YZt0AgJ=K%+>iP7+N?VMNo788;$Pd16#wn0TLWSpU(RG#&MNmXA&^y zgRqcrMxd7Fd=doR`A5VU&M8pE;cP%m9O9U6_nRtRYYx+$m5plyf|~OyT3P6Kk?X)f z{3a#qN45YajAYbZmMKQk#z#q@DVnL@-F3)b_q!5K68pZw5>PmqW-5Eny;G5(pT?3O zL#Xfj2uKt3B??wHO??UF{Ng8waXWql+@*rNOXnLiShcKn2d&+r3w8r$t)1MKh6 z?_@Lntp;t}4kvz9#vX)Zb}EhGh-(8oy8V;P_Ib$ByzIb<*C1MRy$AL@ZCW`%a#(27 z8HhHSY9O+1dkfcjSaGLTw2O?@LYv6|7?T?-ffdsRhQCDt|Wd?U)#V6_p+v{qpbF(6OZZZaSxVLVE#ZMC>|Afa~i)lz3i0?H?}7DX#cUSHEF zv~9Gq?w_6DX1eXPo#AiSl4}|(g?0-K0aQ<5AJ=xUxQ4&YNcao&{RWE)6#eBr*5*G^ z%cLT$H8-lqzHWN_v#E#B)0o-*6!5tgAPbjvWEImaV!`jU(#!-!Gy4ScAfxu(>EIi9 z3PJsI&Btp00V1w=gYEzGV`yGid;(4N&)Jky*H_jH{T#)KL8Zu1cW9b%8vKJLze8h! z!7_nEV~Qa%g+mG!10Moae^ccmklfSQ97Y6lO>JI-kuk!c82T~`KT_9jV4?Uk_}^8G z4ELhtM(Pwln42^ZrbffovSu<=xPs*#EyKebgf>QU5Bn*(&G0NrRAKbD4amexi}|#V zAxr;}#-WDS+^z8X7I78~X)L7n4$DaA=a2R-M?YA;k!Ip&6RWH(loI z(3ml=wCOVAIE^`Tl08D^9Iu&K50_cHG@19vuPCXXE)yR^jz3em-h*66p(Xdz8F~Rs z8M1E-koJ57IMlumBrkLIVL>0dza*>m6eK*Oq;RULboUrE88Z{3wcpSNFKc9aPBC)& zI^um0wL1-tkXnftqxligU(uci%W3!&WHA$Wt z3|>;S^9HXX?7icpQT}Go2>KTH*!mD!+65C$9`^)WKvxtkV`AZ;Y<-J2;|9prG>K+Y z)_yik-6W3f{g1Z#VfB#hsh^v-KVZmTl#0+e>*m@!S6}L4O>0x?3g5-0Ba8W z@vlL{vuvULi(?H~#{UX&`kocJKL^bHF@D4Zvb_nmGw|ADj!UqJiDB^E2Ko{5{J`-v zMCIN_5x3xHl0~`lATVCZvFS4#KZ|jDIkrw{-?r4vc%G%%CDAXymyt{SI}SEZHrN~v zB}O?ByY9x392`VEifApJHf?)OsM0w$-L+8?AiPCb;kH>9{Gipw1C0>c7b zmi0I!weJz)pFsI;ij{hS&ayqs)bfh9K#sKSz%#~id|RaR%J&X&dG#xi*E0=TPULm; zeF&Wmp<12312S{RATD!I(BhgOC zI|iSP?RY}FO)9h%tk^*L8jPqtuCW+{v7wd5;;O(5d2M-|mzEdFI86)TSNm5rHse{P zI0F9_NZWg(pz9U!FQ~)}BuU3zI+-~Z6cc}#_)iV;E(1PpG)k{MVHikn?0J53#$E)p zpBX2>RuB5vbyX{ccFN$biLqzr&BNYj`X}XBpZ6w&Y9AXrkiTr7QxNd71-@p;CTwgu z9%pZ#ZU<*vnafZq+Ec3HsC!AP5J!<07dlk6KP4;fH&K0`(y8yq#FtUOr)5Q506y-0 z3VT*R0aal7aU~=_r_1Z|7WcRWwvk`xERDV;SrzsLT^07&jpK4jw(v9SC(nlR8NC11 zUeQ_5QJ{~DLpIv0rVLlccbLQPBsvphR!B0-T%jt2g{g+G0_|U-1*(t+y9IISQsHF= z72Z!=YP?KV5HJ3!f|kn)dK|dOXIZo#>Kdi)hyN{Nx$2`#^+Rc@KOt_EY$!jJrs{=@ zdWJ0geNxj*;82t^do4pLdH|w6gD(e(i$qFXhE#ML;*=tzr6S)2u8fyywv=NxD)D1w zOL;Qr)ULlFz%7l6cd zD3!cUCg&wrC9jjozYSbzvs!9%AH@}DccY^8AIrI42_$iq=S5In>xa~GhLR>He_fP@ z1VZ!6$=@7YgVJwcC8x_7T$s3={*92+zsG^A`Q9iw-^*%%@FVc8ebKEs_14B|oXpJT zL}LXTPe2N);nfG%?JPNk-vLZyF`W*@WW@>;RR z`ygXa`%UB6WwcqiOcOu7HDdu=;cO}VRc3`X5p9mtBopIn#vWRCuEf7hJjCSlB>T^S zPrCb`F(-u2xR2wc*fGVE{IQtyo3Qf-$ois#lMzu3J^toYfSr%38UuuD&`e z5Xf3pRYgBeu5{yFo|TL+ z)@>Yz9mL_ab=BOXZOV`3bV;tP=Gt{@R+?G}tiXHo%e>J$9e8Z3nD+qvudiY@B9*xW$%RR4 z334!6thod^291nM3Tg?mLSohu49(afw+=kncz=x&%1_Xks2Rw3Z-e zBFrU7$}pE88O4m%5~RYcB}j!?OOOh)mLL_TmLTtgIJE?+Vyz`e#>*v0Msoo*g+I|H zNVyQokyEc{5L&2pA(ldNswK#D7{gqGw8WP%Q4z_L>4#dMVbn z1X+r>zO2)}41xQE{LKf#CCG08{(~h*u( z3Zqq0wZce3Y=!ab$SAhLs4%WD$~0<)k(sz1Y+wBx-PiW|+t*}jA$I_;1^Va18I(&b za!qEST9ctjam8=Ip;c-cZDf2CjH&YaQK>PJ81yK~B^niB?>hmHr46oG4wkpNB@F%u zL)8#WrAo>68;)CUM}Ne7w7F;k`YAbRwjt@G@E?QDhbKd2KDWtyk}v}TcP+VpF1a5A z=g;7Wfx>I2;@&B_rz>vGF!Y~lBOvP(INya|3<{_Fio02IZ$X@z*{zp_94;?o8#LN| zH)viO>KP<{5nkJ@`8EUhPP9i>X}-n4eZ}}mvsnGt0n_(vgyvAap2|EfRi`2s;7>p} zpXDfJ>ZCHSN0nJEm64gB0rOwrwKcZPqmkV*w_>|zK9P2NO}mGx9K`EQ7$X0OjQG4r z%?4^&nS(H6Qy-K2;N8$T0M#PgE(?7B!}TS zT^J?TF>WDk2qrLM_Wg2byxOdAP8BmAgeura+r`D;kP`*NH$>c5kk z*F$R#?)yO+`aY=I0%@YBh|9LJK$`Fs;HnN6$vQj(e6(td8XKLyrygnhXd_bkB^fDw zw7!~~*OGz4NSTs!b&Qfn+09p|tlUHhdMO;)f^ympu4bTcq=D1PGiWT>- zGIbnt8UlpMO2lI#Qm3J@bXF$AAeZ?{=HX^067i0ddiw&}jO3VVtc$!vmMbl$o{q}# z+fdF}O%$R?9brR39cfo2CUO+GOwE}nBc>bC(RNK@iN;(M9Z&T#FUmqjkBt>kha%%_ zSpW?rX-gzqRuWoYUyXvYZ7HBd&QL9Nu{ToMMfKv=8=&z zOq-$sFt5Bsv%dS_+LIr%Q7l10RJ?49F+!nfD@dA=%r3&aJa;@94A&6X2v1Kd}#+V+<>5NK7PA&*f@m zXiPNuF4vz)^V*vtE`_SSrdjRLZ#6Kh@0v|!M6BM~%tyw$#wZ&F@-r@_Bl@jb5)K7O zk7u43%Ehw?>DpH*y>L&Yp)Cq{?Z1E9^S|a+N8M!AHB{BFs}2dF?xT2{6u@H$3lG$y z7;teq9~c=QXxadySHNiU&RDQ)tkKJBBnAc;DFGwwow0CPrjg<`&S`-GX<74gj0@V- z{zjJw^fTN6-*8`6mhrss1}3Eq8!JVbh}y9!fQYZ+o97iw@cGk*P0vQ;>l^$c~NFG={eKpPg^!^nenH%z$9o# z4UMG0a%l6!=Bd!;`M9YFKem~gJs(FcAKT2bzZ6%4@PnIK##iG4D^?q;Dh!Wzy7B6k z?ODTp!_$UQ&rMT}{$8}09AiVk=;vKnY$STK)5fMa?xjD6Z}25OavF(K z(GHE?UjFu(y03PA&b0h#Xpl2tmcp!sSu>{PtB(f~>DE^!bMQ;I1A&19n}o5C!)Y%=h`0P09BgC$`Qtc4`5~dk^RVA6l``Sj}#5 z%gyWtw`k3yj7{EAy@#dc7_|Y!-zMYFiDu)=Efs;>oOwCMZ#A#+&{psC9mcP;X5;a# zf&6LP(3ta=&l~3}$ZE}+k)3t@x^-!}w`7&%WKX+3KX=D8U)p>$rZFYAqw~=>E@)AH`4}8{Dm)z@W#iUM6r{NNIP^Yz zqOF#50r}v%4cCx@l>U7jaed+(ed3KiPBImwtN`7T!6#+Ba@u8BG(Psa9F5PgdeYJ% zhmKFA(xJ@7dCyIm47w$sk9+0R=RgV zQ{{@$$jkiXg2H9=&bGDdcS+-=sOo8Qc9Ko@!p*c8S zK&9}eARji>uWeZ6l|Snmn(9_HgsQ#VE{mnJb)iPNSY2rD7spe?m{!*2?50qCO*m8^ zTw7Dq6l#_yci2yGu%AGJb3Aa;f>|na({^wP1VPXFi}K4wxNcQ#b4*PUTwd0El{}4t zCmM(iYu0S6Qs;-@c#$y9b%-7GFmrZ!aCWG&8YgyPGnskFNKZS!=%wXz7S2*-W+_)z zhQoECaImVfs+Ph~H^upL<}WFoDVjo+;i}r;OdOcdT)7fQhBVgVWQiPUv&-xnr-Id@ zAsniLsIp-3qSC^dW=%xP-E$MV%5xFUV3@TqIJ2T~W=Z*+MGJ$4`AcTaE;lFDL7DaV zV2!jUL`j1q$SE|B zdQsI-l3yXPPdaCksA*8=QOGhWd*Ymu#$ZhYTYCdesiD-_`3sBY&n!hzmn`glc#7I5 zj#l4u?bg(+CIJ<2kj$z=*^|s7_c#G2SXqP4WuARH-v`qU}>wm^vwD<)-FPQ?Nc%!_uHCW}>?rE^Nlm*mgyHY`UKy9N~@ z>YC8WYC_>qLsdw~o`yC_`>$J5*RaYO)C4xtt!l0n)pbo(;W|(%arzEys7{7bJys@W zv!?0l*z>S6)iMkl+hxx+%7&!NoM3}=MI0$GJh1XhIiASzm?MoE9@Hg8W^Bd9&T}%m zGcPzHTqDsy*WfW~knJH@Q(ws=q0FkoAydt;)so`_UoQ37N<7weg7>zO~8j8i`M&l+#Llcz& zih@i(X@X@AUNtcEKo3?KM;O~_T^L(}C^b&*!bO+kE7Hj}OmlR50|qsS!q+sYtEp(N zMYE6%T{Y_xY)r81guaTw(sn8rFT18W%wvj7i-Pl#ujWV<%oH3=L{n`YMiVn;Nnt^- zCcJhH467z3|NV8RtZw&D-3o5K`eQ4d{X8d3ErN}_sz%2t`+G>3fywEhCQ3NF=Bu$XWk<6~wP}WXywy zWKtKZAbzDImD6Wr5~D^lp{CW68r7NVt&mY=D*!vA#<)~+;fIXhf`=WgsND!G#od}FmNWpU zv`b=X`7(-hZcqnG#Kt%(ed!?BZNGe65(iPV;uKo+xllLDr%TmRCF-n>s9i_ zFbF2(BYC@E#udTa1jnMHf@4up!LyNQt`a6;sR~CmCanbCCO8%q6&#C-3NA;YrAnBD zD^$2Y;YNqlezIkF@?8&)ObC{PY#RhfT`8&2{Eh%UE~BnF0iY5@t9=)u_QJzJ9zvC! z+OohbnYs-g+5HUQDHUu7_)-PW16)u+OU3(vMr72|cLC0-U?+gee5u9At(||7)UpXE z#}rwXvZ(+CDp&+CR|Ty!RB$sqn+@SpDjcl@#%+g(!UU&eu$+LLwyJps=yUKCMEGkJ z?oU{R)g?4{E;1=chF9T{o?t2n=tg!b_l0XBYIP>yx{z)3`UL2wGOC1Nq?ECgV5|(5 z5Gct}3sI3`cq&OaUxoVsge}*WU3i-Yb@R15yX{qLy@GJshGM1kZj#e1s5)o&s8b&!} zR8&<)ai(IkXDnfKSf*^gt;W0v`4$?&Zc7)&^@T@X1SI2f#tRT1St8`Cs8F zn~-lG+O5yH=iwonK)#$9o4>@Ui(}MiS>Hs0_f^`D0Qj~p#C!^%#6%|qUm)sBcq&17 zUWNM;^6&*-#W3V3M}~NA1V$YIJOwjgFeUi443-e2aLW^>TwF<(!4iTJ6>FE2C?zeP z4a$5;UAz#0nc4=1SeB*ClJ8TX!ui%Z-D0wpPW)u5yaGEEti zKdOSK0G?987XaE-@NEFTLV;<*CjeilAb~?>Rh9zKUj?av+|wt@sDMlAUluD>S*%pi zj^~9WDuM3FqW91=JxX0ls#zq0N+iF7DoDUr zD`Dd>z+M%kdh>BIT3ItXygve__a);}g7Y$HYY$6fX`=Z>qKwh}-bT~~ znRW?F(xb{U5LGM<90RbdAq??MqD6;Aqkc$@GRpxfb@oN$K<%e&H#bQw=0Nk_W6n=BzX z1G4Q(NvgVqTuh*-(aL9neef7G6LDA3SKf1!_Xo&U!N~xnGFW;F;29Y#c^%+w6?_-j zQ6pQ~r4|qh<@=uj?35Xl5l{xB37?k&$_RLy#rq{f$|eipyYR3t!ACNB503j(`H=+z zrF$E{AHiducNX9i6~wP}>yctRJTyE4pl;Vn>!EX_())D)9x&0P2&P@ik!Gb#Uj8$H zP8GC-pG7*k7aJ8t_$fS8a}dh?tG0S3{WEx5Ju^z(!bdw_C!*rzOq&f(x>xbbJ2&et z-;5T`h~pV4yxIOIc*|XYj=YcW$RbcQcPuTJpMj8E8y4Cy1mh-_&&1mWE-gXp>*%iy(5^62wL#io zT?Cpot-%8`z~-=mwN?mE+(O|-5x|4AS`nz;)Bsimv91}wQ$)t8KqHn=1M*pDAiP#S zI11#KE(l=ZpQ2TeZ(jzml+VNR@t`$axk&`;h1Dvo$p#x( z@pwRI1+8pYAUrn?WBU!B>R3kqhj0iu(0JHz)i;%Z^s}WRjm{6x$|PULHh2)yfmjWN z4S{|%JT_fRzWKLc0tkjY5J;meLN|O4JkwGh&raKg%QnwUvz(RhRfxd#PxA3>G*2?* z0k`Mt0$u=b@$oFR>%hlBoO}>1^Ce#~JY~nj%X87d$19BGr~>^wc#DtUN$CV%TZ+Y{ z%0P@G3;9@%qj;`=6b6kBortrFw9Ll$2>2cWA4Eo-#aFHP8n*+=Z)Ab*G{V%K&f;5( zFzv|l@yt4Y)5_vOl+=lkmqV&eKAvTF^fG+BeBnI^$;UJ9j$MXtKX_PP%Hvu0ZI|J@ z6Li{`d_0ei-_(jAZ0S!(eeZ?0|8 z@2zx#k9M-06@C;ElxI2eO|lR`i}rI{nB)u$T`L$con`ZX18$`uX(#vsY!s%mXm0|y z!X!QFg?^}G%ULva#kFFwLUT3Rfo(Lk_`U#(6(;vx`M6rq@TRk94g{<)N$Imu78=QP zv@sp`tCNp?hi*PP!p-bhrX!8sWAa(?zbePe=Y1?Jme;5re9zUWtC+<}S#%Q-fI5u| zgY9b7SYqK8AG5HjEv^CIOp6Gb6(qEoUz}}#oiQ-^5Rag2Q)~+?nqA)cO={5x(b8G+ zEZh$JZ&R3I=E`xA&M70B^P;T*xxmZP|8bsTT# z3|R_{DN#I8##`U3!ux{~=Qu%Um?ICz1BLgJ(E7fXAx8|=zZIP$gX+f$SG|b+RpF}Q zt?v;T@&rrO{}kPRMPdH-o=bdy5@h}wa_3(x%8(~y+VSY@UPc;XP>hI>A)mp;q6~S0 zrya*&WOIi6`d%!;z}M_p@0PteqOitX-?4ZUZrPI~Iq8-?@#d1mEqihVCY|G@a=j&P zeGiIPTvfx0>cID~1|#V0k)LH>+)BvwB{n*Suc))qbC0ERE@=_&v9#mdV`<@I5V#Nc zKtP-#Ci%JNQaOcl&!rvbo=ZE$zRJI;NT zcAR@DEu7Q$2Z5)fqAdB3?1|B7Kklhi&LvhL&;fidpjAHZt5nXcPaDqk+)ruI*CTKz z@J9fx{ARbBWV1ZnSE-yT5BE}9__q-V0Ur-&<Twk3{>o8V|l7#npIlJc_IF;E^caTl@27ff&>CMgy^na6IP~Gj&+^iK#FbO+=ZFm_-MW5o22A~r>@wMblYZ2OzYm=C#c_b& zulpOI{d<#xkih=E$t>XZ??ui5ZvWoo65#glP1Xaqe{b@Z9_haeT%3T1!;MRCe{k{&|{=La{CY|#6y~*vs?cbX`1l<0;$@_uZzc|0erVPK9c`K;P&rL3QYOz-<$LTUuJ86*}(1Jo16#Sns4xX zlV1aF|K4OHaC`sd*_QV5?gDNv-yY!h?@itZ-2T1EQ^4)toBSPcYyKg>HiH4b*e5H^ zPfJ=~r?gq>?{vjW^e%hC*vCM_X7$*1q}z)f{UYc8na_jv{C;M)dg;Csw|n8uFMYyD U-CJK&|NrV2Me&8(*oQ>_2l+%-xBvhE diff --git a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.c b/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.c deleted file mode 100644 index 0623da0f..00000000 --- a/jni/openal-soft-android/CMakeFiles/CheckTypeSize/SIZEOF_LONG_LONG.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include - - -#undef KEY -#if defined(__i386) -# define KEY '_','_','i','3','8','6' -#elif defined(__x86_64) -# define KEY '_','_','x','8','6','_','6','4' -#elif defined(__ppc__) -# define KEY '_','_','p','p','c','_','_' -#elif defined(__ppc64__) -# define KEY '_','_','p','p','c','6','4','_','_' -#endif - -#define SIZE (sizeof(long long)) -char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[', - ('0' + ((SIZE / 10000)%10)), - ('0' + ((SIZE / 1000)%10)), - ('0' + ((SIZE / 100)%10)), - ('0' + ((SIZE / 10)%10)), - ('0' + (SIZE % 10)), - ']', -#ifdef KEY - ' ','k','e','y','[', KEY, ']', -#endif - '\0'}; - -#ifdef __CLASSIC_C__ -int main(argc, argv) int argc; char *argv[]; -#else -int main(int argc, char *argv[]) -#endif -{ - int require = 0; - require += info_size[argc]; - (void)argv; - return require; -} diff --git a/jni/openal-soft-android/CMakeFiles/CompilerIdC/CMakeCCompilerId.c b/jni/openal-soft-android/CMakeFiles/CompilerIdC/CMakeCCompilerId.c deleted file mode 100644 index efa5677b..00000000 --- a/jni/openal-soft-android/CMakeFiles/CompilerIdC/CMakeCCompilerId.c +++ /dev/null @@ -1,220 +0,0 @@ -#ifdef __cplusplus -# error "A C++ compiler has been selected for C." -#endif - -#if defined(__18CXX) -# define ID_VOID_MAIN -#endif - -#if defined(__INTEL_COMPILER) || defined(__ICC) -# define COMPILER_ID "Intel" - -#elif defined(__clang__) -# define COMPILER_ID "Clang" - -#elif defined(__BORLANDC__) -# define COMPILER_ID "Borland" - -#elif defined(__WATCOMC__) -# define COMPILER_ID "Watcom" - -#elif defined(__SUNPRO_C) -# define COMPILER_ID "SunPro" - -#elif defined(__HP_cc) -# define COMPILER_ID "HP" - -#elif defined(__DECC) -# define COMPILER_ID "Compaq" - -#elif defined(__IBMC__) -# if defined(__COMPILER_VER__) -# define COMPILER_ID "zOS" -# elif __IBMC__ >= 800 -# define COMPILER_ID "XL" -# else -# define COMPILER_ID "VisualAge" -# endif - -#elif defined(__PGI) -# define COMPILER_ID "PGI" - -#elif defined(__PATHSCALE__) -# define COMPILER_ID "PathScale" - -#elif defined(__GNUC__) -# define COMPILER_ID "GNU" - -#elif defined(_MSC_VER) -# define COMPILER_ID "MSVC" - -#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__) -/* Analog Devices C++ compiler for Blackfin, TigerSHARC and - SHARC (21000) DSPs */ -# define COMPILER_ID "ADSP" - -/* IAR Systems compiler for embedded systems. - http://www.iar.com - Not supported yet by CMake -#elif defined(__IAR_SYSTEMS_ICC__) -# define COMPILER_ID "IAR" */ - -/* sdcc, the small devices C compiler for embedded systems, - http://sdcc.sourceforge.net */ -#elif defined(SDCC) -# define COMPILER_ID "SDCC" - -#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) -# define COMPILER_ID "MIPSpro" - -/* This compiler is either not known or is too old to define an - identification macro. Try to identify the platform and guess that - it is the native compiler. */ -#elif defined(__sgi) -# define COMPILER_ID "MIPSpro" - -#elif defined(__hpux) || defined(__hpua) -# define COMPILER_ID "HP" - -#else /* unknown compiler */ -# define COMPILER_ID "" - -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; - -/* Identify known platforms by name. */ -#if defined(__linux) || defined(__linux__) || defined(linux) -# define PLATFORM_ID "Linux" - -#elif defined(__CYGWIN__) -# define PLATFORM_ID "Cygwin" - -#elif defined(__MINGW32__) -# define PLATFORM_ID "MinGW" - -#elif defined(__APPLE__) -# define PLATFORM_ID "Darwin" - -#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) -# define PLATFORM_ID "Windows" - -#elif defined(__FreeBSD__) || defined(__FreeBSD) -# define PLATFORM_ID "FreeBSD" - -#elif defined(__NetBSD__) || defined(__NetBSD) -# define PLATFORM_ID "NetBSD" - -#elif defined(__OpenBSD__) || defined(__OPENBSD) -# define PLATFORM_ID "OpenBSD" - -#elif defined(__sun) || defined(sun) -# define PLATFORM_ID "SunOS" - -#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) -# define PLATFORM_ID "AIX" - -#elif defined(__sgi) || defined(__sgi__) || defined(_SGI) -# define PLATFORM_ID "IRIX" - -#elif defined(__hpux) || defined(__hpux__) -# define PLATFORM_ID "HP-UX" - -#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) -# define PLATFORM_ID "Haiku" -/* Haiku also defines __BEOS__ so we must - put it prior to the check for __BEOS__ -*/ - -#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) -# define PLATFORM_ID "BeOS" - -#elif defined(__QNX__) || defined(__QNXNTO__) -# define PLATFORM_ID "QNX" - -#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) -# define PLATFORM_ID "Tru64" - -#elif defined(__riscos) || defined(__riscos__) -# define PLATFORM_ID "RISCos" - -#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) -# define PLATFORM_ID "SINIX" - -#elif defined(__UNIX_SV__) -# define PLATFORM_ID "UNIX_SV" - -#elif defined(__bsdos__) -# define PLATFORM_ID "BSDOS" - -#elif defined(_MPRAS) || defined(MPRAS) -# define PLATFORM_ID "MP-RAS" - -#elif defined(__osf) || defined(__osf__) -# define PLATFORM_ID "OSF1" - -#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) -# define PLATFORM_ID "SCO_SV" - -#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) -# define PLATFORM_ID "ULTRIX" - -#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) -# define PLATFORM_ID "Xenix" - -#else /* unknown platform */ -# define PLATFORM_ID "" - -#endif - -/* For windows compilers MSVC and Intel we can determine - the architecture of the compiler being used. This is becase - the compilers do not have flags that can change the architecture, - but rather depend on which compiler is being used -*/ -#if defined(_WIN32) && defined(_MSC_VER) -# if defined(_M_IA64) -# define ARCHITECTURE_ID "IA64" - -# elif defined(_M_X64) || defined(_M_AMD64) -# define ARCHITECTURE_ID "x64" - -# elif defined(_M_IX86) -# define ARCHITECTURE_ID "X86" - -# else /* unknown architecture */ -# define ARCHITECTURE_ID "" -# endif - -#else -# define ARCHITECTURE_ID "" -#endif - -/* Construct the string literal in pieces to prevent the source from - getting matched. Store it in a pointer rather than an array - because some compilers will just produce instructions to fill the - array rather than assigning a pointer to a static array. */ -char* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; -char* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; - - - -/*--------------------------------------------------------------------------*/ - -#ifdef ID_VOID_MAIN -void main() {} -#else -int main(int argc, char* argv[]) -{ - int require = 0; - require += info_compiler[argc]; - require += info_platform[argc]; - require += info_arch[argc]; - (void)argv; - return require; -} -#endif diff --git a/jni/openal-soft-android/CMakeFiles/Makefile.cmake b/jni/openal-soft-android/CMakeFiles/Makefile.cmake deleted file mode 100644 index c2299716..00000000 --- a/jni/openal-soft-android/CMakeFiles/Makefile.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# The generator used is: -SET(CMAKE_DEPENDS_GENERATOR "Unix Makefiles") - -# The top level Makefile was generated from the following files: -SET(CMAKE_MAKEFILE_DEPENDS - "CMakeCache.txt" - "CMakeFiles/CMakeCCompiler.cmake" - "CMakeFiles/CMakeSystem.cmake" - "CMakeLists.txt" - "cmake/CheckCCompilerFlag.cmake" - "cmake/CheckSharedFunctionExists.cmake" - "config.h.in" - "openal.pc.in" - "toolchain.android.cmake" - "/usr/share/cmake-2.8/Modules/CMakeCInformation.cmake" - "/usr/share/cmake-2.8/Modules/CMakeCommonLanguageInclude.cmake" - "/usr/share/cmake-2.8/Modules/CMakeForceCompiler.cmake" - "/usr/share/cmake-2.8/Modules/CMakeGenericSystem.cmake" - "/usr/share/cmake-2.8/Modules/CMakeSystemSpecificInformation.cmake" - "/usr/share/cmake-2.8/Modules/CheckCSourceCompiles.cmake" - "/usr/share/cmake-2.8/Modules/CheckFunctionExists.cmake" - "/usr/share/cmake-2.8/Modules/CheckIncludeFile.cmake" - "/usr/share/cmake-2.8/Modules/CheckIncludeFiles.cmake" - "/usr/share/cmake-2.8/Modules/CheckLibraryExists.cmake" - "/usr/share/cmake-2.8/Modules/CheckSymbolExists.cmake" - "/usr/share/cmake-2.8/Modules/CheckTypeSize.cmake" - "/usr/share/cmake-2.8/Modules/Compiler/GNU-C.cmake" - "/usr/share/cmake-2.8/Modules/Compiler/GNU.cmake" - "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU-C.cmake" - "/usr/share/cmake-2.8/Modules/Platform/Linux-GNU.cmake" - "/usr/share/cmake-2.8/Modules/Platform/Linux.cmake" - "/usr/share/cmake-2.8/Modules/Platform/UnixPaths.cmake" - ) - -# The corresponding makefile is: -SET(CMAKE_MAKEFILE_OUTPUTS - "Makefile" - "CMakeFiles/cmake.check_cache" - ) - -# Byproducts of CMake generate step: -SET(CMAKE_MAKEFILE_PRODUCTS - "CMakeFiles/CMakeDirectoryInformation.cmake" - ) - -# Dependency information for all targets: -SET(CMAKE_DEPEND_INFO_FILES - "CMakeFiles/openal.dir/DependInfo.cmake" - "CMakeFiles/openal-info.dir/DependInfo.cmake" - ) diff --git a/jni/openal-soft-android/CMakeFiles/Makefile2 b/jni/openal-soft-android/CMakeFiles/Makefile2 deleted file mode 100644 index b9be427f..00000000 --- a/jni/openal-soft-android/CMakeFiles/Makefile2 +++ /dev/null @@ -1,152 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# Default target executed when no arguments are given to make. -default_target: all -.PHONY : default_target - -# The main recursive all target -all: -.PHONY : all - -# The main recursive preinstall target -preinstall: -.PHONY : preinstall - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canoncical targets will work. -.SUFFIXES: - -# Remove some rules from gmake that .SUFFIXES does not remove. -SUFFIXES = - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/bin/cmake - -# The command to remove a file. -RM = /usr/bin/cmake -E remove -f - -# The program to use to edit the cache. -CMAKE_EDIT_COMMAND = /usr/bin/cmake-gui - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -#============================================================================= -# Target rules for target CMakeFiles/openal.dir - -# All Build rule for target. -CMakeFiles/openal.dir/all: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/depend - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/build - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 - @echo "Built target openal" -.PHONY : CMakeFiles/openal.dir/all - -# Include target in all. -all: CMakeFiles/openal.dir/all -.PHONY : all - -# Build rule for subdir invocation for target. -CMakeFiles/openal.dir/rule: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 28 - $(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/openal.dir/all - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 0 -.PHONY : CMakeFiles/openal.dir/rule - -# Convenience name for target. -openal: CMakeFiles/openal.dir/rule -.PHONY : openal - -# Pre-install relink rule for target. -CMakeFiles/openal.dir/preinstall: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/preinstall -.PHONY : CMakeFiles/openal.dir/preinstall - -# Prepare target for install. -preinstall: CMakeFiles/openal.dir/preinstall -.PHONY : preinstall - -# clean rule for target. -CMakeFiles/openal.dir/clean: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/clean -.PHONY : CMakeFiles/openal.dir/clean - -# clean rule for target. -clean: CMakeFiles/openal.dir/clean -.PHONY : clean - -#============================================================================= -# Target rules for target CMakeFiles/openal-info.dir - -# All Build rule for target. -CMakeFiles/openal-info.dir/all: CMakeFiles/openal.dir/all - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/depend - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/build - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 29 - @echo "Built target openal-info" -.PHONY : CMakeFiles/openal-info.dir/all - -# Include target in all. -all: CMakeFiles/openal-info.dir/all -.PHONY : all - -# Build rule for subdir invocation for target. -CMakeFiles/openal-info.dir/rule: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 29 - $(MAKE) -f CMakeFiles/Makefile2 CMakeFiles/openal-info.dir/all - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 0 -.PHONY : CMakeFiles/openal-info.dir/rule - -# Convenience name for target. -openal-info: CMakeFiles/openal-info.dir/rule -.PHONY : openal-info - -# Pre-install relink rule for target. -CMakeFiles/openal-info.dir/preinstall: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/preinstall -.PHONY : CMakeFiles/openal-info.dir/preinstall - -# Prepare target for install. -preinstall: CMakeFiles/openal-info.dir/preinstall -.PHONY : preinstall - -# clean rule for target. -CMakeFiles/openal-info.dir/clean: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/clean -.PHONY : CMakeFiles/openal-info.dir/clean - -# clean rule for target. -clean: CMakeFiles/openal-info.dir/clean -.PHONY : clean - -#============================================================================= -# Special targets to cleanup operation of make. - -# Special rule to run CMake to check the build system integrity. -# No rule that depends on this can have commands that come from listfiles -# because they might be regenerated. -cmake_check_build_system: - $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 -.PHONY : cmake_check_build_system - diff --git a/jni/openal-soft-android/CMakeFiles/TargetDirectories.txt b/jni/openal-soft-android/CMakeFiles/TargetDirectories.txt deleted file mode 100644 index 212b9dfc..00000000 --- a/jni/openal-soft-android/CMakeFiles/TargetDirectories.txt +++ /dev/null @@ -1,2 +0,0 @@ -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal-info.dir diff --git a/jni/openal-soft-android/CMakeFiles/cmake.check_cache b/jni/openal-soft-android/CMakeFiles/cmake.check_cache deleted file mode 100644 index 3dccd731..00000000 --- a/jni/openal-soft-android/CMakeFiles/cmake.check_cache +++ /dev/null @@ -1 +0,0 @@ -# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/C.includecache b/jni/openal-soft-android/CMakeFiles/openal-info.dir/C.includecache deleted file mode 100644 index aaa2c66b..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/C.includecache +++ /dev/null @@ -1,32 +0,0 @@ -#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) - -#IncludeRegexScan: ^.*$ - -#IncludeRegexComplain: ^$ - -#IncludeRegexTransform: - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c -stdio.h -- -string.h -- -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/AL/alc.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/AL/al.h -AL/alext.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/AL/alext.h - -include/AL/al.h - -include/AL/alc.h - -include/AL/alext.h -stddef.h -- -efx.h -include/AL/efx.h - -include/AL/efx.h - diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/DependInfo.cmake b/jni/openal-soft-android/CMakeFiles/openal-info.dir/DependInfo.cmake deleted file mode 100644 index 55cb9d59..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/DependInfo.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# The set of languages for which implicit dependencies are needed: -SET(CMAKE_DEPENDS_LANGUAGES - "C" - ) -# The set of files for implicit dependencies of each language: -SET(CMAKE_DEPENDS_CHECK_C - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal-info.dir/utils/openal-info.o" - ) -SET(CMAKE_C_COMPILER_ID "GNU") - -# Preprocessor definitions for this target. -SET(CMAKE_TARGET_DEFINITIONS - "_GNU_SOURCE=1" - ) - -# Targets to which this target links. -SET(CMAKE_TARGET_LINKED_INFO_FILES - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake" - ) diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/build.make b/jni/openal-soft-android/CMakeFiles/openal-info.dir/build.make deleted file mode 100644 index 5401004f..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/build.make +++ /dev/null @@ -1,122 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canoncical targets will work. -.SUFFIXES: - -# Remove some rules from gmake that .SUFFIXES does not remove. -SUFFIXES = - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/bin/cmake - -# The command to remove a file. -RM = /usr/bin/cmake -E remove -f - -# The program to use to edit the cache. -CMAKE_EDIT_COMMAND = /usr/bin/cmake-gui - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# Include any dependencies generated for this target. -include CMakeFiles/openal-info.dir/depend.make - -# Include the progress variables for this target. -include CMakeFiles/openal-info.dir/progress.make - -# Include the compile flags for this target's objects. -include CMakeFiles/openal-info.dir/flags.make - -CMakeFiles/openal-info.dir/utils/openal-info.o: CMakeFiles/openal-info.dir/flags.make -CMakeFiles/openal-info.dir/utils/openal-info.o: utils/openal-info.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_1) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal-info.dir/utils/openal-info.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -o CMakeFiles/openal-info.dir/utils/openal-info.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c - -CMakeFiles/openal-info.dir/utils/openal-info.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal-info.dir/utils/openal-info.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c > CMakeFiles/openal-info.dir/utils/openal-info.i - -CMakeFiles/openal-info.dir/utils/openal-info.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal-info.dir/utils/openal-info.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c -o CMakeFiles/openal-info.dir/utils/openal-info.s - -CMakeFiles/openal-info.dir/utils/openal-info.o.requires: -.PHONY : CMakeFiles/openal-info.dir/utils/openal-info.o.requires - -CMakeFiles/openal-info.dir/utils/openal-info.o.provides: CMakeFiles/openal-info.dir/utils/openal-info.o.requires - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/utils/openal-info.o.provides.build -.PHONY : CMakeFiles/openal-info.dir/utils/openal-info.o.provides - -CMakeFiles/openal-info.dir/utils/openal-info.o.provides.build: CMakeFiles/openal-info.dir/utils/openal-info.o -.PHONY : CMakeFiles/openal-info.dir/utils/openal-info.o.provides.build - -# Object files for target openal-info -openal__info_OBJECTS = \ -"CMakeFiles/openal-info.dir/utils/openal-info.o" - -# External object files for target openal-info -openal__info_EXTERNAL_OBJECTS = - -openal-info: CMakeFiles/openal-info.dir/utils/openal-info.o -openal-info: libopenal.so.1.13.0 -openal-info: CMakeFiles/openal-info.dir/build.make -openal-info: CMakeFiles/openal-info.dir/link.txt - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C executable openal-info" - $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/openal-info.dir/link.txt --verbose=$(VERBOSE) - -# Rule to build all files generated by this target. -CMakeFiles/openal-info.dir/build: openal-info -.PHONY : CMakeFiles/openal-info.dir/build - -# Object files for target openal-info -openal__info_OBJECTS = \ -"CMakeFiles/openal-info.dir/utils/openal-info.o" - -# External object files for target openal-info -openal__info_EXTERNAL_OBJECTS = - -CMakeFiles/CMakeRelink.dir/openal-info: CMakeFiles/openal-info.dir/utils/openal-info.o -CMakeFiles/CMakeRelink.dir/openal-info: libopenal.so.1.13.0 -CMakeFiles/CMakeRelink.dir/openal-info: CMakeFiles/openal-info.dir/build.make -CMakeFiles/CMakeRelink.dir/openal-info: CMakeFiles/openal-info.dir/relink.txt - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C executable CMakeFiles/CMakeRelink.dir/openal-info" - $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/openal-info.dir/relink.txt --verbose=$(VERBOSE) - -# Rule to relink during preinstall. -CMakeFiles/openal-info.dir/preinstall: CMakeFiles/CMakeRelink.dir/openal-info -.PHONY : CMakeFiles/openal-info.dir/preinstall - -CMakeFiles/openal-info.dir/requires: CMakeFiles/openal-info.dir/utils/openal-info.o.requires -.PHONY : CMakeFiles/openal-info.dir/requires - -CMakeFiles/openal-info.dir/clean: - $(CMAKE_COMMAND) -P CMakeFiles/openal-info.dir/cmake_clean.cmake -.PHONY : CMakeFiles/openal-info.dir/clean - -CMakeFiles/openal-info.dir/depend: - cd /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal-info.dir/DependInfo.cmake --color=$(COLOR) -.PHONY : CMakeFiles/openal-info.dir/depend - diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/cmake_clean.cmake b/jni/openal-soft-android/CMakeFiles/openal-info.dir/cmake_clean.cmake deleted file mode 100644 index 486bff7c..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/cmake_clean.cmake +++ /dev/null @@ -1,12 +0,0 @@ -FILE(REMOVE_RECURSE - "CMakeFiles/openal-info.dir/utils/openal-info.o" - "openal-info.pdb" - "openal-info" - "CMakeFiles/CMakeRelink.dir/openal-info.pdb" - "CMakeFiles/CMakeRelink.dir/openal-info" -) - -# Per-language clean rules from dependency scanning. -FOREACH(lang C) - INCLUDE(CMakeFiles/openal-info.dir/cmake_clean_${lang}.cmake OPTIONAL) -ENDFOREACH(lang) diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.internal b/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.internal deleted file mode 100644 index 038b0746..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.internal +++ /dev/null @@ -1,9 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -CMakeFiles/openal-info.dir/utils/openal-info.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/utils/openal-info.c - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.make b/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.make deleted file mode 100644 index d1ffef74..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/depend.make +++ /dev/null @@ -1,9 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -CMakeFiles/openal-info.dir/utils/openal-info.o: utils/openal-info.c -CMakeFiles/openal-info.dir/utils/openal-info.o: include/AL/al.h -CMakeFiles/openal-info.dir/utils/openal-info.o: include/AL/alc.h -CMakeFiles/openal-info.dir/utils/openal-info.o: include/AL/alext.h -CMakeFiles/openal-info.dir/utils/openal-info.o: include/AL/efx.h - diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/flags.make b/jni/openal-soft-android/CMakeFiles/openal-info.dir/flags.make deleted file mode 100644 index ae7d1783..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/flags.make +++ /dev/null @@ -1,8 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# compile C with /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -C_FLAGS = --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/Include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android -Winline -Wall -Wextra -fvisibility=internal - -C_DEFINES = -D_GNU_SOURCE=1 - diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/link.txt b/jni/openal-soft-android/CMakeFiles/openal-info.dir/link.txt deleted file mode 100644 index 15999103..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/link.txt +++ /dev/null @@ -1 +0,0 @@ -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ CMakeFiles/openal-info.dir/utils/openal-info.o -o openal-info -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib libopenal.so.1.13.0 -ldl -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib:/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/progress.make b/jni/openal-soft-android/CMakeFiles/openal-info.dir/progress.make deleted file mode 100644 index c7c4328f..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/progress.make +++ /dev/null @@ -1,2 +0,0 @@ -CMAKE_PROGRESS_1 = 29 - diff --git a/jni/openal-soft-android/CMakeFiles/openal-info.dir/relink.txt b/jni/openal-soft-android/CMakeFiles/openal-info.dir/relink.txt deleted file mode 100644 index 806c1533..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal-info.dir/relink.txt +++ /dev/null @@ -1 +0,0 @@ -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ CMakeFiles/openal-info.dir/utils/openal-info.o -o CMakeFiles/CMakeRelink.dir/openal-info -rdynamic -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib libopenal.so.1.13.0 -ldl -lm diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/C.includecache b/jni/openal-soft-android/CMakeFiles/openal.dir/C.includecache deleted file mode 100644 index 5fbc8495..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/C.includecache +++ /dev/null @@ -1,684 +0,0 @@ -#IncludeRegexLine: ^[ ]*#[ ]*(include|import)[ ]*[<"]([^">]+)([">]) - -#IncludeRegexScan: ^.*$ - -#IncludeRegexComplain: ^$ - -#IncludeRegexTransform: - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -stdio.h -- -memory.h -- -ctype.h -- -signal.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alSource.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alThunk.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alSource.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alBuffer.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alError.h -bs2b.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -string.h -- -ctype.h -- -assert.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alSource.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alBuffer.h -alListener.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alListener.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h -bs2b.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdlib.h -- -stdio.h -- -ctype.h -- -string.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -shlobj.h -- - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alFilter.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alFilter.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alError.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alFilter.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alFilter.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alError.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alFilter.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alFilter.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alError.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdio.h -- -stdlib.h -- -math.h -- -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alEffect.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alEffect.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alError.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -string.h -- -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alThunk.h -pthread.h -- - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/config.h -stdlib.h -- -jni.h -- -pthread.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/alc.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/alc.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/alc.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/config.h -stdlib.h -- -stdio.h -- -memory.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/AL/alc.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -bs2b.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdlib.h -- -dlfcn.h -- -windows.h -- -guiddef.h -- -initguid.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -stdlib.h -- -ctype.h -- -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alSource.h -hrtf_tables.inc -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf_tables.inc - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf_tables.inc - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -string.h -- -ctype.h -- -assert.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alSource.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alBuffer.h -alListener.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alListener.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alAuxEffectSlot.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h -bs2b.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.h -arm_neon.h -- - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/config.h -math.h -- -stdlib.h -- -string.h -- -ctype.h -- -assert.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/AL/alc.h -alu.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alu.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -math.h -- -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -stdio.h -- -assert.h -- -limits.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -math.h -- -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -alEffect.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -signal.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -string.h -- -ctype.h -- -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -alFilter.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.h -alEffect.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -alFilter.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alListener.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -math.h -- -float.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -AL/al.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/al.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.h -alBuffer.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -AL/alc.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alc.h -AL/alext.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/AL/alext.h -alError.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.h -alSource.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.h -alAuxEffectSlot.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.h -alState.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.h - -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c -config.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/config.h -stdlib.h -- -alMain.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alMain.h -alThunk.h -/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.h - -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -bits/c++config.h -- -tr1_impl/cfenv -- -tr1_impl/cfenv -- - -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -bits/os_defines.h -- -bits/cpu_defines.h -- - -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - -/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - -OpenAL32/Include/alAuxEffectSlot.h -AL/al.h -OpenAL32/Include/AL/al.h -alEffect.h -OpenAL32/Include/alEffect.h -alFilter.h -OpenAL32/Include/alFilter.h - -OpenAL32/Include/alBuffer.h -AL/al.h -OpenAL32/Include/AL/al.h - -OpenAL32/Include/alEffect.h -AL/al.h -OpenAL32/Include/AL/al.h - -OpenAL32/Include/alError.h -AL/al.h -OpenAL32/Include/AL/al.h -AL/alc.h -OpenAL32/Include/AL/alc.h - -OpenAL32/Include/alFilter.h -AL/al.h -OpenAL32/Include/AL/al.h -alu.h -OpenAL32/Include/alu.h - -OpenAL32/Include/alListener.h -AL/al.h -OpenAL32/Include/AL/al.h - -OpenAL32/Include/alMain.h -string.h -- -stdio.h -- -stdarg.h -- -fenv.h -- -fpu_control.h -- -AL/al.h -OpenAL32/Include/AL/al.h -AL/alc.h -OpenAL32/Include/AL/alc.h -AL/alext.h -OpenAL32/Include/AL/alext.h -stdint.h -- -windows.h -- -unistd.h -- -assert.h -- -pthread.h -- -pthread_np.h -- -sys/time.h -- -time.h -- -errno.h -- -libkern/OSAtomic.h -- -alListener.h -OpenAL32/Include/alListener.h -alu.h -OpenAL32/Include/alu.h - -OpenAL32/Include/alSource.h -alFilter.h -OpenAL32/Include/alFilter.h -alu.h -OpenAL32/Include/alu.h -AL/al.h -OpenAL32/Include/AL/al.h - -OpenAL32/Include/alState.h -AL/al.h -OpenAL32/Include/AL/al.h - -OpenAL32/Include/alThunk.h -alMain.h -OpenAL32/Include/alMain.h - -OpenAL32/Include/alu.h -AL/al.h -OpenAL32/Include/AL/al.h -AL/alc.h -OpenAL32/Include/AL/alc.h -AL/alext.h -OpenAL32/Include/AL/alext.h -limits.h -- -math.h -- -float.h -- -ieeefp.h -- - -OpenAL32/Include/bs2b.h - -config.h - -include/AL/al.h - -include/AL/alc.h - -include/AL/alext.h -stddef.h -- -efx.h -include/AL/efx.h - -include/AL/efx.h - diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake b/jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake deleted file mode 100644 index 3f3d39ad..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# The set of languages for which implicit dependencies are needed: -SET(CMAKE_DEPENDS_LANGUAGES - "C" - ) -# The set of files for implicit dependencies of each language: -SET(CMAKE_DEPENDS_CHECK_C - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/ALc.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/ALu.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcConfig.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcDedicated.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcEcho.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcModulator.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcReverb.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcRing.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/alcThread.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/backends/android.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/backends/loopback.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/backends/null.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/backends/wave.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/bs2b.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/helpers.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/hrtf.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/mixer.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/Alc/panning.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alBuffer.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alEffect.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alError.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alExtension.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alFilter.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alListener.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alSource.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alState.o" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/OpenAL32/alThunk.o" - ) -SET(CMAKE_C_COMPILER_ID "GNU") - -# Preprocessor definitions for this target. -SET(CMAKE_TARGET_DEFINITIONS - "_GNU_SOURCE=1" - ) - -# Pairs of files generated by the same build rule. -SET(CMAKE_MULTIPLE_OUTPUT_PAIRS - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so.1" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/libopenal.so" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/libopenal.so.1.13.0" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/libopenal.so.1" "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/libopenal.so.1.13.0" - ) - - -# Targets to which this target links. -SET(CMAKE_TARGET_LINKED_INFO_FILES - ) diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/build.make b/jni/openal-soft-android/CMakeFiles/openal.dir/build.make deleted file mode 100644 index 46464d46..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/build.make +++ /dev/null @@ -1,913 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canoncical targets will work. -.SUFFIXES: - -# Remove some rules from gmake that .SUFFIXES does not remove. -SUFFIXES = - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/bin/cmake - -# The command to remove a file. -RM = /usr/bin/cmake -E remove -f - -# The program to use to edit the cache. -CMAKE_EDIT_COMMAND = /usr/bin/cmake-gui - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# Include any dependencies generated for this target. -include CMakeFiles/openal.dir/depend.make - -# Include the progress variables for this target. -include CMakeFiles/openal.dir/progress.make - -# Include the compile flags for this target's objects. -include CMakeFiles/openal.dir/flags.make - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/alAuxEffectSlot.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_1) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c > CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.i - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c -o CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.s - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.requires - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.provides: CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.provides - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/alBuffer.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_2) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alBuffer.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alBuffer.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c - -CMakeFiles/openal.dir/OpenAL32/alBuffer.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alBuffer.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c > CMakeFiles/openal.dir/OpenAL32/alBuffer.i - -CMakeFiles/openal.dir/OpenAL32/alBuffer.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alBuffer.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c -o CMakeFiles/openal.dir/OpenAL32/alBuffer.s - -CMakeFiles/openal.dir/OpenAL32/alBuffer.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alBuffer.o.requires - -CMakeFiles/openal.dir/OpenAL32/alBuffer.o.provides: CMakeFiles/openal.dir/OpenAL32/alBuffer.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alBuffer.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alBuffer.o.provides - -CMakeFiles/openal.dir/OpenAL32/alBuffer.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alBuffer.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alBuffer.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alEffect.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/alEffect.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_3) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alEffect.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alEffect.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c - -CMakeFiles/openal.dir/OpenAL32/alEffect.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alEffect.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c > CMakeFiles/openal.dir/OpenAL32/alEffect.i - -CMakeFiles/openal.dir/OpenAL32/alEffect.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alEffect.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c -o CMakeFiles/openal.dir/OpenAL32/alEffect.s - -CMakeFiles/openal.dir/OpenAL32/alEffect.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alEffect.o.requires - -CMakeFiles/openal.dir/OpenAL32/alEffect.o.provides: CMakeFiles/openal.dir/OpenAL32/alEffect.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alEffect.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alEffect.o.provides - -CMakeFiles/openal.dir/OpenAL32/alEffect.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alEffect.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alEffect.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alError.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/alError.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_4) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alError.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alError.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c - -CMakeFiles/openal.dir/OpenAL32/alError.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alError.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c > CMakeFiles/openal.dir/OpenAL32/alError.i - -CMakeFiles/openal.dir/OpenAL32/alError.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alError.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c -o CMakeFiles/openal.dir/OpenAL32/alError.s - -CMakeFiles/openal.dir/OpenAL32/alError.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alError.o.requires - -CMakeFiles/openal.dir/OpenAL32/alError.o.provides: CMakeFiles/openal.dir/OpenAL32/alError.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alError.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alError.o.provides - -CMakeFiles/openal.dir/OpenAL32/alError.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alError.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alError.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alExtension.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/alExtension.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_5) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alExtension.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alExtension.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c - -CMakeFiles/openal.dir/OpenAL32/alExtension.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alExtension.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c > CMakeFiles/openal.dir/OpenAL32/alExtension.i - -CMakeFiles/openal.dir/OpenAL32/alExtension.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alExtension.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c -o CMakeFiles/openal.dir/OpenAL32/alExtension.s - -CMakeFiles/openal.dir/OpenAL32/alExtension.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alExtension.o.requires - -CMakeFiles/openal.dir/OpenAL32/alExtension.o.provides: CMakeFiles/openal.dir/OpenAL32/alExtension.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alExtension.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alExtension.o.provides - -CMakeFiles/openal.dir/OpenAL32/alExtension.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alExtension.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alExtension.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alFilter.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/alFilter.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_6) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alFilter.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alFilter.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c - -CMakeFiles/openal.dir/OpenAL32/alFilter.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alFilter.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c > CMakeFiles/openal.dir/OpenAL32/alFilter.i - -CMakeFiles/openal.dir/OpenAL32/alFilter.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alFilter.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c -o CMakeFiles/openal.dir/OpenAL32/alFilter.s - -CMakeFiles/openal.dir/OpenAL32/alFilter.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alFilter.o.requires - -CMakeFiles/openal.dir/OpenAL32/alFilter.o.provides: CMakeFiles/openal.dir/OpenAL32/alFilter.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alFilter.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alFilter.o.provides - -CMakeFiles/openal.dir/OpenAL32/alFilter.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alFilter.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alFilter.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alListener.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/alListener.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_7) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alListener.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alListener.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c - -CMakeFiles/openal.dir/OpenAL32/alListener.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alListener.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c > CMakeFiles/openal.dir/OpenAL32/alListener.i - -CMakeFiles/openal.dir/OpenAL32/alListener.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alListener.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c -o CMakeFiles/openal.dir/OpenAL32/alListener.s - -CMakeFiles/openal.dir/OpenAL32/alListener.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alListener.o.requires - -CMakeFiles/openal.dir/OpenAL32/alListener.o.provides: CMakeFiles/openal.dir/OpenAL32/alListener.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alListener.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alListener.o.provides - -CMakeFiles/openal.dir/OpenAL32/alListener.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alListener.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alListener.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alSource.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/alSource.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_8) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alSource.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alSource.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c - -CMakeFiles/openal.dir/OpenAL32/alSource.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alSource.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c > CMakeFiles/openal.dir/OpenAL32/alSource.i - -CMakeFiles/openal.dir/OpenAL32/alSource.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alSource.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c -o CMakeFiles/openal.dir/OpenAL32/alSource.s - -CMakeFiles/openal.dir/OpenAL32/alSource.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alSource.o.requires - -CMakeFiles/openal.dir/OpenAL32/alSource.o.provides: CMakeFiles/openal.dir/OpenAL32/alSource.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alSource.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alSource.o.provides - -CMakeFiles/openal.dir/OpenAL32/alSource.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alSource.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alSource.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alState.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/alState.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_9) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alState.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alState.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c - -CMakeFiles/openal.dir/OpenAL32/alState.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alState.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c > CMakeFiles/openal.dir/OpenAL32/alState.i - -CMakeFiles/openal.dir/OpenAL32/alState.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alState.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c -o CMakeFiles/openal.dir/OpenAL32/alState.s - -CMakeFiles/openal.dir/OpenAL32/alState.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alState.o.requires - -CMakeFiles/openal.dir/OpenAL32/alState.o.provides: CMakeFiles/openal.dir/OpenAL32/alState.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alState.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alState.o.provides - -CMakeFiles/openal.dir/OpenAL32/alState.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alState.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alState.o.provides.build - -CMakeFiles/openal.dir/OpenAL32/alThunk.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/alThunk.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_10) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/OpenAL32/alThunk.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/OpenAL32/alThunk.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c - -CMakeFiles/openal.dir/OpenAL32/alThunk.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/OpenAL32/alThunk.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c > CMakeFiles/openal.dir/OpenAL32/alThunk.i - -CMakeFiles/openal.dir/OpenAL32/alThunk.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/OpenAL32/alThunk.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c -o CMakeFiles/openal.dir/OpenAL32/alThunk.s - -CMakeFiles/openal.dir/OpenAL32/alThunk.o.requires: -.PHONY : CMakeFiles/openal.dir/OpenAL32/alThunk.o.requires - -CMakeFiles/openal.dir/OpenAL32/alThunk.o.provides: CMakeFiles/openal.dir/OpenAL32/alThunk.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alThunk.o.provides.build -.PHONY : CMakeFiles/openal.dir/OpenAL32/alThunk.o.provides - -CMakeFiles/openal.dir/OpenAL32/alThunk.o.provides.build: CMakeFiles/openal.dir/OpenAL32/alThunk.o -.PHONY : CMakeFiles/openal.dir/OpenAL32/alThunk.o.provides.build - -CMakeFiles/openal.dir/Alc/ALc.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/ALc.o: Alc/ALc.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_11) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/ALc.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/ALc.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c - -CMakeFiles/openal.dir/Alc/ALc.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/ALc.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c > CMakeFiles/openal.dir/Alc/ALc.i - -CMakeFiles/openal.dir/Alc/ALc.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/ALc.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c -o CMakeFiles/openal.dir/Alc/ALc.s - -CMakeFiles/openal.dir/Alc/ALc.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/ALc.o.requires - -CMakeFiles/openal.dir/Alc/ALc.o.provides: CMakeFiles/openal.dir/Alc/ALc.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALc.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/ALc.o.provides - -CMakeFiles/openal.dir/Alc/ALc.o.provides.build: CMakeFiles/openal.dir/Alc/ALc.o -.PHONY : CMakeFiles/openal.dir/Alc/ALc.o.provides.build - -CMakeFiles/openal.dir/Alc/ALu.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/ALu.o: Alc/ALu.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_12) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/ALu.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/ALu.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c - -CMakeFiles/openal.dir/Alc/ALu.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/ALu.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c > CMakeFiles/openal.dir/Alc/ALu.i - -CMakeFiles/openal.dir/Alc/ALu.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/ALu.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c -o CMakeFiles/openal.dir/Alc/ALu.s - -CMakeFiles/openal.dir/Alc/ALu.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/ALu.o.requires - -CMakeFiles/openal.dir/Alc/ALu.o.provides: CMakeFiles/openal.dir/Alc/ALu.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALu.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/ALu.o.provides - -CMakeFiles/openal.dir/Alc/ALu.o.provides.build: CMakeFiles/openal.dir/Alc/ALu.o -.PHONY : CMakeFiles/openal.dir/Alc/ALu.o.provides.build - -CMakeFiles/openal.dir/Alc/alcConfig.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcConfig.o: Alc/alcConfig.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_13) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcConfig.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcConfig.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c - -CMakeFiles/openal.dir/Alc/alcConfig.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcConfig.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c > CMakeFiles/openal.dir/Alc/alcConfig.i - -CMakeFiles/openal.dir/Alc/alcConfig.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcConfig.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c -o CMakeFiles/openal.dir/Alc/alcConfig.s - -CMakeFiles/openal.dir/Alc/alcConfig.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcConfig.o.requires - -CMakeFiles/openal.dir/Alc/alcConfig.o.provides: CMakeFiles/openal.dir/Alc/alcConfig.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcConfig.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcConfig.o.provides - -CMakeFiles/openal.dir/Alc/alcConfig.o.provides.build: CMakeFiles/openal.dir/Alc/alcConfig.o -.PHONY : CMakeFiles/openal.dir/Alc/alcConfig.o.provides.build - -CMakeFiles/openal.dir/Alc/alcDedicated.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcDedicated.o: Alc/alcDedicated.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_14) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcDedicated.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcDedicated.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c - -CMakeFiles/openal.dir/Alc/alcDedicated.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcDedicated.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c > CMakeFiles/openal.dir/Alc/alcDedicated.i - -CMakeFiles/openal.dir/Alc/alcDedicated.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcDedicated.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c -o CMakeFiles/openal.dir/Alc/alcDedicated.s - -CMakeFiles/openal.dir/Alc/alcDedicated.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcDedicated.o.requires - -CMakeFiles/openal.dir/Alc/alcDedicated.o.provides: CMakeFiles/openal.dir/Alc/alcDedicated.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcDedicated.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcDedicated.o.provides - -CMakeFiles/openal.dir/Alc/alcDedicated.o.provides.build: CMakeFiles/openal.dir/Alc/alcDedicated.o -.PHONY : CMakeFiles/openal.dir/Alc/alcDedicated.o.provides.build - -CMakeFiles/openal.dir/Alc/alcEcho.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcEcho.o: Alc/alcEcho.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_15) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcEcho.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcEcho.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c - -CMakeFiles/openal.dir/Alc/alcEcho.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcEcho.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c > CMakeFiles/openal.dir/Alc/alcEcho.i - -CMakeFiles/openal.dir/Alc/alcEcho.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcEcho.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c -o CMakeFiles/openal.dir/Alc/alcEcho.s - -CMakeFiles/openal.dir/Alc/alcEcho.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcEcho.o.requires - -CMakeFiles/openal.dir/Alc/alcEcho.o.provides: CMakeFiles/openal.dir/Alc/alcEcho.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcEcho.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcEcho.o.provides - -CMakeFiles/openal.dir/Alc/alcEcho.o.provides.build: CMakeFiles/openal.dir/Alc/alcEcho.o -.PHONY : CMakeFiles/openal.dir/Alc/alcEcho.o.provides.build - -CMakeFiles/openal.dir/Alc/alcModulator.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcModulator.o: Alc/alcModulator.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_16) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcModulator.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcModulator.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c - -CMakeFiles/openal.dir/Alc/alcModulator.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcModulator.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c > CMakeFiles/openal.dir/Alc/alcModulator.i - -CMakeFiles/openal.dir/Alc/alcModulator.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcModulator.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c -o CMakeFiles/openal.dir/Alc/alcModulator.s - -CMakeFiles/openal.dir/Alc/alcModulator.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcModulator.o.requires - -CMakeFiles/openal.dir/Alc/alcModulator.o.provides: CMakeFiles/openal.dir/Alc/alcModulator.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcModulator.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcModulator.o.provides - -CMakeFiles/openal.dir/Alc/alcModulator.o.provides.build: CMakeFiles/openal.dir/Alc/alcModulator.o -.PHONY : CMakeFiles/openal.dir/Alc/alcModulator.o.provides.build - -CMakeFiles/openal.dir/Alc/alcReverb.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcReverb.o: Alc/alcReverb.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_17) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcReverb.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcReverb.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c - -CMakeFiles/openal.dir/Alc/alcReverb.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcReverb.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c > CMakeFiles/openal.dir/Alc/alcReverb.i - -CMakeFiles/openal.dir/Alc/alcReverb.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcReverb.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c -o CMakeFiles/openal.dir/Alc/alcReverb.s - -CMakeFiles/openal.dir/Alc/alcReverb.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcReverb.o.requires - -CMakeFiles/openal.dir/Alc/alcReverb.o.provides: CMakeFiles/openal.dir/Alc/alcReverb.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcReverb.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcReverb.o.provides - -CMakeFiles/openal.dir/Alc/alcReverb.o.provides.build: CMakeFiles/openal.dir/Alc/alcReverb.o -.PHONY : CMakeFiles/openal.dir/Alc/alcReverb.o.provides.build - -CMakeFiles/openal.dir/Alc/alcRing.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcRing.o: Alc/alcRing.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_18) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcRing.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcRing.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c - -CMakeFiles/openal.dir/Alc/alcRing.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcRing.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c > CMakeFiles/openal.dir/Alc/alcRing.i - -CMakeFiles/openal.dir/Alc/alcRing.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcRing.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c -o CMakeFiles/openal.dir/Alc/alcRing.s - -CMakeFiles/openal.dir/Alc/alcRing.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcRing.o.requires - -CMakeFiles/openal.dir/Alc/alcRing.o.provides: CMakeFiles/openal.dir/Alc/alcRing.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcRing.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcRing.o.provides - -CMakeFiles/openal.dir/Alc/alcRing.o.provides.build: CMakeFiles/openal.dir/Alc/alcRing.o -.PHONY : CMakeFiles/openal.dir/Alc/alcRing.o.provides.build - -CMakeFiles/openal.dir/Alc/alcThread.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/alcThread.o: Alc/alcThread.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_19) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/alcThread.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/alcThread.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c - -CMakeFiles/openal.dir/Alc/alcThread.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/alcThread.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c > CMakeFiles/openal.dir/Alc/alcThread.i - -CMakeFiles/openal.dir/Alc/alcThread.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/alcThread.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c -o CMakeFiles/openal.dir/Alc/alcThread.s - -CMakeFiles/openal.dir/Alc/alcThread.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/alcThread.o.requires - -CMakeFiles/openal.dir/Alc/alcThread.o.provides: CMakeFiles/openal.dir/Alc/alcThread.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcThread.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/alcThread.o.provides - -CMakeFiles/openal.dir/Alc/alcThread.o.provides.build: CMakeFiles/openal.dir/Alc/alcThread.o -.PHONY : CMakeFiles/openal.dir/Alc/alcThread.o.provides.build - -CMakeFiles/openal.dir/Alc/bs2b.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/bs2b.o: Alc/bs2b.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_20) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/bs2b.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/bs2b.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c - -CMakeFiles/openal.dir/Alc/bs2b.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/bs2b.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c > CMakeFiles/openal.dir/Alc/bs2b.i - -CMakeFiles/openal.dir/Alc/bs2b.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/bs2b.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c -o CMakeFiles/openal.dir/Alc/bs2b.s - -CMakeFiles/openal.dir/Alc/bs2b.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/bs2b.o.requires - -CMakeFiles/openal.dir/Alc/bs2b.o.provides: CMakeFiles/openal.dir/Alc/bs2b.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/bs2b.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/bs2b.o.provides - -CMakeFiles/openal.dir/Alc/bs2b.o.provides.build: CMakeFiles/openal.dir/Alc/bs2b.o -.PHONY : CMakeFiles/openal.dir/Alc/bs2b.o.provides.build - -CMakeFiles/openal.dir/Alc/helpers.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/helpers.o: Alc/helpers.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_21) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/helpers.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/helpers.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c - -CMakeFiles/openal.dir/Alc/helpers.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/helpers.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c > CMakeFiles/openal.dir/Alc/helpers.i - -CMakeFiles/openal.dir/Alc/helpers.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/helpers.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c -o CMakeFiles/openal.dir/Alc/helpers.s - -CMakeFiles/openal.dir/Alc/helpers.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/helpers.o.requires - -CMakeFiles/openal.dir/Alc/helpers.o.provides: CMakeFiles/openal.dir/Alc/helpers.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/helpers.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/helpers.o.provides - -CMakeFiles/openal.dir/Alc/helpers.o.provides.build: CMakeFiles/openal.dir/Alc/helpers.o -.PHONY : CMakeFiles/openal.dir/Alc/helpers.o.provides.build - -CMakeFiles/openal.dir/Alc/hrtf.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/hrtf.o: Alc/hrtf.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_22) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/hrtf.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/hrtf.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c - -CMakeFiles/openal.dir/Alc/hrtf.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/hrtf.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c > CMakeFiles/openal.dir/Alc/hrtf.i - -CMakeFiles/openal.dir/Alc/hrtf.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/hrtf.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c -o CMakeFiles/openal.dir/Alc/hrtf.s - -CMakeFiles/openal.dir/Alc/hrtf.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/hrtf.o.requires - -CMakeFiles/openal.dir/Alc/hrtf.o.provides: CMakeFiles/openal.dir/Alc/hrtf.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/hrtf.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/hrtf.o.provides - -CMakeFiles/openal.dir/Alc/hrtf.o.provides.build: CMakeFiles/openal.dir/Alc/hrtf.o -.PHONY : CMakeFiles/openal.dir/Alc/hrtf.o.provides.build - -CMakeFiles/openal.dir/Alc/mixer.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/mixer.o: Alc/mixer.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_23) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/mixer.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/mixer.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c - -CMakeFiles/openal.dir/Alc/mixer.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/mixer.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c > CMakeFiles/openal.dir/Alc/mixer.i - -CMakeFiles/openal.dir/Alc/mixer.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/mixer.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c -o CMakeFiles/openal.dir/Alc/mixer.s - -CMakeFiles/openal.dir/Alc/mixer.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/mixer.o.requires - -CMakeFiles/openal.dir/Alc/mixer.o.provides: CMakeFiles/openal.dir/Alc/mixer.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/mixer.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/mixer.o.provides - -CMakeFiles/openal.dir/Alc/mixer.o.provides.build: CMakeFiles/openal.dir/Alc/mixer.o -.PHONY : CMakeFiles/openal.dir/Alc/mixer.o.provides.build - -CMakeFiles/openal.dir/Alc/panning.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/panning.o: Alc/panning.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_24) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/panning.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/panning.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c - -CMakeFiles/openal.dir/Alc/panning.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/panning.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c > CMakeFiles/openal.dir/Alc/panning.i - -CMakeFiles/openal.dir/Alc/panning.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/panning.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c -o CMakeFiles/openal.dir/Alc/panning.s - -CMakeFiles/openal.dir/Alc/panning.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/panning.o.requires - -CMakeFiles/openal.dir/Alc/panning.o.provides: CMakeFiles/openal.dir/Alc/panning.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/panning.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/panning.o.provides - -CMakeFiles/openal.dir/Alc/panning.o.provides.build: CMakeFiles/openal.dir/Alc/panning.o -.PHONY : CMakeFiles/openal.dir/Alc/panning.o.provides.build - -CMakeFiles/openal.dir/Alc/backends/loopback.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/backends/loopback.o: Alc/backends/loopback.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_25) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/backends/loopback.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/backends/loopback.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c - -CMakeFiles/openal.dir/Alc/backends/loopback.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/backends/loopback.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c > CMakeFiles/openal.dir/Alc/backends/loopback.i - -CMakeFiles/openal.dir/Alc/backends/loopback.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/backends/loopback.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c -o CMakeFiles/openal.dir/Alc/backends/loopback.s - -CMakeFiles/openal.dir/Alc/backends/loopback.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/backends/loopback.o.requires - -CMakeFiles/openal.dir/Alc/backends/loopback.o.provides: CMakeFiles/openal.dir/Alc/backends/loopback.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/loopback.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/backends/loopback.o.provides - -CMakeFiles/openal.dir/Alc/backends/loopback.o.provides.build: CMakeFiles/openal.dir/Alc/backends/loopback.o -.PHONY : CMakeFiles/openal.dir/Alc/backends/loopback.o.provides.build - -CMakeFiles/openal.dir/Alc/backends/null.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/backends/null.o: Alc/backends/null.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_26) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/backends/null.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/backends/null.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c - -CMakeFiles/openal.dir/Alc/backends/null.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/backends/null.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c > CMakeFiles/openal.dir/Alc/backends/null.i - -CMakeFiles/openal.dir/Alc/backends/null.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/backends/null.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c -o CMakeFiles/openal.dir/Alc/backends/null.s - -CMakeFiles/openal.dir/Alc/backends/null.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/backends/null.o.requires - -CMakeFiles/openal.dir/Alc/backends/null.o.provides: CMakeFiles/openal.dir/Alc/backends/null.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/null.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/backends/null.o.provides - -CMakeFiles/openal.dir/Alc/backends/null.o.provides.build: CMakeFiles/openal.dir/Alc/backends/null.o -.PHONY : CMakeFiles/openal.dir/Alc/backends/null.o.provides.build - -CMakeFiles/openal.dir/Alc/backends/android.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/backends/android.o: Alc/backends/android.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_27) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/backends/android.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/backends/android.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c - -CMakeFiles/openal.dir/Alc/backends/android.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/backends/android.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c > CMakeFiles/openal.dir/Alc/backends/android.i - -CMakeFiles/openal.dir/Alc/backends/android.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/backends/android.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c -o CMakeFiles/openal.dir/Alc/backends/android.s - -CMakeFiles/openal.dir/Alc/backends/android.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/backends/android.o.requires - -CMakeFiles/openal.dir/Alc/backends/android.o.provides: CMakeFiles/openal.dir/Alc/backends/android.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/android.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/backends/android.o.provides - -CMakeFiles/openal.dir/Alc/backends/android.o.provides.build: CMakeFiles/openal.dir/Alc/backends/android.o -.PHONY : CMakeFiles/openal.dir/Alc/backends/android.o.provides.build - -CMakeFiles/openal.dir/Alc/backends/wave.o: CMakeFiles/openal.dir/flags.make -CMakeFiles/openal.dir/Alc/backends/wave.o: Alc/backends/wave.c - $(CMAKE_COMMAND) -E cmake_progress_report /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles $(CMAKE_PROGRESS_28) - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Building C object CMakeFiles/openal.dir/Alc/backends/wave.o" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -o CMakeFiles/openal.dir/Alc/backends/wave.o -c /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c - -CMakeFiles/openal.dir/Alc/backends/wave.i: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Preprocessing C source to CMakeFiles/openal.dir/Alc/backends/wave.i" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -E /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c > CMakeFiles/openal.dir/Alc/backends/wave.i - -CMakeFiles/openal.dir/Alc/backends/wave.s: cmake_force - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green "Compiling C source to assembly CMakeFiles/openal.dir/Alc/backends/wave.s" - /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc $(C_DEFINES) $(C_FLAGS) -DAL_ALEXT_PROTOTYPES -S /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c -o CMakeFiles/openal.dir/Alc/backends/wave.s - -CMakeFiles/openal.dir/Alc/backends/wave.o.requires: -.PHONY : CMakeFiles/openal.dir/Alc/backends/wave.o.requires - -CMakeFiles/openal.dir/Alc/backends/wave.o.provides: CMakeFiles/openal.dir/Alc/backends/wave.o.requires - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/wave.o.provides.build -.PHONY : CMakeFiles/openal.dir/Alc/backends/wave.o.provides - -CMakeFiles/openal.dir/Alc/backends/wave.o.provides.build: CMakeFiles/openal.dir/Alc/backends/wave.o -.PHONY : CMakeFiles/openal.dir/Alc/backends/wave.o.provides.build - -# Object files for target openal -openal_OBJECTS = \ -"CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o" \ -"CMakeFiles/openal.dir/OpenAL32/alBuffer.o" \ -"CMakeFiles/openal.dir/OpenAL32/alEffect.o" \ -"CMakeFiles/openal.dir/OpenAL32/alError.o" \ -"CMakeFiles/openal.dir/OpenAL32/alExtension.o" \ -"CMakeFiles/openal.dir/OpenAL32/alFilter.o" \ -"CMakeFiles/openal.dir/OpenAL32/alListener.o" \ -"CMakeFiles/openal.dir/OpenAL32/alSource.o" \ -"CMakeFiles/openal.dir/OpenAL32/alState.o" \ -"CMakeFiles/openal.dir/OpenAL32/alThunk.o" \ -"CMakeFiles/openal.dir/Alc/ALc.o" \ -"CMakeFiles/openal.dir/Alc/ALu.o" \ -"CMakeFiles/openal.dir/Alc/alcConfig.o" \ -"CMakeFiles/openal.dir/Alc/alcDedicated.o" \ -"CMakeFiles/openal.dir/Alc/alcEcho.o" \ -"CMakeFiles/openal.dir/Alc/alcModulator.o" \ -"CMakeFiles/openal.dir/Alc/alcReverb.o" \ -"CMakeFiles/openal.dir/Alc/alcRing.o" \ -"CMakeFiles/openal.dir/Alc/alcThread.o" \ -"CMakeFiles/openal.dir/Alc/bs2b.o" \ -"CMakeFiles/openal.dir/Alc/helpers.o" \ -"CMakeFiles/openal.dir/Alc/hrtf.o" \ -"CMakeFiles/openal.dir/Alc/mixer.o" \ -"CMakeFiles/openal.dir/Alc/panning.o" \ -"CMakeFiles/openal.dir/Alc/backends/loopback.o" \ -"CMakeFiles/openal.dir/Alc/backends/null.o" \ -"CMakeFiles/openal.dir/Alc/backends/android.o" \ -"CMakeFiles/openal.dir/Alc/backends/wave.o" - -# External object files for target openal -openal_EXTERNAL_OBJECTS = - -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alBuffer.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alEffect.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alError.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alExtension.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alFilter.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alListener.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alSource.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alState.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alThunk.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/ALc.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/ALu.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcConfig.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcDedicated.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcEcho.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcModulator.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcReverb.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcRing.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcThread.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/bs2b.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/helpers.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/hrtf.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/mixer.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/panning.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/loopback.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/null.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/android.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/wave.o -libopenal.so.1.13.0: CMakeFiles/openal.dir/build.make -libopenal.so.1.13.0: CMakeFiles/openal.dir/link.txt - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C shared library libopenal.so" - $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/openal.dir/link.txt --verbose=$(VERBOSE) - $(CMAKE_COMMAND) -E cmake_symlink_library libopenal.so.1.13.0 libopenal.so.1 libopenal.so - -libopenal.so.1: libopenal.so.1.13.0 - -libopenal.so: libopenal.so.1.13.0 - -# Rule to build all files generated by this target. -CMakeFiles/openal.dir/build: libopenal.so -.PHONY : CMakeFiles/openal.dir/build - -# Object files for target openal -openal_OBJECTS = \ -"CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o" \ -"CMakeFiles/openal.dir/OpenAL32/alBuffer.o" \ -"CMakeFiles/openal.dir/OpenAL32/alEffect.o" \ -"CMakeFiles/openal.dir/OpenAL32/alError.o" \ -"CMakeFiles/openal.dir/OpenAL32/alExtension.o" \ -"CMakeFiles/openal.dir/OpenAL32/alFilter.o" \ -"CMakeFiles/openal.dir/OpenAL32/alListener.o" \ -"CMakeFiles/openal.dir/OpenAL32/alSource.o" \ -"CMakeFiles/openal.dir/OpenAL32/alState.o" \ -"CMakeFiles/openal.dir/OpenAL32/alThunk.o" \ -"CMakeFiles/openal.dir/Alc/ALc.o" \ -"CMakeFiles/openal.dir/Alc/ALu.o" \ -"CMakeFiles/openal.dir/Alc/alcConfig.o" \ -"CMakeFiles/openal.dir/Alc/alcDedicated.o" \ -"CMakeFiles/openal.dir/Alc/alcEcho.o" \ -"CMakeFiles/openal.dir/Alc/alcModulator.o" \ -"CMakeFiles/openal.dir/Alc/alcReverb.o" \ -"CMakeFiles/openal.dir/Alc/alcRing.o" \ -"CMakeFiles/openal.dir/Alc/alcThread.o" \ -"CMakeFiles/openal.dir/Alc/bs2b.o" \ -"CMakeFiles/openal.dir/Alc/helpers.o" \ -"CMakeFiles/openal.dir/Alc/hrtf.o" \ -"CMakeFiles/openal.dir/Alc/mixer.o" \ -"CMakeFiles/openal.dir/Alc/panning.o" \ -"CMakeFiles/openal.dir/Alc/backends/loopback.o" \ -"CMakeFiles/openal.dir/Alc/backends/null.o" \ -"CMakeFiles/openal.dir/Alc/backends/android.o" \ -"CMakeFiles/openal.dir/Alc/backends/wave.o" - -# External object files for target openal -openal_EXTERNAL_OBJECTS = - -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alBuffer.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alEffect.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alError.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alExtension.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alFilter.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alListener.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alSource.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alState.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/OpenAL32/alThunk.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/ALc.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/ALu.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcConfig.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcDedicated.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcEcho.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcModulator.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcReverb.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcRing.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/alcThread.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/bs2b.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/helpers.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/hrtf.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/mixer.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/panning.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/loopback.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/null.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/android.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/Alc/backends/wave.o -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/build.make -CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0: CMakeFiles/openal.dir/relink.txt - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red --bold "Linking C shared library CMakeFiles/CMakeRelink.dir/libopenal.so" - $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/openal.dir/relink.txt --verbose=$(VERBOSE) - $(CMAKE_COMMAND) -E cmake_symlink_library CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0 CMakeFiles/CMakeRelink.dir/libopenal.so.1 CMakeFiles/CMakeRelink.dir/libopenal.so - -CMakeFiles/CMakeRelink.dir/libopenal.so.1: CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0 - -CMakeFiles/CMakeRelink.dir/libopenal.so: CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0 - -# Rule to relink during preinstall. -CMakeFiles/openal.dir/preinstall: CMakeFiles/CMakeRelink.dir/libopenal.so -.PHONY : CMakeFiles/openal.dir/preinstall - -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alBuffer.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alEffect.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alError.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alExtension.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alFilter.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alListener.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alSource.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alState.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/OpenAL32/alThunk.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/ALc.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/ALu.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcConfig.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcDedicated.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcEcho.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcModulator.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcReverb.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcRing.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/alcThread.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/bs2b.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/helpers.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/hrtf.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/mixer.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/panning.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/backends/loopback.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/backends/null.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/backends/android.o.requires -CMakeFiles/openal.dir/requires: CMakeFiles/openal.dir/Alc/backends/wave.o.requires -.PHONY : CMakeFiles/openal.dir/requires - -CMakeFiles/openal.dir/clean: - $(CMAKE_COMMAND) -P CMakeFiles/openal.dir/cmake_clean.cmake -.PHONY : CMakeFiles/openal.dir/clean - -CMakeFiles/openal.dir/depend: - cd /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/openal.dir/DependInfo.cmake --color=$(COLOR) -.PHONY : CMakeFiles/openal.dir/depend - diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/cmake_clean.cmake b/jni/openal-soft-android/CMakeFiles/openal.dir/cmake_clean.cmake deleted file mode 100644 index 23e3053c..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/cmake_clean.cmake +++ /dev/null @@ -1,43 +0,0 @@ -FILE(REMOVE_RECURSE - "CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o" - "CMakeFiles/openal.dir/OpenAL32/alBuffer.o" - "CMakeFiles/openal.dir/OpenAL32/alEffect.o" - "CMakeFiles/openal.dir/OpenAL32/alError.o" - "CMakeFiles/openal.dir/OpenAL32/alExtension.o" - "CMakeFiles/openal.dir/OpenAL32/alFilter.o" - "CMakeFiles/openal.dir/OpenAL32/alListener.o" - "CMakeFiles/openal.dir/OpenAL32/alSource.o" - "CMakeFiles/openal.dir/OpenAL32/alState.o" - "CMakeFiles/openal.dir/OpenAL32/alThunk.o" - "CMakeFiles/openal.dir/Alc/ALc.o" - "CMakeFiles/openal.dir/Alc/ALu.o" - "CMakeFiles/openal.dir/Alc/alcConfig.o" - "CMakeFiles/openal.dir/Alc/alcDedicated.o" - "CMakeFiles/openal.dir/Alc/alcEcho.o" - "CMakeFiles/openal.dir/Alc/alcModulator.o" - "CMakeFiles/openal.dir/Alc/alcReverb.o" - "CMakeFiles/openal.dir/Alc/alcRing.o" - "CMakeFiles/openal.dir/Alc/alcThread.o" - "CMakeFiles/openal.dir/Alc/bs2b.o" - "CMakeFiles/openal.dir/Alc/helpers.o" - "CMakeFiles/openal.dir/Alc/hrtf.o" - "CMakeFiles/openal.dir/Alc/mixer.o" - "CMakeFiles/openal.dir/Alc/panning.o" - "CMakeFiles/openal.dir/Alc/backends/loopback.o" - "CMakeFiles/openal.dir/Alc/backends/null.o" - "CMakeFiles/openal.dir/Alc/backends/android.o" - "CMakeFiles/openal.dir/Alc/backends/wave.o" - "libopenal.pdb" - "libopenal.so" - "libopenal.so.1.13.0" - "libopenal.so.1" - "CMakeFiles/CMakeRelink.dir/libopenal.pdb" - "CMakeFiles/CMakeRelink.dir/libopenal.so" - "CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0" - "CMakeFiles/CMakeRelink.dir/libopenal.so.1" -) - -# Per-language clean rules from dependency scanning. -FOREACH(lang C) - INCLUDE(CMakeFiles/openal.dir/cmake_clean_${lang}.cmake OPTIONAL) -ENDFOREACH(lang) diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/depend.internal b/jni/openal-soft-android/CMakeFiles/openal.dir/depend.internal deleted file mode 100644 index bb6d0c7e..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/depend.internal +++ /dev/null @@ -1,491 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -CMakeFiles/openal.dir/Alc/ALc.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALc.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - OpenAL32/Include/bs2b.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/ALu.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/ALu.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alu.h - OpenAL32/Include/bs2b.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcConfig.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcConfig.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcDedicated.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcDedicated.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcEcho.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcEcho.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcModulator.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcModulator.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcReverb.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcReverb.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcRing.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcRing.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/alcThread.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/alcThread.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/backends/android.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/android.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/backends/loopback.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/loopback.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/backends/null.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/null.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/backends/wave.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/backends/wave.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/bs2b.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/bs2b.c - OpenAL32/Include/bs2b.h - config.h -CMakeFiles/openal.dir/Alc/helpers.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/helpers.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/hrtf.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf.c - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/hrtf_tables.inc - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/mixer.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/mixer.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alu.h - OpenAL32/Include/bs2b.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/Alc/panning.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/Alc/panning.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alBuffer.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alError.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alEffect.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alError.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alError.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alError.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alExtension.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alFilter.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alListener.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alListener.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alSource.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alSource.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alBuffer.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alState.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alState.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alAuxEffectSlot.h - OpenAL32/Include/alEffect.h - OpenAL32/Include/alError.h - OpenAL32/Include/alFilter.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alSource.h - OpenAL32/Include/alState.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o - /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/alThunk.c - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h - /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h - OpenAL32/Include/alListener.h - OpenAL32/Include/alMain.h - OpenAL32/Include/alThunk.h - OpenAL32/Include/alu.h - config.h - include/AL/al.h - include/AL/alc.h - include/AL/alext.h - include/AL/efx.h diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/depend.make b/jni/openal-soft-android/CMakeFiles/openal.dir/depend.make deleted file mode 100644 index af7e34c8..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/depend.make +++ /dev/null @@ -1,491 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -CMakeFiles/openal.dir/Alc/ALc.o: Alc/ALc.c -CMakeFiles/openal.dir/Alc/ALc.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/ALc.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/ALc.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/ALc.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/ALc.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/ALc.o: OpenAL32/Include/bs2b.h -CMakeFiles/openal.dir/Alc/ALc.o: config.h -CMakeFiles/openal.dir/Alc/ALc.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/ALc.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/ALc.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/ALc.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/ALu.o: Alc/ALu.c -CMakeFiles/openal.dir/Alc/ALu.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/ALu.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/ALu.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/ALu.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/ALu.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/ALu.o: OpenAL32/Include/bs2b.h -CMakeFiles/openal.dir/Alc/ALu.o: config.h -CMakeFiles/openal.dir/Alc/ALu.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/ALu.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/ALu.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/ALu.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcConfig.o: Alc/alcConfig.c -CMakeFiles/openal.dir/Alc/alcConfig.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcConfig.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcConfig.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcConfig.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcConfig.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcConfig.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcConfig.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcConfig.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcConfig.o: config.h -CMakeFiles/openal.dir/Alc/alcConfig.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcConfig.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcConfig.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcConfig.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcDedicated.o: Alc/alcDedicated.c -CMakeFiles/openal.dir/Alc/alcDedicated.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcDedicated.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: config.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcDedicated.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcEcho.o: Alc/alcEcho.c -CMakeFiles/openal.dir/Alc/alcEcho.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcEcho.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcEcho.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcEcho.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcEcho.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcEcho.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcEcho.o: config.h -CMakeFiles/openal.dir/Alc/alcEcho.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcEcho.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcEcho.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcEcho.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcModulator.o: Alc/alcModulator.c -CMakeFiles/openal.dir/Alc/alcModulator.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcModulator.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcModulator.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcModulator.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcModulator.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcModulator.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcModulator.o: config.h -CMakeFiles/openal.dir/Alc/alcModulator.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcModulator.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcModulator.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcModulator.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcReverb.o: Alc/alcReverb.c -CMakeFiles/openal.dir/Alc/alcReverb.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcReverb.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcReverb.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcReverb.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcReverb.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcReverb.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcReverb.o: config.h -CMakeFiles/openal.dir/Alc/alcReverb.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcReverb.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcReverb.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcReverb.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcRing.o: Alc/alcRing.c -CMakeFiles/openal.dir/Alc/alcRing.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcRing.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcRing.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcRing.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcRing.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcRing.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcRing.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcRing.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcRing.o: config.h -CMakeFiles/openal.dir/Alc/alcRing.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcRing.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcRing.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcRing.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/alcThread.o: Alc/alcThread.c -CMakeFiles/openal.dir/Alc/alcThread.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/alcThread.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/alcThread.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/alcThread.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/alcThread.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/alcThread.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/alcThread.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/alcThread.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/Alc/alcThread.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/alcThread.o: config.h -CMakeFiles/openal.dir/Alc/alcThread.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/alcThread.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/alcThread.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/alcThread.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/backends/android.o: Alc/backends/android.c -CMakeFiles/openal.dir/Alc/backends/android.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/backends/android.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/backends/android.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/backends/android.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/backends/android.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/backends/android.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/backends/android.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/backends/android.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/backends/android.o: config.h -CMakeFiles/openal.dir/Alc/backends/android.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/backends/android.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/backends/android.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/backends/android.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/backends/loopback.o: Alc/backends/loopback.c -CMakeFiles/openal.dir/Alc/backends/loopback.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/backends/loopback.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: config.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/backends/loopback.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/backends/null.o: Alc/backends/null.c -CMakeFiles/openal.dir/Alc/backends/null.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/backends/null.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/backends/null.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/backends/null.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/backends/null.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/backends/null.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/backends/null.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/backends/null.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/backends/null.o: config.h -CMakeFiles/openal.dir/Alc/backends/null.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/backends/null.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/backends/null.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/backends/null.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/backends/wave.o: Alc/backends/wave.c -CMakeFiles/openal.dir/Alc/backends/wave.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/backends/wave.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/backends/wave.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/backends/wave.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/backends/wave.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/backends/wave.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/backends/wave.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/backends/wave.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/backends/wave.o: config.h -CMakeFiles/openal.dir/Alc/backends/wave.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/backends/wave.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/backends/wave.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/backends/wave.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/bs2b.o: Alc/bs2b.c -CMakeFiles/openal.dir/Alc/bs2b.o: OpenAL32/Include/bs2b.h -CMakeFiles/openal.dir/Alc/bs2b.o: config.h - -CMakeFiles/openal.dir/Alc/helpers.o: Alc/helpers.c -CMakeFiles/openal.dir/Alc/helpers.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/helpers.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/helpers.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/helpers.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/helpers.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/helpers.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/helpers.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/helpers.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/helpers.o: config.h -CMakeFiles/openal.dir/Alc/helpers.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/helpers.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/helpers.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/helpers.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/hrtf.o: Alc/hrtf.c -CMakeFiles/openal.dir/Alc/hrtf.o: Alc/hrtf_tables.inc -CMakeFiles/openal.dir/Alc/hrtf.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/hrtf.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/hrtf.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/hrtf.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/hrtf.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/hrtf.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/hrtf.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/hrtf.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/hrtf.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/Alc/hrtf.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/hrtf.o: config.h -CMakeFiles/openal.dir/Alc/hrtf.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/hrtf.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/hrtf.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/hrtf.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/mixer.o: Alc/mixer.c -CMakeFiles/openal.dir/Alc/mixer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/mixer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/mixer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/mixer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/mixer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/mixer.o: OpenAL32/Include/bs2b.h -CMakeFiles/openal.dir/Alc/mixer.o: config.h -CMakeFiles/openal.dir/Alc/mixer.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/mixer.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/mixer.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/mixer.o: include/AL/efx.h - -CMakeFiles/openal.dir/Alc/panning.o: Alc/panning.c -CMakeFiles/openal.dir/Alc/panning.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/Alc/panning.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/Alc/panning.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/Alc/panning.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/Alc/panning.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/Alc/panning.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/Alc/panning.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/Alc/panning.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/Alc/panning.o: config.h -CMakeFiles/openal.dir/Alc/panning.o: include/AL/al.h -CMakeFiles/openal.dir/Alc/panning.o: include/AL/alc.h -CMakeFiles/openal.dir/Alc/panning.o: include/AL/alext.h -CMakeFiles/openal.dir/Alc/panning.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/alAuxEffectSlot.c -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: config.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/alBuffer.c -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: config.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alBuffer.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/alEffect.c -CMakeFiles/openal.dir/OpenAL32/alEffect.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alEffect.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: config.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alEffect.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/alError.c -CMakeFiles/openal.dir/OpenAL32/alError.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alError.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alError.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alError.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alError.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alError.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alError.o: config.h -CMakeFiles/openal.dir/OpenAL32/alError.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alError.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alError.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alError.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/alExtension.c -CMakeFiles/openal.dir/OpenAL32/alExtension.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alExtension.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: config.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alExtension.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/alFilter.c -CMakeFiles/openal.dir/OpenAL32/alFilter.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alFilter.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: config.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alFilter.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/alListener.c -CMakeFiles/openal.dir/OpenAL32/alListener.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alListener.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: config.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alListener.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/alSource.c -CMakeFiles/openal.dir/OpenAL32/alSource.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alSource.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alBuffer.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: config.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alSource.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/alState.c -CMakeFiles/openal.dir/OpenAL32/alState.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alState.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alState.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alState.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alState.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alAuxEffectSlot.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alEffect.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alError.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alFilter.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alSource.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alState.h -CMakeFiles/openal.dir/OpenAL32/alState.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alState.o: config.h -CMakeFiles/openal.dir/OpenAL32/alState.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alState.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alState.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alState.o: include/AL/efx.h - -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/alThunk.c -CMakeFiles/openal.dir/OpenAL32/alThunk.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/fenv.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include/tr1_impl/cfenv -CMakeFiles/openal.dir/OpenAL32/alThunk.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/c++config.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/cpu_defines.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: /opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include/bits/os_defines.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/Include/alListener.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/Include/alMain.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/Include/alThunk.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: OpenAL32/Include/alu.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: config.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: include/AL/al.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: include/AL/alc.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: include/AL/alext.h -CMakeFiles/openal.dir/OpenAL32/alThunk.o: include/AL/efx.h - diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/flags.make b/jni/openal-soft-android/CMakeFiles/openal.dir/flags.make deleted file mode 100644 index 8cb13ff0..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/flags.make +++ /dev/null @@ -1,10 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# compile C with /opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -C_FLAGS = --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -fPIC -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/include -I/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/OpenAL32/Include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include -I/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android -Winline -Wall -Wextra -fvisibility=internal - -C_DEFINES = -DAL_BUILD_LIBRARY -D_GNU_SOURCE=1 - -# TARGET_FLAGS = -DAL_ALEXT_PROTOTYPES - diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/link.txt b/jni/openal-soft-android/CMakeFiles/openal.dir/link.txt deleted file mode 100644 index 1373401f..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/link.txt +++ /dev/null @@ -1 +0,0 @@ -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -fPIC --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ -shared -Wl,-soname,libopenal.so.1 -o libopenal.so.1.13.0 CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o CMakeFiles/openal.dir/OpenAL32/alBuffer.o CMakeFiles/openal.dir/OpenAL32/alEffect.o CMakeFiles/openal.dir/OpenAL32/alError.o CMakeFiles/openal.dir/OpenAL32/alExtension.o CMakeFiles/openal.dir/OpenAL32/alFilter.o CMakeFiles/openal.dir/OpenAL32/alListener.o CMakeFiles/openal.dir/OpenAL32/alSource.o CMakeFiles/openal.dir/OpenAL32/alState.o CMakeFiles/openal.dir/OpenAL32/alThunk.o CMakeFiles/openal.dir/Alc/ALc.o CMakeFiles/openal.dir/Alc/ALu.o CMakeFiles/openal.dir/Alc/alcConfig.o CMakeFiles/openal.dir/Alc/alcDedicated.o CMakeFiles/openal.dir/Alc/alcEcho.o CMakeFiles/openal.dir/Alc/alcModulator.o CMakeFiles/openal.dir/Alc/alcReverb.o CMakeFiles/openal.dir/Alc/alcRing.o CMakeFiles/openal.dir/Alc/alcThread.o CMakeFiles/openal.dir/Alc/bs2b.o CMakeFiles/openal.dir/Alc/helpers.o CMakeFiles/openal.dir/Alc/hrtf.o CMakeFiles/openal.dir/Alc/mixer.o CMakeFiles/openal.dir/Alc/panning.o CMakeFiles/openal.dir/Alc/backends/loopback.o CMakeFiles/openal.dir/Alc/backends/null.o CMakeFiles/openal.dir/Alc/backends/android.o CMakeFiles/openal.dir/Alc/backends/wave.o -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -ldl -lm -Wl,-rpath,/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/progress.make b/jni/openal-soft-android/CMakeFiles/openal.dir/progress.make deleted file mode 100644 index 90381011..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/progress.make +++ /dev/null @@ -1,29 +0,0 @@ -CMAKE_PROGRESS_1 = 1 -CMAKE_PROGRESS_2 = 2 -CMAKE_PROGRESS_3 = 3 -CMAKE_PROGRESS_4 = 4 -CMAKE_PROGRESS_5 = 5 -CMAKE_PROGRESS_6 = 6 -CMAKE_PROGRESS_7 = 7 -CMAKE_PROGRESS_8 = 8 -CMAKE_PROGRESS_9 = 9 -CMAKE_PROGRESS_10 = 10 -CMAKE_PROGRESS_11 = 11 -CMAKE_PROGRESS_12 = 12 -CMAKE_PROGRESS_13 = 13 -CMAKE_PROGRESS_14 = 14 -CMAKE_PROGRESS_15 = 15 -CMAKE_PROGRESS_16 = 16 -CMAKE_PROGRESS_17 = 17 -CMAKE_PROGRESS_18 = 18 -CMAKE_PROGRESS_19 = 19 -CMAKE_PROGRESS_20 = 20 -CMAKE_PROGRESS_21 = 21 -CMAKE_PROGRESS_22 = 22 -CMAKE_PROGRESS_23 = 23 -CMAKE_PROGRESS_24 = 24 -CMAKE_PROGRESS_25 = 25 -CMAKE_PROGRESS_26 = 26 -CMAKE_PROGRESS_27 = 27 -CMAKE_PROGRESS_28 = 28 - diff --git a/jni/openal-soft-android/CMakeFiles/openal.dir/relink.txt b/jni/openal-soft-android/CMakeFiles/openal.dir/relink.txt deleted file mode 100644 index ac64364c..00000000 --- a/jni/openal-soft-android/CMakeFiles/openal.dir/relink.txt +++ /dev/null @@ -1 +0,0 @@ -/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -fPIC --sysroot=/opt/android-ndk-r6/platforms/android-5/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -g -O2 -D_DEBUG -Wl,--fix-cortex-a8 -L"/opt/android-ndk-r6/sources/cxx-stl/gnu-libstdc++/libs/armeabi" -L"/usr/local/libs/armeabi" -lstdc++ -lsupc++ -shared -Wl,-soname,libopenal.so.1 -o CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0 CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o CMakeFiles/openal.dir/OpenAL32/alBuffer.o CMakeFiles/openal.dir/OpenAL32/alEffect.o CMakeFiles/openal.dir/OpenAL32/alError.o CMakeFiles/openal.dir/OpenAL32/alExtension.o CMakeFiles/openal.dir/OpenAL32/alFilter.o CMakeFiles/openal.dir/OpenAL32/alListener.o CMakeFiles/openal.dir/OpenAL32/alSource.o CMakeFiles/openal.dir/OpenAL32/alState.o CMakeFiles/openal.dir/OpenAL32/alThunk.o CMakeFiles/openal.dir/Alc/ALc.o CMakeFiles/openal.dir/Alc/ALu.o CMakeFiles/openal.dir/Alc/alcConfig.o CMakeFiles/openal.dir/Alc/alcDedicated.o CMakeFiles/openal.dir/Alc/alcEcho.o CMakeFiles/openal.dir/Alc/alcModulator.o CMakeFiles/openal.dir/Alc/alcReverb.o CMakeFiles/openal.dir/Alc/alcRing.o CMakeFiles/openal.dir/Alc/alcThread.o CMakeFiles/openal.dir/Alc/bs2b.o CMakeFiles/openal.dir/Alc/helpers.o CMakeFiles/openal.dir/Alc/hrtf.o CMakeFiles/openal.dir/Alc/mixer.o CMakeFiles/openal.dir/Alc/panning.o CMakeFiles/openal.dir/Alc/backends/loopback.o CMakeFiles/openal.dir/Alc/backends/null.o CMakeFiles/openal.dir/Alc/backends/android.o CMakeFiles/openal.dir/Alc/backends/wave.o -L/opt/android-ndk-r6/platforms/android-5/arch-arm/usr/lib -ldl -lm diff --git a/jni/openal-soft-android/CMakeFiles/progress.marks b/jni/openal-soft-android/CMakeFiles/progress.marks deleted file mode 100644 index f04c001f..00000000 --- a/jni/openal-soft-android/CMakeFiles/progress.marks +++ /dev/null @@ -1 +0,0 @@ -29 diff --git a/jni/openal-soft-android/CMakeLists.txt b/jni/openal-soft-android/CMakeLists.txt index 1483a9b3..ff746764 100644 --- a/jni/openal-soft-android/CMakeLists.txt +++ b/jni/openal-soft-android/CMakeLists.txt @@ -1,12 +1,15 @@ # CMake build file list for OpenAL -CMAKE_MINIMUM_REQUIRED(VERSION 2.4) +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +PROJECT(OpenAL) IF(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0003 NEW) + CMAKE_POLICY(SET CMP0005 NEW) ENDIF(COMMAND CMAKE_POLICY) -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +SET(CMAKE_MODULE_PATH "${OpenAL_SOURCE_DIR}/cmake") INCLUDE(CheckFunctionExists) INCLUDE(CheckLibraryExists) @@ -19,79 +22,161 @@ INCLUDE(CheckCSourceCompiles) INCLUDE(CheckTypeSize) -PROJECT(OpenAL C) - - SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE) -OPTION(ALSA "Check for ALSA backend" ON) -OPTION(OSS "Check for OSS backend" ON) -OPTION(SOLARIS "Check for Solaris backend" ON) -OPTION(SNDIO "Check for SndIO backend" ON) -OPTION(MMDEVAPI "Check for MMDevApi" ON) -OPTION(DSOUND "Check for DirectSound backend" ON) -OPTION(WINMM "Check for Windows Multimedia backend" ON) -OPTION(PORTAUDIO "Check for PortAudio backend" ON) -OPTION(PULSEAUDIO "Check for PulseAudio backend" ON) -OPTION(COREAUDIO "Check for CoreAudio backend" ON) -OPTION(OPENSL "Check for OpenSL backend" ON) -OPTION(ANDROID "Check for Android backend" ON) -OPTION(ANDROID_LOW_LATENCY "Enable Android low-latency backend" OFF) -OPTION(WAVE "Enable Wave Writer backend" ON) +OPTION(ALSOFT_CPUEXT_SSE "Check for SSE/SSE2 support" ON) +OPTION(ALSOFT_CPUEXT_NEON "Check for ARM Neon support" ON) -OPTION(REQUIRE_ALSA "Require ALSA backend" OFF) -OPTION(REQUIRE_OSS "Require OSS backend" OFF) -OPTION(REQUIRE_SOLARIS "Require Solaris backend" OFF) -OPTION(REQUIRE_SNDIO "Require SndIO backend" OFF) -OPTION(REQUIRE_MMDEVAPI "Require MMDevApi" OFF) -OPTION(REQUIRE_DSOUND "Require DirectSound backend" OFF) -OPTION(REQUIRE_WINMM "Require Windows Multimedia backend" OFF) -OPTION(REQUIRE_PORTAUDIO "Require PortAudio backend" OFF) -OPTION(REQUIRE_PULSEAUDIO "Require PulseAudio backend" OFF) -OPTION(REQUIRE_COREAUDIO "Require CoreAudio backend" OFF) -OPTION(REQUIRE_OPENSL "Require OpenSL backend" OFF) -OPTION(REQUIRE_ANDROID "Require Android backend" OFF) +OPTION(ALSOFT_REQUIRE_SSE "Require SSE/SSE2 support" OFF) +OPTION(ALSOFT_REQUIRE_NEON "Require ARM Neon support" OFF) -OPTION(DLOPEN "Check for the dlopen API for loading optional libs" ON) +IF(WIN32) + # This option is mainly for static linking OpenAL Soft into another project + # that already defines the IDs. It is up to that project to ensure all + # required IDs are defined. + OPTION(ALSOFT_NO_UID_DEFS "Do not define GUIDs, IIDs, CLSIDs, or PropertyKeys" OFF) +ENDIF() -OPTION(WERROR "Treat compile warnings as errors" OFF) -OPTION(UTILS "Build and install utility programs" ON) +OPTION(ALSOFT_BACKEND_ALSA "Check for ALSA backend" ON) +OPTION(ALSOFT_BACKEND_OSS "Check for OSS backend" ON) +OPTION(ALSOFT_BACKEND_SOLARIS "Check for Solaris backend" ON) +OPTION(ALSOFT_BACKEND_SNDIO "Check for SndIO backend" ON) +OPTION(ALSOFT_BACKEND_QSA "Check for QSA backend" ON) +OPTION(ALSOFT_BACKEND_MMDEVAPI "Check for MMDevApi backend" ON) +OPTION(ALSOFT_BACKEND_DSOUND "Check for DirectSound backend" ON) +OPTION(ALSOFT_BACKEND_WINMM "Check for Windows Multimedia backend" ON) +OPTION(ALSOFT_BACKEND_PORTAUDIO "Check for PortAudio backend" ON) +OPTION(ALSOFT_BACKEND_PULSEAUDIO "Check for PulseAudio backend" ON) +OPTION(ALSOFT_BACKEND_COREAUDIO "Check for CoreAudio backend" ON) +OPTION(ALSOFT_BACKEND_OPENSL "Check for OpenSL backend" ON) +OPTION(ALSOFT_BACKEND_WAVE "Enable Wave Writer backend" ON) -OPTION(ALSOFT_CONFIG "Install alsoft.conf configuration file" OFF) +OPTION(ALSOFT_MIDI_FLUIDSYNTH "Check for FluidSynth MIDI" ON) + +OPTION(ALSOFT_REQUIRE_ALSA "Require ALSA backend" OFF) +OPTION(ALSOFT_REQUIRE_OSS "Require OSS backend" OFF) +OPTION(ALSOFT_REQUIRE_SOLARIS "Require Solaris backend" OFF) +OPTION(ALSOFT_REQUIRE_SNDIO "Require SndIO backend" OFF) +OPTION(ALSOFT_REQUIRE_QSA "Require QSA backend" OFF) +OPTION(ALSOFT_REQUIRE_MMDEVAPI "Require MMDevApi" OFF) +OPTION(ALSOFT_REQUIRE_DSOUND "Require DirectSound backend" OFF) +OPTION(ALSOFT_REQUIRE_WINMM "Require Windows Multimedia backend" OFF) +OPTION(ALSOFT_REQUIRE_PORTAUDIO "Require PortAudio backend" OFF) +OPTION(ALSOFT_REQUIRE_PULSEAUDIO "Require PulseAudio backend" OFF) +OPTION(ALSOFT_REQUIRE_COREAUDIO "Require CoreAudio backend" OFF) +OPTION(ALSOFT_REQUIRE_OPENSL "Require OpenSL backend" OFF) + +OPTION(ALSOFT_REQUIRE_FLUIDSYNTH "Require FluidSynth MIDI" OFF) + +OPTION(ALSOFT_DLOPEN "Check for the dlopen API for loading optional libs" ON) + +OPTION(ALSOFT_WERROR "Treat compile warnings as errors" OFF) + +OPTION(ALSOFT_UTILS "Build and install utility programs" ON) +OPTION(ALSOFT_NO_CONFIG_UTIL "Disable building the alsoft-config utility" OFF) + +OPTION(ALSOFT_EXAMPLES "Build and install example programs" ON) + +OPTION(ALSOFT_CONFIG "Install alsoft.conf sample configuration file" ON) IF(WIN32) SET(LIBNAME OpenAL32) - ADD_DEFINITIONS("-D_WIN32 -D_WIN32_WINNT=0x0500") + ADD_DEFINITIONS("-D_WIN32 -D_WIN32_WINNT=0x0501") ELSE() SET(LIBNAME openal) ENDIF() +# QNX's gcc do not uses /usr/include and /usr/lib pathes by default +IF ("${CMAKE_C_PLATFORM_ID}" STREQUAL "QNX") + ADD_DEFINITIONS("-I/usr/include") + SET(EXTRA_LIBS ${EXTRA_LIBS} -L/usr/lib) +ENDIF() + IF(NOT LIBTYPE) SET(LIBTYPE SHARED) ENDIF() SET(LIB_MAJOR_VERSION "1") -SET(LIB_MINOR_VERSION "13") -SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}") +SET(LIB_MINOR_VERSION "15") +SET(LIB_REVISION "1") +SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}") SET(EXPORT_DECL "") +SET(ALIGN_DECL "") CHECK_TYPE_SIZE("long" SIZEOF_LONG) CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG) -CHECK_C_SOURCE_COMPILES("int *restrict foo; - int main() {return 0;}" HAVE_RESTRICT) -CHECK_C_SOURCE_COMPILES("int *__restrict foo; - int main() {return 0;}" HAVE___RESTRICT) +CHECK_C_COMPILER_FLAG(-std=c99 HAVE_STD_C99) +IF(HAVE_STD_C99) + SET(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}") +ENDIF() +# MSVC may need workarounds for C99 restrict and inline +IF(MSVC) + # TODO: Once we truly require C99, these restrict and inline checks should go + # away. + CHECK_C_SOURCE_COMPILES("int *restrict foo; + int main() {return 0;}" HAVE_RESTRICT) + IF(NOT HAVE_RESTRICT) + # Slightly convoluted way to do this, because MSVC may barf if restrict is + # defined to __restrict. + CHECK_C_SOURCE_COMPILES("#define restrict __restrict + #include + int *restrict foo; + int main() {return 0;}" HAVE___RESTRICT) + IF(HAVE___RESTRICT) + ADD_DEFINITIONS(-Drestrict=__restrict) + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Drestrict=__restrict") + ELSE() + ADD_DEFINITIONS("-Drestrict=") + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Drestrict=") + ENDIF() + ENDIF() + + CHECK_C_SOURCE_COMPILES("inline void foo(void) { } + int main() {return 0;}" HAVE_INLINE) + IF(NOT HAVE_INLINE) + CHECK_C_SOURCE_COMPILES("__inline void foo(void) { } + int main() {return 0;}" HAVE___INLINE) + IF(NOT HAVE___INLINE) + MESSAGE(FATAL_ERROR "No inline keyword found, please report!") + ENDIF() + + ADD_DEFINITIONS(-Dinline=__inline) + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Dinline=__inline") + ENDIF() +ENDIF() + +# Make sure we have C99-style inline semantics with GCC (4.3 or newer). +IF(CMAKE_COMPILER_IS_GNUCC) + SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + # Force no inlining for the next test. + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS} -fno-inline") + + CHECK_C_SOURCE_COMPILES("extern inline int foo() { return 0; } + int main() {return foo();}" INLINE_IS_C99) + IF(NOT INLINE_IS_C99) + MESSAGE(FATAL_ERROR "Your compiler does not seem to have C99 inline semantics! + Please update your compiler for better C99 compliance.") + ENDIF() + + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") +ENDIF() # Add definitions, compiler switches, etc. -INCLUDE_DIRECTORIES(OpenAL32/Include include "${OpenAL_BINARY_DIR}") +INCLUDE_DIRECTORIES("${OpenAL_SOURCE_DIR}/include" "${OpenAL_BINARY_DIR}") +IF(CMAKE_VERSION VERSION_LESS "2.8.8") + INCLUDE_DIRECTORIES("${OpenAL_SOURCE_DIR}/OpenAL32/Include" "${OpenAL_SOURCE_DIR}/Alc") + IF(WIN32 AND ALSOFT_NO_UID_DEFS) + ADD_DEFINITIONS("-DAL_NO_UID_DEFS") + ENDIF() +ENDIF() IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING @@ -112,6 +197,7 @@ IF(MSVC) SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE) + ADD_DEFINITIONS("/wd4098") IF(NOT DXSDK_DIR) STRING(REGEX REPLACE "\\\\" "/" DXSDK_DIR "$ENV{DXSDK_DIR}") @@ -142,7 +228,7 @@ ELSE() ADD_DEFINITIONS(-Wextra) ENDIF() - IF(WERROR) + IF(ALSOFT_WERROR) ADD_DEFINITIONS(-Werror) ENDIF() @@ -166,21 +252,10 @@ ENDIF() # Set visibility/export options if available IF(WIN32) SET(EXPORT_DECL "__declspec(dllexport)") - - OPTION(WINE "Enable use of Wine headers when compiling" OFF) - IF(WINE) - FIND_PATH(WINE_INCLUDE_DIR library.h - PATHS - /usr/include/wine - /usr/local/include/wine - CMAKE_FIND_ROOT_PATH_BOTH) - IF(WINE_INCLUDE_DIR) - MESSAGE(STATUS "Found Wine header files - ${WINE_INCLUDE_DIR}" ) - INCLUDE_DIRECTORIES("${WINE_INCLUDE_DIR}/windows") - SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} "${WINE_INCLUDE_DIR}/windows") - ELSE() - MESSAGE(STATUS "Could not find Wine header files" ) - ENDIF() + IF(NOT MINGW) + SET(ALIGN_DECL "__declspec(align(x))") + ELSE() + SET(ALIGN_DECL "__declspec(aligned(x))") ENDIF() ELSE() SET(OLD_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") @@ -211,21 +286,43 @@ ELSE() ENDIF() ENDIF() + CHECK_C_SOURCE_COMPILES("int foo __attribute__((aligned(16))); + int main() {return 0;}" HAVE_ATTRIBUTE_ALIGNED) + IF(HAVE_ATTRIBUTE_ALIGNED) + SET(ALIGN_DECL "__attribute__((aligned(x)))") + ENDIF() + SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}") ENDIF() +SET(SSE_SWITCH "") +IF(MSVC) + CHECK_C_COMPILER_FLAG(/arch:SSE HAVE_ARCHSSE_SWITCH) + IF(HAVE_ARCHSSE_SWITCH) + SET(SSE_SWITCH "/arch:SSE") + ENDIF() +ENDIF() +IF(NOT SSE_SWITCH) + CHECK_C_COMPILER_FLAG(-msse HAVE_MSSE_SWITCH) + IF(HAVE_MSSE_SWITCH) + SET(SSE_SWITCH "-msse") + ENDIF() +ENDIF() + CHECK_C_SOURCE_COMPILES("int foo(const char *str, ...) __attribute__((format(printf, 1, 2))); int main() {return 0;}" HAVE_GCC_FORMAT) +CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H) +CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H) +CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H) +CHECK_INCLUDE_FILE(sys/sysconf.h HAVE_SYS_SYSCONF_H) CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H) -CHECK_INCLUDE_FILE(fpu_control.h HAVE_FPU_CONTROL_H) CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H) CHECK_INCLUDE_FILE(ieeefp.h HAVE_IEEEFP_H) CHECK_INCLUDE_FILE(guiddef.h HAVE_GUIDDEF_H) IF(NOT HAVE_GUIDDEF_H) CHECK_INCLUDE_FILE(initguid.h HAVE_INITGUID_H) ENDIF() -CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H) # Some systems need libm for some of the following math functions to work CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM) @@ -235,25 +332,17 @@ IF(HAVE_LIBM) ENDIF() -CHECK_SYMBOL_EXISTS(powf math.h HAVE_POWF) -CHECK_SYMBOL_EXISTS(sqrtf math.h HAVE_SQRTF) -CHECK_SYMBOL_EXISTS(cosf math.h HAVE_COSF) -CHECK_SYMBOL_EXISTS(sinf math.h HAVE_SINF) -CHECK_SYMBOL_EXISTS(acosf math.h HAVE_ACOSF) -CHECK_SYMBOL_EXISTS(asinf math.h HAVE_ASINF) -CHECK_SYMBOL_EXISTS(atanf math.h HAVE_ATANF) -CHECK_SYMBOL_EXISTS(atan2f math.h HAVE_ATAN2F) -CHECK_SYMBOL_EXISTS(fabsf math.h HAVE_FABSF) -CHECK_SYMBOL_EXISTS(log10f math.h HAVE_LOG10F) -CHECK_SYMBOL_EXISTS(floorf math.h HAVE_FLOORF) +CHECK_SYMBOL_EXISTS(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) +CHECK_SYMBOL_EXISTS(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) +CHECK_SYMBOL_EXISTS(_aligned_malloc malloc.h HAVE__ALIGNED_MALLOC) +CHECK_SYMBOL_EXISTS(lrintf math.h HAVE_LRINTF) -IF(HAVE_FENV_H) - CHECK_SYMBOL_EXISTS(fesetround fenv.h HAVE_FESETROUND) +IF(HAVE_FLOAT_H) + CHECK_SYMBOL_EXISTS(_controlfp float.h HAVE__CONTROLFP) + CHECK_SYMBOL_EXISTS(__control87_2 float.h HAVE___CONTROL87_2) ENDIF() CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF) -CHECK_FUNCTION_EXISTS(_controlfp HAVE__CONTROLFP) - CHECK_FUNCTION_EXISTS(stat HAVE_STAT) CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP) IF(NOT HAVE_STRCASECMP) @@ -285,16 +374,6 @@ IF(NOT HAVE_SNPRINTF) ADD_DEFINITIONS(-Dsnprintf=_snprintf) ENDIF() -CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF) -IF(NOT HAVE_VSNPRINTF) - CHECK_FUNCTION_EXISTS(_vsnprintf HAVE__VSNPRINTF) - IF(NOT HAVE__VSNPRINTF) - MESSAGE(FATAL_ERROR "No vsnprintf function found, please report!") - ENDIF() - - ADD_DEFINITIONS(-Dvsnprintf=_vsnprintf) -ENDIF() - CHECK_SYMBOL_EXISTS(isfinite math.h HAVE_ISFINITE) IF(NOT HAVE_ISFINITE) CHECK_FUNCTION_EXISTS(finite HAVE_FINITE) @@ -321,7 +400,7 @@ ENDIF() # Check for the dlopen API (for dynamicly loading backend libs) -IF(DLOPEN) +IF(ALSOFT_DLOPEN) CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H) IF(HAVE_DLFCN_H) CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_LIBDL) @@ -332,8 +411,12 @@ IF(DLOPEN) ENDIF() # Check if we have Windows headers -CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H -D_WIN32_WINNT=0x0500) +CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H -D_WIN32_WINNT=0x0501) IF(NOT HAVE_WINDOWS_H) + # These are needed on some systems for extra features + ADD_DEFINITIONS(-D_GNU_SOURCE=1 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700) + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -D_GNU_SOURCE=1 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700") + CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY) IF(NOT HAVE_GETTIMEOFDAY) MESSAGE(FATAL_ERROR "No timing function found!") @@ -344,12 +427,6 @@ IF(NOT HAVE_WINDOWS_H) MESSAGE(FATAL_ERROR "No sleep function found!") ENDIF() - CHECK_C_COMPILER_FLAG(-pthread HAVE_PTHREAD) - IF(HAVE_PTHREAD) - ADD_DEFINITIONS(-pthread) - SET(EXTRA_LIBS ${EXTRA_LIBS} -pthread) - ENDIF() - # We need pthreads outside of Windows CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H) IF(NOT HAVE_PTHREAD_H) @@ -358,15 +435,24 @@ IF(NOT HAVE_WINDOWS_H) # Some systems need pthread_np.h to get recursive mutexes CHECK_INCLUDE_FILES("pthread.h;pthread_np.h" HAVE_PTHREAD_NP_H) - # _GNU_SOURCE is needed on some systems for extra attributes, and - # _REENTRANT is needed for libc thread-safety - ADD_DEFINITIONS(-D_GNU_SOURCE=1) + CHECK_C_COMPILER_FLAG(-pthread HAVE_PTHREAD) + IF(HAVE_PTHREAD) + ADD_DEFINITIONS(-pthread) + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -pthread") + SET(EXTRA_LIBS ${EXTRA_LIBS} -pthread) + ENDIF() + CHECK_LIBRARY_EXISTS(pthread pthread_create "" HAVE_LIBPTHREAD) IF(HAVE_LIBPTHREAD) SET(EXTRA_LIBS pthread ${EXTRA_LIBS}) ENDIF() - CHECK_LIBRARY_EXISTS(pthread pthread_setschedparam "" HAVE_PTHREAD_SETSCHEDPARAM) + CHECK_SYMBOL_EXISTS(pthread_setschedparam pthread.h HAVE_PTHREAD_SETSCHEDPARAM) + + CHECK_SYMBOL_EXISTS(pthread_setname_np pthread.h HAVE_PTHREAD_SETNAME_NP) + IF(NOT HAVE_PTHREAD_SETNAME_NP) + CHECK_SYMBOL_EXISTS(pthread_set_name_np pthread.h HAVE_PTHREAD_SET_NAME_NP) + ENDIF() CHECK_LIBRARY_EXISTS(rt clock_gettime "" HAVE_LIBRT) IF(HAVE_LIBRT) @@ -378,8 +464,8 @@ ENDIF() CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) IF(NOT HAVE_STDINT_H) IF(HAVE_WINDOWS_H) - CHECK_C_SOURCE_COMPILES("\#define _WIN32_WINNT 0x0500 - \#include + CHECK_C_SOURCE_COMPILES("#define _WIN32_WINNT 0x0501 + #include __int64 foo; int main() {return 0;}" HAVE___INT64) ENDIF() @@ -406,7 +492,11 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c OpenAL32/alError.c OpenAL32/alExtension.c OpenAL32/alFilter.c + OpenAL32/alFontsound.c OpenAL32/alListener.c + OpenAL32/alMidi.c + OpenAL32/alPreset.c + OpenAL32/alSoundfont.c OpenAL32/alSource.c OpenAL32/alState.c OpenAL32/alThunk.c @@ -414,17 +504,90 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c SET(ALC_OBJS Alc/ALc.c Alc/ALu.c Alc/alcConfig.c - Alc/alcDedicated.c - Alc/alcEcho.c - Alc/alcModulator.c - Alc/alcReverb.c Alc/alcRing.c - Alc/alcThread.c Alc/bs2b.c + Alc/effects/autowah.c + Alc/effects/chorus.c + Alc/effects/compressor.c + Alc/effects/dedicated.c + Alc/effects/distortion.c + Alc/effects/echo.c + Alc/effects/equalizer.c + Alc/effects/flanger.c + Alc/effects/modulator.c + Alc/effects/null.c + Alc/effects/reverb.c Alc/helpers.c Alc/hrtf.c - Alc/mixer.c Alc/panning.c + Alc/threads.c + Alc/mixer.c + Alc/mixer_c.c +) + + +SET(CPU_EXTS "Default") +SET(HAVE_SSE 0) +SET(HAVE_NEON 0) + +# Check for SSE support +IF(ALSOFT_CPUEXT_SSE AND ALIGN_DECL) + CHECK_INCLUDE_FILE(xmmintrin.h HAVE_XMMINTRIN_H "${SSE_SWITCH}") + IF(HAVE_XMMINTRIN_H) + SET(HAVE_SSE 1) + SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_sse.c) + IF(SSE_SWITCH) + SET_SOURCE_FILES_PROPERTIES(Alc/mixer_sse.c PROPERTIES + COMPILE_FLAGS "${SSE_SWITCH}") + ENDIF() + SET(CPU_EXTS "${CPU_EXTS}, SSE") + ENDIF() +ENDIF() +IF(ALSOFT_REQUIRE_SSE AND NOT HAVE_SSE) + MESSAGE(FATAL_ERROR "Failed to enabled required SSE CPU extensions") +ENDIF() + +# Check for ARM Neon support +IF(ALSOFT_CPUEXT_NEON) + CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H) + IF(HAVE_ARM_NEON_H) + SET(HAVE_NEON 1) + SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_neon.c) + SET(CPU_EXTS "${CPU_EXTS}, Neon") + ENDIF() +ENDIF() +IF(ALSOFT_REQUIRE_NEON AND NOT HAVE_NEON) + MESSAGE(FATAL_ERROR "Failed to enabled required ARM Neon CPU extensions") +ENDIF() + + +SET(ALC_OBJS ${ALC_OBJS} + Alc/midi/base.c + Alc/midi/sf2load.c + Alc/midi/dummy.c + Alc/midi/fluidsynth.c +) + +SET(HAVE_FLUIDSYNTH 0) + +# Check for FluidSynth support +IF(ALSOFT_MIDI_FLUIDSYNTH) + FIND_PACKAGE(FluidSynth) + IF(FLUIDSYNTH_FOUND) + SET(HAVE_FLUIDSYNTH 1) + IF(CMAKE_VERSION VERSION_LESS "2.8.8") + INCLUDE_DIRECTORIES(${FLUIDSYNTH_INCLUDE_DIR}) + ENDIF() + SET(EXTRA_LIBS ${FLUIDSYNTH_LIBRARIES} ${EXTRA_LIBS}) + ENDIF() +ENDIF() +IF(ALSOFT_REQUIRE_FLUIDSYNTH AND NOT HAVE_FLUIDSYNTH) + MESSAGE(FATAL_ERROR "Failed to enabled required FluidSynth support") +ENDIF() + + +SET(ALC_OBJS ${ALC_OBJS} + Alc/backends/base.c # Default backends, always available Alc/backends/loopback.c Alc/backends/null.c @@ -435,17 +598,18 @@ SET(HAVE_ALSA 0) SET(HAVE_OSS 0) SET(HAVE_SOLARIS 0) SET(HAVE_SNDIO 0) +SET(HAVE_QSA 0) SET(HAVE_DSOUND 0) +SET(HAVE_MMDEVAPI 0) SET(HAVE_WINMM 0) SET(HAVE_PORTAUDIO 0) SET(HAVE_PULSEAUDIO 0) SET(HAVE_COREAUDIO 0) SET(HAVE_OPENSL 0) -SET(HAVE_ANDROID 0) SET(HAVE_WAVE 0) # Check ALSA backend -IF(ALSA) +IF(ALSOFT_BACKEND_ALSA) CHECK_INCLUDE_FILE(alsa/asoundlib.h HAVE_ALSA_ASOUNDLIB_H) IF(HAVE_ALSA_ASOUNDLIB_H) CHECK_SHARED_FUNCTION_EXISTS(snd_pcm_open "alsa/asoundlib.h" asound "" HAVE_LIBASOUND) @@ -461,12 +625,12 @@ IF(ALSA) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_ALSA AND NOT HAVE_ALSA) +IF(ALSOFT_REQUIRE_ALSA AND NOT HAVE_ALSA) MESSAGE(FATAL_ERROR "Failed to enabled required ALSA backend") ENDIF() # Check OSS backend -IF(OSS) +IF(ALSOFT_BACKEND_OSS) CHECK_INCLUDE_FILE(sys/soundcard.h HAVE_SYS_SOUNDCARD_H) IF(HAVE_SYS_SOUNDCARD_H) SET(HAVE_OSS 1) @@ -474,12 +638,12 @@ IF(OSS) SET(BACKENDS "${BACKENDS} OSS,") ENDIF() ENDIF() -IF(REQUIRE_OSS AND NOT HAVE_OSS) +IF(ALSOFT_REQUIRE_OSS AND NOT HAVE_OSS) MESSAGE(FATAL_ERROR "Failed to enabled required OSS backend") ENDIF() # Check Solaris backend -IF(SOLARIS) +IF(ALSOFT_BACKEND_SOLARIS) CHECK_INCLUDE_FILE(sys/audioio.h HAVE_SYS_AUDIOIO_H) IF(HAVE_SYS_AUDIOIO_H) SET(HAVE_SOLARIS 1) @@ -487,34 +651,47 @@ IF(SOLARIS) SET(BACKENDS "${BACKENDS} Solaris,") ENDIF() ENDIF() -IF(REQUIRE_SOLARIS AND NOT HAVE_SOLARIS) +IF(ALSOFT_REQUIRE_SOLARIS AND NOT HAVE_SOLARIS) MESSAGE(FATAL_ERROR "Failed to enabled required Solaris backend") ENDIF() # Check SndIO backend -IF(SNDIO) +IF(ALSOFT_BACKEND_SNDIO) CHECK_INCLUDE_FILE(sndio.h HAVE_SNDIO_H) IF(HAVE_SNDIO_H) CHECK_SHARED_FUNCTION_EXISTS(sio_open "sndio.h" sndio "" HAVE_LIBSNDIO) - IF(HAVE_LIBSNDIO OR HAVE_DLFCN_H OR WIN32) + IF(HAVE_LIBSNDIO) SET(HAVE_SNDIO 1) SET(ALC_OBJS ${ALC_OBJS} Alc/backends/sndio.c) - IF(HAVE_DLFCN_H OR WIN32) - SET(BACKENDS "${BACKENDS} SndIO,") - ELSE() - SET(BACKENDS "${BACKENDS} SndIO \(linked\),") - SET(EXTRA_LIBS sndio ${EXTRA_LIBS}) - ENDIF() + SET(BACKENDS "${BACKENDS} SndIO \(linked\),") + SET(EXTRA_LIBS sndio ${EXTRA_LIBS}) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_SNDIO AND NOT HAVE_SNDIO) +IF(ALSOFT_REQUIRE_SNDIO AND NOT HAVE_SNDIO) MESSAGE(FATAL_ERROR "Failed to enabled required SndIO backend") ENDIF() +# Check QSA backend +IF (ALSOFT_BACKEND_QSA AND "${CMAKE_C_PLATFORM_ID}" STREQUAL "QNX") + CHECK_INCLUDE_FILE(sys/asoundlib.h HAVE_SYS_ASOUNDLIB_H) + IF(HAVE_SYS_ASOUNDLIB_H) + CHECK_SHARED_FUNCTION_EXISTS(snd_pcm_open "sys/asoundlib.h" asound "" HAVE_LIBASOUND) + IF(HAVE_LIBASOUND) + SET(HAVE_QSA 1) + SET(ALC_OBJS ${ALC_OBJS} Alc/backends/qsa.c) + SET(EXTRA_LIBS asound ${EXTRA_LIBS}) + SET(BACKENDS "${BACKENDS} QSA \(linked\),") + ENDIF() + ENDIF() +ENDIF() +IF(ALSOFT_REQUIRE_QSA AND NOT HAVE_QSA) + MESSAGE(FATAL_ERROR "Failed to enabled required QSA backend") +ENDIF() + # Check for MMDevApi backend IF(HAVE_WINDOWS_H) - IF(MMDEVAPI) + IF(ALSOFT_BACKEND_MMDEVAPI) CHECK_INCLUDE_FILE(mmdeviceapi.h HAVE_MMDEVICEAPI_H) IF(HAVE_MMDEVICEAPI_H) SET(HAVE_MMDEVAPI 1) @@ -524,12 +701,12 @@ IF(HAVE_WINDOWS_H) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_MMDEVAPI AND NOT HAVE_MMDEVAPI) +IF(ALSOFT_REQUIRE_MMDEVAPI AND NOT HAVE_MMDEVAPI) MESSAGE(FATAL_ERROR "Failed to enabled required MMDevApi backend") ENDIF() # Check DSound/MMSystem backend -IF(DSOUND) +IF(ALSOFT_BACKEND_DSOUND) CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H) IF(HAVE_DSOUND_H) CHECK_SHARED_FUNCTION_EXISTS(DirectSoundCreate "dsound.h" dsound "" HAVE_LIBDSOUND) @@ -546,13 +723,13 @@ IF(DSOUND) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_DSOUND AND NOT HAVE_DSOUND) +IF(ALSOFT_REQUIRE_DSOUND AND NOT HAVE_DSOUND) MESSAGE(FATAL_ERROR "Failed to enabled required DSound backend") ENDIF() IF(HAVE_WINDOWS_H) - IF(WINMM) - CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0500) + IF(ALSOFT_BACKEND_WINMM) + CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0501) IF(HAVE_MMSYSTEM_H AND HAVE_LIBWINMM) SET(HAVE_WINMM 1) SET(ALC_OBJS ${ALC_OBJS} Alc/backends/winmm.c) @@ -560,12 +737,12 @@ IF(HAVE_WINDOWS_H) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_WINMM AND NOT HAVE_WINMM) +IF(ALSOFT_REQUIRE_WINMM AND NOT HAVE_WINMM) MESSAGE(FATAL_ERROR "Failed to enabled required WinMM backend") ENDIF() # Check PortAudio backend -IF(PORTAUDIO) +IF(ALSOFT_BACKEND_PORTAUDIO) CHECK_INCLUDE_FILE(portaudio.h HAVE_PORTAUDIO_H) IF(HAVE_PORTAUDIO_H) CHECK_SHARED_FUNCTION_EXISTS(Pa_Initialize "portaudio.h" portaudio "" HAVE_LIBPORTAUDIO) @@ -581,12 +758,12 @@ IF(PORTAUDIO) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_PORTAUDIO AND NOT HAVE_PORTAUDIO) +IF(ALSOFT_REQUIRE_PORTAUDIO AND NOT HAVE_PORTAUDIO) MESSAGE(FATAL_ERROR "Failed to enabled required PortAudio backend") ENDIF() # Check PulseAudio backend -IF(PULSEAUDIO) +IF(ALSOFT_BACKEND_PULSEAUDIO) CHECK_INCLUDE_FILE(pulse/pulseaudio.h HAVE_PULSE_PULSEAUDIO_H) IF(HAVE_PULSE_PULSEAUDIO_H) CHECK_SHARED_FUNCTION_EXISTS(pa_context_new "pulse/pulseaudio.h" pulse "" HAVE_LIBPULSE) @@ -602,12 +779,12 @@ IF(PULSEAUDIO) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO) +IF(ALSOFT_REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO) MESSAGE(FATAL_ERROR "Failed to enabled required PulseAudio backend") ENDIF() # Check CoreAudio backend -IF(COREAUDIO) +IF(ALSOFT_BACKEND_COREAUDIO) CHECK_INCLUDE_FILE(/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h HAVE_COREAUDIO_FRAMEWORK) IF(HAVE_COREAUDIO_FRAMEWORK) SET(HAVE_COREAUDIO 1) @@ -616,54 +793,43 @@ IF(COREAUDIO) SET(EXTRA_LIBS /System/Library/Frameworks/CoreAudio.framework ${EXTRA_LIBS}) SET(EXTRA_LIBS /System/Library/Frameworks/AudioUnit.framework ${EXTRA_LIBS}) SET(EXTRA_LIBS /System/Library/Frameworks/ApplicationServices.framework ${EXTRA_LIBS}) + + # Some versions of OSX may need the AudioToolbox framework. Add it if + # it's found. + FIND_LIBRARY(AUDIOTOOLBOX_LIBRARY + NAMES AudioToolbox + PATHS ~/Library/Frameworks + /Library/Frameworks + /System/Library/Frameworks + ) + IF(AUDIOTOOLBOX_LIBRARY) + SET(EXTRA_LIBS ${AUDIOTOOLBOX_LIBRARY} ${EXTRA_LIBS}) + ENDIF() ENDIF() ENDIF() -IF(REQUIRE_COREAUDIO AND NOT HAVE_COREAUDIO) +IF(ALSOFT_REQUIRE_COREAUDIO AND NOT HAVE_COREAUDIO) MESSAGE(FATAL_ERROR "Failed to enabled required CoreAudio backend") ENDIF() # Check for OpenSL (Android) backend -IF(OPENSL) +IF(ALSOFT_BACKEND_OPENSL) CHECK_INCLUDE_FILES("SLES/OpenSLES.h;SLES/OpenSLES_Android.h" HAVE_SLES_OPENSLES_ANDROID_H) IF(HAVE_SLES_OPENSLES_ANDROID_H) CHECK_SHARED_FUNCTION_EXISTS(slCreateEngine "SLES/OpenSLES.h" OpenSLES "" HAVE_LIBOPENSLES) IF(HAVE_LIBOPENSLES) SET(HAVE_OPENSL 1) - CHECK_SYMBOL_EXISTS(SL_BYTEORDER_NATIVE "SLES/OpenSLES.h" HAVE_OPENSLES_1_1) - IF (HAVE_OPENSLES_1_1) - SET(HAVE_OPENSL_1_1 1) - ENDIF() SET(ALC_OBJS ${ALC_OBJS} Alc/backends/opensl.c) SET(BACKENDS "${BACKENDS} OpenSL,") SET(EXTRA_LIBS OpenSLES ${EXTRA_LIBS}) ENDIF() ENDIF() ENDIF() -IF(REQUIRE_OPENSL AND NOT HAVE_OPENSL) +IF(ALSOFT_REQUIRE_OPENSL AND NOT HAVE_OPENSL) MESSAGE(FATAL_ERROR "Failed to enabled required OpenSL backend") ENDIF() -# Check for Android backend -IF(ANDROID) - CHECK_INCLUDE_FILE(android/api-level.h HAVE_ANDROID_API_LEVEL_H) - IF(HAVE_ANDROID_API_LEVEL_H) - CHECK_SYMBOL_EXISTS(__ANDROID_API__ "android/api-level.h" HAVE_ANDROID_INTERNAL) - IF(HAVE_ANDROID_INTERNAL) - SET(HAVE_ANDROID 1) - SET(ALC_OBJS ${ALC_OBJS} Alc/backends/android.c) - SET(BACKENDS "${BACKENDS} Android,") - IF(ANDROID_LOW_LATENCY) - SET(HAVE_ANDROID_LOW_LATENCY 1) - ENDIF() - ENDIF() - ENDIF() -ENDIF() -IF(REQUIRE_ANDROID AND NOT HAVE_ANDROID) - MESSAGE(FATAL_ERROR "Failed to enabled required Android backend") -ENDIF() - # Optionally enable the Wave Writer backend -IF(WAVE) +IF(ALSOFT_BACKEND_WAVE) SET(HAVE_WAVE 1) SET(ALC_OBJS ${ALC_OBJS} Alc/backends/wave.c) SET(BACKENDS "${BACKENDS} WaveFile,") @@ -672,6 +838,19 @@ ENDIF() # This is always available SET(BACKENDS "${BACKENDS} Null") +IF(ALSOFT_UTILS AND NOT ALSOFT_NO_CONFIG_UTIL) + add_subdirectory(utils/alsoft-config) +ENDIF() +IF(ALSOFT_EXAMPLES) + FIND_PACKAGE(SDL) + IF(SDL_FOUND) + FIND_PACKAGE(SDL_sound) + IF(SDL_SOUND_FOUND AND CMAKE_VERSION VERSION_LESS "2.8.8") + INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR}) + ENDIF() + ENDIF() +ENDIF() + IF(LIBTYPE STREQUAL "STATIC") ADD_DEFINITIONS(-DAL_LIBTYPE_STATIC) SET(PKG_CONFIG_CFLAGS -DAL_LIBTYPE_STATIC ${PKG_CONFIG_CFLAGS}) @@ -696,9 +875,15 @@ CONFIGURE_FILE( # Build a library ADD_LIBRARY(${LIBNAME} ${LIBTYPE} ${OPENAL_OBJS} ${ALC_OBJS}) -SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES DEFINE_SYMBOL AL_BUILD_LIBRARY - COMPILE_FLAGS -DAL_ALEXT_PROTOTYPES - VERSION ${LIB_VERSION}.0 +SET_PROPERTY(TARGET ${LIBNAME} APPEND PROPERTY COMPILE_DEFINITIONS AL_BUILD_LIBRARY AL_ALEXT_PROTOTYPES) +IF(WIN32 AND ALSOFT_NO_UID_DEFS) + SET_PROPERTY(TARGET ${LIBNAME} APPEND PROPERTY COMPILE_DEFINITIONS AL_NO_UID_DEFS) +ENDIF() +SET_PROPERTY(TARGET ${LIBNAME} APPEND PROPERTY INCLUDE_DIRECTORIES "${OpenAL_SOURCE_DIR}/OpenAL32/Include" "${OpenAL_SOURCE_DIR}/Alc") +IF(FLUIDSYNTH_FOUND) + SET_PROPERTY(TARGET ${LIBNAME} APPEND PROPERTY INCLUDE_DIRECTORIES ${FLUIDSYNTH_INCLUDE_DIR}) +ENDIF() +SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION} SOVERSION ${LIB_MAJOR_VERSION}) IF(WIN32 AND NOT LIBTYPE STREQUAL "STATIC") SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "") @@ -717,6 +902,7 @@ INSTALL(FILES include/AL/al.h include/AL/alext.h include/AL/efx.h include/AL/efx-creative.h + include/AL/efx-presets.h DESTINATION include/AL ) INSTALL(FILES "${OpenAL_BINARY_DIR}/openal.pc" @@ -727,6 +913,13 @@ MESSAGE(STATUS "") MESSAGE(STATUS "Building OpenAL with support for the following backends:") MESSAGE(STATUS " ${BACKENDS}") MESSAGE(STATUS "") +MESSAGE(STATUS "Building with support for CPU extensions:") +MESSAGE(STATUS " ${CPU_EXTS}") +MESSAGE(STATUS "") +IF(HAVE_FLUIDSYNTH) + MESSAGE(STATUS "FluidSynth support for ALC_SOFT_midi_interface enabled") + MESSAGE(STATUS "") +ENDIF() IF(WIN32) IF(NOT HAVE_DSOUND) @@ -739,21 +932,64 @@ ENDIF() # Install alsoft.conf configuration file IF(ALSOFT_CONFIG) INSTALL(FILES alsoftrc.sample - DESTINATION /etc/openal - RENAME alsoft.conf + DESTINATION share/openal ) - MESSAGE(STATUS "Installing sample alsoft.conf") + MESSAGE(STATUS "Installing sample configuration") MESSAGE(STATUS "") ENDIF() -IF(UTILS) +IF(ALSOFT_UTILS) ADD_EXECUTABLE(openal-info utils/openal-info.c) TARGET_LINK_LIBRARIES(openal-info ${LIBNAME}) - INSTALL(TARGETS openal-info + + ADD_EXECUTABLE(makehrtf utils/makehrtf.c) + IF(HAVE_LIBM) + TARGET_LINK_LIBRARIES(makehrtf m) + ENDIF() + + INSTALL(TARGETS openal-info makehrtf RUNTIME DESTINATION bin LIBRARY DESTINATION "lib${LIB_SUFFIX}" ARCHIVE DESTINATION "lib${LIB_SUFFIX}" ) + MESSAGE(STATUS "Building utility programs") + IF(TARGET alsoft-config) + MESSAGE(STATUS "Building configuration program") + ENDIF() MESSAGE(STATUS "") ENDIF() + +IF(ALSOFT_EXAMPLES) + IF(SDL_FOUND AND SDL_SOUND_FOUND) + ADD_LIBRARY(ex-common STATIC examples/common/alhelpers.c + examples/common/sdl_sound.c) + SET_PROPERTY(TARGET ex-common APPEND PROPERTY INCLUDE_DIRECTORIES ${SDL_SOUND_INCLUDE_DIR}) + + ADD_EXECUTABLE(alstream examples/alstream.c) + TARGET_LINK_LIBRARIES(alstream ex-common ${SDL_SOUND_LIBRARIES} ${LIBNAME}) + SET_PROPERTY(TARGET alstream APPEND PROPERTY INCLUDE_DIRECTORIES ${SDL_SOUND_INCLUDE_DIR}) + + ADD_EXECUTABLE(alreverb examples/alreverb.c) + TARGET_LINK_LIBRARIES(alreverb ex-common ${SDL_SOUND_LIBRARIES} ${LIBNAME}) + SET_PROPERTY(TARGET alreverb APPEND PROPERTY INCLUDE_DIRECTORIES ${SDL_SOUND_INCLUDE_DIR}) + + ADD_EXECUTABLE(allatency examples/allatency.c) + TARGET_LINK_LIBRARIES(allatency ex-common ${SDL_SOUND_LIBRARIES} ${LIBNAME}) + SET_PROPERTY(TARGET allatency APPEND PROPERTY INCLUDE_DIRECTORIES ${SDL_SOUND_INCLUDE_DIR}) + + ADD_EXECUTABLE(alloopback examples/alloopback.c) + TARGET_LINK_LIBRARIES(alloopback ex-common ${SDL_SOUND_LIBRARIES} ${SDL_LIBRARY} ${LIBNAME}) + SET_PROPERTY(TARGET alloopback APPEND PROPERTY INCLUDE_DIRECTORIES ${SDL_INCLUDE_DIR} + ${SDL_SOUND_INCLUDE_DIR}) + + INSTALL(TARGETS alstream alreverb allatency alloopback + RUNTIME DESTINATION bin + LIBRARY DESTINATION "lib${LIB_SUFFIX}" + ARCHIVE DESTINATION "lib${LIB_SUFFIX}" + ) + + MESSAGE(STATUS "Building example programs") + MESSAGE(STATUS "") + ENDIF() +ENDIF() diff --git a/jni/openal-soft-android/Makefile b/jni/openal-soft-android/Makefile deleted file mode 100644 index e492402d..00000000 --- a/jni/openal-soft-android/Makefile +++ /dev/null @@ -1,727 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# Default target executed when no arguments are given to make. -default_target: all -.PHONY : default_target - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canoncical targets will work. -.SUFFIXES: - -# Remove some rules from gmake that .SUFFIXES does not remove. -SUFFIXES = - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /usr/bin/cmake - -# The command to remove a file. -RM = /usr/bin/cmake -E remove -f - -# The program to use to edit the cache. -CMAKE_EDIT_COMMAND = /usr/bin/cmake-gui - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -#============================================================================= -# Targets provided globally by CMake. - -# Special rule for the target edit_cache -edit_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." - /usr/bin/cmake-gui -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : edit_cache - -# Special rule for the target edit_cache -edit_cache/fast: edit_cache -.PHONY : edit_cache/fast - -# Special rule for the target install -install: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install - -# Special rule for the target install -install/fast: preinstall/fast - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..." - /usr/bin/cmake -P cmake_install.cmake -.PHONY : install/fast - -# Special rule for the target install/local -install/local: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..." - /usr/bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake -.PHONY : install/local - -# Special rule for the target install/local -install/local/fast: install/local -.PHONY : install/local/fast - -# Special rule for the target install/strip -install/strip: preinstall - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..." - /usr/bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake -.PHONY : install/strip - -# Special rule for the target install/strip -install/strip/fast: install/strip -.PHONY : install/strip/fast - -# Special rule for the target list_install_components -list_install_components: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\"" -.PHONY : list_install_components - -# Special rule for the target list_install_components -list_install_components/fast: list_install_components -.PHONY : list_install_components/fast - -# Special rule for the target rebuild_cache -rebuild_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." - /usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : rebuild_cache - -# Special rule for the target rebuild_cache -rebuild_cache/fast: rebuild_cache -.PHONY : rebuild_cache/fast - -# The main all target -all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/progress.marks - $(MAKE) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles 0 -.PHONY : all - -# The main clean target -clean: - $(MAKE) -f CMakeFiles/Makefile2 clean -.PHONY : clean - -# The main clean target -clean/fast: clean -.PHONY : clean/fast - -# Prepare targets for installation. -preinstall: all - $(MAKE) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall - -# Prepare targets for installation. -preinstall/fast: - $(MAKE) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall/fast - -# clear depends -depend: - $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 -.PHONY : depend - -#============================================================================= -# Target rules for targets named openal - -# Build rule for target. -openal: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 openal -.PHONY : openal - -# fast build rule for target. -openal/fast: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/build -.PHONY : openal/fast - -# Manual pre-install relink rule for target. -openal/preinstall: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/preinstall -.PHONY : openal/preinstall - -#============================================================================= -# Target rules for targets named openal-info - -# Build rule for target. -openal-info: cmake_check_build_system - $(MAKE) -f CMakeFiles/Makefile2 openal-info -.PHONY : openal-info - -# fast build rule for target. -openal-info/fast: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/build -.PHONY : openal-info/fast - -# Manual pre-install relink rule for target. -openal-info/preinstall: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/preinstall -.PHONY : openal-info/preinstall - -# target to build an object file -Alc/ALc.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALc.o -.PHONY : Alc/ALc.o - -# target to preprocess a source file -Alc/ALc.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALc.i -.PHONY : Alc/ALc.i - -# target to generate assembly for a file -Alc/ALc.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALc.s -.PHONY : Alc/ALc.s - -# target to build an object file -Alc/ALu.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALu.o -.PHONY : Alc/ALu.o - -# target to preprocess a source file -Alc/ALu.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALu.i -.PHONY : Alc/ALu.i - -# target to generate assembly for a file -Alc/ALu.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/ALu.s -.PHONY : Alc/ALu.s - -# target to build an object file -Alc/alcConfig.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcConfig.o -.PHONY : Alc/alcConfig.o - -# target to preprocess a source file -Alc/alcConfig.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcConfig.i -.PHONY : Alc/alcConfig.i - -# target to generate assembly for a file -Alc/alcConfig.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcConfig.s -.PHONY : Alc/alcConfig.s - -# target to build an object file -Alc/alcDedicated.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcDedicated.o -.PHONY : Alc/alcDedicated.o - -# target to preprocess a source file -Alc/alcDedicated.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcDedicated.i -.PHONY : Alc/alcDedicated.i - -# target to generate assembly for a file -Alc/alcDedicated.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcDedicated.s -.PHONY : Alc/alcDedicated.s - -# target to build an object file -Alc/alcEcho.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcEcho.o -.PHONY : Alc/alcEcho.o - -# target to preprocess a source file -Alc/alcEcho.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcEcho.i -.PHONY : Alc/alcEcho.i - -# target to generate assembly for a file -Alc/alcEcho.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcEcho.s -.PHONY : Alc/alcEcho.s - -# target to build an object file -Alc/alcModulator.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcModulator.o -.PHONY : Alc/alcModulator.o - -# target to preprocess a source file -Alc/alcModulator.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcModulator.i -.PHONY : Alc/alcModulator.i - -# target to generate assembly for a file -Alc/alcModulator.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcModulator.s -.PHONY : Alc/alcModulator.s - -# target to build an object file -Alc/alcReverb.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcReverb.o -.PHONY : Alc/alcReverb.o - -# target to preprocess a source file -Alc/alcReverb.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcReverb.i -.PHONY : Alc/alcReverb.i - -# target to generate assembly for a file -Alc/alcReverb.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcReverb.s -.PHONY : Alc/alcReverb.s - -# target to build an object file -Alc/alcRing.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcRing.o -.PHONY : Alc/alcRing.o - -# target to preprocess a source file -Alc/alcRing.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcRing.i -.PHONY : Alc/alcRing.i - -# target to generate assembly for a file -Alc/alcRing.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcRing.s -.PHONY : Alc/alcRing.s - -# target to build an object file -Alc/alcThread.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcThread.o -.PHONY : Alc/alcThread.o - -# target to preprocess a source file -Alc/alcThread.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcThread.i -.PHONY : Alc/alcThread.i - -# target to generate assembly for a file -Alc/alcThread.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/alcThread.s -.PHONY : Alc/alcThread.s - -# target to build an object file -Alc/backends/android.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/android.o -.PHONY : Alc/backends/android.o - -# target to preprocess a source file -Alc/backends/android.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/android.i -.PHONY : Alc/backends/android.i - -# target to generate assembly for a file -Alc/backends/android.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/android.s -.PHONY : Alc/backends/android.s - -# target to build an object file -Alc/backends/loopback.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/loopback.o -.PHONY : Alc/backends/loopback.o - -# target to preprocess a source file -Alc/backends/loopback.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/loopback.i -.PHONY : Alc/backends/loopback.i - -# target to generate assembly for a file -Alc/backends/loopback.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/loopback.s -.PHONY : Alc/backends/loopback.s - -# target to build an object file -Alc/backends/null.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/null.o -.PHONY : Alc/backends/null.o - -# target to preprocess a source file -Alc/backends/null.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/null.i -.PHONY : Alc/backends/null.i - -# target to generate assembly for a file -Alc/backends/null.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/null.s -.PHONY : Alc/backends/null.s - -# target to build an object file -Alc/backends/wave.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/wave.o -.PHONY : Alc/backends/wave.o - -# target to preprocess a source file -Alc/backends/wave.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/wave.i -.PHONY : Alc/backends/wave.i - -# target to generate assembly for a file -Alc/backends/wave.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/backends/wave.s -.PHONY : Alc/backends/wave.s - -# target to build an object file -Alc/bs2b.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/bs2b.o -.PHONY : Alc/bs2b.o - -# target to preprocess a source file -Alc/bs2b.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/bs2b.i -.PHONY : Alc/bs2b.i - -# target to generate assembly for a file -Alc/bs2b.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/bs2b.s -.PHONY : Alc/bs2b.s - -# target to build an object file -Alc/helpers.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/helpers.o -.PHONY : Alc/helpers.o - -# target to preprocess a source file -Alc/helpers.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/helpers.i -.PHONY : Alc/helpers.i - -# target to generate assembly for a file -Alc/helpers.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/helpers.s -.PHONY : Alc/helpers.s - -# target to build an object file -Alc/hrtf.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/hrtf.o -.PHONY : Alc/hrtf.o - -# target to preprocess a source file -Alc/hrtf.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/hrtf.i -.PHONY : Alc/hrtf.i - -# target to generate assembly for a file -Alc/hrtf.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/hrtf.s -.PHONY : Alc/hrtf.s - -# target to build an object file -Alc/mixer.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/mixer.o -.PHONY : Alc/mixer.o - -# target to preprocess a source file -Alc/mixer.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/mixer.i -.PHONY : Alc/mixer.i - -# target to generate assembly for a file -Alc/mixer.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/mixer.s -.PHONY : Alc/mixer.s - -# target to build an object file -Alc/panning.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/panning.o -.PHONY : Alc/panning.o - -# target to preprocess a source file -Alc/panning.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/panning.i -.PHONY : Alc/panning.i - -# target to generate assembly for a file -Alc/panning.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/Alc/panning.s -.PHONY : Alc/panning.s - -# target to build an object file -OpenAL32/alAuxEffectSlot.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.o -.PHONY : OpenAL32/alAuxEffectSlot.o - -# target to preprocess a source file -OpenAL32/alAuxEffectSlot.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.i -.PHONY : OpenAL32/alAuxEffectSlot.i - -# target to generate assembly for a file -OpenAL32/alAuxEffectSlot.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alAuxEffectSlot.s -.PHONY : OpenAL32/alAuxEffectSlot.s - -# target to build an object file -OpenAL32/alBuffer.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alBuffer.o -.PHONY : OpenAL32/alBuffer.o - -# target to preprocess a source file -OpenAL32/alBuffer.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alBuffer.i -.PHONY : OpenAL32/alBuffer.i - -# target to generate assembly for a file -OpenAL32/alBuffer.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alBuffer.s -.PHONY : OpenAL32/alBuffer.s - -# target to build an object file -OpenAL32/alEffect.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alEffect.o -.PHONY : OpenAL32/alEffect.o - -# target to preprocess a source file -OpenAL32/alEffect.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alEffect.i -.PHONY : OpenAL32/alEffect.i - -# target to generate assembly for a file -OpenAL32/alEffect.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alEffect.s -.PHONY : OpenAL32/alEffect.s - -# target to build an object file -OpenAL32/alError.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alError.o -.PHONY : OpenAL32/alError.o - -# target to preprocess a source file -OpenAL32/alError.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alError.i -.PHONY : OpenAL32/alError.i - -# target to generate assembly for a file -OpenAL32/alError.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alError.s -.PHONY : OpenAL32/alError.s - -# target to build an object file -OpenAL32/alExtension.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alExtension.o -.PHONY : OpenAL32/alExtension.o - -# target to preprocess a source file -OpenAL32/alExtension.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alExtension.i -.PHONY : OpenAL32/alExtension.i - -# target to generate assembly for a file -OpenAL32/alExtension.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alExtension.s -.PHONY : OpenAL32/alExtension.s - -# target to build an object file -OpenAL32/alFilter.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alFilter.o -.PHONY : OpenAL32/alFilter.o - -# target to preprocess a source file -OpenAL32/alFilter.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alFilter.i -.PHONY : OpenAL32/alFilter.i - -# target to generate assembly for a file -OpenAL32/alFilter.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alFilter.s -.PHONY : OpenAL32/alFilter.s - -# target to build an object file -OpenAL32/alListener.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alListener.o -.PHONY : OpenAL32/alListener.o - -# target to preprocess a source file -OpenAL32/alListener.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alListener.i -.PHONY : OpenAL32/alListener.i - -# target to generate assembly for a file -OpenAL32/alListener.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alListener.s -.PHONY : OpenAL32/alListener.s - -# target to build an object file -OpenAL32/alSource.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alSource.o -.PHONY : OpenAL32/alSource.o - -# target to preprocess a source file -OpenAL32/alSource.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alSource.i -.PHONY : OpenAL32/alSource.i - -# target to generate assembly for a file -OpenAL32/alSource.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alSource.s -.PHONY : OpenAL32/alSource.s - -# target to build an object file -OpenAL32/alState.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alState.o -.PHONY : OpenAL32/alState.o - -# target to preprocess a source file -OpenAL32/alState.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alState.i -.PHONY : OpenAL32/alState.i - -# target to generate assembly for a file -OpenAL32/alState.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alState.s -.PHONY : OpenAL32/alState.s - -# target to build an object file -OpenAL32/alThunk.o: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alThunk.o -.PHONY : OpenAL32/alThunk.o - -# target to preprocess a source file -OpenAL32/alThunk.i: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alThunk.i -.PHONY : OpenAL32/alThunk.i - -# target to generate assembly for a file -OpenAL32/alThunk.s: - $(MAKE) -f CMakeFiles/openal.dir/build.make CMakeFiles/openal.dir/OpenAL32/alThunk.s -.PHONY : OpenAL32/alThunk.s - -# target to build an object file -utils/openal-info.o: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/utils/openal-info.o -.PHONY : utils/openal-info.o - -# target to preprocess a source file -utils/openal-info.i: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/utils/openal-info.i -.PHONY : utils/openal-info.i - -# target to generate assembly for a file -utils/openal-info.s: - $(MAKE) -f CMakeFiles/openal-info.dir/build.make CMakeFiles/openal-info.dir/utils/openal-info.s -.PHONY : utils/openal-info.s - -# Help Target -help: - @echo "The following are some of the valid targets for this Makefile:" - @echo "... all (the default if no target is provided)" - @echo "... clean" - @echo "... depend" - @echo "... edit_cache" - @echo "... install" - @echo "... install/local" - @echo "... install/strip" - @echo "... list_install_components" - @echo "... openal" - @echo "... openal-info" - @echo "... rebuild_cache" - @echo "... Alc/ALc.o" - @echo "... Alc/ALc.i" - @echo "... Alc/ALc.s" - @echo "... Alc/ALu.o" - @echo "... Alc/ALu.i" - @echo "... Alc/ALu.s" - @echo "... Alc/alcConfig.o" - @echo "... Alc/alcConfig.i" - @echo "... Alc/alcConfig.s" - @echo "... Alc/alcDedicated.o" - @echo "... Alc/alcDedicated.i" - @echo "... Alc/alcDedicated.s" - @echo "... Alc/alcEcho.o" - @echo "... Alc/alcEcho.i" - @echo "... Alc/alcEcho.s" - @echo "... Alc/alcModulator.o" - @echo "... Alc/alcModulator.i" - @echo "... Alc/alcModulator.s" - @echo "... Alc/alcReverb.o" - @echo "... Alc/alcReverb.i" - @echo "... Alc/alcReverb.s" - @echo "... Alc/alcRing.o" - @echo "... Alc/alcRing.i" - @echo "... Alc/alcRing.s" - @echo "... Alc/alcThread.o" - @echo "... Alc/alcThread.i" - @echo "... Alc/alcThread.s" - @echo "... Alc/backends/android.o" - @echo "... Alc/backends/android.i" - @echo "... Alc/backends/android.s" - @echo "... Alc/backends/loopback.o" - @echo "... Alc/backends/loopback.i" - @echo "... Alc/backends/loopback.s" - @echo "... Alc/backends/null.o" - @echo "... Alc/backends/null.i" - @echo "... Alc/backends/null.s" - @echo "... Alc/backends/wave.o" - @echo "... Alc/backends/wave.i" - @echo "... Alc/backends/wave.s" - @echo "... Alc/bs2b.o" - @echo "... Alc/bs2b.i" - @echo "... Alc/bs2b.s" - @echo "... Alc/helpers.o" - @echo "... Alc/helpers.i" - @echo "... Alc/helpers.s" - @echo "... Alc/hrtf.o" - @echo "... Alc/hrtf.i" - @echo "... Alc/hrtf.s" - @echo "... Alc/mixer.o" - @echo "... Alc/mixer.i" - @echo "... Alc/mixer.s" - @echo "... Alc/panning.o" - @echo "... Alc/panning.i" - @echo "... Alc/panning.s" - @echo "... OpenAL32/alAuxEffectSlot.o" - @echo "... OpenAL32/alAuxEffectSlot.i" - @echo "... OpenAL32/alAuxEffectSlot.s" - @echo "... OpenAL32/alBuffer.o" - @echo "... OpenAL32/alBuffer.i" - @echo "... OpenAL32/alBuffer.s" - @echo "... OpenAL32/alEffect.o" - @echo "... OpenAL32/alEffect.i" - @echo "... OpenAL32/alEffect.s" - @echo "... OpenAL32/alError.o" - @echo "... OpenAL32/alError.i" - @echo "... OpenAL32/alError.s" - @echo "... OpenAL32/alExtension.o" - @echo "... OpenAL32/alExtension.i" - @echo "... OpenAL32/alExtension.s" - @echo "... OpenAL32/alFilter.o" - @echo "... OpenAL32/alFilter.i" - @echo "... OpenAL32/alFilter.s" - @echo "... OpenAL32/alListener.o" - @echo "... OpenAL32/alListener.i" - @echo "... OpenAL32/alListener.s" - @echo "... OpenAL32/alSource.o" - @echo "... OpenAL32/alSource.i" - @echo "... OpenAL32/alSource.s" - @echo "... OpenAL32/alState.o" - @echo "... OpenAL32/alState.i" - @echo "... OpenAL32/alState.s" - @echo "... OpenAL32/alThunk.o" - @echo "... OpenAL32/alThunk.i" - @echo "... OpenAL32/alThunk.s" - @echo "... utils/openal-info.o" - @echo "... utils/openal-info.i" - @echo "... utils/openal-info.s" -.PHONY : help - - - -#============================================================================= -# Special targets to cleanup operation of make. - -# Special rule to run CMake to check the build system integrity. -# No rule that depends on this can have commands that come from listfiles -# because they might be regenerated. -cmake_check_build_system: - $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 -.PHONY : cmake_check_build_system - diff --git a/jni/openal-soft-android/OpenAL32/Include/alAuxEffectSlot.h b/jni/openal-soft-android/OpenAL32/Include/alAuxEffectSlot.h index cdff330f..c7182d9b 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alAuxEffectSlot.h +++ b/jni/openal-soft-android/OpenAL32/Include/alAuxEffectSlot.h @@ -1,19 +1,69 @@ #ifndef _AL_AUXEFFECTSLOT_H_ #define _AL_AUXEFFECTSLOT_H_ -#include "AL/al.h" +#include "alMain.h" #include "alEffect.h" -#include "alFilter.h" #ifdef __cplusplus extern "C" { #endif -typedef struct ALeffectState ALeffectState; +struct ALeffectStateVtable; +struct ALeffectslot; -typedef struct ALeffectslot -{ - ALeffect effect; +typedef struct ALeffectState { + const struct ALeffectStateVtable *vtbl; +} ALeffectState; + +struct ALeffectStateVtable { + void (*const Destruct)(ALeffectState *state); + + ALboolean (*const deviceUpdate)(ALeffectState *state, ALCdevice *device); + void (*const update)(ALeffectState *state, ALCdevice *device, const struct ALeffectslot *slot); + void (*const process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE]); + + void (*const Delete)(struct ALeffectState *state); +}; + +#define DEFINE_ALEFFECTSTATE_VTABLE(T) \ +DECLARE_THUNK(T, ALeffectState, void, Destruct) \ +DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \ +DECLARE_THUNK2(T, ALeffectState, void, update, ALCdevice*, const ALeffectslot*) \ +DECLARE_THUNK3(T, ALeffectState, void, process, ALuint, const ALfloat*restrict, ALfloatBUFFERSIZE*restrict) \ +DECLARE_THUNK(T, ALeffectState, void, Delete) \ + \ +static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ + T##_ALeffectState_Destruct, \ + \ + T##_ALeffectState_deviceUpdate, \ + T##_ALeffectState_update, \ + T##_ALeffectState_process, \ + \ + T##_ALeffectState_Delete, \ +} + + +struct ALeffectStateFactoryVtable; + +typedef struct ALeffectStateFactory { + const struct ALeffectStateFactoryVtable *vtbl; +} ALeffectStateFactory; + +struct ALeffectStateFactoryVtable { + ALeffectState *(*const create)(ALeffectStateFactory *factory); +}; + +#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \ +DECLARE_THUNK(T, ALeffectStateFactory, ALeffectState*, create) \ + \ +static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \ + T##_ALeffectStateFactory_create, \ +} + + +typedef struct ALeffectslot { + ALenum EffectType; + ALeffectProps EffectProps; volatile ALfloat Gain; volatile ALboolean AuxSendAuto; @@ -21,41 +71,44 @@ typedef struct ALeffectslot volatile ALenum NeedsUpdate; ALeffectState *EffectState; - ALfloat WetBuffer[BUFFERSIZE]; + ALIGN(16) ALfloat WetBuffer[1][BUFFERSIZE]; ALfloat ClickRemoval[1]; ALfloat PendingClicks[1]; RefCount ref; - // Index to itself - ALuint effectslot; - - struct ALeffectslot *next; + /* Self ID */ + ALuint id; } ALeffectslot; +inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) +{ return (struct ALeffectslot*)LookupUIntMapKey(&context->EffectSlotMap, id); } +inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) +{ return (struct ALeffectslot*)RemoveUIntMapKey(&context->EffectSlotMap, id); } +ALenum InitEffectSlot(ALeffectslot *slot); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); -struct ALeffectState { - ALvoid (*Destroy)(ALeffectState *State); - ALboolean (*DeviceUpdate)(ALeffectState *State, ALCdevice *Device); - ALvoid (*Update)(ALeffectState *State, ALCcontext *Context, const ALeffectslot *Slot); - ALvoid (*Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]); -}; +ALeffectStateFactory *ALnullStateFactory_getFactory(void); +ALeffectStateFactory *ALreverbStateFactory_getFactory(void); +ALeffectStateFactory *ALautowahStateFactory_getFactory(void); +ALeffectStateFactory *ALchorusStateFactory_getFactory(void); +ALeffectStateFactory *ALcompressorStateFactory_getFactory(void); +ALeffectStateFactory *ALdistortionStateFactory_getFactory(void); +ALeffectStateFactory *ALechoStateFactory_getFactory(void); +ALeffectStateFactory *ALequalizerStateFactory_getFactory(void); +ALeffectStateFactory *ALflangerStateFactory_getFactory(void); +ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void); -ALeffectState *NoneCreate(void); -ALeffectState *ReverbCreate(void); -ALeffectState *EchoCreate(void); -ALeffectState *ModulatorCreate(void); -ALeffectState *DedicatedCreate(void); +ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); -#define ALeffectState_Destroy(a) ((a)->Destroy((a))) -#define ALeffectState_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b))) -#define ALeffectState_Update(a,b,c) ((a)->Update((a),(b),(c))) -#define ALeffectState_Process(a,b,c,d) ((a)->Process((a),(b),(c),(d))) +ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect); + +void InitEffectFactoryMap(void); +void DeinitEffectFactoryMap(void); #ifdef __cplusplus } diff --git a/jni/openal-soft-android/OpenAL32/Include/alBuffer.h b/jni/openal-soft-android/OpenAL32/Include/alBuffer.h index cacaa716..d22b3b9b 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alBuffer.h +++ b/jni/openal-soft-android/OpenAL32/Include/alBuffer.h @@ -1,7 +1,7 @@ #ifndef _AL_BUFFER_H_ #define _AL_BUFFER_H_ -#include "AL/al.h" +#include "alMain.h" #ifdef __cplusplus extern "C" { @@ -9,34 +9,33 @@ extern "C" { /* User formats */ enum UserFmtType { - UserFmtByte = AL_BYTE, - UserFmtUByte = AL_UNSIGNED_BYTE, - UserFmtShort = AL_SHORT, - UserFmtUShort = AL_UNSIGNED_SHORT, - UserFmtInt = AL_INT, - UserFmtUInt = AL_UNSIGNED_INT, - UserFmtFloat = AL_FLOAT, - UserFmtDouble = AL_DOUBLE, - UserFmtMulaw = AL_MULAW, - UserFmtAlaw = AL_ALAW, - UserFmtIMA4 = AL_IMA4, - UserFmtByte3 = AL_BYTE3, - UserFmtUByte3 = AL_UNSIGNED_BYTE3, + UserFmtByte = AL_BYTE_SOFT, + UserFmtUByte = AL_UNSIGNED_BYTE_SOFT, + UserFmtShort = AL_SHORT_SOFT, + UserFmtUShort = AL_UNSIGNED_SHORT_SOFT, + UserFmtInt = AL_INT_SOFT, + UserFmtUInt = AL_UNSIGNED_INT_SOFT, + UserFmtFloat = AL_FLOAT_SOFT, + UserFmtDouble = AL_DOUBLE_SOFT, + UserFmtByte3 = AL_BYTE3_SOFT, + UserFmtUByte3 = AL_UNSIGNED_BYTE3_SOFT, + UserFmtMulaw, + UserFmtAlaw, + UserFmtIMA4, }; enum UserFmtChannels { - UserFmtMono = AL_MONO, - UserFmtStereo = AL_STEREO, - UserFmtRear = AL_REAR, - UserFmtQuad = AL_QUAD, - UserFmtX51 = AL_5POINT1, /* (WFX order) */ - UserFmtX61 = AL_6POINT1, /* (WFX order) */ - UserFmtX71 = AL_7POINT1 /* (WFX order) */ + UserFmtMono = AL_MONO_SOFT, + UserFmtStereo = AL_STEREO_SOFT, + UserFmtRear = AL_REAR_SOFT, + UserFmtQuad = AL_QUAD_SOFT, + UserFmtX51 = AL_5POINT1_SOFT, /* (WFX order) */ + UserFmtX61 = AL_6POINT1_SOFT, /* (WFX order) */ + UserFmtX71 = AL_7POINT1_SOFT, /* (WFX order) */ }; ALuint BytesFromUserFmt(enum UserFmtType type); ALuint ChannelsFromUserFmt(enum UserFmtChannels chans); -static __inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, - enum UserFmtType type) +inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type) { return ChannelsFromUserFmt(chans) * BytesFromUserFmt(type); } @@ -57,17 +56,17 @@ enum FmtChannels { FmtX61 = UserFmtX61, FmtX71 = UserFmtX71, }; +#define MAX_INPUT_CHANNELS (8) ALuint BytesFromFmt(enum FmtType type); ALuint ChannelsFromFmt(enum FmtChannels chans); -static __inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type) +inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type) { return ChannelsFromFmt(chans) * BytesFromFmt(type); } -typedef struct ALbuffer -{ +typedef struct ALbuffer { ALvoid *data; ALsizei Frequency; @@ -84,14 +83,20 @@ typedef struct ALbuffer ALsizei LoopStart; ALsizei LoopEnd; - RefCount ref; // Number of sources using this buffer (deletion can only occur when this is 0) + /* Number of times buffer was attached to a source (deletion can only occur when 0) */ + RefCount ref; RWLock lock; - // Index to itself - ALuint buffer; + /* Self ID */ + ALuint id; } ALbuffer; +inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) +{ return (struct ALbuffer*)LookupUIntMapKey(&device->BufferMap, id); } +inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id) +{ return (struct ALbuffer*)RemoveUIntMapKey(&device->BufferMap, id); } + ALvoid ReleaseALBuffers(ALCdevice *device); #ifdef __cplusplus diff --git a/jni/openal-soft-android/OpenAL32/Include/alEffect.h b/jni/openal-soft-android/OpenAL32/Include/alEffect.h index 566458c6..f656c56a 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alEffect.h +++ b/jni/openal-soft-android/OpenAL32/Include/alEffect.h @@ -1,16 +1,24 @@ #ifndef _AL_EFFECT_H_ #define _AL_EFFECT_H_ -#include "AL/al.h" +#include "alMain.h" #ifdef __cplusplus extern "C" { #endif +struct ALeffect; + enum { EAXREVERB = 0, REVERB, + AUTOWAH, + CHORUS, + COMPRESSOR, + DISTORTION, ECHO, + EQUALIZER, + FLANGER, MODULATOR, DEDICATED, @@ -21,11 +29,41 @@ extern ALboolean DisabledEffects[MAX_EFFECTS]; extern ALfloat ReverbBoost; extern ALboolean EmulateEAXReverb; -typedef struct ALeffect -{ - // Effect type (AL_EFFECT_NULL, ...) - ALenum type; +struct ALeffectVtable { + void (*const setParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint val); + void (*const setParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals); + void (*const setParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val); + void (*const setParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals); + void (*const getParami)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *val); + void (*const getParamiv)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals); + void (*const getParamf)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val); + void (*const getParamfv)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals); +}; + +#define DEFINE_ALEFFECT_VTABLE(T) \ +const struct ALeffectVtable T##_vtable = { \ + T##_setParami, T##_setParamiv, \ + T##_setParamf, T##_setParamfv, \ + T##_getParami, T##_getParamiv, \ + T##_getParamf, T##_getParamfv, \ +} + +extern const struct ALeffectVtable ALeaxreverb_vtable; +extern const struct ALeffectVtable ALreverb_vtable; +extern const struct ALeffectVtable ALautowah_vtable; +extern const struct ALeffectVtable ALchorus_vtable; +extern const struct ALeffectVtable ALcompressor_vtable; +extern const struct ALeffectVtable ALdistortion_vtable; +extern const struct ALeffectVtable ALecho_vtable; +extern const struct ALeffectVtable ALequalizer_vtable; +extern const struct ALeffectVtable ALflanger_vtable; +extern const struct ALeffectVtable ALmodulator_vtable; +extern const struct ALeffectVtable ALnull_vtable; +extern const struct ALeffectVtable ALdedicated_vtable; + + +typedef union ALeffectProps { struct { // Shared Reverb Properties ALfloat Density; @@ -55,6 +93,34 @@ typedef struct ALeffect ALfloat LFReference; } Reverb; + struct { + ALfloat AttackTime; + ALfloat ReleaseTime; + ALfloat PeakGain; + ALfloat Resonance; + } Autowah; + + struct { + ALint Waveform; + ALint Phase; + ALfloat Rate; + ALfloat Depth; + ALfloat Feedback; + ALfloat Delay; + } Chorus; + + struct { + ALboolean OnOff; + } Compressor; + + struct { + ALfloat Edge; + ALfloat Gain; + ALfloat LowpassCutoff; + ALfloat EQCenter; + ALfloat EQBandwidth; + } Distortion; + struct { ALfloat Delay; ALfloat LRDelay; @@ -65,6 +131,29 @@ typedef struct ALeffect ALfloat Spread; } Echo; + struct { + ALfloat Delay; + ALfloat LowCutoff; + ALfloat LowGain; + ALfloat Mid1Center; + ALfloat Mid1Gain; + ALfloat Mid1Width; + ALfloat Mid2Center; + ALfloat Mid2Gain; + ALfloat Mid2Width; + ALfloat HighCutoff; + ALfloat HighGain; + } Equalizer; + + struct { + ALint Waveform; + ALint Phase; + ALfloat Rate; + ALfloat Depth; + ALfloat Feedback; + ALfloat Delay; + } Flanger; + struct { ALfloat Frequency; ALfloat HighPassCutoff; @@ -74,36 +163,33 @@ typedef struct ALeffect struct { ALfloat Gain; } Dedicated; +} ALeffectProps; - void (*SetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint val); - void (*SetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals); - void (*SetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val); - void (*SetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals); +typedef struct ALeffect { + // Effect type (AL_EFFECT_NULL, ...) + ALenum type; - void (*GetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *val); - void (*GetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals); - void (*GetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val); - void (*GetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals); + ALeffectProps Props; - // Index to itself - ALuint effect; + const struct ALeffectVtable *vtbl; + + /* Self ID */ + ALuint id; } ALeffect; -#define ALeffect_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v))) -#define ALeffect_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v))) -#define ALeffect_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v))) -#define ALeffect_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v))) +inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id) +{ return (struct ALeffect*)LookupUIntMapKey(&device->EffectMap, id); } +inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id) +{ return (struct ALeffect*)RemoveUIntMapKey(&device->EffectMap, id); } -#define ALeffect_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v))) -#define ALeffect_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v))) -#define ALeffect_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v))) -#define ALeffect_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v))) - -static __inline ALboolean IsReverbEffect(ALenum type) +inline ALboolean IsReverbEffect(ALenum type) { return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; } +ALenum InitEffect(ALeffect *effect); ALvoid ReleaseALEffects(ALCdevice *device); +ALvoid LoadReverbPreset(const char *name, ALeffect *effect); + #ifdef __cplusplus } #endif diff --git a/jni/openal-soft-android/OpenAL32/Include/alError.h b/jni/openal-soft-android/OpenAL32/Include/alError.h index f3a9c12d..ab91d27b 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alError.h +++ b/jni/openal-soft-android/OpenAL32/Include/alError.h @@ -1,8 +1,7 @@ #ifndef _AL_ERROR_H_ #define _AL_ERROR_H_ -#include "AL/al.h" -#include "AL/alc.h" +#include "alMain.h" #ifdef __cplusplus extern "C" { @@ -12,6 +11,21 @@ extern ALboolean TrapALError; ALvoid alSetError(ALCcontext *Context, ALenum errorCode); +#define SET_ERROR_AND_RETURN(ctx, err) do { \ + alSetError((ctx), (err)); \ + return; \ +} while(0) + +#define SET_ERROR_AND_RETURN_VALUE(ctx, err, val) do { \ + alSetError((ctx), (err)); \ + return (val); \ +} while(0) + +#define SET_ERROR_AND_GOTO(ctx, err, lbl) do { \ + alSetError((ctx), (err)); \ + goto lbl; \ +} while(0) + #ifdef __cplusplus } #endif diff --git a/jni/openal-soft-android/OpenAL32/Include/alFilter.h b/jni/openal-soft-android/OpenAL32/Include/alFilter.h index 7d1f7ec0..5167c125 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alFilter.h +++ b/jni/openal-soft-android/OpenAL32/Include/alFilter.h @@ -1,73 +1,64 @@ #ifndef _AL_FILTER_H_ #define _AL_FILTER_H_ -#include "AL/al.h" -#include "alu.h" +#include "alMain.h" #ifdef __cplusplus extern "C" { #endif -typedef struct { - ALfloat coeff; -#ifndef _MSC_VER - ALfloat history[0]; -#else - ALfloat history[1]; -#endif -} FILTER; +#define LOWPASSFREQREF (5000) -static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input) + +/* Filters implementation is based on the "Cookbook formulae for audio * + * EQ biquad filter coefficients" by Robert Bristow-Johnson * + * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ + +typedef enum ALfilterType { + ALfilterType_HighShelf, + ALfilterType_LowShelf, + ALfilterType_Peaking, + + ALfilterType_LowPass, + ALfilterType_HighPass, + ALfilterType_BandPass, +} ALfilterType; + +typedef struct ALfilterState { + ALfloat x[2]; /* History of two last input samples */ + ALfloat y[2]; /* History of two last output samples */ + ALfloat a[3]; /* Transfer function coefficients "a" */ + ALfloat b[3]; /* Transfer function coefficients "b" */ +} ALfilterState; + +void ALfilterState_clear(ALfilterState *filter); +void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth); + +inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample) { - ALfloat *history = &iir->history[offset*2]; - ALfloat a = iir->coeff; - ALfloat output = input; + ALfloat outsmp; - output = output + (history[0]-output)*a; - history[0] = output; - output = output + (history[1]-output)*a; - history[1] = output; + outsmp = filter->b[0] * sample + + filter->b[1] * filter->x[0] + + filter->b[2] * filter->x[1] - + filter->a[1] * filter->y[0] - + filter->a[2] * filter->y[1]; + filter->x[1] = filter->x[0]; + filter->x[0] = sample; + filter->y[1] = filter->y[0]; + filter->y[0] = outsmp; - return output; -} -static __inline ALfloat lpFilter1P(FILTER *iir, ALuint offset, ALfloat input) -{ - ALfloat *history = &iir->history[offset]; - ALfloat a = iir->coeff; - ALfloat output = input; - - output = output + (history[0]-output)*a; - history[0] = output; - - return output; + return outsmp; } -static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input) +inline ALfloat ALfilterState_processSingleC(const ALfilterState *filter, ALfloat sample) { - const ALfloat *history = &iir->history[offset*2]; - ALfloat a = iir->coeff; - ALfloat output = input; - - output = output + (history[0]-output)*a; - output = output + (history[1]-output)*a; - - return output; + return filter->b[0] * sample + + filter->b[1] * filter->x[0] + + filter->b[2] * filter->x[1] - + filter->a[1] * filter->y[0] - + filter->a[2] * filter->y[1]; } -static __inline ALfloat lpFilter1PC(FILTER *iir, ALuint offset, ALfloat input) -{ - const ALfloat *history = &iir->history[offset]; - ALfloat a = iir->coeff; - ALfloat output = input; - - output = output + (history[0]-output)*a; - - return output; -} - -/* Calculates the low-pass filter coefficient given the pre-scaled gain and - * cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole, - * sqrt(gain) for four-pole, etc) */ -ALfloat lpCoeffCalc(ALfloat g, ALfloat cw); typedef struct ALfilter { @@ -87,8 +78,8 @@ typedef struct ALfilter { void (*GetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val); void (*GetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals); - // Index to itself - ALuint filter; + /* Self ID */ + ALuint id; } ALfilter; #define ALfilter_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v))) @@ -101,6 +92,11 @@ typedef struct ALfilter { #define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v))) #define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v))) +inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id) +{ return (struct ALfilter*)LookupUIntMapKey(&device->FilterMap, id); } +inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id) +{ return (struct ALfilter*)RemoveUIntMapKey(&device->FilterMap, id); } + ALvoid ReleaseALFilters(ALCdevice *device); #ifdef __cplusplus diff --git a/jni/openal-soft-android/OpenAL32/Include/alListener.h b/jni/openal-soft-android/OpenAL32/Include/alListener.h index 0f399e5f..ee07d87c 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alListener.h +++ b/jni/openal-soft-android/OpenAL32/Include/alListener.h @@ -1,20 +1,24 @@ #ifndef _AL_LISTENER_H_ #define _AL_LISTENER_H_ -#include "AL/al.h" +#include "alMain.h" #ifdef __cplusplus extern "C" { #endif -typedef struct ALlistener_struct -{ +typedef struct ALlistener { volatile ALfloat Position[3]; volatile ALfloat Velocity[3]; volatile ALfloat Forward[3]; volatile ALfloat Up[3]; volatile ALfloat Gain; volatile ALfloat MetersPerUnit; + + struct { + ALfloat Matrix[4][4]; + ALfloat Velocity[3]; + } Params; } ALlistener; #ifdef __cplusplus diff --git a/jni/openal-soft-android/OpenAL32/Include/alMain.h b/jni/openal-soft-android/OpenAL32/Include/alMain.h index 147518c5..b6a9f0ae 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alMain.h +++ b/jni/openal-soft-android/OpenAL32/Include/alMain.h @@ -4,504 +4,412 @@ #include #include #include +#include +#include + +#ifdef HAVE_STRINGS_H +#include +#endif #ifdef HAVE_FENV_H #include #endif -#ifdef HAVE_FPU_CONTROL_H -#include -#endif - #include "AL/al.h" #include "AL/alc.h" #include "AL/alext.h" -#ifndef ALC_SOFT_device_loopback -#define ALC_SOFT_device_loopback 1 -#define ALC_FORMAT_CHANNELS_SOFT 0x1990 -#define ALC_FORMAT_TYPE_SOFT 0x1991 +#include "atomic.h" +#include "uintmap.h" -/* Sample types */ -#define ALC_BYTE 0x1400 -#define ALC_UNSIGNED_BYTE 0x1401 -#define ALC_SHORT 0x1402 -#define ALC_UNSIGNED_SHORT 0x1403 -#define ALC_INT 0x1404 -#define ALC_UNSIGNED_INT 0x1405 -#define ALC_FLOAT 0x1406 +#ifndef ALC_SOFT_HRTF +#define ALC_SOFT_HRTF 1 +#define ALC_HRTF_SOFT 0x1992 +#endif -/* Channel configurations */ -#define ALC_MONO 0x1500 -#define ALC_STEREO 0x1501 -#define ALC_QUAD 0x1503 -#define ALC_5POINT1 0x1504 /* (WFX order) */ -#define ALC_6POINT1 0x1505 /* (WFX order) */ -#define ALC_7POINT1 0x1506 /* (WFX order) */ +#ifndef ALC_SOFT_midi_interface +#define ALC_SOFT_midi_interface 1 +#define AL_MIDI_CLOCK_SOFT 0x9999 +#define AL_MIDI_STATE_SOFT 0x9986 +#define AL_MIDI_GAIN_SOFT 0x9998 +#define AL_MIDI_PRESET_SOFT 0x9997 +#define AL_MIDI_BANK_SOFT 0x9996 +#define AL_SOUNDFONTS_SIZE_SOFT 0x9995 +#define AL_SOUNDFONTS_SOFT 0x9994 +#define AL_PRESETS_SIZE_SOFT 0x9993 +#define AL_PRESETS_SOFT 0x9992 +#define AL_FONTSOUNDS_SIZE_SOFT 0x9991 +#define AL_FONTSOUNDS_SOFT 0x9990 -typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(void); -typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); -typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); +#define AL_SOURCE0_INPUT_SOFT 0x998F +#define AL_SOURCE0_TYPE_SOFT 0x998E +#define AL_SOURCE0_FORM_SOFT 0x998D +#define AL_SOURCE1_INPUT_SOFT 0x998C +#define AL_SOURCE1_TYPE_SOFT 0x998B +#define AL_SOURCE1_FORM_SOFT 0x998A +#define AL_AMOUNT_SOFT 0x9989 +#define AL_TRANSFORM_OP_SOFT 0x9988 +#define AL_DESTINATION_SOFT 0x9987 + +/* Sounce Input */ +#define AL_ONE_SOFT 0x0080 +#define AL_NOTEON_VELOCITY_SOFT 0x0082 +#define AL_NOTEON_KEY_SOFT 0x0083 +/* AL_KEYPRESSURE_SOFT */ +/* AL_CHANNELPRESSURE_SOFT */ +/* AL_PITCHBEND_SOFT */ +#define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090 +/* CC 0...127 */ + +/* Source Type */ +#define AL_UNORM_SOFT 0x0000 +#define AL_UNORM_REV_SOFT 0x0100 +#define AL_SNORM_SOFT 0x0200 +#define AL_SNORM_REV_SOFT 0x0300 + +/* Source Form */ +#define AL_LINEAR_SOFT 0x0000 +#define AL_CONCAVE_SOFT 0x0400 +#define AL_CONVEX_SOFT 0x0800 +#define AL_SWITCH_SOFT 0x0C00 + +/* Transform op */ +/* AL_LINEAR_SOFT */ +#define AL_ABSOLUTE_SOFT 0x0002 + +#define AL_SAMPLE_START_SOFT 0x2000 +#define AL_SAMPLE_END_SOFT 0x2001 +#define AL_SAMPLE_LOOP_START_SOFT 0x2002 +#define AL_SAMPLE_LOOP_END_SOFT 0x2003 +#define AL_SAMPLE_RATE_SOFT 0x2004 +#define AL_BASE_KEY_SOFT 0x2005 +#define AL_KEY_CORRECTION_SOFT 0x2006 +#define AL_SAMPLE_TYPE_SOFT 0x2007 +#define AL_FONTSOUND_LINK_SOFT 0x2008 +#define AL_MOD_LFO_TO_PITCH_SOFT 0x0005 +#define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006 +#define AL_MOD_ENV_TO_PITCH_SOFT 0x0007 +#define AL_FILTER_CUTOFF_SOFT 0x0008 +#define AL_FILTER_RESONANCE_SOFT 0x0009 +#define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A +#define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B +#define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D +#define AL_CHORUS_SEND_SOFT 0x000F +#define AL_REVERB_SEND_SOFT 0x0010 +#define AL_PAN_SOFT 0x0011 +#define AL_MOD_LFO_DELAY_SOFT 0x0015 +#define AL_MOD_LFO_FREQUENCY_SOFT 0x0016 +#define AL_VIBRATO_LFO_DELAY_SOFT 0x0017 +#define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018 +#define AL_MOD_ENV_DELAYTIME_SOFT 0x0019 +#define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A +#define AL_MOD_ENV_HOLDTIME_SOFT 0x001B +#define AL_MOD_ENV_DECAYTIME_SOFT 0x001C +#define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D +#define AL_MOD_ENV_RELEASETIME_SOFT 0x002E +#define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F +#define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020 +#define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021 +#define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022 +#define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023 +#define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024 +#define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025 +#define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026 +#define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027 +#define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028 +#define AL_KEY_RANGE_SOFT 0x002B +#define AL_VELOCITY_RANGE_SOFT 0x002C +#define AL_ATTENUATION_SOFT 0x0030 +#define AL_TUNING_COARSE_SOFT 0x0033 +#define AL_TUNING_FINE_SOFT 0x0034 +#define AL_LOOP_MODE_SOFT 0x0036 +#define AL_TUNING_SCALE_SOFT 0x0038 +#define AL_EXCLUSIVE_CLASS_SOFT 0x0039 +#define AL_LOOP_CONTINUOUS_SOFT 0x0001 +#define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003 +#define AL_RIGHT_SOFT 0x0002 +#define AL_LEFT_SOFT 0x0004 +#define AL_FORMAT_TYPE_SOFT 0x1991 +#define AL_NOTEOFF_SOFT 0x0080 +#define AL_NOTEON_SOFT 0x0090 +#define AL_KEYPRESSURE_SOFT 0x00A0 +#define AL_CONTROLLERCHANGE_SOFT 0x00B0 +#define AL_PROGRAMCHANGE_SOFT 0x00C0 +#define AL_CHANNELPRESSURE_SOFT 0x00D0 +#define AL_PITCHBEND_SOFT 0x00E0 +typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids); +typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids); +typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id); +typedef void (AL_APIENTRY*LPALSOUNDFONTSAMPLESSOFT)(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples); +typedef void (AL_APIENTRY*LPALGETSOUNDFONTSAMPLESSOFT)(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples); +typedef ALvoid* (AL_APIENTRY*LPALSOUNDFONTMAPSAMPLESSOFT)(ALuint sfid, ALsizei offset, ALsizei length); +typedef void (AL_APIENTRY*LPALSOUNDFONTUNMAPSAMPLESSOFT)(ALuint sfid); +typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values); +typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids); +typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids); +typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids); +typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id); +typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value); +typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values); +typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids); +typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values); +typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids); +typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids); +typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id); +typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value); +typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2); +typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values); +typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values); +typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value); +typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values); +typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id); +typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids); +typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); +typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size); +typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void); +typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void); +typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void); +typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void); +typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value); +typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname); +typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values); +typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user); #ifdef AL_ALEXT_PROTOTYPES -ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(void); -ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); -ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids); +AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids); +AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id); +AL_API void AL_APIENTRY alSoundfontSamplesSOFT(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples); +AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples); +AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint sfid, ALsizei offset, ALsizei length); +AL_API void AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint sfid); +AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values); +AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids); + +AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids); +AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids); +AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id); +AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value); +AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values); +AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values); +AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids); + +AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids); +AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids); +AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id); +AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value); +AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2); +AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values); +AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values); +AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value); +AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values); + +AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id); +AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids); +AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); +AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size); +AL_API void AL_APIENTRY alMidiPlaySOFT(void); +AL_API void AL_APIENTRY alMidiPauseSOFT(void); +AL_API void AL_APIENTRY alMidiStopSOFT(void); +AL_API void AL_APIENTRY alMidiResetSOFT(void); +AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value); +AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname); +AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values); +AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user); #endif #endif -#ifndef AL_SOFT_buffer_samples -#define AL_SOFT_buffer_samples 1 -/* Sample types */ -#define AL_BYTE 0x1400 -#define AL_UNSIGNED_BYTE 0x1401 -#define AL_SHORT 0x1402 -#define AL_UNSIGNED_SHORT 0x1403 -#define AL_INT 0x1404 -#define AL_UNSIGNED_INT 0x1405 -#define AL_FLOAT 0x1406 -#define AL_DOUBLE 0x1407 -#define AL_BYTE3 0x1408 -#define AL_UNSIGNED_BYTE3 0x1409 -#define AL_MULAW 0x1410 -#define AL_ALAW 0x1411 -#define AL_IMA4 0x1412 - -/* Channel configurations */ -#define AL_MONO 0x1500 -#define AL_STEREO 0x1501 -#define AL_REAR 0x1502 -#define AL_QUAD 0x1503 -#define AL_5POINT1 0x1504 /* (WFX order) */ -#define AL_6POINT1 0x1505 /* (WFX order) */ -#define AL_7POINT1 0x1506 /* (WFX order) */ - -/* Storage formats */ -#define AL_MONO8 0x1100 -#define AL_MONO16 0x1101 -#define AL_MONO32F 0x10010 -#define AL_STEREO8 0x1102 -#define AL_STEREO16 0x1103 -#define AL_STEREO32F 0x10011 -#define AL_QUAD8 0x1204 -#define AL_QUAD16 0x1205 -#define AL_QUAD32F 0x1206 -#define AL_REAR8 0x1207 -#define AL_REAR16 0x1208 -#define AL_REAR32F 0x1209 -#define AL_5POINT1_8 0x120A -#define AL_5POINT1_16 0x120B -#define AL_5POINT1_32F 0x120C -#define AL_6POINT1_8 0x120D -#define AL_6POINT1_16 0x120E -#define AL_6POINT1_32F 0x120F -#define AL_7POINT1_8 0x1210 -#define AL_7POINT1_16 0x1211 -#define AL_7POINT1_32F 0x1212 - -/* Buffer attributes */ -#define AL_INTERNAL_FORMAT 0x2008 -#define AL_BYTE_LENGTH 0x2009 -#define AL_SAMPLE_LENGTH 0x200A -#define AL_SEC_LENGTH 0x200B - -typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); -typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); -typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*); -typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); +#ifndef ALC_SOFT_pause_device +#define ALC_SOFT_pause_device 1 +typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device); +typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device); #ifdef AL_ALEXT_PROTOTYPES -AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, - ALuint samplerate, ALenum internalformat, ALsizei samples, - ALenum channels, ALenum type, const ALvoid *data); -AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, - ALsizei offset, ALsizei samples, - ALenum channels, ALenum type, const ALvoid *data); -AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, - ALsizei offset, ALsizei samples, - ALenum channels, ALenum type, ALvoid *data); -AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); -#endif -#endif - -#ifndef AL_SOFT_non_virtual_channels -#define AL_SOFT_non_virtual_channels 1 -#define AL_VIRTUAL_CHANNELS_SOFT 0x1033 -#endif - -#ifndef AL_SOFT_deferred_updates -#define AL_SOFT_deferred_updates 1 -#define AL_DEFERRED_UPDATES_SOFT 0xC002 -typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void); -typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void); -#ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void); -AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); +ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device); +ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device); #endif #endif -#if defined(HAVE_STDINT_H) -#include -typedef int64_t ALint64; -typedef uint64_t ALuint64; -#elif defined(HAVE___INT64) -typedef __int64 ALint64; -typedef unsigned __int64 ALuint64; -#elif (SIZEOF_LONG == 8) -typedef long ALint64; -typedef unsigned long ALuint64; -#elif (SIZEOF_LONG_LONG == 8) -typedef long long ALint64; -typedef unsigned long long ALuint64; +#ifdef IN_IDE_PARSER +/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but + * recent versions (at least 4.5.1) do recognize GCC's __restrict. */ +#define restrict __restrict +/* KDevelop won't see the ALIGN macro from config.h when viewing files that + * don't include it directly (e.g. headers). */ +#ifndef ALIGN +#define ALIGN(x) #endif +#endif + + +typedef ALint64SOFT ALint64; +typedef ALuint64SOFT ALuint64; typedef ptrdiff_t ALintptrEXT; typedef ptrdiff_t ALsizeiptrEXT; +#ifndef U64 +#if defined(_MSC_VER) +#define U64(x) ((ALuint64)(x##ui64)) +#elif SIZEOF_LONG == 8 +#define U64(x) ((ALuint64)(x##ul)) +#elif SIZEOF_LONG_LONG == 8 +#define U64(x) ((ALuint64)(x##ull)) +#endif +#endif + +#ifndef UINT64_MAX +#define UINT64_MAX U64(18446744073709551615) +#endif + +#ifndef UNUSED +#if defined(__cplusplus) +#define UNUSED(x) +#elif defined(__GNUC__) +#define UNUSED(x) UNUSED_##x __attribute__((unused)) +#elif defined(__LCLINT__) +#define UNUSED(x) /*@unused@*/ x +#else +#define UNUSED(x) x +#endif +#endif + #ifdef HAVE_GCC_FORMAT #define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y)))) #else #define PRINTF_STYLE(x, y) #endif -#if defined(HAVE_RESTRICT) -#define RESTRICT restrict -#elif defined(HAVE___RESTRICT) -#define RESTRICT __restrict +#if defined(__GNUC__) && defined(__i386__) +/* force_align_arg_pointer is required for proper function arguments aligning + * when SSE code is used. Some systems (Windows, QNX) do not guarantee our + * thread functions will be properly aligned on the stack, even though GCC may + * generate code with the assumption that it is. */ +#define FORCE_ALIGN __attribute__((force_align_arg_pointer)) #else -#define RESTRICT +#define FORCE_ALIGN #endif -#ifdef _WIN32 +static const union { + ALuint u; + ALubyte b[sizeof(ALuint)]; +} EndianTest = { 1 }; +#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1) -#include - -typedef DWORD pthread_key_t; -int pthread_key_create(pthread_key_t *key, void (*callback)(void*)); -int pthread_key_delete(pthread_key_t key); -void *pthread_getspecific(pthread_key_t key); -int pthread_setspecific(pthread_key_t key, void *val); - -#define HAVE_DYNLOAD 1 -void *LoadLib(const char *name); -void CloseLib(void *handle); -void *GetSymbol(void *handle, const char *name); - -typedef LONG pthread_once_t; -#define PTHREAD_ONCE_INIT 0 -void pthread_once(pthread_once_t *once, void (*callback)(void)); - -static __inline int sched_yield(void) -{ SwitchToThread(); return 0; } - -#else - -#include -#include -#include -#ifdef HAVE_PTHREAD_NP_H -#include -#endif -#include -#include -#include - -#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0) - -typedef pthread_mutex_t CRITICAL_SECTION; -void InitializeCriticalSection(CRITICAL_SECTION *cs); -void DeleteCriticalSection(CRITICAL_SECTION *cs); -void EnterCriticalSection(CRITICAL_SECTION *cs); -void LeaveCriticalSection(CRITICAL_SECTION *cs); - -ALuint timeGetTime(void); -void Sleep(ALuint t); - -#if defined(HAVE_DLFCN_H) -#define HAVE_DYNLOAD 1 -void *LoadLib(const char *name); -void CloseLib(void *handle); -void *GetSymbol(void *handle, const char *name); -#endif - -#endif - -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) -typedef ALuint RefCount; -static __inline RefCount IncrementRef(volatile RefCount *ptr) -{ return __sync_add_and_fetch(ptr, 1); } -static __inline RefCount DecrementRef(volatile RefCount *ptr) -{ return __sync_sub_and_fetch(ptr, 1); } - -static __inline int ExchangeInt(volatile int *ptr, int newval) -{ - return __sync_lock_test_and_set(ptr, newval); -} -static __inline void *ExchangePtr(void *volatile*ptr, void *newval) -{ - return __sync_lock_test_and_set(ptr, newval); -} -static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) -{ - return __sync_bool_compare_and_swap(ptr, oldval, newval); -} -static __inline ALboolean CompExchangePtr(void *volatile*ptr, void *oldval, void *newval) -{ - return __sync_bool_compare_and_swap(ptr, oldval, newval); -} - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - -static __inline int xaddl(volatile int *dest, int incr) -{ - int ret; - __asm__ __volatile__("lock; xaddl %0,(%1)" - : "=r" (ret) - : "r" (dest), "0" (incr) - : "memory"); - return ret; -} - -typedef int RefCount; -static __inline RefCount IncrementRef(volatile RefCount *ptr) -{ return xaddl(ptr, 1)+1; } -static __inline RefCount DecrementRef(volatile RefCount *ptr) -{ return xaddl(ptr, -1)-1; } - -static __inline int ExchangeInt(volatile int *dest, int newval) -{ - int ret; - __asm__ __volatile__("lock; xchgl %0,(%1)" - : "=r" (ret) - : "r" (dest), "0" (newval) - : "memory"); - return ret; -} - -static __inline ALboolean CompExchangeInt(volatile int *dest, int oldval, int newval) -{ - int ret; - __asm__ __volatile__("lock; cmpxchgl %2,(%1)" - : "=a" (ret) - : "r" (dest), "r" (newval), "0" (oldval) - : "memory"); - return ret == oldval; -} - -static __inline void *ExchangePtr(void *volatile*dest, void *newval) -{ - void *ret; - __asm__ __volatile__( -#ifdef __i386__ - "lock; xchgl %0,(%1)" -#else - "lock; xchgq %0,(%1)" -#endif - : "=r" (ret) - : "r" (dest), "0" (newval) - : "memory" - ); - return ret; -} - -static __inline ALboolean CompExchangePtr(void *volatile*dest, void *oldval, void *newval) -{ - void *ret; - __asm__ __volatile__( -#ifdef __i386__ - "lock; cmpxchgl %2,(%1)" -#else - "lock; cmpxchgq %2,(%1)" -#endif - : "=a" (ret) - : "r" (dest), "r" (newval), "0" (oldval) - : "memory" - ); - return ret == oldval; -} - -#elif defined(_WIN32) - -typedef LONG RefCount; -static __inline RefCount IncrementRef(volatile RefCount *ptr) -{ return InterlockedIncrement(ptr); } -static __inline RefCount DecrementRef(volatile RefCount *ptr) -{ return InterlockedDecrement(ptr); } - -extern ALbyte LONG_size_does_not_match_int[(sizeof(LONG)==sizeof(int))?1:-1]; - -static __inline int ExchangeInt(volatile int *ptr, int newval) -{ - union { - volatile int *i; - volatile LONG *l; - } u = { ptr }; - return InterlockedExchange(u.l, newval); -} -static __inline void *ExchangePtr(void *volatile*ptr, void *newval) -{ - return InterlockedExchangePointer(ptr, newval); -} -static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) -{ - union { - volatile int *i; - volatile LONG *l; - } u = { ptr }; - return InterlockedCompareExchange(u.l, newval, oldval) == oldval; -} -static __inline ALboolean CompExchangePtr(void *volatile*ptr, void *oldval, void *newval) -{ - return InterlockedCompareExchangePointer(ptr, newval, oldval) == oldval; -} - -#elif defined(__APPLE__) - -#include - -typedef int32_t RefCount; -static __inline RefCount IncrementRef(volatile RefCount *ptr) -{ return OSAtomicIncrement32Barrier(ptr); } -static __inline RefCount DecrementRef(volatile RefCount *ptr) -{ return OSAtomicDecrement32Barrier(ptr); } - -static __inline int ExchangeInt(volatile int *ptr, int newval) -{ - /* Really? No regular old atomic swap? */ - int oldval; - do { - oldval = *ptr; - } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr)); - return oldval; -} -static __inline void *ExchangePtr(void *volatile*ptr, void *newval) -{ - void *oldval; - do { - oldval = *ptr; - } while(!OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr)); - return oldval; -} -static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval) -{ - return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr); -} -static __inline ALboolean CompExchangePtr(void *volatile*ptr, void *oldval, void *newval) -{ - return OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr); -} - -#else -#error "No atomic functions available on this platform!" -typedef ALuint RefCount; -#endif +#define COUNTOF(x) (sizeof((x))/sizeof((x)[0])) -typedef struct { - volatile RefCount read_count; - volatile RefCount write_count; - volatile ALenum read_lock; - volatile ALenum read_entry_lock; - volatile ALenum write_lock; -} RWLock; - -void RWLockInit(RWLock *lock); -void ReadLock(RWLock *lock); -void ReadUnlock(RWLock *lock); -void WriteLock(RWLock *lock); -void WriteUnlock(RWLock *lock); +#define DERIVE_FROM_TYPE(t) t t##_parent +#define STATIC_CAST(to, obj) (&(obj)->to##_parent) +#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent))) -typedef struct UIntMap { - struct { - ALuint key; - ALvoid *value; - } *array; - ALsizei size; - ALsizei maxsize; - ALsizei limit; - RWLock lock; -} UIntMap; -extern UIntMap TlsDestructor; +#define DECLARE_FORWARD(T1, T2, rettype, func) \ +rettype T1##_##func(T1 *obj) \ +{ return T2##_##func(STATIC_CAST(T2, obj)); } -void InitUIntMap(UIntMap *map, ALsizei limit); -void ResetUIntMap(UIntMap *map); -ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); -ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); -ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key); +#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \ +rettype T1##_##func(T1 *obj, argtype1 a) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a); } -static __inline void LockUIntMapRead(UIntMap *map) -{ ReadLock(&map->lock); } -static __inline void UnlockUIntMapRead(UIntMap *map) -{ ReadUnlock(&map->lock); } -static __inline void LockUIntMapWrite(UIntMap *map) -{ WriteLock(&map->lock); } -static __inline void UnlockUIntMapWrite(UIntMap *map) -{ WriteUnlock(&map->lock); } +#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \ +rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a, b); } + +#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ +rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \ +{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); } + + +#define GET_VTABLE1(T1) (&(T1##_vtable)) +#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable)) + +#define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1)) +#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2)) + +#define DECLARE_THUNK(T1, T2, rettype, func) \ +static rettype T1##_##T2##_##func(T2 *obj) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); } + +#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); } + +#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); } + +#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ +static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \ +{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); } + + +/* Helper to extract an argument list for VCALL. Not used directly. */ +#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__)) + +/* Call a "virtual" method on an object, with arguments. */ +#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS +/* Call a "virtual" method on an object, with no arguments. */ +#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS + +#define DELETE_OBJ(obj) do { \ + if((obj) != NULL) \ + { \ + V0((obj),Destruct)(); \ + V0((obj),Delete)(); \ + } \ +} while(0) -#include "alListener.h" -#include "alu.h" #ifdef __cplusplus extern "C" { #endif - -#define DEFAULT_OUTPUT_RATE (44100) - -#define SPEEDOFSOUNDMETRESPERSEC (343.3f) -#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */ - -#define LOWPASSFREQREF (5000) - - struct Hrtf; -// Find the next power-of-2 for non-power-of-2 numbers. -static __inline ALuint NextPowerOf2(ALuint value) -{ - ALuint powerOf2 = 1; +#define DEFAULT_OUTPUT_RATE (44100) +#define MIN_OUTPUT_RATE (8000) - if(value) + +/* Find the next power-of-2 for non-power-of-2 numbers. */ +inline ALuint NextPowerOf2(ALuint value) +{ + if(value > 0) { value--; - while(value) - { - value >>= 1; - powerOf2 <<= 1; - } + value |= value>>1; + value |= value>>2; + value |= value>>4; + value |= value>>8; + value |= value>>16; } - return powerOf2; + return value+1; } /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero * mode. */ -static __inline ALint fastf2i(ALfloat f) +inline ALint fastf2i(ALfloat f) { +#ifdef HAVE_LRINTF + return lrintf(f); +#elif defined(_MSC_VER) && defined(_M_IX86) ALint i; -#if defined(_MSC_VER) && !defined(_WIN64) __asm fld f __asm fistp i -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - __asm__ __volatile__("flds %1\n\t" - "fistpl %0\n\t" - : "=m" (i) - : "m" (f)); -#else - i = (ALint)f; -#endif return i; +#else + return (ALint)f; +#endif } /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero * mode. */ -static __inline ALuint fastf2u(ALfloat f) +inline ALuint fastf2u(ALfloat f) { return fastf2i(f); } enum DevProbe { - DEVICE_PROBE, ALL_DEVICE_PROBE, CAPTURE_DEVICE_PROBE }; @@ -510,6 +418,7 @@ typedef struct { ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*); void (*ClosePlayback)(ALCdevice*); ALCboolean (*ResetPlayback)(ALCdevice*); + ALCboolean (*StartPlayback)(ALCdevice*); void (*StopPlayback)(ALCdevice*); ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*); @@ -518,22 +427,10 @@ typedef struct { void (*StopCapture)(ALCdevice*); ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint); ALCuint (*AvailableSamples)(ALCdevice*); + + ALint64 (*GetLatency)(ALCdevice*); } BackendFuncs; -struct BackendInfo { - const char *name; - ALCboolean (*Init)(BackendFuncs*); - void (*Deinit)(void); - void (*Probe)(enum DevProbe); - BackendFuncs Funcs; -}; - -ALCboolean alc_alsa_init(BackendFuncs *func_list); -void alc_alsa_deinit(void); -void alc_alsa_probe(enum DevProbe type); -ALCboolean alc_oss_init(BackendFuncs *func_list); -void alc_oss_deinit(void); -void alc_oss_probe(enum DevProbe type); ALCboolean alc_solaris_init(BackendFuncs *func_list); void alc_solaris_deinit(void); void alc_solaris_probe(enum DevProbe type); @@ -555,50 +452,83 @@ void alc_pa_probe(enum DevProbe type); ALCboolean alc_wave_init(BackendFuncs *func_list); void alc_wave_deinit(void); void alc_wave_probe(enum DevProbe type); -ALCboolean alc_pulse_init(BackendFuncs *func_list); -void alc_pulse_deinit(void); -void alc_pulse_probe(enum DevProbe type); ALCboolean alc_ca_init(BackendFuncs *func_list); void alc_ca_deinit(void); void alc_ca_probe(enum DevProbe type); ALCboolean alc_opensl_init(BackendFuncs *func_list); void alc_opensl_deinit(void); void alc_opensl_probe(enum DevProbe type); -ALCboolean alc_android_init(BackendFuncs *func_list); -void alc_android_deinit(void); -void alc_android_probe(enum DevProbe type); -ALCboolean alc_null_init(BackendFuncs *func_list); -void alc_null_deinit(void); -void alc_null_probe(enum DevProbe type); -ALCboolean alc_loopback_init(BackendFuncs *func_list); -void alc_loopback_deinit(void); -void alc_loopback_probe(enum DevProbe type); +ALCboolean alc_qsa_init(BackendFuncs *func_list); +void alc_qsa_deinit(void); +void alc_qsa_probe(enum DevProbe type); + +struct ALCbackend; + + +enum DistanceModel { + InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED, + LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED, + ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED, + InverseDistance = AL_INVERSE_DISTANCE, + LinearDistance = AL_LINEAR_DISTANCE, + ExponentDistance = AL_EXPONENT_DISTANCE, + DisableDistance = AL_NONE, + + DefaultDistanceModel = InverseDistanceClamped +}; + +enum Resampler { + PointResampler, + LinearResampler, + CubicResampler, + + ResamplerMax, +}; + +enum Channel { + FrontLeft = 0, + FrontRight, + FrontCenter, + LFE, + BackLeft, + BackRight, + BackCenter, + SideLeft, + SideRight, + + MaxChannels, +}; /* Device formats */ enum DevFmtType { - DevFmtByte = ALC_BYTE, - DevFmtUByte = ALC_UNSIGNED_BYTE, - DevFmtShort = ALC_SHORT, - DevFmtUShort = ALC_UNSIGNED_SHORT, - DevFmtFloat = ALC_FLOAT + DevFmtByte = ALC_BYTE_SOFT, + DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT, + DevFmtShort = ALC_SHORT_SOFT, + DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT, + DevFmtInt = ALC_INT_SOFT, + DevFmtUInt = ALC_UNSIGNED_INT_SOFT, + DevFmtFloat = ALC_FLOAT_SOFT, + + DevFmtTypeDefault = DevFmtFloat }; enum DevFmtChannels { - DevFmtMono = ALC_MONO, - DevFmtStereo = ALC_STEREO, - DevFmtQuad = ALC_QUAD, - DevFmtX51 = ALC_5POINT1, - DevFmtX61 = ALC_6POINT1, - DevFmtX71 = ALC_7POINT1, + DevFmtMono = ALC_MONO_SOFT, + DevFmtStereo = ALC_STEREO_SOFT, + DevFmtQuad = ALC_QUAD_SOFT, + DevFmtX51 = ALC_5POINT1_SOFT, + DevFmtX61 = ALC_6POINT1_SOFT, + DevFmtX71 = ALC_7POINT1_SOFT, /* Similar to 5.1, except using the side channels instead of back */ - DevFmtX51Side = 0x80000000 | ALC_5POINT1 + DevFmtX51Side = 0x80000000, + + DevFmtChannelsDefault = DevFmtStereo }; ALuint BytesFromDevFmt(enum DevFmtType type); ALuint ChannelsFromDevFmt(enum DevFmtChannels chans); -static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, - enum DevFmtType type) +inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type) { return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type); } @@ -612,15 +542,27 @@ extern const struct EffectList { } EffectList[]; +enum DeviceType { + Playback, + Capture, + Loopback +}; + + +/* Size for temporary storage of buffer data, in ALfloats. Larger values need + * more memory, while smaller values may need more iterations. The value needs + * to be a sensible size, however, as it constrains the max stepping value used + * for mixing, as well as the maximum number of samples per mixing iteration. + */ +#define BUFFERSIZE (2048u) + + struct ALCdevice_struct { volatile RefCount ref; - ALCboolean Connected; - ALboolean IsCaptureDevice; - ALboolean IsLoopbackDevice; - - CRITICAL_SECTION Mutex; + ALCboolean Connected; + enum DeviceType Type; ALuint Frequency; ALuint UpdateSize; @@ -628,7 +570,7 @@ struct ALCdevice_struct enum DevFmtChannels FmtChans; enum DevFmtType FmtType; - ALCchar *szDeviceName; + ALCchar *DeviceName; volatile ALCenum LastError; @@ -650,6 +592,21 @@ struct ALCdevice_struct // Map of Filters for this device UIntMap FilterMap; + // Map of Soundfonts for this device + UIntMap SfontMap; + + // Map of Presets for this device + UIntMap PresetMap; + + // Map of Fontsounds for this device + UIntMap FontsoundMap; + + /* Default soundfont (accessible as ID 0) */ + struct ALsoundfont *DefaultSfont; + + /* MIDI synth engine */ + struct MidiSynth *Synth; + /* HRTF filter tables */ const struct Hrtf *Hrtf; @@ -660,66 +617,73 @@ struct ALCdevice_struct // Device flags ALuint Flags; - // Dry path buffer mix - ALfloat DryBuffer[BUFFERSIZE][MAXCHANNELS]; + ALuint ChannelOffsets[MaxChannels]; - enum Channel DevChannels[MAXCHANNELS]; - - enum Channel Speaker2Chan[MAXCHANNELS]; - ALfloat PanningLUT[LUT_NUM][MAXCHANNELS]; + enum Channel Speaker2Chan[MaxChannels]; + ALfloat SpeakerAngle[MaxChannels]; ALuint NumChan; - ALfloat ClickRemoval[MAXCHANNELS]; - ALfloat PendingClicks[MAXCHANNELS]; + /* Temp storage used for mixing. +1 for the predictive sample. */ + ALIGN(16) ALfloat SampleData1[BUFFERSIZE+1]; + ALIGN(16) ALfloat SampleData2[BUFFERSIZE+1]; + + // Dry path buffer mix + ALIGN(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE]; + + ALIGN(16) ALfloat ClickRemoval[MaxChannels]; + ALIGN(16) ALfloat PendingClicks[MaxChannels]; + + /* Default effect slot */ + struct ALeffectslot *DefaultSlot; // Contexts created on this device ALCcontext *volatile ContextList; + struct ALCbackend *Backend; + BackendFuncs *Funcs; void *ExtraData; // For the backend's use ALCdevice *volatile next; }; -#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b))) -#define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a))) -#define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a))) -#define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a))) -#define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b))) -#define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a))) -#define ALCdevice_StartCapture(a) ((a)->Funcs->StartCapture((a))) -#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a))) -#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c))) -#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a))) - -// Duplicate stereo sources on the side/rear channels -#define DEVICE_DUPLICATE_STEREO (1<<0) // Frequency was requested by the app or config file #define DEVICE_FREQUENCY_REQUEST (1<<1) // Channel configuration was requested by the config file #define DEVICE_CHANNELS_REQUEST (1<<2) +// Sample type was requested by the config file +#define DEVICE_SAMPLE_TYPE_REQUEST (1<<3) +// HRTF was requested by the app +#define DEVICE_HRTF_REQUEST (1<<4) + +// Stereo sources cover 120-degree angles around +/-90 +#define DEVICE_WIDE_STEREO (1<<16) + +// Specifies if the DSP is paused at user request +#define DEVICE_PAUSED (1<<30) // Specifies if the device is currently running #define DEVICE_RUNNING (1<<31) -#define LookupBuffer(m, k) ((struct ALbuffer*)LookupUIntMapKey(&(m)->BufferMap, (k))) -#define LookupEffect(m, k) ((struct ALeffect*)LookupUIntMapKey(&(m)->EffectMap, (k))) -#define LookupFilter(m, k) ((struct ALfilter*)LookupUIntMapKey(&(m)->FilterMap, (k))) -#define RemoveBuffer(m, k) ((struct ALbuffer*)RemoveUIntMapKey(&(m)->BufferMap, (k))) -#define RemoveEffect(m, k) ((struct ALeffect*)RemoveUIntMapKey(&(m)->EffectMap, (k))) -#define RemoveFilter(m, k) ((struct ALfilter*)RemoveUIntMapKey(&(m)->FilterMap, (k))) +/* Invalid channel offset */ +#define INVALID_OFFSET (~0u) + + +/* Must be less than 15 characters (16 including terminating null) for + * compatibility with pthread_setname_np limitations. */ +#define MIXER_THREAD_NAME "alsoft-mixer" struct ALCcontext_struct { volatile RefCount ref; - ALlistener Listener; + struct ALlistener *Listener; UIntMap SourceMap; UIntMap EffectSlotMap; - ALenum LastError; + volatile ALenum LastError; volatile ALenum UpdateSources; @@ -728,7 +692,7 @@ struct ALCcontext_struct volatile ALfloat DopplerFactor; volatile ALfloat DopplerVelocity; - volatile ALfloat flSpeedOfSound; + volatile ALfloat SpeedOfSound; volatile ALenum DeferUpdates; struct ALsource **ActiveSources; @@ -745,27 +709,45 @@ struct ALCcontext_struct ALCcontext *volatile next; }; -#define LookupSource(m, k) ((struct ALsource*)LookupUIntMapKey(&(m)->SourceMap, (k))) -#define LookupEffectSlot(m, k) ((struct ALeffectslot*)LookupUIntMapKey(&(m)->EffectSlotMap, (k))) -#define RemoveSource(m, k) ((struct ALsource*)RemoveUIntMapKey(&(m)->SourceMap, (k))) -#define RemoveEffectSlot(m, k) ((struct ALeffectslot*)RemoveUIntMapKey(&(m)->EffectSlotMap, (k))) - ALCcontext *GetContextRef(void); void ALCcontext_IncRef(ALCcontext *context); void ALCcontext_DecRef(ALCcontext *context); -void AppendDeviceList(const ALCchar *name); -void AppendAllDeviceList(const ALCchar *name); +void AppendAllDevicesList(const ALCchar *name); void AppendCaptureDeviceList(const ALCchar *name); -ALCvoid LockDevice(ALCdevice *device); -ALCvoid UnlockDevice(ALCdevice *device); -ALCvoid LockContext(ALCcontext *context); -ALCvoid UnlockContext(ALCcontext *context); +ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device); + +void ALCdevice_Lock(ALCdevice *device); +void ALCdevice_Unlock(ALCdevice *device); +ALint64 ALCdevice_GetLatency(ALCdevice *device); + +inline void LockContext(ALCcontext *context) +{ ALCdevice_Lock(context->Device); } + +inline void UnlockContext(ALCcontext *context) +{ ALCdevice_Unlock(context->Device); } + + +void *al_malloc(size_t alignment, size_t size); +void *al_calloc(size_t alignment, size_t size); +void al_free(void *ptr); + + +typedef struct { +#ifdef HAVE_FENV_H + DERIVE_FROM_TYPE(fenv_t); +#else + int state; +#endif +#ifdef HAVE_SSE + int sse_state; +#endif +} FPUCtl; +void SetMixerFPUMode(FPUCtl *ctl); +void RestoreFPUMode(const FPUCtl *ctl); -ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr); -ALuint StopThread(ALvoid *thread); typedef struct RingBuffer RingBuffer; RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length); @@ -792,20 +774,30 @@ void SetDefaultWFXChannelOrder(ALCdevice *device); const ALCchar *DevFmtTypeString(enum DevFmtType type); const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans); -#define HRIR_BITS (5) +#define HRIR_BITS (7) #define HRIR_LENGTH (1<= LogRef) \ - AL_PRINT(__VA_ARGS__); \ + AL_PRINT("(--)", __VA_ARGS__); \ } while(0) #define TRACE(...) do { \ if(LogLevel >= LogTrace) \ - AL_PRINT(__VA_ARGS__); \ + AL_PRINT("(II)", __VA_ARGS__); \ } while(0) #define WARN(...) do { \ if(LogLevel >= LogWarning) \ - AL_PRINT(__VA_ARGS__); \ + AL_PRINT("(WW)", __VA_ARGS__); \ } while(0) #define ERR(...) do { \ if(LogLevel >= LogError) \ - AL_PRINT(__VA_ARGS__); \ + AL_PRINT("(EE)", __VA_ARGS__); \ } while(0) extern ALint RTPrioLevel; + +extern ALuint CPUCapFlags; +enum { + CPU_CAP_SSE = 1<<0, + CPU_CAP_SSE2 = 1<<1, + CPU_CAP_NEON = 1<<2, +}; + +void FillCPUCaps(ALuint capfilter); + + +/* Small hack to use a pointer-to-array type as a normal argument type. + * Shouldn't be used directly. */ +typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE]; + + #ifdef __cplusplus } #endif diff --git a/jni/openal-soft-android/OpenAL32/Include/alMidi.h b/jni/openal-soft-android/OpenAL32/Include/alMidi.h new file mode 100644 index 00000000..24e6675f --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/Include/alMidi.h @@ -0,0 +1,166 @@ +#ifndef ALMIDI_H +#define ALMIDI_H + +#include "alMain.h" +#include "atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALsfmodulator { + struct { + ALenum Input; + ALenum Type; + ALenum Form; + } Source[2]; + ALint Amount; + ALenum TransformOp; + ALenum Dest; +} ALsfmodulator; + +typedef struct ALenvelope { + ALint DelayTime; + ALint AttackTime; + ALint HoldTime; + ALint DecayTime; + ALint SustainAttn; + ALint ReleaseTime; + ALint KeyToHoldTime; + ALint KeyToDecayTime; +} ALenvelope; + + +typedef struct ALfontsound { + volatile RefCount ref; + + ALint MinKey, MaxKey; + ALint MinVelocity, MaxVelocity; + + ALint ModLfoToPitch; + ALint VibratoLfoToPitch; + ALint ModEnvToPitch; + + ALint FilterCutoff; + ALint FilterQ; + ALint ModLfoToFilterCutoff; + ALint ModEnvToFilterCutoff; + ALint ModLfoToVolume; + + ALint ChorusSend; + ALint ReverbSend; + + ALint Pan; + + struct { + ALint Delay; + ALint Frequency; + } ModLfo; + struct { + ALint Delay; + ALint Frequency; + } VibratoLfo; + + ALenvelope ModEnv; + ALenvelope VolEnv; + + ALint Attenuation; + + ALint CoarseTuning; + ALint FineTuning; + + ALenum LoopMode; + + ALint TuningScale; + + ALint ExclusiveClass; + + ALuint Start; + ALuint End; + ALuint LoopStart; + ALuint LoopEnd; + ALuint SampleRate; + ALubyte PitchKey; + ALbyte PitchCorrection; + ALenum SampleType; + struct ALfontsound *Link; + + UIntMap ModulatorMap; + + ALuint id; +} ALfontsound; + +void ALfontsound_Destruct(ALfontsound *self); +void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value); +void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value); + +ALfontsound *NewFontsound(ALCcontext *context); + +inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id) +{ return (struct ALfontsound*)LookupUIntMapKey(&device->FontsoundMap, id); } +inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id) +{ return (struct ALfontsound*)RemoveUIntMapKey(&device->FontsoundMap, id); } + +inline struct ALsfmodulator *LookupModulator(ALfontsound *sound, ALuint id) +{ return (struct ALsfmodulator*)LookupUIntMapKey(&sound->ModulatorMap, id); } +inline struct ALsfmodulator *RemoveModulator(ALfontsound *sound, ALuint id) +{ return (struct ALsfmodulator*)RemoveUIntMapKey(&sound->ModulatorMap, id); } + +void ReleaseALFontsounds(ALCdevice *device); + + +typedef struct ALsfpreset { + volatile RefCount ref; + + ALint Preset; /* a.k.a. MIDI program number */ + ALint Bank; /* MIDI bank 0...127, or percussion (bank 128) */ + + ALfontsound **Sounds; + ALsizei NumSounds; + + ALuint id; +} ALsfpreset; + +ALsfpreset *NewPreset(ALCcontext *context); +void DeletePreset(ALsfpreset *preset, ALCdevice *device); + +inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id) +{ return (struct ALsfpreset*)LookupUIntMapKey(&device->PresetMap, id); } +inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id) +{ return (struct ALsfpreset*)RemoveUIntMapKey(&device->PresetMap, id); } + +void ReleaseALPresets(ALCdevice *device); + + +typedef struct ALsoundfont { + volatile RefCount ref; + + ALsfpreset **Presets; + ALsizei NumPresets; + + ALshort *Samples; + ALint NumSamples; + + RWLock Lock; + volatile ALenum Mapped; + + ALuint id; +} ALsoundfont; + +void ALsoundfont_Construct(ALsoundfont *self); +void ALsoundfont_Destruct(ALsoundfont *self); +ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context); +void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device); + +inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id) +{ return (struct ALsoundfont*)LookupUIntMapKey(&device->SfontMap, id); } +inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id) +{ return (struct ALsoundfont*)RemoveUIntMapKey(&device->SfontMap, id); } + +void ReleaseALSoundfonts(ALCdevice *device); + +#ifdef __cplusplus +} +#endif + +#endif /* ALMIDI_H */ diff --git a/jni/openal-soft-android/OpenAL32/Include/alSource.h b/jni/openal-soft-android/OpenAL32/Include/alSource.h index ee2a5cd1..31a0d229 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alSource.h +++ b/jni/openal-soft-android/OpenAL32/Include/alSource.h @@ -3,9 +3,10 @@ #define MAX_SENDS 4 -#include "alFilter.h" +#include "alMain.h" #include "alu.h" -#include "AL/al.h" +#include "alFilter.h" +#include "alBuffer.h" #ifdef __cplusplus extern "C" { @@ -17,56 +18,85 @@ extern "C" { extern enum Resampler DefaultResampler; -extern const ALsizei ResamplerPadding[RESAMPLER_MAX]; -extern const ALsizei ResamplerPrePadding[RESAMPLER_MAX]; +extern const ALsizei ResamplerPadding[ResamplerMax]; +extern const ALsizei ResamplerPrePadding[ResamplerMax]; -typedef struct ALbufferlistitem -{ +typedef struct ALbufferlistitem { struct ALbuffer *buffer; struct ALbufferlistitem *next; struct ALbufferlistitem *prev; } ALbufferlistitem; -typedef struct ALsource -{ - volatile ALfloat flPitch; - volatile ALfloat flGain; - volatile ALfloat flOuterGain; - volatile ALfloat flMinGain; - volatile ALfloat flMaxGain; - volatile ALfloat flInnerAngle; - volatile ALfloat flOuterAngle; - volatile ALfloat flRefDistance; - volatile ALfloat flMaxDistance; - volatile ALfloat flRollOffFactor; - volatile ALfloat vPosition[3]; - volatile ALfloat vVelocity[3]; - volatile ALfloat vOrientation[3]; - volatile ALboolean bHeadRelative; - volatile ALboolean bLooping; - volatile enum DistanceModel DistanceModel; - volatile ALboolean VirtualChannels; +typedef struct HrtfState { + ALboolean Moving; + ALuint Counter; + ALIGN(16) ALfloat History[MAX_INPUT_CHANNELS][SRC_HISTORY_LENGTH]; + ALIGN(16) ALfloat Values[MAX_INPUT_CHANNELS][HRIR_LENGTH][2]; + ALuint Offset; +} HrtfState; - enum Resampler Resampler; +typedef struct HrtfParams { + ALfloat Gain; + ALfloat Dir[3]; + ALIGN(16) ALfloat Coeffs[MAX_INPUT_CHANNELS][HRIR_LENGTH][2]; + ALIGN(16) ALfloat CoeffStep[HRIR_LENGTH][2]; + ALuint Delay[MAX_INPUT_CHANNELS][2]; + ALint DelayStep[2]; + ALuint IrSize; +} HrtfParams; - volatile ALenum state; - ALenum new_state; - ALuint position; - ALuint position_fraction; - - ALbufferlistitem *queue; // Linked list of buffers in queue - ALuint BuffersInQueue; // Number of buffers in queue - ALuint BuffersPlayed; // Number of buffers played on this loop - - ALfloat DirectGain; - ALfloat DirectGainHF; +typedef struct DirectParams { + ALfloat (*OutBuffer)[BUFFERSIZE]; + ALfloat *ClickRemoval; + ALfloat *PendingClicks; struct { - struct ALeffectslot *Slot; - ALfloat WetGain; - ALfloat WetGainHF; - } Send[MAX_SENDS]; + HrtfParams Params; + HrtfState *State; + } Hrtf; + + /* A mixing matrix. First subscript is the channel number of the input data + * (regardless of channel configuration) and the second is the channel + * target (eg. FrontLeft). Not used with HRTF. */ + ALfloat Gains[MAX_INPUT_CHANNELS][MaxChannels]; + + ALfilterState LpFilter[MAX_INPUT_CHANNELS]; +} DirectParams; + +typedef struct SendParams { + ALfloat (*OutBuffer)[BUFFERSIZE]; + ALfloat *ClickRemoval; + ALfloat *PendingClicks; + + /* Gain control, which applies to all input channels to a single (mono) + * output buffer. */ + ALfloat Gain; + + ALfilterState LpFilter[MAX_INPUT_CHANNELS]; +} SendParams; + + +typedef struct ALsource +{ + /** Source properties. */ + volatile ALfloat Pitch; + volatile ALfloat Gain; + volatile ALfloat OuterGain; + volatile ALfloat MinGain; + volatile ALfloat MaxGain; + volatile ALfloat InnerAngle; + volatile ALfloat OuterAngle; + volatile ALfloat RefDistance; + volatile ALfloat MaxDistance; + volatile ALfloat RollOffFactor; + volatile ALfloat Position[3]; + volatile ALfloat Velocity[3]; + volatile ALfloat Orientation[3]; + volatile ALboolean HeadRelative; + volatile ALboolean Looping; + volatile enum DistanceModel DistanceModel; + volatile ALboolean DirectChannels; volatile ALboolean DryGainHFAuto; volatile ALboolean WetGainAuto; @@ -77,59 +107,80 @@ typedef struct ALsource volatile ALfloat RoomRolloffFactor; volatile ALfloat DopplerFactor; - ALint lOffset; - ALint lOffsetType; + enum Resampler Resampler; - // Source Type (Static, Streaming, or Undetermined) - volatile ALint lSourceType; + /** + * Last user-specified offset, and the offset type (bytes, samples, or + * seconds). + */ + ALdouble Offset; + ALenum OffsetType; + /** Source type (static, streaming, or undetermined) */ + volatile ALint SourceType; + + /** Source state (initial, playing, paused, or stopped) */ + volatile ALenum state; + ALenum new_state; + + /** + * Source offset in samples, relative to the currently playing buffer, NOT + * the whole queue, and the fractional (fixed-point) offset to the next + * sample. + */ + ALuint position; + ALuint position_fraction; + + /** Source Buffer Queue info. */ + ALbufferlistitem *queue; + ALuint BuffersInQueue; + ALuint BuffersPlayed; + + /** Current buffer sample info. */ ALuint NumChannels; ALuint SampleSize; - /* HRTF info */ - ALboolean HrtfMoving; - ALuint HrtfCounter; - ALfloat HrtfHistory[MAXCHANNELS][SRC_HISTORY_LENGTH]; - ALfloat HrtfValues[MAXCHANNELS][HRIR_LENGTH][2]; - ALuint HrtfOffset; + /** Direct filter and auxiliary send info. */ + ALfloat DirectGain; + ALfloat DirectGainHF; - /* Current target parameters used for mixing */ struct { - MixerFunc DoMix; + struct ALeffectslot *Slot; + ALfloat Gain; + ALfloat GainHF; + } Send[MAX_SENDS]; + + /** HRTF info. */ + HrtfState Hrtf; + + /** Current target parameters used for mixing. */ + struct { + ResamplerFunc Resample; + DryMixerFunc DryMix; + WetMixerFunc WetMix; ALint Step; - ALfloat HrtfGain; - ALfloat HrtfDir[3]; - ALfloat HrtfCoeffs[MAXCHANNELS][HRIR_LENGTH][2]; - ALuint HrtfDelay[MAXCHANNELS][2]; - ALfloat HrtfCoeffStep[HRIR_LENGTH][2]; - ALint HrtfDelayStep[2]; + DirectParams Direct; - /* A mixing matrix. First subscript is the channel number of the input - * data (regardless of channel configuration) and the second is the - * channel target (eg. FRONT_LEFT) */ - ALfloat DryGains[MAXCHANNELS][MAXCHANNELS]; - - FILTER iirFilter; - ALfloat history[MAXCHANNELS*2]; - - struct { - struct ALeffectslot *Slot; - ALfloat WetGain; - FILTER iirFilter; - ALfloat history[MAXCHANNELS]; - } Send[MAX_SENDS]; + SendParams Send[MAX_SENDS]; } Params; + /** Source needs to update its mixing parameters. */ volatile ALenum NeedsUpdate; + /** Method to update mixing parameters. */ ALvoid (*Update)(struct ALsource *self, const ALCcontext *context); - // Index to itself - ALuint source; + /** Self ID */ + ALuint id; } ALsource; #define ALsource_Update(s,a) ((s)->Update(s,a)) +inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) +{ return (struct ALsource*)LookupUIntMapKey(&context->SourceMap, id); } +inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) +{ return (struct ALsource*)RemoveUIntMapKey(&context->SourceMap, id); } + ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/jni/openal-soft-android/OpenAL32/Include/alState.h b/jni/openal-soft-android/OpenAL32/Include/alState.h deleted file mode 100644 index 332176b0..00000000 --- a/jni/openal-soft-android/OpenAL32/Include/alState.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _AL_STATE_H_ -#define _AL_STATE_H_ - -#include "AL/al.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/jni/openal-soft-android/OpenAL32/Include/alu.h b/jni/openal-soft-android/OpenAL32/Include/alu.h index 7ee2aa31..d88e860c 100644 --- a/jni/openal-soft-android/OpenAL32/Include/alu.h +++ b/jni/openal-soft-android/OpenAL32/Include/alu.h @@ -1,9 +1,7 @@ #ifndef _ALU_H_ #define _ALU_H_ -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" +#include "alMain.h" #include #include @@ -15,77 +13,17 @@ #endif -#define F_PI (3.14159265358979323846f) /* pi */ -#define F_PI_2 (1.57079632679489661923f) /* pi/2 */ +#define F_PI (3.14159265358979323846f) +#define F_PI_2 (1.57079632679489661923f) +#define F_2PI (6.28318530717958647692f) -#ifdef HAVE_POWF -#define aluPow(x,y) (powf((x),(y))) -#else -#define aluPow(x,y) ((ALfloat)pow((double)(x),(double)(y))) +#ifndef FLT_EPSILON +#define FLT_EPSILON (1.19209290e-07f) #endif -#ifdef HAVE_SQRTF -#define aluSqrt(x) (sqrtf((x))) -#else -#define aluSqrt(x) ((ALfloat)sqrt((double)(x))) -#endif +#define DEG2RAD(x) ((ALfloat)(x) * (F_PI/180.0f)) +#define RAD2DEG(x) ((ALfloat)(x) * (180.0f/F_PI)) -#ifdef HAVE_COSF -#define aluCos(x) (cosf((x))) -#else -#define aluCos(x) ((ALfloat)cos((double)(x))) -#endif - -#ifdef HAVE_SINF -#define aluSin(x) (sinf((x))) -#else -#define aluSin(x) ((ALfloat)sin((double)(x))) -#endif - -#ifdef HAVE_ACOSF -#define aluAcos(x) (acosf((x))) -#else -#define aluAcos(x) ((ALfloat)acos((double)(x))) -#endif - -#ifdef HAVE_ASINF -#define aluAsin(x) (asinf((x))) -#else -#define aluAsin(x) ((ALfloat)asin((double)(x))) -#endif - -#ifdef HAVE_ATANF -#define aluAtan(x) (atanf((x))) -#else -#define aluAtan(x) ((ALfloat)atan((double)(x))) -#endif - -#ifdef HAVE_ATAN2F -#define aluAtan2(x,y) (atan2f((x),(y))) -#else -#define aluAtan2(x,y) ((ALfloat)atan2((double)(x),(double)(y))) -#endif - -#ifdef HAVE_FABSF -#define aluFabs(x) (fabsf((x))) -#else -#define aluFabs(x) ((ALfloat)fabs((double)(x))) -#endif - -#ifdef HAVE_LOG10F -#define aluLog10(x) (log10f((x))) -#else -#define aluLog10(x) ((ALfloat)log10((double)(x))) -#endif - -#ifdef HAVE_FLOORF -#define aluFloor(x) (floorf((x))) -#else -#define aluFloor(x) ((ALfloat)floor((double)(x))) -#endif - -#define QUADRANT_NUM 128 -#define LUT_NUM (4 * QUADRANT_NUM) #ifdef __cplusplus extern "C" { @@ -93,101 +31,80 @@ extern "C" { struct ALsource; struct ALbuffer; +struct DirectParams; +struct SendParams; -typedef ALvoid (*MixerFunc)(struct ALsource *self, ALCdevice *Device, - const ALvoid *RESTRICT data, - ALuint *DataPosInt, ALuint *DataPosFrac, - ALuint OutPos, ALuint SamplesToDo, - ALuint BufferSize); +typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment, + ALfloat *restrict dst, ALuint dstlen); -enum Resampler { - POINT_RESAMPLER = 0, - LINEAR_RESAMPLER, - CUBIC_RESAMPLER, +typedef ALvoid (*DryMixerFunc)(const struct DirectParams *params, + const ALfloat *restrict data, ALuint srcchan, + ALuint OutPos, ALuint SamplesToDo, + ALuint BufferSize); +typedef ALvoid (*WetMixerFunc)(const struct SendParams *params, + const ALfloat *restrict data, + ALuint OutPos, ALuint SamplesToDo, + ALuint BufferSize); - RESAMPLER_MAX, - RESAMPLER_MIN = -1, - RESAMPLER_DEFAULT = LINEAR_RESAMPLER -}; -enum Channel { - FRONT_LEFT = 0, - FRONT_RIGHT, - FRONT_CENTER, - LFE, - BACK_LEFT, - BACK_RIGHT, - BACK_CENTER, - SIDE_LEFT, - SIDE_RIGHT, +#define GAIN_SILENCE_THRESHOLD (0.00001f) - MAXCHANNELS -}; - -enum DistanceModel { - InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED, - LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED, - ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED, - InverseDistance = AL_INVERSE_DISTANCE, - LinearDistance = AL_LINEAR_DISTANCE, - ExponentDistance = AL_EXPONENT_DISTANCE, - DisableDistance = AL_NONE -}; - -#define BUFFERSIZE 4096 +#define SPEEDOFSOUNDMETRESPERSEC (343.3f) +#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */ #define FRACTIONBITS (14) #define FRACTIONONE (1< b) ? b : a); } -static __inline ALfloat maxf(ALfloat a, ALfloat b) +inline ALfloat maxf(ALfloat a, ALfloat b) { return ((a > b) ? a : b); } -static __inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max) +inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max) { return minf(max, maxf(min, val)); } -static __inline ALuint minu(ALuint a, ALuint b) +inline ALdouble mind(ALdouble a, ALdouble b) { return ((a > b) ? b : a); } -static __inline ALuint maxu(ALuint a, ALuint b) +inline ALdouble maxd(ALdouble a, ALdouble b) { return ((a > b) ? a : b); } -static __inline ALuint clampu(ALuint val, ALuint min, ALuint max) +inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max) +{ return mind(max, maxd(min, val)); } + +inline ALuint minu(ALuint a, ALuint b) +{ return ((a > b) ? b : a); } +inline ALuint maxu(ALuint a, ALuint b) +{ return ((a > b) ? a : b); } +inline ALuint clampu(ALuint val, ALuint min, ALuint max) { return minu(max, maxu(min, val)); } -static __inline ALint mini(ALint a, ALint b) +inline ALint mini(ALint a, ALint b) { return ((a > b) ? b : a); } -static __inline ALint maxi(ALint a, ALint b) +inline ALint maxi(ALint a, ALint b) { return ((a > b) ? a : b); } -static __inline ALint clampi(ALint val, ALint min, ALint max) +inline ALint clampi(ALint val, ALint min, ALint max) { return mini(max, maxi(min, val)); } -static __inline ALint64 mini64(ALint64 a, ALint64 b) +inline ALint64 mini64(ALint64 a, ALint64 b) { return ((a > b) ? b : a); } -static __inline ALint64 maxi64(ALint64 a, ALint64 b) +inline ALint64 maxi64(ALint64 a, ALint64 b) { return ((a > b) ? a : b); } -static __inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max) +inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max) { return mini64(max, maxi64(min, val)); } +inline ALuint64 minu64(ALuint64 a, ALuint64 b) +{ return ((a > b) ? b : a); } +inline ALuint64 maxu64(ALuint64 a, ALuint64 b) +{ return ((a > b) ? a : b); } +inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max) +{ return minu64(max, maxu64(min, val)); } -static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) + +inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) { return val1 + (val2-val1)*mu; } -static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu) +inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu) { ALfloat mu2 = mu*mu; ALfloat a0 = -0.5f*val0 + 1.5f*val1 + -1.5f*val2 + 0.5f*val3; @@ -199,53 +116,34 @@ static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat } -static __inline int SetMixerFPUMode(void) -{ -#if defined(_FPU_GETCW) && defined(_FPU_SETCW) - fpu_control_t fpuState, newState; - _FPU_GETCW(fpuState); - newState = fpuState&~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE | - _FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO); - newState |= _FPU_SINGLE | _FPU_RC_ZERO; - _FPU_SETCW(newState); -#else - int fpuState; -#if defined(HAVE__CONTROLFP) - fpuState = _controlfp(0, 0); - (void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC); -#elif defined(HAVE_FESETROUND) - fpuState = fegetround(); - fesetround(FE_TOWARDZERO); -#endif -#endif - return fpuState; -} - -static __inline void RestoreFPUMode(int state) -{ -#if defined(_FPU_GETCW) && defined(_FPU_SETCW) - fpu_control_t fpuState = state; - _FPU_SETCW(fpuState); -#elif defined(HAVE__CONTROLFP) - _controlfp(state, _MCW_RC|_MCW_PC); -#elif defined(HAVE_FESETROUND) - fesetround(state); -#endif -} - - ALvoid aluInitPanning(ALCdevice *Device); -ALint aluCart2LUTpos(ALfloat re, ALfloat im); + +/** + * ComputeAngleGains + * + * Sets channel gains based on a given source's angle and its half-width. The + * angle and hwidth parameters are in radians. + */ +void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]); + +/** + * SetGains + * + * Helper to set the appropriate channels to the specified gain. + */ +inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxChannels]) +{ + ComputeAngleGains(device, 0.0f, F_PI, ingain, gains); +} + ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext); ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext); -MixerFunc SelectMixer(enum Resampler Resampler); -MixerFunc SelectHrtfMixer(enum Resampler Resampler); - ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo); ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size); +/* Caller must lock the device. */ ALvoid aluHandleDisconnect(ALCdevice *device); extern ALfloat ConeScale; diff --git a/jni/openal-soft-android/OpenAL32/Include/bs2b.h b/jni/openal-soft-android/OpenAL32/Include/bs2b.h index 3e5cd83c..0f06b1ca 100644 --- a/jni/openal-soft-android/OpenAL32/Include/bs2b.h +++ b/jni/openal-soft-android/OpenAL32/Include/bs2b.h @@ -91,9 +91,6 @@ int bs2b_get_srate(struct bs2b *bs2b); /* Clear buffer */ void bs2b_clear(struct bs2b *bs2b); -/* Return 1 if buffer is clear */ -int bs2b_is_clear(struct bs2b *bs2b); - /* Crossfeeds one stereo sample that are pointed by sample. * [0] - first channel, [1] - second channel. * Returns crossfided samle by sample pointer. diff --git a/jni/openal-soft-android/OpenAL32/Include/threads.h b/jni/openal-soft-android/OpenAL32/Include/threads.h new file mode 100644 index 00000000..26493101 --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/Include/threads.h @@ -0,0 +1,14 @@ +#ifndef AL_THREADS_H +#define AL_THREADS_H + +#include "alMain.h" + +struct althread_info; +typedef struct althread_info* althread_t; + +ALboolean StartThread(althread_t *out, ALuint (*func)(ALvoid*), ALvoid *ptr); +ALuint StopThread(althread_t thread); + +void SetThreadName(const char *name); + +#endif /* AL_THREADS_H */ diff --git a/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c b/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c index c8a12d33..aa071de2 100644 --- a/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c +++ b/jni/openal-soft-android/OpenAL32/alAuxEffectSlot.c @@ -32,574 +32,523 @@ #include "alSource.h" -static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); -static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count); -static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *val); +extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); +extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); + +static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots); +static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot); + + +static UIntMap EffectStateFactoryMap; +static inline ALeffectStateFactory *getFactoryByType(ALenum type) +{ + ALeffectStateFactory* (*getFactory)(void) = LookupUIntMapKey(&EffectStateFactoryMap, type); + if(getFactory != NULL) + return getFactory(); + return NULL; +} AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *context; + ALsizei cur; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - Device = Context->Device; - if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint))) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(cur = 0;cur < n;cur++) { - ALenum err; - ALsizei i, j; + ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); + err = AL_OUT_OF_MEMORY; + if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) + { + al_free(slot); + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); + } - err = ResizeEffectSlotArray(Context, n); + err = NewThunkEntry(&slot->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&context->EffectSlotMap, slot->id, slot); if(err != AL_NO_ERROR) { - alSetError(Context, err); - n = 0; + FreeThunkEntry(slot->id); + DELETE_OBJ(slot->EffectState); + al_free(slot); + + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); } - for(i = 0;i < n;i++) - { - ALeffectslot *slot = calloc(1, sizeof(ALeffectslot)); - if(!slot || !(slot->EffectState=NoneCreate())) - { - free(slot); - // We must have run out or memory - alSetError(Context, AL_OUT_OF_MEMORY); - alDeleteAuxiliaryEffectSlots(i, effectslots); - break; - } - - slot->Gain = 1.0; - slot->AuxSendAuto = AL_TRUE; - slot->NeedsUpdate = AL_FALSE; - for(j = 0;j < BUFFERSIZE;j++) - slot->WetBuffer[j] = 0.0f; - for(j = 0;j < 1;j++) - { - slot->ClickRemoval[j] = 0.0f; - slot->PendingClicks[j] = 0.0f; - } - slot->ref = 0; - - LockContext(Context); - err = ResizeEffectSlotArray(Context, 1); - if(err == AL_NO_ERROR) - Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot; - UnlockContext(Context); - if(err == AL_NO_ERROR) - err = NewThunkEntry(&slot->effectslot); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot); - if(err != AL_NO_ERROR) - { - RemoveEffectSlotArray(Context, slot); - FreeThunkEntry(slot->effectslot); - ALeffectState_Destroy(slot->EffectState); - free(slot); - - alSetError(Context, err); - alDeleteAuxiliaryEffectSlots(i, effectslots); - break; - } - - effectslots[i] = slot->effectslot; - } + effectslots[cur] = slot->id; + } + err = AddEffectSlotArray(context, n, effectslots); + if(err != AL_NO_ERROR) + { + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) { - ALCcontext *Context; - ALeffectslot *EffectSlot; + ALCcontext *context; + ALeffectslot *slot; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - // Check that all effectslots are valid - for(i = 0;i < n;i++) - { - if((EffectSlot=LookupEffectSlot(Context, effectslots[i])) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - n = 0; - break; - } - else if(EffectSlot->ref != 0) - { - alSetError(Context, AL_INVALID_OPERATION); - n = 0; - break; - } - } - - // All effectslots are valid - for(i = 0;i < n;i++) - { - // Recheck that the effectslot is valid, because there could be duplicated names - if((EffectSlot=RemoveEffectSlot(Context, effectslots[i])) == NULL) - continue; - FreeThunkEntry(EffectSlot->effectslot); - - RemoveEffectSlotArray(Context, EffectSlot); - ALeffectState_Destroy(EffectSlot->EffectState); - - memset(EffectSlot, 0, sizeof(ALeffectslot)); - free(EffectSlot); - } + if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(slot->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } - ALCcontext_DecRef(Context); + // All effectslots are valid + for(i = 0;i < n;i++) + { + if((slot=RemoveEffectSlot(context, effectslots[i])) == NULL) + continue; + FreeThunkEntry(slot->id); + + RemoveEffectSlotArray(context, slot); + DELETE_OBJ(slot->EffectState); + + memset(slot, 0, sizeof(*slot)); + al_free(slot); + } + +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) { - ALCcontext *Context; - ALboolean result; + ALCcontext *context; + ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - result = (LookupEffectSlot(Context, effectslot) ? AL_TRUE : AL_FALSE); + ret = (LookupEffectSlot(context, effectslot) ? AL_TRUE : AL_FALSE); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); - return result; + return ret; } -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue) +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value) { - ALCdevice *Device; - ALCcontext *Context; - ALeffectslot *EffectSlot; + ALCdevice *device; + ALCcontext *context; + ALeffectslot *slot; + ALeffect *effect = NULL; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - Device = Context->Device; - if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL) + device = context->Device; + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - case AL_EFFECTSLOT_EFFECT: { - ALeffect *effect = NULL; + case AL_EFFECTSLOT_EFFECT: + effect = (value ? LookupEffect(device, value) : NULL); + if(!(value == 0 || effect != NULL)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if(iValue == 0 || - (effect=LookupEffect(Device, iValue)) != NULL) - { - InitializeEffect(Context, EffectSlot, effect); - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); - } break; + err = InitializeEffect(device, slot, effect); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + context->UpdateSources = AL_TRUE; + break; - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - if(iValue == AL_TRUE || iValue == AL_FALSE) - { - EffectSlot->AuxSendAuto = iValue; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + if(!(value == AL_TRUE || value == AL_FALSE)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + slot->AuxSendAuto = value; + context->UpdateSources = AL_TRUE; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues) +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_EFFECT: - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - alAuxiliaryEffectSloti(effectslot, param, piValues[0]); - return; + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alAuxiliaryEffectSloti(effectslot, param, values[0]); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(LookupEffectSlot(Context, effectslot) != NULL) + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue) +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value) { - ALCcontext *Context; - ALeffectslot *EffectSlot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL) + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - case AL_EFFECTSLOT_GAIN: - if(flValue >= 0.0f && flValue <= 1.0f) - { - EffectSlot->Gain = flValue; - EffectSlot->NeedsUpdate = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + case AL_EFFECTSLOT_GAIN: + if(!(value >= 0.0f && value <= 1.0f)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + slot->Gain = value; + slot->NeedsUpdate = AL_TRUE; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues) +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_GAIN: - alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]); - return; + case AL_EFFECTSLOT_GAIN: + alAuxiliaryEffectSlotf(effectslot, param, values[0]); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(LookupEffectSlot(Context, effectslot) != NULL) + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue) +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *value) { - ALCcontext *Context; - ALeffectslot *EffectSlot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL) + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - case AL_EFFECTSLOT_EFFECT: - *piValue = EffectSlot->effect.effect; - break; + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + *value = slot->AuxSendAuto; + break; - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - *piValue = EffectSlot->AuxSendAuto; - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues) +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_EFFECT: - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - alGetAuxiliaryEffectSloti(effectslot, param, piValues); - return; + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alGetAuxiliaryEffectSloti(effectslot, param, values); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(LookupEffectSlot(Context, effectslot) != NULL) + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue) +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *value) { - ALCcontext *Context; - ALeffectslot *EffectSlot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL) + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - case AL_EFFECTSLOT_GAIN: - *pflValue = EffectSlot->Gain; - break; + case AL_EFFECTSLOT_GAIN: + *value = slot->Gain; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues) +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_GAIN: - alGetAuxiliaryEffectSlotf(effectslot, param, pflValues); - return; + case AL_EFFECTSLOT_GAIN: + alGetAuxiliaryEffectSlotf(effectslot, param, values); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(LookupEffectSlot(Context, effectslot) != NULL) + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - switch(param) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_NAME); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -static ALvoid NoneDestroy(ALeffectState *State) -{ free(State); } -static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device) -{ - return AL_TRUE; - (void)State; - (void)Device; -} -static ALvoid NoneUpdate(ALeffectState *State, ALCcontext *Context, const ALeffectslot *Slot) -{ - (void)State; - (void)Context; - (void)Slot; -} -static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) -{ - (void)State; - (void)SamplesToDo; - (void)SamplesIn; - (void)SamplesOut; -} -ALeffectState *NoneCreate(void) -{ - ALeffectState *state; - - state = calloc(1, sizeof(*state)); - if(!state) - return NULL; - - state->Destroy = NoneDestroy; - state->DeviceUpdate = NoneDeviceUpdate; - state->Update = NoneUpdate; - state->Process = NoneProcess; - - return state; -} - - -static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot) +static ALvoid RemoveEffectSlotArray(ALCcontext *context, ALeffectslot *slot) { ALeffectslot **slotlist, **slotlistend; - LockContext(Context); - slotlist = Context->ActiveEffectSlots; - slotlistend = slotlist + Context->ActiveEffectSlotCount; + LockContext(context); + slotlist = context->ActiveEffectSlots; + slotlistend = slotlist + context->ActiveEffectSlotCount; while(slotlist != slotlistend) { if(*slotlist == slot) { *slotlist = *(--slotlistend); - Context->ActiveEffectSlotCount--; + context->ActiveEffectSlotCount--; break; } slotlist++; } - UnlockContext(Context); + UnlockContext(context); } -static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count) +static ALenum AddEffectSlotArray(ALCcontext *context, ALsizei count, const ALuint *slots) { - ALsizei newcount; - void *temp; + ALsizei i; - if(count <= Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount) - return AL_NO_ERROR; + LockContext(context); + if(count > context->MaxActiveEffectSlots-context->ActiveEffectSlotCount) + { + ALsizei newcount; + void *temp = NULL; - newcount = Context->MaxActiveEffectSlots ? - (Context->MaxActiveEffectSlots<<1) : 1; - if(newcount <= Context->MaxActiveEffectSlots || - !(temp=realloc(Context->ActiveEffectSlots, newcount * - sizeof(*Context->ActiveEffectSlots)))) - return AL_OUT_OF_MEMORY; - - Context->ActiveEffectSlots = temp; - Context->MaxActiveEffectSlots = newcount; + newcount = context->MaxActiveEffectSlots ? (context->MaxActiveEffectSlots<<1) : 1; + if(newcount > context->MaxActiveEffectSlots) + temp = realloc(context->ActiveEffectSlots, + newcount * sizeof(*context->ActiveEffectSlots)); + if(!temp) + { + UnlockContext(context); + return AL_OUT_OF_MEMORY; + } + context->ActiveEffectSlots = temp; + context->MaxActiveEffectSlots = newcount; + } + for(i = 0;i < count;i++) + { + ALeffectslot *slot = LookupEffectSlot(context, slots[i]); + assert(slot != NULL); + context->ActiveEffectSlots[context->ActiveEffectSlotCount++] = slot; + } + UnlockContext(context); return AL_NO_ERROR; } -static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect) + +void InitEffectFactoryMap(void) +{ + InitUIntMap(&EffectStateFactoryMap, ~0); + + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnullStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_REVERB, ALreverbStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_AUTOWAH, ALautowahStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_COMPRESSOR, ALcompressorStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_ECHO, ALechoStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory); +} + +void DeinitEffectFactoryMap(void) +{ + ResetUIntMap(&EffectStateFactoryMap); +} + + +ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); - ALeffectState *State = NULL; - ALenum err = AL_NO_ERROR; + ALeffectStateFactory *factory; - LockContext(Context); - if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL) + if(newtype != EffectSlot->EffectType) { - State = NoneCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_EAXREVERB || newtype == AL_EFFECT_REVERB) - { - if(EffectSlot->effect.type != AL_EFFECT_EAXREVERB && EffectSlot->effect.type != AL_EFFECT_REVERB) + ALeffectState *State; + FPUCtl oldMode; + + factory = getFactoryByType(newtype); + if(!factory) { - State = ReverbCreate(); - if(!State) err = AL_OUT_OF_MEMORY; + ERR("Failed to find factory for effect type 0x%04x\n", newtype); + return AL_INVALID_ENUM; } - } - else if(newtype == AL_EFFECT_ECHO && EffectSlot->effect.type != AL_EFFECT_ECHO) - { - State = EchoCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_RING_MODULATOR && EffectSlot->effect.type != AL_EFFECT_RING_MODULATOR) - { - State = ModulatorCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_DEDICATED_DIALOGUE || newtype == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) - { - if(EffectSlot->effect.type != AL_EFFECT_DEDICATED_DIALOGUE && EffectSlot->effect.type != AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + State = V0(factory,create)(); + if(!State) + return AL_OUT_OF_MEMORY; + + SetMixerFPUMode(&oldMode); + + ALCdevice_Lock(Device); + if(V(State,deviceUpdate)(Device) == AL_FALSE) { - State = DedicatedCreate(); - if(!State) err = AL_OUT_OF_MEMORY; + ALCdevice_Unlock(Device); + RestoreFPUMode(&oldMode); + DELETE_OBJ(State); + return AL_OUT_OF_MEMORY; } - } - - if(err != AL_NO_ERROR) - { - UnlockContext(Context); - alSetError(Context, err); - return; - } - - if(State) - { - int oldMode; - oldMode = SetMixerFPUMode(); - - if(ALeffectState_DeviceUpdate(State, Context->Device) == AL_FALSE) - { - UnlockContext(Context); - ALeffectState_Destroy(State); - alSetError(Context, AL_OUT_OF_MEMORY); - return; - } - State = ExchangePtr((void**)&EffectSlot->EffectState, State); + State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State); if(!effect) - memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); + { + memset(&EffectSlot->EffectProps, 0, sizeof(EffectSlot->EffectProps)); + EffectSlot->EffectType = AL_EFFECT_NULL; + } else - memcpy(&EffectSlot->effect, effect, sizeof(*effect)); + { + memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); + EffectSlot->EffectType = effect->type; + } + /* FIXME: This should be done asynchronously, but since the EffectState * object was changed, it needs an update before its Process method can * be called. */ EffectSlot->NeedsUpdate = AL_FALSE; - ALeffectState_Update(EffectSlot->EffectState, Context, EffectSlot); - UnlockContext(Context); + V(EffectSlot->EffectState,update)(Device, EffectSlot); + ALCdevice_Unlock(Device); - RestoreFPUMode(oldMode); + RestoreFPUMode(&oldMode); - ALeffectState_Destroy(State); + DELETE_OBJ(State); State = NULL; } else { - if(!effect) - memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); - else - memcpy(&EffectSlot->effect, effect, sizeof(*effect)); - UnlockContext(Context); - EffectSlot->NeedsUpdate = AL_TRUE; + if(effect) + { + ALCdevice_Lock(Device); + memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); + ALCdevice_Unlock(Device); + EffectSlot->NeedsUpdate = AL_TRUE; + } } + + return AL_NO_ERROR; } +ALenum InitEffectSlot(ALeffectslot *slot) +{ + ALeffectStateFactory *factory; + ALuint i, c; + + slot->EffectType = AL_EFFECT_NULL; + + factory = getFactoryByType(AL_EFFECT_NULL); + if(!(slot->EffectState=V0(factory,create)())) + return AL_OUT_OF_MEMORY; + + slot->Gain = 1.0; + slot->AuxSendAuto = AL_TRUE; + slot->NeedsUpdate = AL_FALSE; + for(c = 0;c < 1;c++) + { + for(i = 0;i < BUFFERSIZE;i++) + slot->WetBuffer[c][i] = 0.0f; + slot->ClickRemoval[c] = 0.0f; + slot->PendingClicks[c] = 0.0f; + } + slot->ref = 0; + + return AL_NO_ERROR; +} + ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; @@ -608,11 +557,10 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; - // Release effectslot structure - ALeffectState_Destroy(temp->EffectState); + DELETE_OBJ(temp->EffectState); - FreeThunkEntry(temp->effectslot); + FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffectslot)); - free(temp); + al_free(temp); } } diff --git a/jni/openal-soft-android/OpenAL32/alBuffer.c b/jni/openal-soft-android/OpenAL32/alBuffer.c index 083a2fc1..d9c91c2f 100644 --- a/jni/openal-soft-android/OpenAL32/alBuffer.c +++ b/jni/openal-soft-android/OpenAL32/alBuffer.c @@ -26,13 +26,17 @@ #include #include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" +#include "alu.h" #include "alError.h" #include "alBuffer.h" #include "alThunk.h" +extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id); +extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id); +extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type); +extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type); + static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels chans, enum UserFmtType type, const ALvoid *data, ALboolean storesrc); static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len); static ALboolean IsValidType(ALenum type); @@ -46,7 +50,7 @@ static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum Fm */ /* IMA ADPCM Stepsize table */ -static const long IMAStep_size[89] = { +static const int IMAStep_size[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, @@ -59,13 +63,13 @@ static const long IMAStep_size[89] = { }; /* IMA4 ADPCM Codeword decode table */ -static const long IMA4Codeword[16] = { +static const int IMA4Codeword[16] = { 1, 3, 5, 7, 9, 11, 13, 15, -1,-3,-5,-7,-9,-11,-13,-15, }; /* IMA4 ADPCM Step index adjust decode table */ -static const long IMA4Index_adjust[16] = { +static const int IMA4Index_adjust[16] = { -1,-1,-1,-1, 2, 4, 6, 8, -1,-1,-1,-1, 2, 4, 6, 8 }; @@ -181,314 +185,287 @@ static const char aLawCompressTable[128] = { }; -/* - * alGenBuffers(ALsizei n, ALuint *buffers) - * - * Generates n AL Buffers, and stores the Buffers Names in the array pointed - * to by buffers - */ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers) { - ALCcontext *Context; - ALsizei i=0; + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - /* Check that we are actually generating some Buffers */ - if(n < 0 || IsBadWritePtr((void*)buffers, n * sizeof(ALuint))) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) { - ALCdevice *device = Context->Device; - ALenum err; - - // Create all the new Buffers - while(i < n) + ALbuffer *buffer = calloc(1, sizeof(ALbuffer)); + if(!buffer) { - ALbuffer *buffer = calloc(1, sizeof(ALbuffer)); - if(!buffer) - { - alSetError(Context, AL_OUT_OF_MEMORY); - alDeleteBuffers(i, buffers); - break; - } - RWLockInit(&buffer->lock); - - err = NewThunkEntry(&buffer->buffer); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->BufferMap, buffer->buffer, buffer); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(buffer->buffer); - memset(buffer, 0, sizeof(ALbuffer)); - free(buffer); - - alSetError(Context, err); - alDeleteBuffers(i, buffers); - break; - } - - buffers[i++] = buffer->buffer; + alDeleteBuffers(cur, buffers); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } + RWLockInit(&buffer->lock); + + err = NewThunkEntry(&buffer->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(buffer->id); + memset(buffer, 0, sizeof(ALbuffer)); + free(buffer); + + alDeleteBuffers(cur, buffers); + SET_ERROR_AND_GOTO(context, err, done); + } + + buffers[cur] = buffer->id; } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -/* - * alDeleteBuffers(ALsizei n, ALuint *buffers) - * - * Deletes the n AL Buffers pointed to by buffers - */ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) { - ALCcontext *Context; ALCdevice *device; + ALCcontext *context; ALbuffer *ALBuf; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - /* Check we are actually Deleting some Buffers */ - if(n < 0) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) { - /* Check that all the buffers are valid and can actually be deleted */ - for(i = 0;i < n;i++) - { - if(!buffers[i]) - continue; + if(!buffers[i]) + continue; - /* Check for valid Buffer ID */ - if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - n = 0; - break; - } - else if(ALBuf->ref != 0) - { - /* Buffer still in use, cannot be deleted */ - alSetError(Context, AL_INVALID_OPERATION); - n = 0; - break; - } - } - - for(i = 0;i < n;i++) - { - if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL) - continue; - FreeThunkEntry(ALBuf->buffer); - - /* Release the memory used to store audio data */ - free(ALBuf->data); - - /* Release buffer structure */ - memset(ALBuf, 0, sizeof(ALbuffer)); - free(ALBuf); - } + /* Check for valid Buffer ID */ + if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(ALBuf->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } - ALCcontext_DecRef(Context); + for(i = 0;i < n;i++) + { + if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL) + continue; + FreeThunkEntry(ALBuf->id); + + free(ALBuf->data); + + memset(ALBuf, 0, sizeof(*ALBuf)); + free(ALBuf); + } + +done: + ALCcontext_DecRef(context); } -/* - * alIsBuffer(ALuint buffer) - * - * Checks if buffer is a valid Buffer Name - */ AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) { - ALCcontext *Context; - ALboolean result; + ALCcontext *context; + ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - result = ((!buffer || LookupBuffer(Context->Device, buffer)) ? - AL_TRUE : AL_FALSE); + ret = ((!buffer || LookupBuffer(context->Device, buffer)) ? + AL_TRUE : AL_FALSE); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); - return result; + return ret; } -/* - * alBufferData(ALuint buffer, ALenum format, const ALvoid *data, - * ALsizei size, ALsizei freq) - * - * Fill buffer with audio data - */ -AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq) + +AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq) { - enum UserFmtChannels SrcChannels; - enum UserFmtType SrcType; - ALCcontext *Context; + enum UserFmtChannels srcchannels; + enum UserFmtType srctype; ALCdevice *device; - ALbuffer *ALBuf; + ALCcontext *context; + ALuint framesize; + ALenum newformat; + ALbuffer *albuf; ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(size < 0 || freq < 0) - alSetError(Context, AL_INVALID_VALUE); - else if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE) - alSetError(Context, AL_INVALID_ENUM); - else switch(SrcType) + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(size >= 0 && freq > 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + switch(srctype) { case UserFmtByte: case UserFmtUByte: case UserFmtShort: case UserFmtUShort: + case UserFmtFloat: + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + err = LoadData(albuf, freq, format, size/framesize, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; + case UserFmtInt: case UserFmtUInt: - case UserFmtFloat: { - ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType); - if((size%FrameSize) != 0) - err = AL_INVALID_VALUE; - else - err = LoadData(ALBuf, freq, format, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); - if(err != AL_NO_ERROR) - alSetError(Context, err); - } break; - case UserFmtByte3: case UserFmtUByte3: - case UserFmtDouble: { - ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType); - ALenum NewFormat = AL_FORMAT_MONO_FLOAT32; - switch(SrcChannels) + case UserFmtDouble: + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO_FLOAT32; + switch(srcchannels) { - case UserFmtMono: NewFormat = AL_FORMAT_MONO_FLOAT32; break; - case UserFmtStereo: NewFormat = AL_FORMAT_STEREO_FLOAT32; break; - case UserFmtRear: NewFormat = AL_FORMAT_REAR32; break; - case UserFmtQuad: NewFormat = AL_FORMAT_QUAD32; break; - case UserFmtX51: NewFormat = AL_FORMAT_51CHN32; break; - case UserFmtX61: NewFormat = AL_FORMAT_61CHN32; break; - case UserFmtX71: NewFormat = AL_FORMAT_71CHN32; break; + case UserFmtMono: newformat = AL_FORMAT_MONO_FLOAT32; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO_FLOAT32; break; + case UserFmtRear: newformat = AL_FORMAT_REAR32; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD32; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN32; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN32; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN32; break; } - if((size%FrameSize) != 0) - err = AL_INVALID_VALUE; - else - err = LoadData(ALBuf, freq, NewFormat, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); + err = LoadData(albuf, freq, newformat, size/framesize, + srcchannels, srctype, data, AL_TRUE); if(err != AL_NO_ERROR) - alSetError(Context, err); - } break; + SET_ERROR_AND_GOTO(context, err, done); + break; case UserFmtMulaw: case UserFmtAlaw: - case UserFmtIMA4: { + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO16; + switch(srcchannels) + { + case UserFmtMono: newformat = AL_FORMAT_MONO16; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; + case UserFmtRear: newformat = AL_FORMAT_REAR16; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; + } + err = LoadData(albuf, freq, newformat, size/framesize, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; + + case UserFmtIMA4: /* Here is where things vary: * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel */ - ALuint FrameSize = (SrcType == UserFmtIMA4) ? - (ChannelsFromUserFmt(SrcChannels) * 36) : - FrameSizeFromUserFmt(SrcChannels, SrcType); - ALenum NewFormat = AL_FORMAT_MONO16; - switch(SrcChannels) + framesize = ChannelsFromUserFmt(srcchannels) * 36; + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO16; + switch(srcchannels) { - case UserFmtMono: NewFormat = AL_FORMAT_MONO16; break; - case UserFmtStereo: NewFormat = AL_FORMAT_STEREO16; break; - case UserFmtRear: NewFormat = AL_FORMAT_REAR16; break; - case UserFmtQuad: NewFormat = AL_FORMAT_QUAD16; break; - case UserFmtX51: NewFormat = AL_FORMAT_51CHN16; break; - case UserFmtX61: NewFormat = AL_FORMAT_61CHN16; break; - case UserFmtX71: NewFormat = AL_FORMAT_71CHN16; break; + case UserFmtMono: newformat = AL_FORMAT_MONO16; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; + case UserFmtRear: newformat = AL_FORMAT_REAR16; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; } - if((size%FrameSize) != 0) - err = AL_INVALID_VALUE; - else - err = LoadData(ALBuf, freq, NewFormat, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); + err = LoadData(albuf, freq, newformat, size/framesize*65, + srcchannels, srctype, data, AL_TRUE); if(err != AL_NO_ERROR) - alSetError(Context, err); - } break; + SET_ERROR_AND_GOTO(context, err, done); + break; } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -/* - * alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, - * ALsizei offset, ALsizei length) - * - * Update buffer's audio data - */ -AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length) +AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length) { - enum UserFmtChannels SrcChannels; - enum UserFmtType SrcType; - ALCcontext *Context; - ALCdevice *device; - ALbuffer *ALBuf; + enum UserFmtChannels srcchannels; + enum UserFmtType srctype; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; + ALuint original_align; + ALuint channels; + ALuint bytes; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(length < 0 || offset < 0 || (length > 0 && data == NULL)) - alSetError(Context, AL_INVALID_VALUE); - else if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE) - alSetError(Context, AL_INVALID_ENUM); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(length >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + WriteLock(&albuf->lock); + original_align = ((albuf->OriginalType == UserFmtIMA4) ? + (ChannelsFromUserFmt(albuf->OriginalChannels)*36) : + FrameSizeFromUserFmt(albuf->OriginalChannels, + albuf->OriginalType)); + + if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType) { - ALuint original_align; - - WriteLock(&ALBuf->lock); - - original_align = ((ALBuf->OriginalType == UserFmtIMA4) ? - (ChannelsFromUserFmt(ALBuf->OriginalChannels)*36) : - FrameSizeFromUserFmt(ALBuf->OriginalChannels, - ALBuf->OriginalType)); - - if(SrcChannels != ALBuf->OriginalChannels || SrcType != ALBuf->OriginalType) - alSetError(Context, AL_INVALID_ENUM); - else if(offset > ALBuf->OriginalSize || - length > ALBuf->OriginalSize-offset || - (offset%original_align) != 0 || - (length%original_align) != 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - ALuint Channels = ChannelsFromFmt(ALBuf->FmtChannels); - ALuint Bytes = BytesFromFmt(ALBuf->FmtType); - if(SrcType == UserFmtIMA4) - { - /* offset -> byte offset, length -> block count */ - offset /= 36; - offset *= 65; - offset *= Bytes; - length /= original_align; - } - else - { - ALuint OldBytes = BytesFromUserFmt(SrcType); - - offset /= OldBytes; - offset *= Bytes; - length /= OldBytes * Channels; - } - ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - data, SrcType, Channels, length); - } - WriteUnlock(&ALBuf->lock); + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset || + (offset%original_align) != 0 || (length%original_align) != 0) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - ALCcontext_DecRef(Context); + channels = ChannelsFromFmt(albuf->FmtChannels); + bytes = BytesFromFmt(albuf->FmtType); + /* offset -> byte offset, length -> sample count */ + if(srctype == UserFmtIMA4) + { + offset = offset/36*65 * bytes; + length = length/original_align * 65; + } + else + { + ALuint OldBytes = BytesFromUserFmt(srctype); + offset = offset/OldBytes * bytes; + length = length/OldBytes/channels; + } + ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + data, srctype, channels, length); + WriteUnlock(&albuf->lock); + +done: + ALCcontext_DecRef(context); } @@ -496,560 +473,519 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { - ALCcontext *Context; ALCdevice *device; - ALbuffer *ALBuf; + ALCcontext *context; + ALbuffer *albuf; ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(samples < 0 || samplerate == 0) - alSetError(Context, AL_INVALID_VALUE); - else if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) - alSetError(Context, AL_INVALID_ENUM); - else - { - err = AL_NO_ERROR; - if(type == UserFmtIMA4) - { - if((samples%65) == 0) samples /= 65; - else err = AL_INVALID_VALUE; - } - if(err == AL_NO_ERROR) - err = LoadData(ALBuf, samplerate, internalformat, samples, - channels, type, data, AL_FALSE); - if(err != AL_NO_ERROR) - alSetError(Context, err); - } + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && samplerate != 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - ALCcontext_DecRef(Context); + err = LoadData(albuf, samplerate, internalformat, samples, + channels, type, data, AL_FALSE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { - ALCcontext *Context; - ALCdevice *device; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALuint framesize; + ALbuffer *albuf; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(samples < 0 || offset < 0 || (samples > 0 && data == NULL)) - alSetError(Context, AL_INVALID_VALUE); - else if(IsValidType(type) == AL_FALSE) - alSetError(Context, AL_INVALID_ENUM); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + WriteLock(&albuf->lock); + framesize = FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); + if(channels != (ALenum)albuf->FmtChannels) { - ALuint FrameSize; - - WriteLock(&ALBuf->lock); - FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - if(channels != (ALenum)ALBuf->FmtChannels) - alSetError(Context, AL_INVALID_ENUM); - else if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) - alSetError(Context, AL_INVALID_VALUE); - else if(type == UserFmtIMA4 && (samples%65) != 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - /* offset -> byte offset */ - offset *= FrameSize; - /* samples -> IMA4 block count */ - if(type == UserFmtIMA4) samples /= 65; - ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - data, type, - ChannelsFromFmt(ALBuf->FmtChannels), samples); - } - WriteUnlock(&ALBuf->lock); + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + else if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - ALCcontext_DecRef(Context); + /* offset -> byte offset */ + offset *= framesize; + ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + data, type, ChannelsFromFmt(albuf->FmtChannels), samples); + WriteUnlock(&albuf->lock); + +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data) { - ALCcontext *Context; - ALCdevice *device; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALuint framesize; + ALbuffer *albuf; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(samples < 0 || offset < 0 || (samples > 0 && data == NULL)) - alSetError(Context, AL_INVALID_VALUE); - else if(IsValidType(type) == AL_FALSE) - alSetError(Context, AL_INVALID_ENUM); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + ReadLock(&albuf->lock); + framesize = FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); + if(channels != (ALenum)albuf->FmtChannels) { - ALuint FrameSize; - - ReadLock(&ALBuf->lock); - FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - if(channels != (ALenum)ALBuf->FmtChannels) - alSetError(Context, AL_INVALID_ENUM); - else if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) - alSetError(Context, AL_INVALID_VALUE); - else if(type == UserFmtIMA4 && (samples%65) != 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - /* offset -> byte offset */ - offset *= FrameSize; - /* samples -> IMA4 block count */ - if(type == UserFmtIMA4) samples /= 65; - ConvertData(data, type, - &((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - ChannelsFromFmt(ALBuf->FmtChannels), samples); - } - ReadUnlock(&ALBuf->lock); + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset) + { + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + if(type == UserFmtIMA4 && (samples%65) != 0) + { + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - ALCcontext_DecRef(Context); + /* offset -> byte offset */ + offset *= framesize; + ConvertData(data, type, (char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + ChannelsFromFmt(albuf->FmtChannels), samples); + ReadUnlock(&albuf->lock); + +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format) { - enum FmtChannels DstChannels; - enum FmtType DstType; - ALCcontext *Context; + enum FmtChannels dstchannels; + enum FmtType dsttype; + ALCcontext *context; ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - ret = DecomposeFormat(format, &DstChannels, &DstType); + ret = DecomposeFormat(format, &dstchannels, &dsttype); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); return ret; } -AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue) +AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(value)) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - (void)flValue; + context = GetContextRef(); + if(!context) return; - pContext = GetContextRef(); - if(!pContext) return; - - device = pContext->Device; + device = context->Device; if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3) +AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(value1), ALfloat UNUSED(value2), ALfloat UNUSED(value3)) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - (void)flValue1; - (void)flValue2; - (void)flValue3; + context = GetContextRef(); + if(!context) return; - pContext = GetContextRef(); - if(!pContext) return; - - device = pContext->Device; + device = context->Device; if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues) +AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!flValues) - alSetError(pContext, AL_INVALID_VALUE); - else if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else - { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - - ALCcontext_DecRef(pContext); -} - - -AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue) -{ - ALCcontext *pContext; - ALCdevice *device; - - (void)lValue; - - pContext = GetContextRef(); - if(!pContext) return; - - device = pContext->Device; + device = context->Device; if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3) +AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint UNUSED(value)) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - (void)lValue1; - (void)lValue2; - (void)lValue3; + context = GetContextRef(); + if(!context) return; - pContext = GetContextRef(); - if(!pContext) return; - - device = pContext->Device; + device = context->Device; if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues) +AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(value1), ALint UNUSED(value2), ALint UNUSED(value3)) { - ALCcontext *pContext; - ALCdevice *device; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!plValues) - alSetError(pContext, AL_INVALID_VALUE); - else if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + switch(param) { - switch(eParam) - { - case AL_LOOP_POINTS_SOFT: - WriteLock(&ALBuf->lock); - if(ALBuf->ref != 0) - alSetError(pContext, AL_INVALID_OPERATION); - else if(plValues[0] >= plValues[1] || plValues[0] < 0 || - plValues[1] > ALBuf->SampleLen) - alSetError(pContext, AL_INVALID_VALUE); - else - { - ALBuf->LoopStart = plValues[0]; - ALBuf->LoopEnd = plValues[1]; - } - WriteUnlock(&ALBuf->lock); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue) +AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values) { - ALCcontext *pContext; - ALCdevice *device; - ALbuffer *pBuffer; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!pflValue) - alSetError(pContext, AL_INVALID_VALUE); - else if((pBuffer=LookupBuffer(device, buffer)) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) + case AL_LOOP_POINTS_SOFT: + WriteLock(&albuf->lock); + if(albuf->ref != 0) { - case AL_SEC_LENGTH: - ReadLock(&pBuffer->lock); - if(pBuffer->SampleLen != 0) - *pflValue = pBuffer->SampleLen / (ALfloat)pBuffer->Frequency; - else - *pflValue = 0.0f; - ReadUnlock(&pBuffer->lock); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } + if(values[0] >= values[1] || values[0] < 0 || + values[1] > albuf->SampleLen) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + + albuf->LoopStart = values[0]; + albuf->LoopEnd = values[1]; + WriteUnlock(&albuf->lock); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3) +AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!pflValue1 || !pflValue2 || !pflValue3) - alSetError(pContext, AL_INVALID_VALUE); - else if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + case AL_SEC_LENGTH_SOFT: + ReadLock(&albuf->lock); + if(albuf->SampleLen != 0) + *value = albuf->SampleLen / (ALfloat)albuf->Frequency; + else + *value = 0.0f; + ReadUnlock(&albuf->lock); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues) +AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - switch(eParam) + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - case AL_SEC_LENGTH: - alGetBufferf(buffer, eParam, pflValues); + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values) +{ + ALCdevice *device; + ALCcontext *context; + + switch(param) + { + case AL_SEC_LENGTH_SOFT: + alGetBufferf(buffer, param, values); return; } - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!pflValues) - alSetError(pContext, AL_INVALID_VALUE); - else if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue) +AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value) { - ALCcontext *pContext; - ALbuffer *pBuffer; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!plValue) - alSetError(pContext, AL_INVALID_VALUE); - else if((pBuffer=LookupBuffer(device, buffer)) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - case AL_FREQUENCY: - *plValue = pBuffer->Frequency; - break; + case AL_FREQUENCY: + *value = albuf->Frequency; + break; - case AL_BITS: - *plValue = BytesFromFmt(pBuffer->FmtType) * 8; - break; + case AL_BITS: + *value = BytesFromFmt(albuf->FmtType) * 8; + break; - case AL_CHANNELS: - *plValue = ChannelsFromFmt(pBuffer->FmtChannels); - break; + case AL_CHANNELS: + *value = ChannelsFromFmt(albuf->FmtChannels); + break; - case AL_SIZE: - ReadLock(&pBuffer->lock); - *plValue = pBuffer->SampleLen * - FrameSizeFromFmt(pBuffer->FmtChannels, pBuffer->FmtType); - ReadUnlock(&pBuffer->lock); - break; + case AL_SIZE: + ReadLock(&albuf->lock); + *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels, + albuf->FmtType); + ReadUnlock(&albuf->lock); + break; - case AL_INTERNAL_FORMAT: - *plValue = pBuffer->Format; - break; + case AL_INTERNAL_FORMAT_SOFT: + *value = albuf->Format; + break; - case AL_BYTE_LENGTH: - *plValue = pBuffer->OriginalSize; - break; + case AL_BYTE_LENGTH_SOFT: + *value = albuf->OriginalSize; + break; - case AL_SAMPLE_LENGTH: - *plValue = pBuffer->SampleLen; - break; + case AL_SAMPLE_LENGTH_SOFT: + *value = albuf->SampleLen; + break; - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3) +AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) { - ALCcontext *pContext; - ALCdevice *device; + ALCdevice *device; + ALCcontext *context; - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!plValue1 || !plValue2 || !plValue3) - alSetError(pContext, AL_INVALID_VALUE); - else if(LookupBuffer(device, buffer) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues) +AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values) { - ALCcontext *pContext; - ALCdevice *device; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - switch(eParam) + switch(param) { case AL_FREQUENCY: case AL_BITS: case AL_CHANNELS: case AL_SIZE: - case AL_INTERNAL_FORMAT: - case AL_BYTE_LENGTH: - case AL_SAMPLE_LENGTH: - alGetBufferi(buffer, eParam, plValues); + case AL_INTERNAL_FORMAT_SOFT: + case AL_BYTE_LENGTH_SOFT: + case AL_SAMPLE_LENGTH_SOFT: + alGetBufferi(buffer, param, values); return; } - pContext = GetContextRef(); - if(!pContext) return; + context = GetContextRef(); + if(!context) return; - device = pContext->Device; - if(!plValues) - alSetError(pContext, AL_INVALID_VALUE); - else if((ALBuf=LookupBuffer(device, buffer)) == NULL) - alSetError(pContext, AL_INVALID_NAME); - else + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - switch(eParam) - { - case AL_LOOP_POINTS_SOFT: - ReadLock(&ALBuf->lock); - plValues[0] = ALBuf->LoopStart; - plValues[1] = ALBuf->LoopEnd; - ReadUnlock(&ALBuf->lock); - break; + case AL_LOOP_POINTS_SOFT: + ReadLock(&albuf->lock); + values[0] = albuf->LoopStart; + values[1] = albuf->LoopEnd; + ReadUnlock(&albuf->lock); + break; - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(pContext); +done: + ALCcontext_DecRef(context); } @@ -1059,11 +995,13 @@ typedef ALubyte ALima4; typedef struct { ALbyte b[3]; } ALbyte3; +extern ALbyte ALbyte3_size_is_not_3[(sizeof(ALbyte3)==sizeof(ALbyte[3]))?1:-1]; typedef struct { ALubyte b[3]; } ALubyte3; +extern ALbyte ALubyte3_size_is_not_3[(sizeof(ALubyte3)==sizeof(ALubyte[3]))?1:-1]; -static __inline ALshort DecodeMuLaw(ALmulaw val) +static inline ALshort DecodeMuLaw(ALmulaw val) { return muLawDecompressionTable[val]; } static ALmulaw EncodeMuLaw(ALshort val) @@ -1088,7 +1026,7 @@ static ALmulaw EncodeMuLaw(ALshort val) return ~(sign | (exp<<4) | mant); } -static __inline ALshort DecodeALaw(ALalaw val) +static inline ALshort DecodeALaw(ALalaw val) { return aLawDecompressionTable[val]; } static ALalaw EncodeALaw(ALshort val) @@ -1119,8 +1057,8 @@ static ALalaw EncodeALaw(ALshort val) static void DecodeIMA4Block(ALshort *dst, const ALima4 *src, ALint numchans) { - ALint sample[MAXCHANNELS], index[MAXCHANNELS]; - ALuint code[MAXCHANNELS]; + ALint sample[MAX_INPUT_CHANNELS], index[MAX_INPUT_CHANNELS]; + ALuint code[MAX_INPUT_CHANNELS]; ALsizei j,k,c; for(c = 0;c < numchans;c++) @@ -1234,20 +1172,15 @@ static void EncodeIMA4Block(ALima4 *dst, const ALshort *src, ALint *sample, ALin } } -static const union { - ALuint u; - ALubyte b[sizeof(ALuint)]; -} EndianTest = { 1 }; -#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1) -static __inline ALint DecodeByte3(ALbyte3 val) +static inline ALint DecodeByte3(ALbyte3 val) { if(IS_LITTLE_ENDIAN) return (val.b[2]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[0]); return (val.b[0]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[2]); } -static __inline ALbyte3 EncodeByte3(ALint val) +static inline ALbyte3 EncodeByte3(ALint val) { if(IS_LITTLE_ENDIAN) { @@ -1261,14 +1194,14 @@ static __inline ALbyte3 EncodeByte3(ALint val) } } -static __inline ALint DecodeUByte3(ALubyte3 val) +static inline ALint DecodeUByte3(ALubyte3 val) { if(IS_LITTLE_ENDIAN) return (val.b[2]<<16) | (val.b[1]<<8) | (val.b[0]); return (val.b[0]<<16) | (val.b[1]<<8) | val.b[2]; } -static __inline ALubyte3 EncodeUByte3(ALint val) +static inline ALubyte3 EncodeUByte3(ALint val) { if(IS_LITTLE_ENDIAN) { @@ -1283,256 +1216,256 @@ static __inline ALubyte3 EncodeUByte3(ALint val) } -static __inline ALbyte Conv_ALbyte_ALbyte(ALbyte val) +static inline ALbyte Conv_ALbyte_ALbyte(ALbyte val) { return val; } -static __inline ALbyte Conv_ALbyte_ALubyte(ALubyte val) +static inline ALbyte Conv_ALbyte_ALubyte(ALubyte val) { return val-128; } -static __inline ALbyte Conv_ALbyte_ALshort(ALshort val) +static inline ALbyte Conv_ALbyte_ALshort(ALshort val) { return val>>8; } -static __inline ALbyte Conv_ALbyte_ALushort(ALushort val) +static inline ALbyte Conv_ALbyte_ALushort(ALushort val) { return (val>>8)-128; } -static __inline ALbyte Conv_ALbyte_ALint(ALint val) +static inline ALbyte Conv_ALbyte_ALint(ALint val) { return val>>24; } -static __inline ALbyte Conv_ALbyte_ALuint(ALuint val) +static inline ALbyte Conv_ALbyte_ALuint(ALuint val) { return (val>>24)-128; } -static __inline ALbyte Conv_ALbyte_ALfloat(ALfloat val) +static inline ALbyte Conv_ALbyte_ALfloat(ALfloat val) { if(val > 1.0f) return 127; if(val < -1.0f) return -128; return (ALint)(val * 127.0f); } -static __inline ALbyte Conv_ALbyte_ALdouble(ALdouble val) +static inline ALbyte Conv_ALbyte_ALdouble(ALdouble val) { if(val > 1.0) return 127; if(val < -1.0) return -128; return (ALint)(val * 127.0); } -static __inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val) +static inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val) { return Conv_ALbyte_ALshort(DecodeMuLaw(val)); } -static __inline ALbyte Conv_ALbyte_ALalaw(ALalaw val) +static inline ALbyte Conv_ALbyte_ALalaw(ALalaw val) { return Conv_ALbyte_ALshort(DecodeALaw(val)); } -static __inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val) +static inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val) { return DecodeByte3(val)>>16; } -static __inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val) +static inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)>>16)-128; } -static __inline ALubyte Conv_ALubyte_ALbyte(ALbyte val) +static inline ALubyte Conv_ALubyte_ALbyte(ALbyte val) { return val+128; } -static __inline ALubyte Conv_ALubyte_ALubyte(ALubyte val) +static inline ALubyte Conv_ALubyte_ALubyte(ALubyte val) { return val; } -static __inline ALubyte Conv_ALubyte_ALshort(ALshort val) +static inline ALubyte Conv_ALubyte_ALshort(ALshort val) { return (val>>8)+128; } -static __inline ALubyte Conv_ALubyte_ALushort(ALushort val) +static inline ALubyte Conv_ALubyte_ALushort(ALushort val) { return val>>8; } -static __inline ALubyte Conv_ALubyte_ALint(ALint val) +static inline ALubyte Conv_ALubyte_ALint(ALint val) { return (val>>24)+128; } -static __inline ALubyte Conv_ALubyte_ALuint(ALuint val) +static inline ALubyte Conv_ALubyte_ALuint(ALuint val) { return val>>24; } -static __inline ALubyte Conv_ALubyte_ALfloat(ALfloat val) +static inline ALubyte Conv_ALubyte_ALfloat(ALfloat val) { if(val > 1.0f) return 255; if(val < -1.0f) return 0; return (ALint)(val * 127.0f) + 128; } -static __inline ALubyte Conv_ALubyte_ALdouble(ALdouble val) +static inline ALubyte Conv_ALubyte_ALdouble(ALdouble val) { if(val > 1.0) return 255; if(val < -1.0) return 0; return (ALint)(val * 127.0) + 128; } -static __inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val) +static inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val) { return Conv_ALubyte_ALshort(DecodeMuLaw(val)); } -static __inline ALubyte Conv_ALubyte_ALalaw(ALalaw val) +static inline ALubyte Conv_ALubyte_ALalaw(ALalaw val) { return Conv_ALubyte_ALshort(DecodeALaw(val)); } -static __inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val) +static inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)>>16)+128; } -static __inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val) +static inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)>>16; } -static __inline ALshort Conv_ALshort_ALbyte(ALbyte val) +static inline ALshort Conv_ALshort_ALbyte(ALbyte val) { return val<<8; } -static __inline ALshort Conv_ALshort_ALubyte(ALubyte val) +static inline ALshort Conv_ALshort_ALubyte(ALubyte val) { return (val-128)<<8; } -static __inline ALshort Conv_ALshort_ALshort(ALshort val) +static inline ALshort Conv_ALshort_ALshort(ALshort val) { return val; } -static __inline ALshort Conv_ALshort_ALushort(ALushort val) +static inline ALshort Conv_ALshort_ALushort(ALushort val) { return val-32768; } -static __inline ALshort Conv_ALshort_ALint(ALint val) +static inline ALshort Conv_ALshort_ALint(ALint val) { return val>>16; } -static __inline ALshort Conv_ALshort_ALuint(ALuint val) +static inline ALshort Conv_ALshort_ALuint(ALuint val) { return (val>>16)-32768; } -static __inline ALshort Conv_ALshort_ALfloat(ALfloat val) +static inline ALshort Conv_ALshort_ALfloat(ALfloat val) { if(val > 1.0f) return 32767; if(val < -1.0f) return -32768; return (ALint)(val * 32767.0f); } -static __inline ALshort Conv_ALshort_ALdouble(ALdouble val) +static inline ALshort Conv_ALshort_ALdouble(ALdouble val) { if(val > 1.0) return 32767; if(val < -1.0) return -32768; return (ALint)(val * 32767.0); } -static __inline ALshort Conv_ALshort_ALmulaw(ALmulaw val) +static inline ALshort Conv_ALshort_ALmulaw(ALmulaw val) { return Conv_ALshort_ALshort(DecodeMuLaw(val)); } -static __inline ALshort Conv_ALshort_ALalaw(ALalaw val) +static inline ALshort Conv_ALshort_ALalaw(ALalaw val) { return Conv_ALshort_ALshort(DecodeALaw(val)); } -static __inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val) +static inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val) { return DecodeByte3(val)>>8; } -static __inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val) +static inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)>>8)-32768; } -static __inline ALushort Conv_ALushort_ALbyte(ALbyte val) +static inline ALushort Conv_ALushort_ALbyte(ALbyte val) { return (val+128)<<8; } -static __inline ALushort Conv_ALushort_ALubyte(ALubyte val) +static inline ALushort Conv_ALushort_ALubyte(ALubyte val) { return val<<8; } -static __inline ALushort Conv_ALushort_ALshort(ALshort val) +static inline ALushort Conv_ALushort_ALshort(ALshort val) { return val+32768; } -static __inline ALushort Conv_ALushort_ALushort(ALushort val) +static inline ALushort Conv_ALushort_ALushort(ALushort val) { return val; } -static __inline ALushort Conv_ALushort_ALint(ALint val) +static inline ALushort Conv_ALushort_ALint(ALint val) { return (val>>16)+32768; } -static __inline ALushort Conv_ALushort_ALuint(ALuint val) +static inline ALushort Conv_ALushort_ALuint(ALuint val) { return val>>16; } -static __inline ALushort Conv_ALushort_ALfloat(ALfloat val) +static inline ALushort Conv_ALushort_ALfloat(ALfloat val) { if(val > 1.0f) return 65535; if(val < -1.0f) return 0; return (ALint)(val * 32767.0f) + 32768; } -static __inline ALushort Conv_ALushort_ALdouble(ALdouble val) +static inline ALushort Conv_ALushort_ALdouble(ALdouble val) { if(val > 1.0) return 65535; if(val < -1.0) return 0; return (ALint)(val * 32767.0) + 32768; } -static __inline ALushort Conv_ALushort_ALmulaw(ALmulaw val) +static inline ALushort Conv_ALushort_ALmulaw(ALmulaw val) { return Conv_ALushort_ALshort(DecodeMuLaw(val)); } -static __inline ALushort Conv_ALushort_ALalaw(ALalaw val) +static inline ALushort Conv_ALushort_ALalaw(ALalaw val) { return Conv_ALushort_ALshort(DecodeALaw(val)); } -static __inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val) +static inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)>>8)+32768; } -static __inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val) +static inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)>>8; } -static __inline ALint Conv_ALint_ALbyte(ALbyte val) +static inline ALint Conv_ALint_ALbyte(ALbyte val) { return val<<24; } -static __inline ALint Conv_ALint_ALubyte(ALubyte val) +static inline ALint Conv_ALint_ALubyte(ALubyte val) { return (val-128)<<24; } -static __inline ALint Conv_ALint_ALshort(ALshort val) +static inline ALint Conv_ALint_ALshort(ALshort val) { return val<<16; } -static __inline ALint Conv_ALint_ALushort(ALushort val) +static inline ALint Conv_ALint_ALushort(ALushort val) { return (val-32768)<<16; } -static __inline ALint Conv_ALint_ALint(ALint val) +static inline ALint Conv_ALint_ALint(ALint val) { return val; } -static __inline ALint Conv_ALint_ALuint(ALuint val) +static inline ALint Conv_ALint_ALuint(ALuint val) { return val-2147483648u; } -static __inline ALint Conv_ALint_ALfloat(ALfloat val) +static inline ALint Conv_ALint_ALfloat(ALfloat val) { if(val > 1.0f) return 2147483647; if(val < -1.0f) return -2147483647-1; - return (ALint)(val * 2147483647.0); + return (ALint)(val*16777215.0f) << 7; } -static __inline ALint Conv_ALint_ALdouble(ALdouble val) +static inline ALint Conv_ALint_ALdouble(ALdouble val) { if(val > 1.0) return 2147483647; if(val < -1.0) return -2147483647-1; return (ALint)(val * 2147483647.0); } -static __inline ALint Conv_ALint_ALmulaw(ALmulaw val) +static inline ALint Conv_ALint_ALmulaw(ALmulaw val) { return Conv_ALint_ALshort(DecodeMuLaw(val)); } -static __inline ALint Conv_ALint_ALalaw(ALalaw val) +static inline ALint Conv_ALint_ALalaw(ALalaw val) { return Conv_ALint_ALshort(DecodeALaw(val)); } -static __inline ALint Conv_ALint_ALbyte3(ALbyte3 val) +static inline ALint Conv_ALint_ALbyte3(ALbyte3 val) { return DecodeByte3(val)<<8; } -static __inline ALint Conv_ALint_ALubyte3(ALubyte3 val) +static inline ALint Conv_ALint_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)-8388608)<<8; } -static __inline ALuint Conv_ALuint_ALbyte(ALbyte val) +static inline ALuint Conv_ALuint_ALbyte(ALbyte val) { return (val+128)<<24; } -static __inline ALuint Conv_ALuint_ALubyte(ALubyte val) +static inline ALuint Conv_ALuint_ALubyte(ALubyte val) { return val<<24; } -static __inline ALuint Conv_ALuint_ALshort(ALshort val) +static inline ALuint Conv_ALuint_ALshort(ALshort val) { return (val+32768)<<16; } -static __inline ALuint Conv_ALuint_ALushort(ALushort val) +static inline ALuint Conv_ALuint_ALushort(ALushort val) { return val<<16; } -static __inline ALuint Conv_ALuint_ALint(ALint val) +static inline ALuint Conv_ALuint_ALint(ALint val) { return val+2147483648u; } -static __inline ALuint Conv_ALuint_ALuint(ALuint val) +static inline ALuint Conv_ALuint_ALuint(ALuint val) { return val; } -static __inline ALuint Conv_ALuint_ALfloat(ALfloat val) +static inline ALuint Conv_ALuint_ALfloat(ALfloat val) { if(val > 1.0f) return 4294967295u; if(val < -1.0f) return 0; - return (ALint)(val * 2147483647.0) + 2147483648u; + return ((ALint)(val*16777215.0f)<<7) + 2147483648u; } -static __inline ALuint Conv_ALuint_ALdouble(ALdouble val) +static inline ALuint Conv_ALuint_ALdouble(ALdouble val) { if(val > 1.0) return 4294967295u; if(val < -1.0) return 0; return (ALint)(val * 2147483647.0) + 2147483648u; } -static __inline ALuint Conv_ALuint_ALmulaw(ALmulaw val) +static inline ALuint Conv_ALuint_ALmulaw(ALmulaw val) { return Conv_ALuint_ALshort(DecodeMuLaw(val)); } -static __inline ALuint Conv_ALuint_ALalaw(ALalaw val) +static inline ALuint Conv_ALuint_ALalaw(ALalaw val) { return Conv_ALuint_ALshort(DecodeALaw(val)); } -static __inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val) +static inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)+8388608)<<8; } -static __inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val) +static inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)<<8; } -static __inline ALfloat Conv_ALfloat_ALbyte(ALbyte val) +static inline ALfloat Conv_ALfloat_ALbyte(ALbyte val) { return val * (1.0f/127.0f); } -static __inline ALfloat Conv_ALfloat_ALubyte(ALubyte val) +static inline ALfloat Conv_ALfloat_ALubyte(ALubyte val) { return (val-128) * (1.0f/127.0f); } -static __inline ALfloat Conv_ALfloat_ALshort(ALshort val) +static inline ALfloat Conv_ALfloat_ALshort(ALshort val) { return val * (1.0f/32767.0f); } -static __inline ALfloat Conv_ALfloat_ALushort(ALushort val) +static inline ALfloat Conv_ALfloat_ALushort(ALushort val) { return (val-32768) * (1.0f/32767.0f); } -static __inline ALfloat Conv_ALfloat_ALint(ALint val) +static inline ALfloat Conv_ALfloat_ALint(ALint val) { return (ALfloat)(val * (1.0/2147483647.0)); } -static __inline ALfloat Conv_ALfloat_ALuint(ALuint val) +static inline ALfloat Conv_ALfloat_ALuint(ALuint val) { return (ALfloat)((ALint)(val-2147483648u) * (1.0/2147483647.0)); } -static __inline ALfloat Conv_ALfloat_ALfloat(ALfloat val) +static inline ALfloat Conv_ALfloat_ALfloat(ALfloat val) { return (val==val) ? val : 0.0f; } -static __inline ALfloat Conv_ALfloat_ALdouble(ALdouble val) +static inline ALfloat Conv_ALfloat_ALdouble(ALdouble val) { return (val==val) ? (ALfloat)val : 0.0f; } -static __inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val) +static inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val) { return Conv_ALfloat_ALshort(DecodeMuLaw(val)); } -static __inline ALfloat Conv_ALfloat_ALalaw(ALalaw val) +static inline ALfloat Conv_ALfloat_ALalaw(ALalaw val) { return Conv_ALfloat_ALshort(DecodeALaw(val)); } -static __inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val) +static inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val) { return (ALfloat)(DecodeByte3(val) * (1.0/8388607.0)); } -static __inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val) +static inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val) { return (ALfloat)((DecodeUByte3(val)-8388608) * (1.0/8388607.0)); } -static __inline ALdouble Conv_ALdouble_ALbyte(ALbyte val) +static inline ALdouble Conv_ALdouble_ALbyte(ALbyte val) { return val * (1.0/127.0); } -static __inline ALdouble Conv_ALdouble_ALubyte(ALubyte val) +static inline ALdouble Conv_ALdouble_ALubyte(ALubyte val) { return (val-128) * (1.0/127.0); } -static __inline ALdouble Conv_ALdouble_ALshort(ALshort val) +static inline ALdouble Conv_ALdouble_ALshort(ALshort val) { return val * (1.0/32767.0); } -static __inline ALdouble Conv_ALdouble_ALushort(ALushort val) +static inline ALdouble Conv_ALdouble_ALushort(ALushort val) { return (val-32768) * (1.0/32767.0); } -static __inline ALdouble Conv_ALdouble_ALint(ALint val) +static inline ALdouble Conv_ALdouble_ALint(ALint val) { return val * (1.0/2147483647.0); } -static __inline ALdouble Conv_ALdouble_ALuint(ALuint val) +static inline ALdouble Conv_ALdouble_ALuint(ALuint val) { return (ALint)(val-2147483648u) * (1.0/2147483647.0); } -static __inline ALdouble Conv_ALdouble_ALfloat(ALfloat val) +static inline ALdouble Conv_ALdouble_ALfloat(ALfloat val) { return (val==val) ? val : 0.0f; } -static __inline ALdouble Conv_ALdouble_ALdouble(ALdouble val) +static inline ALdouble Conv_ALdouble_ALdouble(ALdouble val) { return (val==val) ? val : 0.0; } -static __inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val) +static inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val) { return Conv_ALdouble_ALshort(DecodeMuLaw(val)); } -static __inline ALdouble Conv_ALdouble_ALalaw(ALalaw val) +static inline ALdouble Conv_ALdouble_ALalaw(ALalaw val) { return Conv_ALdouble_ALshort(DecodeALaw(val)); } -static __inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val) +static inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val) { return DecodeByte3(val) * (1.0/8388607.0); } -static __inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val) +static inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)-8388608) * (1.0/8388607.0); } #define DECL_TEMPLATE(T) \ -static __inline ALmulaw Conv_ALmulaw_##T(T val) \ +static inline ALmulaw Conv_ALmulaw_##T(T val) \ { return EncodeMuLaw(Conv_ALshort_##T(val)); } DECL_TEMPLATE(ALbyte) @@ -1543,7 +1476,7 @@ DECL_TEMPLATE(ALint) DECL_TEMPLATE(ALuint) DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) -static __inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val) +static inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val) { return val; } DECL_TEMPLATE(ALalaw) DECL_TEMPLATE(ALbyte3) @@ -1552,7 +1485,7 @@ DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALalaw Conv_ALalaw_##T(T val) \ +static inline ALalaw Conv_ALalaw_##T(T val) \ { return EncodeALaw(Conv_ALshort_##T(val)); } DECL_TEMPLATE(ALbyte) @@ -1564,7 +1497,7 @@ DECL_TEMPLATE(ALuint) DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) -static __inline ALalaw Conv_ALalaw_ALalaw(ALalaw val) +static inline ALalaw Conv_ALalaw_ALalaw(ALalaw val) { return val; } DECL_TEMPLATE(ALbyte3) DECL_TEMPLATE(ALubyte3) @@ -1572,7 +1505,7 @@ DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALbyte3 Conv_ALbyte3_##T(T val) \ +static inline ALbyte3 Conv_ALbyte3_##T(T val) \ { return EncodeByte3(Conv_ALint_##T(val)>>8); } DECL_TEMPLATE(ALbyte) @@ -1585,14 +1518,14 @@ DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) DECL_TEMPLATE(ALalaw) -static __inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val) +static inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val) { return val; } DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALubyte3 Conv_ALubyte3_##T(T val) \ +static inline ALubyte3 Conv_ALubyte3_##T(T val) \ { return EncodeUByte3(Conv_ALuint_##T(val)>>8); } DECL_TEMPLATE(ALbyte) @@ -1606,7 +1539,7 @@ DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) DECL_TEMPLATE(ALalaw) DECL_TEMPLATE(ALbyte3) -static __inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val) +static inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val) { return val; } #undef DECL_TEMPLATE @@ -1784,16 +1717,22 @@ DECL_TEMPLATE(ALubyte3, ALubyte3) #define DECL_TEMPLATE(T) \ static void Convert_##T##_ALima4(T *dst, const ALima4 *src, ALuint numchans, \ - ALuint numblocks) \ + ALuint len) \ { \ - ALuint i, j; \ - ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */ \ - for(i = 0;i < numblocks;i++) \ + ALshort tmp[65*MAX_INPUT_CHANNELS]; /* Max samples an IMA4 frame can be */\ + ALuint i, j, k; \ + \ + i = 0; \ + while(i < len) \ { \ DecodeIMA4Block(tmp, src, numchans); \ src += 36*numchans; \ - for(j = 0;j < 65*numchans;j++) \ - *(dst++) = Conv_##T##_ALshort(tmp[j]); \ + \ + for(j = 0;j < 65 && i < len;j++,i++) \ + { \ + for(k = 0;k < numchans;k++) \ + *(dst++) = Conv_##T##_ALshort(tmp[j*numchans + k]); \ + } \ } \ } @@ -1814,13 +1753,14 @@ DECL_TEMPLATE(ALubyte3) #define DECL_TEMPLATE(T) \ static void Convert_ALima4_##T(ALima4 *dst, const T *src, ALuint numchans, \ - ALuint numblocks) \ + ALuint len) \ { \ + ALshort tmp[65*MAX_INPUT_CHANNELS]; /* Max samples an IMA4 frame can be */\ + ALint sample[MaxChannels] = {0,0,0,0,0,0,0,0}; \ + ALint index[MaxChannels] = {0,0,0,0,0,0,0,0}; \ ALuint i, j; \ - ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */ \ - ALint sample[MAXCHANNELS] = {0,0,0,0,0,0,0,0}; \ - ALint index[MAXCHANNELS] = {0,0,0,0,0,0,0,0}; \ - for(i = 0;i < numblocks;i++) \ + \ + for(i = 0;i < len;i += 65) \ { \ for(j = 0;j < 65*numchans;j++) \ tmp[j] = Conv_ALshort_##T(*(src++)); \ @@ -1974,6 +1914,19 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f ALuint64 newsize; ALvoid *temp; + if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE || + (long)SrcChannels != (long)DstChannels) + return AL_INVALID_ENUM; + + NewChannels = ChannelsFromFmt(DstChannels); + NewBytes = BytesFromFmt(DstType); + + newsize = frames; + newsize *= NewBytes; + newsize *= NewChannels; + if(newsize > INT_MAX) + return AL_OUT_OF_MEMORY; + WriteLock(&ALBuf->lock); if(ALBuf->ref != 0) { @@ -1981,94 +1934,39 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f return AL_INVALID_OPERATION; } - if(DecomposeFormat(NewFormat, &DstChannels, &DstType) == AL_FALSE || - (long)SrcChannels != (long)DstChannels) + temp = realloc(ALBuf->data, (size_t)newsize); + if(!temp && newsize) { WriteUnlock(&ALBuf->lock); - return AL_INVALID_ENUM; + return AL_OUT_OF_MEMORY; } + ALBuf->data = temp; - NewChannels = ChannelsFromFmt(DstChannels); - NewBytes = BytesFromFmt(DstType); + if(data != NULL) + ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames); - if(SrcType == UserFmtIMA4) + if(storesrc) { - ALuint OrigChannels = ChannelsFromUserFmt(SrcChannels); - - newsize = frames; - newsize *= 65; - newsize *= NewBytes; - newsize *= NewChannels; - if(newsize > INT_MAX) - { - WriteUnlock(&ALBuf->lock); - return AL_OUT_OF_MEMORY; - } - - temp = realloc(ALBuf->data, (size_t)newsize); - if(!temp && newsize) - { - WriteUnlock(&ALBuf->lock); - return AL_OUT_OF_MEMORY; - } - ALBuf->data = temp; - ALBuf->SampleLen = frames*65; - - if(data != NULL) - ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames); - - if(storesrc) - { - ALBuf->OriginalChannels = SrcChannels; - ALBuf->OriginalType = SrcType; - ALBuf->OriginalSize = frames * 36 * OrigChannels; - } + ALBuf->OriginalChannels = SrcChannels; + ALBuf->OriginalType = SrcType; + if(SrcType == UserFmtIMA4) + ALBuf->OriginalSize = frames / 65 * 36 * ChannelsFromUserFmt(SrcChannels); + else + ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType); } else { - ALuint OrigBytes = BytesFromUserFmt(SrcType); - ALuint OrigChannels = ChannelsFromUserFmt(SrcChannels); - - newsize = frames; - newsize *= NewBytes; - newsize *= NewChannels; - if(newsize > INT_MAX) - { - WriteUnlock(&ALBuf->lock); - return AL_OUT_OF_MEMORY; - } - - temp = realloc(ALBuf->data, (size_t)newsize); - if(!temp && newsize) - { - WriteUnlock(&ALBuf->lock); - return AL_OUT_OF_MEMORY; - } - ALBuf->data = temp; - ALBuf->SampleLen = frames; - - if(data != NULL) - ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames); - - if(storesrc) - { - ALBuf->OriginalChannels = SrcChannels; - ALBuf->OriginalType = SrcType; - ALBuf->OriginalSize = frames * OrigBytes * OrigChannels; - } - } - - if(!storesrc) - { - ALBuf->OriginalChannels = DstChannels; - ALBuf->OriginalType = DstType; + ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels; + ALBuf->OriginalType = (enum UserFmtType)DstType; ALBuf->OriginalSize = frames * NewBytes * NewChannels; } + ALBuf->Frequency = freq; ALBuf->FmtChannels = DstChannels; ALBuf->FmtType = DstType; ALBuf->Format = NewFormat; + ALBuf->SampleLen = frames; ALBuf->LoopStart = 0; ALBuf->LoopEnd = ALBuf->SampleLen; @@ -2165,7 +2063,7 @@ static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans, }; ALuint i; - for(i = 0;i < sizeof(list)/sizeof(list[0]);i++) + for(i = 0;i < COUNTOF(list);i++) { if(list[i].format == format) { @@ -2209,40 +2107,40 @@ static ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum Fm enum FmtChannels channels; enum FmtType type; } list[] = { - { AL_MONO8, FmtMono, FmtByte }, - { AL_MONO16, FmtMono, FmtShort }, - { AL_MONO32F, FmtMono, FmtFloat }, + { AL_MONO8_SOFT, FmtMono, FmtByte }, + { AL_MONO16_SOFT, FmtMono, FmtShort }, + { AL_MONO32F_SOFT, FmtMono, FmtFloat }, - { AL_STEREO8, FmtStereo, FmtByte }, - { AL_STEREO16, FmtStereo, FmtShort }, - { AL_STEREO32F, FmtStereo, FmtFloat }, + { AL_STEREO8_SOFT, FmtStereo, FmtByte }, + { AL_STEREO16_SOFT, FmtStereo, FmtShort }, + { AL_STEREO32F_SOFT, FmtStereo, FmtFloat }, - { AL_REAR8, FmtRear, FmtByte }, - { AL_REAR16, FmtRear, FmtShort }, - { AL_REAR32F, FmtRear, FmtFloat }, + { AL_REAR8_SOFT, FmtRear, FmtByte }, + { AL_REAR16_SOFT, FmtRear, FmtShort }, + { AL_REAR32F_SOFT, FmtRear, FmtFloat }, { AL_FORMAT_QUAD8_LOKI, FmtQuad, FmtByte }, { AL_FORMAT_QUAD16_LOKI, FmtQuad, FmtShort }, - { AL_QUAD8, FmtQuad, FmtByte }, - { AL_QUAD16, FmtQuad, FmtShort }, - { AL_QUAD32F, FmtQuad, FmtFloat }, + { AL_QUAD8_SOFT, FmtQuad, FmtByte }, + { AL_QUAD16_SOFT, FmtQuad, FmtShort }, + { AL_QUAD32F_SOFT, FmtQuad, FmtFloat }, - { AL_5POINT1_8, FmtX51, FmtByte }, - { AL_5POINT1_16, FmtX51, FmtShort }, - { AL_5POINT1_32F, FmtX51, FmtFloat }, + { AL_5POINT1_8_SOFT, FmtX51, FmtByte }, + { AL_5POINT1_16_SOFT, FmtX51, FmtShort }, + { AL_5POINT1_32F_SOFT, FmtX51, FmtFloat }, - { AL_6POINT1_8, FmtX61, FmtByte }, - { AL_6POINT1_16, FmtX61, FmtShort }, - { AL_6POINT1_32F, FmtX61, FmtFloat }, + { AL_6POINT1_8_SOFT, FmtX61, FmtByte }, + { AL_6POINT1_16_SOFT, FmtX61, FmtShort }, + { AL_6POINT1_32F_SOFT, FmtX61, FmtFloat }, - { AL_7POINT1_8, FmtX71, FmtByte }, - { AL_7POINT1_16, FmtX71, FmtShort }, - { AL_7POINT1_32F, FmtX71, FmtFloat }, + { AL_7POINT1_8_SOFT, FmtX71, FmtByte }, + { AL_7POINT1_16_SOFT, FmtX71, FmtShort }, + { AL_7POINT1_32F_SOFT, FmtX71, FmtFloat }, }; ALuint i; - for(i = 0;i < sizeof(list)/sizeof(list[0]);i++) + for(i = 0;i < COUNTOF(list);i++) { if(list[i].format == format) { @@ -2260,19 +2158,16 @@ static ALboolean IsValidType(ALenum type) { switch(type) { - case AL_BYTE: - case AL_UNSIGNED_BYTE: - case AL_SHORT: - case AL_UNSIGNED_SHORT: - case AL_INT: - case AL_UNSIGNED_INT: - case AL_FLOAT: - case AL_DOUBLE: - case AL_MULAW: - case AL_ALAW: - case AL_IMA4: - case AL_BYTE3: - case AL_UNSIGNED_BYTE3: + case AL_BYTE_SOFT: + case AL_UNSIGNED_BYTE_SOFT: + case AL_SHORT_SOFT: + case AL_UNSIGNED_SHORT_SOFT: + case AL_INT_SOFT: + case AL_UNSIGNED_INT_SOFT: + case AL_FLOAT_SOFT: + case AL_DOUBLE_SOFT: + case AL_BYTE3_SOFT: + case AL_UNSIGNED_BYTE3_SOFT: return AL_TRUE; } return AL_FALSE; @@ -2282,13 +2177,13 @@ static ALboolean IsValidChannels(ALenum channels) { switch(channels) { - case AL_MONO: - case AL_STEREO: - case AL_REAR: - case AL_QUAD: - case AL_5POINT1: - case AL_6POINT1: - case AL_7POINT1: + case AL_MONO_SOFT: + case AL_STEREO_SOFT: + case AL_REAR_SOFT: + case AL_QUAD_SOFT: + case AL_5POINT1_SOFT: + case AL_6POINT1_SOFT: + case AL_7POINT1_SOFT: return AL_TRUE; } return AL_FALSE; @@ -2310,7 +2205,7 @@ ALvoid ReleaseALBuffers(ALCdevice *device) free(temp->data); - FreeThunkEntry(temp->buffer); + FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALbuffer)); free(temp); } diff --git a/jni/openal-soft-android/OpenAL32/alEffect.c b/jni/openal-soft-android/OpenAL32/alEffect.c index 11212009..c9e5928f 100644 --- a/jni/openal-soft-android/OpenAL32/alEffect.c +++ b/jni/openal-soft-android/OpenAL32/alEffect.c @@ -22,6 +22,7 @@ #include #include +#include #include "AL/al.h" #include "AL/alc.h" @@ -33,99 +34,88 @@ ALboolean DisabledEffects[MAX_EFFECTS]; +extern inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id); +extern inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id); +extern inline ALboolean IsReverbEffect(ALenum type); static void InitEffectParams(ALeffect *effect, ALenum type); AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) { - ALCcontext *Context; - ALsizei i; + ALCdevice *device; + ALCcontext *context; + ALsizei cur; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0 || IsBadWritePtr((void*)effects, n * sizeof(ALuint))) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) { - ALCdevice *device = Context->Device; - ALenum err; - - for(i = 0;i < n;i++) + ALeffect *effect = calloc(1, sizeof(ALeffect)); + ALenum err = AL_OUT_OF_MEMORY; + if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR) { - ALeffect *effect = calloc(1, sizeof(ALeffect)); - if(!effect) - { - alSetError(Context, AL_OUT_OF_MEMORY); - alDeleteEffects(i, effects); - break; - } - InitEffectParams(effect, AL_EFFECT_NULL); - - err = NewThunkEntry(&effect->effect); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->EffectMap, effect->effect, effect); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(effect->effect); - memset(effect, 0, sizeof(ALeffect)); - free(effect); - - alSetError(Context, err); - alDeleteEffects(i, effects); - break; - } - - effects[i] = effect->effect; + free(effect); + alDeleteEffects(cur, effects); + SET_ERROR_AND_GOTO(context, err, done); } + + err = NewThunkEntry(&effect->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(effect->id); + memset(effect, 0, sizeof(ALeffect)); + free(effect); + + alDeleteEffects(cur, effects); + SET_ERROR_AND_GOTO(context, err, done); + } + + effects[cur] = effect->id; } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) { - ALCcontext *Context; ALCdevice *device; - ALeffect *ALEffect; + ALCcontext *context; + ALeffect *effect; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if(n < 0) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) { - // Check that all effects are valid - for(i = 0;i < n;i++) - { - if(!effects[i]) - continue; + if(effects[i] && LookupEffect(device, effects[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + if((effect=RemoveEffect(device, effects[i])) == NULL) + continue; + FreeThunkEntry(effect->id); - if(LookupEffect(device, effects[i]) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - n = 0; - break; - } - } - - for(i = 0;i < n;i++) - { - // Recheck that the effect is valid, because there could be duplicated names - if((ALEffect=RemoveEffect(device, effects[i])) == NULL) - continue; - FreeThunkEntry(ALEffect->effect); - - memset(ALEffect, 0, sizeof(ALeffect)); - free(ALEffect); - } + memset(effect, 0, sizeof(*effect)); + free(effect); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) @@ -144,7 +134,7 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) return result; } -AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) +AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) { ALCcontext *Context; ALCdevice *Device; @@ -154,58 +144,65 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { if(param == AL_EFFECT_TYPE) { - ALboolean isOk = (iValue == AL_EFFECT_NULL); + ALboolean isOk = (value == AL_EFFECT_NULL); ALint i; for(i = 0;!isOk && EffectList[i].val;i++) { - if(iValue == EffectList[i].val && + if(value == EffectList[i].val && !DisabledEffects[EffectList[i].type]) isOk = AL_TRUE; } if(isOk) - InitEffectParams(ALEffect, iValue); + InitEffectParams(ALEffect, value); else alSetError(Context, AL_INVALID_VALUE); } else { /* Call the appropriate handler */ - ALeffect_SetParami(ALEffect, Context, param, iValue); + V(ALEffect,setParami)(Context, param, value); } } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues) +AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *values) { ALCcontext *Context; ALCdevice *Device; ALeffect *ALEffect; + switch(param) + { + case AL_EFFECT_TYPE: + alEffecti(effect, param, values[0]); + return; + } + Context = GetContextRef(); if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALeffect_SetParamiv(ALEffect, Context, param, piValues); + V(ALEffect,setParamiv)(Context, param, values); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue) +AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) { ALCcontext *Context; ALCdevice *Device; @@ -215,18 +212,18 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALeffect_SetParamf(ALEffect, Context, param, flValue); + V(ALEffect,setParamf)(Context, param, value); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues) +AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *values) { ALCcontext *Context; ALCdevice *Device; @@ -236,18 +233,18 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALeffect_SetParamfv(ALEffect, Context, param, pflValues); + V(ALEffect,setParamfv)(Context, param, values); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue) +AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value) { ALCcontext *Context; ALCdevice *Device; @@ -257,25 +254,51 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piVal if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { if(param == AL_EFFECT_TYPE) - { - *piValue = ALEffect->type; - } + *value = ALEffect->type; else { /* Call the appropriate handler */ - ALeffect_GetParamiv(ALEffect, Context, param, piValue); + V(ALEffect,getParami)(Context, param, value); } } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues) +AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *values) +{ + ALCcontext *Context; + ALCdevice *Device; + ALeffect *ALEffect; + + switch(param) + { + case AL_EFFECT_TYPE: + alGetEffecti(effect, param, values); + return; + } + + Context = GetContextRef(); + if(!Context) return; + + Device = Context->Device; + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else + { + /* Call the appropriate handler */ + V(ALEffect,getParamiv)(Context, param, values); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value) { ALCcontext *Context; ALCdevice *Device; @@ -285,18 +308,18 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piVa if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALeffect_GetParamiv(ALEffect, Context, param, piValues); + V(ALEffect,getParamf)(Context, param, value); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) +AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *values) { ALCcontext *Context; ALCdevice *Device; @@ -306,872 +329,23 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pfl if(!Context) return; Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) + if((ALEffect=LookupEffect(Device, effect)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALeffect_GetParamf(ALEffect, Context, param, pflValue); + V(ALEffect,getParamfv)(Context, param, values); } - else - alSetError(Context, AL_INVALID_NAME); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) -{ - ALCcontext *Context; - ALCdevice *Device; - ALeffect *ALEffect; - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if((ALEffect=LookupEffect(Device, effect)) != NULL) - { - /* Call the appropriate handler */ - ALeffect_GetParamfv(ALEffect, Context, param, pflValues); - } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -static void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +ALenum InitEffect(ALeffect *effect) { - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - if(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT) - effect->Reverb.DecayHFLimit = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } + InitEffectParams(effect, AL_EFFECT_NULL); + return AL_NO_ERROR; } -static void eaxreverb_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - eaxreverb_SetParami(effect, context, param, vals[0]); -} -static void eaxreverb_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_EAXREVERB_DENSITY: - if(val >= AL_EAXREVERB_MIN_DENSITY && - val <= AL_EAXREVERB_MAX_DENSITY) - effect->Reverb.Density = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DIFFUSION: - if(val >= AL_EAXREVERB_MIN_DIFFUSION && - val <= AL_EAXREVERB_MAX_DIFFUSION) - effect->Reverb.Diffusion = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAIN: - if(val >= AL_EAXREVERB_MIN_GAIN && - val <= AL_EAXREVERB_MAX_GAIN) - effect->Reverb.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAINHF: - if(val >= AL_EAXREVERB_MIN_GAINHF && - val <= AL_EAXREVERB_MAX_GAINHF) - effect->Reverb.GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAINLF: - if(val >= AL_EAXREVERB_MIN_GAINLF && - val <= AL_EAXREVERB_MAX_GAINLF) - effect->Reverb.GainLF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_TIME: - if(val >= AL_EAXREVERB_MIN_DECAY_TIME && - val <= AL_EAXREVERB_MAX_DECAY_TIME) - effect->Reverb.DecayTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - if(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && - val <= AL_EAXREVERB_MAX_DECAY_HFRATIO) - effect->Reverb.DecayHFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - if(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && - val <= AL_EAXREVERB_MAX_DECAY_LFRATIO) - effect->Reverb.DecayLFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - if(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && - val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN) - effect->Reverb.ReflectionsGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - if(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && - val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY) - effect->Reverb.ReflectionsDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - if(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && - val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN) - effect->Reverb.LateReverbGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - if(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && - val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY) - effect->Reverb.LateReverbDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - if(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && - val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF) - effect->Reverb.AirAbsorptionGainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ECHO_TIME: - if(val >= AL_EAXREVERB_MIN_ECHO_TIME && - val <= AL_EAXREVERB_MAX_ECHO_TIME) - effect->Reverb.EchoTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ECHO_DEPTH: - if(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && - val <= AL_EAXREVERB_MAX_ECHO_DEPTH) - effect->Reverb.EchoDepth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_MODULATION_TIME: - if(val >= AL_EAXREVERB_MIN_MODULATION_TIME && - val <= AL_EAXREVERB_MAX_MODULATION_TIME) - effect->Reverb.ModulationTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - if(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && - val <= AL_EAXREVERB_MAX_MODULATION_DEPTH) - effect->Reverb.ModulationDepth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_HFREFERENCE: - if(val >= AL_EAXREVERB_MIN_HFREFERENCE && - val <= AL_EAXREVERB_MAX_HFREFERENCE) - effect->Reverb.HFReference = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LFREFERENCE: - if(val >= AL_EAXREVERB_MIN_LFREFERENCE && - val <= AL_EAXREVERB_MAX_LFREFERENCE) - effect->Reverb.LFReference = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - if(val >= 0.0f && val <= 10.0f) - effect->Reverb.RoomRolloffFactor = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - if(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])) - { - LockContext(context); - effect->Reverb.ReflectionsPan[0] = vals[0]; - effect->Reverb.ReflectionsPan[1] = vals[1]; - effect->Reverb.ReflectionsPan[2] = vals[2]; - UnlockContext(context); - } - else - alSetError(context, AL_INVALID_VALUE); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - if(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])) - { - LockContext(context); - effect->Reverb.LateReverbPan[0] = vals[0]; - effect->Reverb.LateReverbPan[1] = vals[1]; - effect->Reverb.LateReverbPan[2] = vals[2]; - UnlockContext(context); - } - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - eaxreverb_SetParamf(effect, context, param, vals[0]); - break; - } -} - -static void eaxreverb_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - *val = effect->Reverb.DecayHFLimit; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - eaxreverb_GetParami(effect, context, param, vals); -} -static void eaxreverb_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_EAXREVERB_DENSITY: - *val = effect->Reverb.Density; - break; - - case AL_EAXREVERB_DIFFUSION: - *val = effect->Reverb.Diffusion; - break; - - case AL_EAXREVERB_GAIN: - *val = effect->Reverb.Gain; - break; - - case AL_EAXREVERB_GAINHF: - *val = effect->Reverb.GainHF; - break; - - case AL_EAXREVERB_GAINLF: - *val = effect->Reverb.GainLF; - break; - - case AL_EAXREVERB_DECAY_TIME: - *val = effect->Reverb.DecayTime; - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - *val = effect->Reverb.DecayHFRatio; - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - *val = effect->Reverb.DecayLFRatio; - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - *val = effect->Reverb.ReflectionsGain; - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - *val = effect->Reverb.ReflectionsDelay; - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - *val = effect->Reverb.LateReverbGain; - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - *val = effect->Reverb.LateReverbDelay; - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - *val = effect->Reverb.AirAbsorptionGainHF; - break; - - case AL_EAXREVERB_ECHO_TIME: - *val = effect->Reverb.EchoTime; - break; - - case AL_EAXREVERB_ECHO_DEPTH: - *val = effect->Reverb.EchoDepth; - break; - - case AL_EAXREVERB_MODULATION_TIME: - *val = effect->Reverb.ModulationTime; - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - *val = effect->Reverb.ModulationDepth; - break; - - case AL_EAXREVERB_HFREFERENCE: - *val = effect->Reverb.HFReference; - break; - - case AL_EAXREVERB_LFREFERENCE: - *val = effect->Reverb.LFReference; - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - *val = effect->Reverb.RoomRolloffFactor; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - LockContext(context); - vals[0] = effect->Reverb.ReflectionsPan[0]; - vals[1] = effect->Reverb.ReflectionsPan[1]; - vals[2] = effect->Reverb.ReflectionsPan[2]; - UnlockContext(context); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - LockContext(context); - vals[0] = effect->Reverb.LateReverbPan[0]; - vals[1] = effect->Reverb.LateReverbPan[1]; - vals[2] = effect->Reverb.LateReverbPan[2]; - UnlockContext(context); - break; - - default: - eaxreverb_GetParamf(effect, context, param, vals); - break; - } -} - - -static void reverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - if(val >= AL_REVERB_MIN_DECAY_HFLIMIT && - val <= AL_REVERB_MAX_DECAY_HFLIMIT) - effect->Reverb.DecayHFLimit = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - reverb_SetParami(effect, context, param, vals[0]); -} -static void reverb_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_REVERB_DENSITY: - if(val >= AL_REVERB_MIN_DENSITY && - val <= AL_REVERB_MAX_DENSITY) - effect->Reverb.Density = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DIFFUSION: - if(val >= AL_REVERB_MIN_DIFFUSION && - val <= AL_REVERB_MAX_DIFFUSION) - effect->Reverb.Diffusion = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_GAIN: - if(val >= AL_REVERB_MIN_GAIN && - val <= AL_REVERB_MAX_GAIN) - effect->Reverb.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_GAINHF: - if(val >= AL_REVERB_MIN_GAINHF && - val <= AL_REVERB_MAX_GAINHF) - effect->Reverb.GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DECAY_TIME: - if(val >= AL_REVERB_MIN_DECAY_TIME && - val <= AL_REVERB_MAX_DECAY_TIME) - effect->Reverb.DecayTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DECAY_HFRATIO: - if(val >= AL_REVERB_MIN_DECAY_HFRATIO && - val <= AL_REVERB_MAX_DECAY_HFRATIO) - effect->Reverb.DecayHFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_REFLECTIONS_GAIN: - if(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && - val <= AL_REVERB_MAX_REFLECTIONS_GAIN) - effect->Reverb.ReflectionsGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_REFLECTIONS_DELAY: - if(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && - val <= AL_REVERB_MAX_REFLECTIONS_DELAY) - effect->Reverb.ReflectionsDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_LATE_REVERB_GAIN: - if(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && - val <= AL_REVERB_MAX_LATE_REVERB_GAIN) - effect->Reverb.LateReverbGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_LATE_REVERB_DELAY: - if(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && - val <= AL_REVERB_MAX_LATE_REVERB_DELAY) - effect->Reverb.LateReverbDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - if(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && - val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF) - effect->Reverb.AirAbsorptionGainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - if(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && - val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR) - effect->Reverb.RoomRolloffFactor = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - reverb_SetParamf(effect, context, param, vals[0]); -} - -static void reverb_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - *val = effect->Reverb.DecayHFLimit; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - reverb_GetParami(effect, context, param, vals); -} -static void reverb_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_REVERB_DENSITY: - *val = effect->Reverb.Density; - break; - - case AL_REVERB_DIFFUSION: - *val = effect->Reverb.Diffusion; - break; - - case AL_REVERB_GAIN: - *val = effect->Reverb.Gain; - break; - - case AL_REVERB_GAINHF: - *val = effect->Reverb.GainHF; - break; - - case AL_REVERB_DECAY_TIME: - *val = effect->Reverb.DecayTime; - break; - - case AL_REVERB_DECAY_HFRATIO: - *val = effect->Reverb.DecayHFRatio; - break; - - case AL_REVERB_REFLECTIONS_GAIN: - *val = effect->Reverb.ReflectionsGain; - break; - - case AL_REVERB_REFLECTIONS_DELAY: - *val = effect->Reverb.ReflectionsDelay; - break; - - case AL_REVERB_LATE_REVERB_GAIN: - *val = effect->Reverb.LateReverbGain; - break; - - case AL_REVERB_LATE_REVERB_DELAY: - *val = effect->Reverb.LateReverbDelay; - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - *val = effect->Reverb.AirAbsorptionGainHF; - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - *val = effect->Reverb.RoomRolloffFactor; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - reverb_GetParamf(effect, context, param, vals); -} - - -static void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - echo_SetParami(effect, context, param, vals[0]); -} -static void echo_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_ECHO_DELAY: - if(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY) - effect->Echo.Delay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_LRDELAY: - if(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY) - effect->Echo.LRDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_DAMPING: - if(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING) - effect->Echo.Damping = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_FEEDBACK: - if(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK) - effect->Echo.Feedback = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_SPREAD: - if(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD) - effect->Echo.Spread = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void echo_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - echo_SetParamf(effect, context, param, vals[0]); -} - -static void echo_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void echo_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - echo_GetParami(effect, context, param, vals); -} -static void echo_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_ECHO_DELAY: - *val = effect->Echo.Delay; - break; - - case AL_ECHO_LRDELAY: - *val = effect->Echo.LRDelay; - break; - - case AL_ECHO_DAMPING: - *val = effect->Echo.Damping; - break; - - case AL_ECHO_FEEDBACK: - *val = effect->Echo.Feedback; - break; - - case AL_ECHO_SPREAD: - *val = effect->Echo.Spread; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void echo_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - echo_GetParamf(effect, context, param, vals); -} - - -static void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - if(val >= AL_RING_MODULATOR_MIN_FREQUENCY && - val <= AL_RING_MODULATOR_MAX_FREQUENCY) - effect->Modulator.Frequency = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - if(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && - val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF) - effect->Modulator.HighPassCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - mod_SetParamf(effect, context, param, vals[0]); -} -static void mod_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - mod_SetParamf(effect, context, param, (ALfloat)val); - break; - - case AL_RING_MODULATOR_WAVEFORM: - if(val >= AL_RING_MODULATOR_MIN_WAVEFORM && - val <= AL_RING_MODULATOR_MAX_WAVEFORM) - effect->Modulator.Waveform = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - mod_SetParami(effect, context, param, vals[0]); -} - -static void mod_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = (ALint)effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = (ALint)effect->Modulator.HighPassCutoff; - break; - case AL_RING_MODULATOR_WAVEFORM: - *val = effect->Modulator.Waveform; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - mod_GetParami(effect, context, param, vals); -} -static void mod_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = effect->Modulator.HighPassCutoff; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - mod_GetParamf(effect, context, param, vals); -} - - -static void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ded_SetParami(effect, context, param, vals[0]); -} -static void ded_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - if(val >= 0.0f && isfinite(val)) - effect->Dedicated.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void ded_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ded_SetParamf(effect, context, param, vals[0]); -} - -static void ded_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void ded_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ded_GetParami(effect, context, param, vals); -} -static void ded_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - *val = effect->Dedicated.Gain; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void ded_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ded_GetParamf(effect, context, param, vals); -} - - -static void null_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } - -static void null_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } - ALvoid ReleaseALEffects(ALCdevice *device) { @@ -1182,7 +356,7 @@ ALvoid ReleaseALEffects(ALCdevice *device) device->EffectMap.array[i].value = NULL; // Release effect structure - FreeThunkEntry(temp->effect); + FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffect)); free(temp); } @@ -1194,115 +368,319 @@ static void InitEffectParams(ALeffect *effect, ALenum type) switch(type) { case AL_EFFECT_EAXREVERB: - effect->Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY; - effect->Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; - effect->Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN; - effect->Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; - effect->Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; - effect->Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; - effect->Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; - effect->Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; - effect->Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; - effect->Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; - effect->Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; - effect->Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; - effect->Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; - effect->Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; - effect->Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; - effect->Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; - effect->Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - effect->Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; - effect->Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; - effect->Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - effect->Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; - effect->SetParami = eaxreverb_SetParami; - effect->SetParamiv = eaxreverb_SetParamiv; - effect->SetParamf = eaxreverb_SetParamf; - effect->SetParamfv = eaxreverb_SetParamfv; - effect->GetParami = eaxreverb_GetParami; - effect->GetParamiv = eaxreverb_GetParamiv; - effect->GetParamf = eaxreverb_GetParamf; - effect->GetParamfv = eaxreverb_GetParamfv; + effect->Props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY; + effect->Props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; + effect->Props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN; + effect->Props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; + effect->Props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; + effect->Props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; + effect->Props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; + effect->Props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; + effect->Props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; + effect->Props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; + effect->Props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; + effect->Props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; + effect->Props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; + effect->Props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; + effect->Props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; + effect->Props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; + effect->Props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + effect->Props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; + effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; + effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; + SET_VTABLE1(ALeaxreverb, effect); break; case AL_EFFECT_REVERB: - effect->Reverb.Density = AL_REVERB_DEFAULT_DENSITY; - effect->Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; - effect->Reverb.Gain = AL_REVERB_DEFAULT_GAIN; - effect->Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF; - effect->Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; - effect->Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; - effect->Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; - effect->Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; - effect->Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; - effect->Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; - effect->Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - effect->Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - effect->Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; - effect->SetParami = reverb_SetParami; - effect->SetParamiv = reverb_SetParamiv; - effect->SetParamf = reverb_SetParamf; - effect->SetParamfv = reverb_SetParamfv; - effect->GetParami = reverb_GetParami; - effect->GetParamiv = reverb_GetParamiv; - effect->GetParamf = reverb_GetParamf; - effect->GetParamfv = reverb_GetParamfv; + effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY; + effect->Props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; + effect->Props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN; + effect->Props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF; + effect->Props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; + effect->Props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; + effect->Props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; + effect->Props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; + effect->Props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; + effect->Props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; + effect->Props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; + SET_VTABLE1(ALreverb, effect); + break; + case AL_EFFECT_AUTOWAH: + effect->Props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; + effect->Props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; + effect->Props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; + effect->Props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; + SET_VTABLE1(ALautowah, effect); + break; + case AL_EFFECT_CHORUS: + effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM; + effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE; + effect->Props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE; + effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH; + effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK; + effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY; + SET_VTABLE1(ALchorus, effect); + break; + case AL_EFFECT_COMPRESSOR: + effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF; + SET_VTABLE1(ALcompressor, effect); + break; + case AL_EFFECT_DISTORTION: + effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE; + effect->Props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN; + effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF; + effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER; + effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH; + SET_VTABLE1(ALdistortion, effect); break; case AL_EFFECT_ECHO: - effect->Echo.Delay = AL_ECHO_DEFAULT_DELAY; - effect->Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; - effect->Echo.Damping = AL_ECHO_DEFAULT_DAMPING; - effect->Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; - effect->Echo.Spread = AL_ECHO_DEFAULT_SPREAD; - effect->SetParami = echo_SetParami; - effect->SetParamiv = echo_SetParamiv; - effect->SetParamf = echo_SetParamf; - effect->SetParamfv = echo_SetParamfv; - effect->GetParami = echo_GetParami; - effect->GetParamiv = echo_GetParamiv; - effect->GetParamf = echo_GetParamf; - effect->GetParamfv = echo_GetParamfv; + effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY; + effect->Props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; + effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING; + effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; + effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD; + SET_VTABLE1(ALecho, effect); + break; + case AL_EFFECT_EQUALIZER: + effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF; + effect->Props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN; + effect->Props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER; + effect->Props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN; + effect->Props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH; + effect->Props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER; + effect->Props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN; + effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH; + effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF; + effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN; + SET_VTABLE1(ALequalizer, effect); + break; + case AL_EFFECT_FLANGER: + effect->Props.Flanger.Waveform = AL_FLANGER_DEFAULT_WAVEFORM; + effect->Props.Flanger.Phase = AL_FLANGER_DEFAULT_PHASE; + effect->Props.Flanger.Rate = AL_FLANGER_DEFAULT_RATE; + effect->Props.Flanger.Depth = AL_FLANGER_DEFAULT_DEPTH; + effect->Props.Flanger.Feedback = AL_FLANGER_DEFAULT_FEEDBACK; + effect->Props.Flanger.Delay = AL_FLANGER_DEFAULT_DELAY; + SET_VTABLE1(ALflanger, effect); break; case AL_EFFECT_RING_MODULATOR: - effect->Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; - effect->Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; - effect->Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; - effect->SetParami = mod_SetParami; - effect->SetParamiv = mod_SetParamiv; - effect->SetParamf = mod_SetParamf; - effect->SetParamfv = mod_SetParamfv; - effect->GetParami = mod_GetParami; - effect->GetParamiv = mod_GetParamiv; - effect->GetParamf = mod_GetParamf; - effect->GetParamfv = mod_GetParamfv; + effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; + effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; + effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; + SET_VTABLE1(ALmodulator, effect); break; case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: case AL_EFFECT_DEDICATED_DIALOGUE: - effect->Dedicated.Gain = 1.0f; - effect->SetParami = ded_SetParami; - effect->SetParamiv = ded_SetParamiv; - effect->SetParamf = ded_SetParamf; - effect->SetParamfv = ded_SetParamfv; - effect->GetParami = ded_GetParami; - effect->GetParamiv = ded_GetParamiv; - effect->GetParamf = ded_GetParamf; - effect->GetParamfv = ded_GetParamfv; + effect->Props.Dedicated.Gain = 1.0f; + SET_VTABLE1(ALdedicated, effect); break; default: - effect->SetParami = null_SetParami; - effect->SetParamiv = null_SetParamiv; - effect->SetParamf = null_SetParamf; - effect->SetParamfv = null_SetParamfv; - effect->GetParami = null_GetParami; - effect->GetParamiv = null_GetParamiv; - effect->GetParamf = null_GetParamf; - effect->GetParamfv = null_GetParamfv; + SET_VTABLE1(ALnull, effect); break; } effect->type = type; } + + +#include "AL/efx-presets.h" + +#define DECL(x) { #x, EFX_REVERB_PRESET_##x } +static const struct { + const char name[32]; + EFXEAXREVERBPROPERTIES props; +} reverblist[] = { + DECL(GENERIC), + DECL(PADDEDCELL), + DECL(ROOM), + DECL(BATHROOM), + DECL(LIVINGROOM), + DECL(STONEROOM), + DECL(AUDITORIUM), + DECL(CONCERTHALL), + DECL(CAVE), + DECL(ARENA), + DECL(HANGAR), + DECL(CARPETEDHALLWAY), + DECL(HALLWAY), + DECL(STONECORRIDOR), + DECL(ALLEY), + DECL(FOREST), + DECL(CITY), + DECL(MOUNTAINS), + DECL(QUARRY), + DECL(PLAIN), + DECL(PARKINGLOT), + DECL(SEWERPIPE), + DECL(UNDERWATER), + DECL(DRUGGED), + DECL(DIZZY), + DECL(PSYCHOTIC), + + DECL(CASTLE_SMALLROOM), + DECL(CASTLE_SHORTPASSAGE), + DECL(CASTLE_MEDIUMROOM), + DECL(CASTLE_LARGEROOM), + DECL(CASTLE_LONGPASSAGE), + DECL(CASTLE_HALL), + DECL(CASTLE_CUPBOARD), + DECL(CASTLE_COURTYARD), + DECL(CASTLE_ALCOVE), + + DECL(FACTORY_SMALLROOM), + DECL(FACTORY_SHORTPASSAGE), + DECL(FACTORY_MEDIUMROOM), + DECL(FACTORY_LARGEROOM), + DECL(FACTORY_LONGPASSAGE), + DECL(FACTORY_HALL), + DECL(FACTORY_CUPBOARD), + DECL(FACTORY_COURTYARD), + DECL(FACTORY_ALCOVE), + + DECL(ICEPALACE_SMALLROOM), + DECL(ICEPALACE_SHORTPASSAGE), + DECL(ICEPALACE_MEDIUMROOM), + DECL(ICEPALACE_LARGEROOM), + DECL(ICEPALACE_LONGPASSAGE), + DECL(ICEPALACE_HALL), + DECL(ICEPALACE_CUPBOARD), + DECL(ICEPALACE_COURTYARD), + DECL(ICEPALACE_ALCOVE), + + DECL(SPACESTATION_SMALLROOM), + DECL(SPACESTATION_SHORTPASSAGE), + DECL(SPACESTATION_MEDIUMROOM), + DECL(SPACESTATION_LARGEROOM), + DECL(SPACESTATION_LONGPASSAGE), + DECL(SPACESTATION_HALL), + DECL(SPACESTATION_CUPBOARD), + DECL(SPACESTATION_ALCOVE), + + DECL(WOODEN_SMALLROOM), + DECL(WOODEN_SHORTPASSAGE), + DECL(WOODEN_MEDIUMROOM), + DECL(WOODEN_LARGEROOM), + DECL(WOODEN_LONGPASSAGE), + DECL(WOODEN_HALL), + DECL(WOODEN_CUPBOARD), + DECL(WOODEN_COURTYARD), + DECL(WOODEN_ALCOVE), + + DECL(SPORT_EMPTYSTADIUM), + DECL(SPORT_SQUASHCOURT), + DECL(SPORT_SMALLSWIMMINGPOOL), + DECL(SPORT_LARGESWIMMINGPOOL), + DECL(SPORT_GYMNASIUM), + DECL(SPORT_FULLSTADIUM), + DECL(SPORT_STADIUMTANNOY), + + DECL(PREFAB_WORKSHOP), + DECL(PREFAB_SCHOOLROOM), + DECL(PREFAB_PRACTISEROOM), + DECL(PREFAB_OUTHOUSE), + DECL(PREFAB_CARAVAN), + + DECL(DOME_TOMB), + DECL(PIPE_SMALL), + DECL(DOME_SAINTPAULS), + DECL(PIPE_LONGTHIN), + DECL(PIPE_LARGE), + DECL(PIPE_RESONANT), + + DECL(OUTDOORS_BACKYARD), + DECL(OUTDOORS_ROLLINGPLAINS), + DECL(OUTDOORS_DEEPCANYON), + DECL(OUTDOORS_CREEK), + DECL(OUTDOORS_VALLEY), + + DECL(MOOD_HEAVEN), + DECL(MOOD_HELL), + DECL(MOOD_MEMORY), + + DECL(DRIVING_COMMENTATOR), + DECL(DRIVING_PITGARAGE), + DECL(DRIVING_INCAR_RACER), + DECL(DRIVING_INCAR_SPORTS), + DECL(DRIVING_INCAR_LUXURY), + DECL(DRIVING_FULLGRANDSTAND), + DECL(DRIVING_EMPTYGRANDSTAND), + DECL(DRIVING_TUNNEL), + + DECL(CITY_STREETS), + DECL(CITY_SUBWAY), + DECL(CITY_MUSEUM), + DECL(CITY_LIBRARY), + DECL(CITY_UNDERPASS), + DECL(CITY_ABANDONED), + + DECL(DUSTYROOM), + DECL(CHAPEL), + DECL(SMALLWATERROOM), +}; +#undef DECL + +ALvoid LoadReverbPreset(const char *name, ALeffect *effect) +{ + size_t i; + + if(strcasecmp(name, "NONE") == 0) + { + InitEffectParams(effect, AL_EFFECT_NULL); + TRACE("Loading reverb '%s'\n", "NONE"); + return; + } + + if(!DisabledEffects[EAXREVERB]) + InitEffectParams(effect, AL_EFFECT_EAXREVERB); + else if(!DisabledEffects[REVERB]) + InitEffectParams(effect, AL_EFFECT_REVERB); + else + InitEffectParams(effect, AL_EFFECT_NULL); + for(i = 0;i < COUNTOF(reverblist);i++) + { + const EFXEAXREVERBPROPERTIES *props; + + if(strcasecmp(name, reverblist[i].name) != 0) + continue; + + TRACE("Loading reverb '%s'\n", reverblist[i].name); + props = &reverblist[i].props; + effect->Props.Reverb.Density = props->flDensity; + effect->Props.Reverb.Diffusion = props->flDiffusion; + effect->Props.Reverb.Gain = props->flGain; + effect->Props.Reverb.GainHF = props->flGainHF; + effect->Props.Reverb.GainLF = props->flGainLF; + effect->Props.Reverb.DecayTime = props->flDecayTime; + effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio; + effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio; + effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain; + effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay; + effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0]; + effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1]; + effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2]; + effect->Props.Reverb.LateReverbGain = props->flLateReverbGain; + effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay; + effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0]; + effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1]; + effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2]; + effect->Props.Reverb.EchoTime = props->flEchoTime; + effect->Props.Reverb.EchoDepth = props->flEchoDepth; + effect->Props.Reverb.ModulationTime = props->flModulationTime; + effect->Props.Reverb.ModulationDepth = props->flModulationDepth; + effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF; + effect->Props.Reverb.HFReference = props->flHFReference; + effect->Props.Reverb.LFReference = props->flLFReference; + effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor; + effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit; + return; + } + + WARN("Reverb preset '%s' not found\n", name); +} diff --git a/jni/openal-soft-android/OpenAL32/alError.c b/jni/openal-soft-android/OpenAL32/alError.c index 56f4248e..b557532e 100644 --- a/jni/openal-soft-android/OpenAL32/alError.c +++ b/jni/openal-soft-android/OpenAL32/alError.c @@ -22,27 +22,17 @@ #include +#ifdef HAVE_WINDOWS_H +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include "alMain.h" #include "AL/alc.h" #include "alError.h" ALboolean TrapALError = AL_FALSE; -AL_API ALenum AL_APIENTRY alGetError(void) -{ - ALCcontext *Context; - ALenum errorCode; - - Context = GetContextRef(); - if(!Context) return AL_INVALID_OPERATION; - - errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR); - - ALCcontext_DecRef(Context); - - return errorCode; -} - ALvoid alSetError(ALCcontext *Context, ALenum errorCode) { if(TrapALError) @@ -57,3 +47,30 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode) } CompExchangeInt(&Context->LastError, AL_NO_ERROR, errorCode); } + +AL_API ALenum AL_APIENTRY alGetError(void) +{ + ALCcontext *Context; + ALenum errorCode; + + Context = GetContextRef(); + if(!Context) + { + if(TrapALError) + { +#ifdef _WIN32 + if(IsDebuggerPresent()) + DebugBreak(); +#elif defined(SIGTRAP) + raise(SIGTRAP); +#endif + } + return AL_INVALID_OPERATION; + } + + errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR); + + ALCcontext_DecRef(Context); + + return errorCode; +} diff --git a/jni/openal-soft-android/OpenAL32/alExtension.c b/jni/openal-soft-android/OpenAL32/alExtension.c index 3309338e..fc23a932 100644 --- a/jni/openal-soft-android/OpenAL32/alExtension.c +++ b/jni/openal-soft-android/OpenAL32/alExtension.c @@ -34,347 +34,58 @@ #include "AL/al.h" #include "AL/alc.h" -typedef struct ALenums { - const ALchar *enumName; - ALenum value; -} ALenums; - - -static const ALenums enumeration[] = { - // Types - { "AL_INVALID", AL_INVALID }, - { "AL_NONE", AL_NONE }, - { "AL_FALSE", AL_FALSE }, - { "AL_TRUE", AL_TRUE }, - - // Source and Listener Properties - { "AL_SOURCE_RELATIVE", AL_SOURCE_RELATIVE }, - { "AL_CONE_INNER_ANGLE", AL_CONE_INNER_ANGLE }, - { "AL_CONE_OUTER_ANGLE", AL_CONE_OUTER_ANGLE }, - { "AL_PITCH", AL_PITCH }, - { "AL_POSITION", AL_POSITION }, - { "AL_DIRECTION", AL_DIRECTION }, - { "AL_VELOCITY", AL_VELOCITY }, - { "AL_LOOPING", AL_LOOPING }, - { "AL_BUFFER", AL_BUFFER }, - { "AL_GAIN", AL_GAIN }, - { "AL_MIN_GAIN", AL_MIN_GAIN }, - { "AL_MAX_GAIN", AL_MAX_GAIN }, - { "AL_ORIENTATION", AL_ORIENTATION }, - { "AL_REFERENCE_DISTANCE", AL_REFERENCE_DISTANCE }, - { "AL_ROLLOFF_FACTOR", AL_ROLLOFF_FACTOR }, - { "AL_CONE_OUTER_GAIN", AL_CONE_OUTER_GAIN }, - { "AL_MAX_DISTANCE", AL_MAX_DISTANCE }, - { "AL_SEC_OFFSET", AL_SEC_OFFSET }, - { "AL_SAMPLE_OFFSET", AL_SAMPLE_OFFSET }, - { "AL_SAMPLE_RW_OFFSETS_SOFT", AL_SAMPLE_RW_OFFSETS_SOFT }, - { "AL_BYTE_OFFSET", AL_BYTE_OFFSET }, - { "AL_BYTE_RW_OFFSETS_SOFT", AL_BYTE_RW_OFFSETS_SOFT }, - { "AL_SOURCE_TYPE", AL_SOURCE_TYPE }, - { "AL_STATIC", AL_STATIC }, - { "AL_STREAMING", AL_STREAMING }, - { "AL_UNDETERMINED", AL_UNDETERMINED }, - { "AL_METERS_PER_UNIT", AL_METERS_PER_UNIT }, - { "AL_VIRTUAL_CHANNELS_SOFT", AL_VIRTUAL_CHANNELS_SOFT }, - - // Source EFX Properties - { "AL_DIRECT_FILTER", AL_DIRECT_FILTER }, - { "AL_AUXILIARY_SEND_FILTER", AL_AUXILIARY_SEND_FILTER }, - { "AL_AIR_ABSORPTION_FACTOR", AL_AIR_ABSORPTION_FACTOR }, - { "AL_ROOM_ROLLOFF_FACTOR", AL_ROOM_ROLLOFF_FACTOR }, - { "AL_CONE_OUTER_GAINHF", AL_CONE_OUTER_GAINHF }, - { "AL_DIRECT_FILTER_GAINHF_AUTO", AL_DIRECT_FILTER_GAINHF_AUTO }, - { "AL_AUXILIARY_SEND_FILTER_GAIN_AUTO", AL_AUXILIARY_SEND_FILTER_GAIN_AUTO }, - { "AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO", AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO}, - - // Source State information - { "AL_SOURCE_STATE", AL_SOURCE_STATE }, - { "AL_INITIAL", AL_INITIAL }, - { "AL_PLAYING", AL_PLAYING }, - { "AL_PAUSED", AL_PAUSED }, - { "AL_STOPPED", AL_STOPPED }, - - // Queue information - { "AL_BUFFERS_QUEUED", AL_BUFFERS_QUEUED }, - { "AL_BUFFERS_PROCESSED", AL_BUFFERS_PROCESSED }, - - // Buffer Formats - { "AL_FORMAT_MONO8", AL_FORMAT_MONO8 }, - { "AL_FORMAT_MONO16", AL_FORMAT_MONO16 }, - { "AL_FORMAT_MONO_FLOAT32", AL_FORMAT_MONO_FLOAT32 }, - { "AL_FORMAT_MONO_DOUBLE_EXT", AL_FORMAT_MONO_DOUBLE_EXT }, - { "AL_FORMAT_STEREO8", AL_FORMAT_STEREO8 }, - { "AL_FORMAT_STEREO16", AL_FORMAT_STEREO16 }, - { "AL_FORMAT_STEREO_FLOAT32", AL_FORMAT_STEREO_FLOAT32 }, - { "AL_FORMAT_STEREO_DOUBLE_EXT", AL_FORMAT_STEREO_DOUBLE_EXT }, - { "AL_FORMAT_MONO_IMA4", AL_FORMAT_MONO_IMA4 }, - { "AL_FORMAT_STEREO_IMA4", AL_FORMAT_STEREO_IMA4 }, - { "AL_FORMAT_QUAD8_LOKI", AL_FORMAT_QUAD8_LOKI }, - { "AL_FORMAT_QUAD16_LOKI", AL_FORMAT_QUAD16_LOKI }, - { "AL_FORMAT_QUAD8", AL_FORMAT_QUAD8 }, - { "AL_FORMAT_QUAD16", AL_FORMAT_QUAD16 }, - { "AL_FORMAT_QUAD32", AL_FORMAT_QUAD32 }, - { "AL_FORMAT_51CHN8", AL_FORMAT_51CHN8 }, - { "AL_FORMAT_51CHN16", AL_FORMAT_51CHN16 }, - { "AL_FORMAT_51CHN32", AL_FORMAT_51CHN32 }, - { "AL_FORMAT_61CHN8", AL_FORMAT_61CHN8 }, - { "AL_FORMAT_61CHN16", AL_FORMAT_61CHN16 }, - { "AL_FORMAT_61CHN32", AL_FORMAT_61CHN32 }, - { "AL_FORMAT_71CHN8", AL_FORMAT_71CHN8 }, - { "AL_FORMAT_71CHN16", AL_FORMAT_71CHN16 }, - { "AL_FORMAT_71CHN32", AL_FORMAT_71CHN32 }, - { "AL_FORMAT_REAR8", AL_FORMAT_REAR8 }, - { "AL_FORMAT_REAR16", AL_FORMAT_REAR16 }, - { "AL_FORMAT_REAR32", AL_FORMAT_REAR32 }, - { "AL_FORMAT_MONO_MULAW", AL_FORMAT_MONO_MULAW }, - { "AL_FORMAT_MONO_MULAW_EXT", AL_FORMAT_MONO_MULAW_EXT }, - { "AL_FORMAT_STEREO_MULAW", AL_FORMAT_STEREO_MULAW }, - { "AL_FORMAT_STEREO_MULAW_EXT", AL_FORMAT_STEREO_MULAW_EXT }, - { "AL_FORMAT_QUAD_MULAW", AL_FORMAT_QUAD_MULAW }, - { "AL_FORMAT_51CHN_MULAW", AL_FORMAT_51CHN_MULAW }, - { "AL_FORMAT_61CHN_MULAW", AL_FORMAT_61CHN_MULAW }, - { "AL_FORMAT_71CHN_MULAW", AL_FORMAT_71CHN_MULAW }, - { "AL_FORMAT_REAR_MULAW", AL_FORMAT_REAR_MULAW }, - { "AL_FORMAT_MONO_ALAW_EXT", AL_FORMAT_MONO_ALAW_EXT }, - { "AL_FORMAT_STEREO_ALAW_EXT", AL_FORMAT_STEREO_ALAW_EXT }, - - // Internal Buffer Formats - { "AL_MONO8", AL_MONO8 }, - { "AL_MONO16", AL_MONO16 }, - { "AL_MONO32F", AL_MONO32F }, - { "AL_STEREO8", AL_STEREO8 }, - { "AL_STEREO16", AL_STEREO16 }, - { "AL_STEREO32F", AL_STEREO32F }, - { "AL_QUAD8", AL_QUAD8 }, - { "AL_QUAD16", AL_QUAD16 }, - { "AL_QUAD32F", AL_QUAD32F }, - { "AL_REAR8", AL_REAR8 }, - { "AL_REAR16", AL_REAR16 }, - { "AL_REAR32F", AL_REAR32F }, - { "AL_5POINT1_8", AL_5POINT1_8 }, - { "AL_5POINT1_16", AL_5POINT1_16 }, - { "AL_5POINT1_32F", AL_5POINT1_32F }, - { "AL_6POINT1_8", AL_6POINT1_8 }, - { "AL_6POINT1_16", AL_6POINT1_16 }, - { "AL_6POINT1_32F", AL_6POINT1_32F }, - { "AL_7POINT1_8", AL_7POINT1_8 }, - { "AL_7POINT1_16", AL_7POINT1_16 }, - { "AL_7POINT1_32F", AL_7POINT1_32F }, - - // Buffer Channel Configurations - { "AL_MONO", AL_MONO }, - { "AL_STEREO", AL_STEREO }, - { "AL_QUAD", AL_QUAD }, - { "AL_REAR", AL_REAR }, - { "AL_5POINT1", AL_5POINT1 }, - { "AL_6POINT1", AL_6POINT1 }, - { "AL_7POINT1", AL_7POINT1 }, - - // Buffer Sample Types - { "AL_BYTE", AL_BYTE }, - { "AL_UNSIGNED_BYTE", AL_UNSIGNED_BYTE }, - { "AL_SHORT", AL_SHORT }, - { "AL_UNSIGNED_SHORT", AL_UNSIGNED_SHORT }, - { "AL_INT", AL_INT }, - { "AL_UNSIGNED_INT", AL_UNSIGNED_INT }, - { "AL_FLOAT", AL_FLOAT }, - { "AL_DOUBLE", AL_DOUBLE }, - { "AL_MULAW", AL_MULAW }, - { "AL_ALAW", AL_ALAW }, - { "AL_IMA4", AL_IMA4 }, - { "AL_BYTE3", AL_BYTE3 }, - { "AL_UNSIGNED_BYTE3", AL_UNSIGNED_BYTE3 }, - - // Buffer attributes - { "AL_FREQUENCY", AL_FREQUENCY }, - { "AL_BITS", AL_BITS }, - { "AL_CHANNELS", AL_CHANNELS }, - { "AL_SIZE", AL_SIZE }, - { "AL_INTERNAL_FORMAT", AL_INTERNAL_FORMAT }, - { "AL_BYTE_LENGTH", AL_BYTE_LENGTH }, - { "AL_SAMPLE_LENGTH", AL_SAMPLE_LENGTH }, - { "AL_SEC_LENGTH", AL_SEC_LENGTH }, - - // Buffer States (not supported yet) - { "AL_UNUSED", AL_UNUSED }, - { "AL_PENDING", AL_PENDING }, - { "AL_PROCESSED", AL_PROCESSED }, - - // AL Error Messages - { "AL_NO_ERROR", AL_NO_ERROR }, - { "AL_INVALID_NAME", AL_INVALID_NAME }, - { "AL_INVALID_ENUM", AL_INVALID_ENUM }, - { "AL_INVALID_VALUE", AL_INVALID_VALUE }, - { "AL_INVALID_OPERATION", AL_INVALID_OPERATION }, - { "AL_OUT_OF_MEMORY", AL_OUT_OF_MEMORY }, - - // Context strings - { "AL_VENDOR", AL_VENDOR }, - { "AL_VERSION", AL_VERSION }, - { "AL_RENDERER", AL_RENDERER }, - { "AL_EXTENSIONS", AL_EXTENSIONS }, - - // Global states - { "AL_DOPPLER_FACTOR", AL_DOPPLER_FACTOR }, - { "AL_DOPPLER_VELOCITY", AL_DOPPLER_VELOCITY }, - { "AL_DISTANCE_MODEL", AL_DISTANCE_MODEL }, - { "AL_SPEED_OF_SOUND", AL_SPEED_OF_SOUND }, - { "AL_SOURCE_DISTANCE_MODEL", AL_SOURCE_DISTANCE_MODEL }, - { "AL_DEFERRED_UPDATES_SOFT", AL_DEFERRED_UPDATES_SOFT }, - - // Distance Models - { "AL_INVERSE_DISTANCE", AL_INVERSE_DISTANCE }, - { "AL_INVERSE_DISTANCE_CLAMPED", AL_INVERSE_DISTANCE_CLAMPED }, - { "AL_LINEAR_DISTANCE", AL_LINEAR_DISTANCE }, - { "AL_LINEAR_DISTANCE_CLAMPED", AL_LINEAR_DISTANCE_CLAMPED }, - { "AL_EXPONENT_DISTANCE", AL_EXPONENT_DISTANCE }, - { "AL_EXPONENT_DISTANCE_CLAMPED", AL_EXPONENT_DISTANCE_CLAMPED }, - - // Filter types - { "AL_FILTER_TYPE", AL_FILTER_TYPE }, - { "AL_FILTER_NULL", AL_FILTER_NULL }, - { "AL_FILTER_LOWPASS", AL_FILTER_LOWPASS }, -#if 0 - { "AL_FILTER_HIGHPASS", AL_FILTER_HIGHPASS }, - { "AL_FILTER_BANDPASS", AL_FILTER_BANDPASS }, -#endif - - // Filter params - { "AL_LOWPASS_GAIN", AL_LOWPASS_GAIN }, - { "AL_LOWPASS_GAINHF", AL_LOWPASS_GAINHF }, - - // Effect types - { "AL_EFFECT_TYPE", AL_EFFECT_TYPE }, - { "AL_EFFECT_NULL", AL_EFFECT_NULL }, - { "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, - { "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, -#if 0 - { "AL_EFFECT_CHORUS", AL_EFFECT_CHORUS }, - { "AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION }, -#endif - { "AL_EFFECT_ECHO", AL_EFFECT_ECHO }, -#if 0 - { "AL_EFFECT_FLANGER", AL_EFFECT_FLANGER }, - { "AL_EFFECT_FREQUENCY_SHIFTER", AL_EFFECT_FREQUENCY_SHIFTER }, - { "AL_EFFECT_VOCAL_MORPHER", AL_EFFECT_VOCAL_MORPHER }, - { "AL_EFFECT_PITCH_SHIFTER", AL_EFFECT_PITCH_SHIFTER }, -#endif - { "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, -#if 0 - { "AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH }, - { "AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR }, - { "AL_EFFECT_EQUALIZER", AL_EFFECT_EQUALIZER }, -#endif - { "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT",AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT}, - { "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE }, - - // Reverb params - { "AL_REVERB_DENSITY", AL_REVERB_DENSITY }, - { "AL_REVERB_DIFFUSION", AL_REVERB_DIFFUSION }, - { "AL_REVERB_GAIN", AL_REVERB_GAIN }, - { "AL_REVERB_GAINHF", AL_REVERB_GAINHF }, - { "AL_REVERB_DECAY_TIME", AL_REVERB_DECAY_TIME }, - { "AL_REVERB_DECAY_HFRATIO", AL_REVERB_DECAY_HFRATIO }, - { "AL_REVERB_REFLECTIONS_GAIN", AL_REVERB_REFLECTIONS_GAIN }, - { "AL_REVERB_REFLECTIONS_DELAY", AL_REVERB_REFLECTIONS_DELAY }, - { "AL_REVERB_LATE_REVERB_GAIN", AL_REVERB_LATE_REVERB_GAIN }, - { "AL_REVERB_LATE_REVERB_DELAY", AL_REVERB_LATE_REVERB_DELAY }, - { "AL_REVERB_AIR_ABSORPTION_GAINHF", AL_REVERB_AIR_ABSORPTION_GAINHF }, - { "AL_REVERB_ROOM_ROLLOFF_FACTOR", AL_REVERB_ROOM_ROLLOFF_FACTOR }, - { "AL_REVERB_DECAY_HFLIMIT", AL_REVERB_DECAY_HFLIMIT }, - - // EAX Reverb params - { "AL_EAXREVERB_DENSITY", AL_EAXREVERB_DENSITY }, - { "AL_EAXREVERB_DIFFUSION", AL_EAXREVERB_DIFFUSION }, - { "AL_EAXREVERB_GAIN", AL_EAXREVERB_GAIN }, - { "AL_EAXREVERB_GAINHF", AL_EAXREVERB_GAINHF }, - { "AL_EAXREVERB_GAINLF", AL_EAXREVERB_GAINLF }, - { "AL_EAXREVERB_DECAY_TIME", AL_EAXREVERB_DECAY_TIME }, - { "AL_EAXREVERB_DECAY_HFRATIO", AL_EAXREVERB_DECAY_HFRATIO }, - { "AL_EAXREVERB_DECAY_LFRATIO", AL_EAXREVERB_DECAY_LFRATIO }, - { "AL_EAXREVERB_REFLECTIONS_GAIN", AL_EAXREVERB_REFLECTIONS_GAIN }, - { "AL_EAXREVERB_REFLECTIONS_DELAY", AL_EAXREVERB_REFLECTIONS_DELAY }, - { "AL_EAXREVERB_REFLECTIONS_PAN", AL_EAXREVERB_REFLECTIONS_PAN }, - { "AL_EAXREVERB_LATE_REVERB_GAIN", AL_EAXREVERB_LATE_REVERB_GAIN }, - { "AL_EAXREVERB_LATE_REVERB_DELAY", AL_EAXREVERB_LATE_REVERB_DELAY }, - { "AL_EAXREVERB_LATE_REVERB_PAN", AL_EAXREVERB_LATE_REVERB_PAN }, - { "AL_EAXREVERB_ECHO_TIME", AL_EAXREVERB_ECHO_TIME }, - { "AL_EAXREVERB_ECHO_DEPTH", AL_EAXREVERB_ECHO_DEPTH }, - { "AL_EAXREVERB_MODULATION_TIME", AL_EAXREVERB_MODULATION_TIME }, - { "AL_EAXREVERB_MODULATION_DEPTH", AL_EAXREVERB_MODULATION_DEPTH }, - { "AL_EAXREVERB_AIR_ABSORPTION_GAINHF", AL_EAXREVERB_AIR_ABSORPTION_GAINHF }, - { "AL_EAXREVERB_HFREFERENCE", AL_EAXREVERB_HFREFERENCE }, - { "AL_EAXREVERB_LFREFERENCE", AL_EAXREVERB_LFREFERENCE }, - { "AL_EAXREVERB_ROOM_ROLLOFF_FACTOR", AL_EAXREVERB_ROOM_ROLLOFF_FACTOR }, - { "AL_EAXREVERB_DECAY_HFLIMIT", AL_EAXREVERB_DECAY_HFLIMIT }, - - // Echo params - { "AL_ECHO_DELAY", AL_ECHO_DELAY }, - { "AL_ECHO_LRDELAY", AL_ECHO_LRDELAY }, - { "AL_ECHO_DAMPING", AL_ECHO_DAMPING }, - { "AL_ECHO_FEEDBACK", AL_ECHO_FEEDBACK }, - { "AL_ECHO_SPREAD", AL_ECHO_SPREAD }, - - // Ring Modulator params - { "AL_RING_MODULATOR_FREQUENCY", AL_RING_MODULATOR_FREQUENCY }, - { "AL_RING_MODULATOR_HIGHPASS_CUTOFF", AL_RING_MODULATOR_HIGHPASS_CUTOFF }, - { "AL_RING_MODULATOR_WAVEFORM", AL_RING_MODULATOR_WAVEFORM }, - - // Dedicated Dialogue/LFE params - { "AL_DEDICATED_GAIN", AL_DEDICATED_GAIN }, - - - // Default - { NULL, (ALenum)0 } -}; - const struct EffectList EffectList[] = { - { "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, - { "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, - { "echo", ECHO, "AL_EFFECT_ECHO", AL_EFFECT_ECHO }, - { "modulator", MODULATOR, "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, - { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, - { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE }, + { "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, + { "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, + { "autowah", AUTOWAH, "AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH }, + { "chorus", CHORUS, "AL_EFFECT_CHORUS", AL_EFFECT_CHORUS }, + { "compressor", COMPRESSOR, "AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR }, + { "distortion", DISTORTION, "AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION }, + { "echo", ECHO, "AL_EFFECT_ECHO", AL_EFFECT_ECHO }, + { "equalizer", EQUALIZER, "AL_EFFECT_EQUALIZER", AL_EFFECT_EQUALIZER }, + { "flanger", FLANGER, "AL_EFFECT_FLANGER", AL_EFFECT_FLANGER }, + { "modulator", MODULATOR, "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, + { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, + { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE }, { NULL, 0, NULL, (ALenum)0 } }; AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName) { - ALboolean bIsSupported = AL_FALSE; - ALCcontext *Context; + ALboolean ret = AL_FALSE; + ALCcontext *context; const char *ptr; size_t len; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - if(!extName) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(extName)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + len = strlen(extName); + ptr = context->ExtensionList; + while(ptr && *ptr) { - len = strlen(extName); - ptr = Context->ExtensionList; - while(ptr && *ptr) + if(strncasecmp(ptr, extName, len) == 0 && + (ptr[len] == '\0' || isspace(ptr[len]))) { - if(strncasecmp(ptr, extName, len) == 0 && - (ptr[len] == '\0' || isspace(ptr[len]))) - { - bIsSupported = AL_TRUE; - break; - } - if((ptr=strchr(ptr, ' ')) != NULL) - { - do { - ++ptr; - } while(isspace(*ptr)); - } + ret = AL_TRUE; + break; + } + if((ptr=strchr(ptr, ' ')) != NULL) + { + do { + ++ptr; + } while(isspace(*ptr)); } } - ALCcontext_DecRef(Context); - return bIsSupported; +done: + ALCcontext_DecRef(context); + return ret; } @@ -387,19 +98,7 @@ AL_API ALvoid* AL_APIENTRY alGetProcAddress(const ALchar *funcName) AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *enumName) { - ALsizei i; - - for(i = 0;EffectList[i].ename;i++) - { - if(DisabledEffects[EffectList[i].type] && - strcmp(EffectList[i].ename, enumName) == 0) - return (ALenum)0; - } - - i = 0; - while(enumeration[i].enumName && - strcmp(enumeration[i].enumName, enumName) != 0) - i++; - - return enumeration[i].value; + if(!enumName) + return (ALenum)0; + return alcGetEnumValue(NULL, enumName); } diff --git a/jni/openal-soft-android/OpenAL32/alFilter.c b/jni/openal-soft-android/OpenAL32/alFilter.c index 5697b868..692109f5 100644 --- a/jni/openal-soft-android/OpenAL32/alFilter.c +++ b/jni/openal-soft-android/OpenAL32/alFilter.c @@ -22,106 +22,96 @@ #include -#include "AL/al.h" -#include "AL/alc.h" #include "alMain.h" +#include "alu.h" #include "alFilter.h" #include "alThunk.h" #include "alError.h" +extern inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id); +extern inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id); +extern inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample); +extern inline ALfloat ALfilterState_processSingleC(const ALfilterState *filter, ALfloat sample); + static void InitFilterParams(ALfilter *filter, ALenum type); AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) { - ALCcontext *Context; - ALsizei i; + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0 || IsBadWritePtr((void*)filters, n * sizeof(ALuint))) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) { - ALCdevice *device = Context->Device; - ALenum err; - - for(i = 0;i < n;i++) + ALfilter *filter = calloc(1, sizeof(ALfilter)); + if(!filter) { - ALfilter *filter = calloc(1, sizeof(ALfilter)); - if(!filter) - { - alSetError(Context, AL_OUT_OF_MEMORY); - alDeleteFilters(i, filters); - break; - } - InitFilterParams(filter, AL_FILTER_NULL); - - err = NewThunkEntry(&filter->filter); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->FilterMap, filter->filter, filter); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(filter->filter); - memset(filter, 0, sizeof(ALfilter)); - free(filter); - - alSetError(Context, err); - alDeleteFilters(i, filters); - break; - } - - filters[i] = filter->filter; + alDeleteFilters(cur, filters); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } + InitFilterParams(filter, AL_FILTER_NULL); + + err = NewThunkEntry(&filter->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(filter->id); + memset(filter, 0, sizeof(ALfilter)); + free(filter); + + alDeleteFilters(cur, filters); + SET_ERROR_AND_GOTO(context, err, done); + } + + filters[cur] = filter->id; } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) { - ALCcontext *Context; ALCdevice *device; - ALfilter *ALFilter; + ALCcontext *context; + ALfilter *filter; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - device = Context->Device; - if(n < 0) - alSetError(Context, AL_INVALID_VALUE); - else + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) { - // Check that all filters are valid - for(i = 0;i < n;i++) - { - if(!filters[i]) - continue; + if(filters[i] && LookupFilter(device, filters[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + if((filter=RemoveFilter(device, filters[i])) == NULL) + continue; + FreeThunkEntry(filter->id); - if(LookupFilter(device, filters[i]) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - n = 0; - break; - } - } - - for(i = 0;i < n;i++) - { - // Recheck that the filter is valid, because there could be duplicated names - if((ALFilter=RemoveFilter(device, filters[i])) == NULL) - continue; - FreeThunkEntry(ALFilter->filter); - - memset(ALFilter, 0, sizeof(ALfilter)); - free(ALFilter); - } + memset(filter, 0, sizeof(*filter)); + free(filter); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) @@ -140,7 +130,7 @@ AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) return result; } -AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue) +AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value) { ALCcontext *Context; ALCdevice *Device; @@ -150,130 +140,28 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue) if(!Context) return; Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { - switch(param) + if(param == AL_FILTER_TYPE) { - case AL_FILTER_TYPE: - if(iValue == AL_FILTER_NULL || iValue == AL_FILTER_LOWPASS) - InitFilterParams(ALFilter, iValue); + if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS) + InitFilterParams(ALFilter, value); else alSetError(Context, AL_INVALID_VALUE); - break; - - default: - /* Call the appropriate handler */ - ALfilter_SetParami(ALFilter, Context, param, iValue); - break; } - } - else - alSetError(Context, AL_INVALID_NAME); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues) -{ - ALCcontext *Context; - ALCdevice *Device; - ALfilter *ALFilter; - - switch(param) - { - case AL_FILTER_TYPE: - alFilteri(filter, param, piValues[0]); - return; - } - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) - { - /* Call the appropriate handler */ - ALfilter_SetParamiv(ALFilter, Context, param, piValues); - } - else - alSetError(Context, AL_INVALID_NAME); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue) -{ - ALCcontext *Context; - ALCdevice *Device; - ALfilter *ALFilter; - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) - { - /* Call the appropriate handler */ - ALfilter_SetParamf(ALFilter, Context, param, flValue); - } - else - alSetError(Context, AL_INVALID_NAME); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues) -{ - ALCcontext *Context; - ALCdevice *Device; - ALfilter *ALFilter; - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) - { - /* Call the appropriate handler */ - ALfilter_SetParamfv(ALFilter, Context, param, pflValues); - } - else - alSetError(Context, AL_INVALID_NAME); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue) -{ - ALCcontext *Context; - ALCdevice *Device; - ALfilter *ALFilter; - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) - { - switch(param) + else { - case AL_FILTER_TYPE: - *piValue = ALFilter->type; - break; - - default: /* Call the appropriate handler */ - ALfilter_GetParami(ALFilter, Context, param, piValue); - break; + ALfilter_SetParami(ALFilter, Context, param, value); } } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues) +AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values) { ALCcontext *Context; ALCdevice *Device; @@ -282,7 +170,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piVa switch(param) { case AL_FILTER_TYPE: - alGetFilteri(filter, param, piValues); + alFilteri(filter, param, values[0]); return; } @@ -290,18 +178,18 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piVa if(!Context) return; Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALfilter_GetParamiv(ALFilter, Context, param, piValues); + ALfilter_SetParamiv(ALFilter, Context, param, values); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue) +AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value) { ALCcontext *Context; ALCdevice *Device; @@ -311,18 +199,18 @@ AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pfl if(!Context) return; Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALfilter_GetParamf(ALFilter, Context, param, pflValue); + ALfilter_SetParamf(ALFilter, Context, param, value); } - else - alSetError(Context, AL_INVALID_NAME); ALCcontext_DecRef(Context); } -AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues) +AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values) { ALCcontext *Context; ALCdevice *Device; @@ -332,60 +220,245 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pf if(!Context) return; Device = Context->Device; - if((ALFilter=LookupFilter(Device, filter)) != NULL) + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else { /* Call the appropriate handler */ - ALfilter_GetParamfv(ALFilter, Context, param, pflValues); + ALfilter_SetParamfv(ALFilter, Context, param, values); } - else + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value) +{ + ALCcontext *Context; + ALCdevice *Device; + ALfilter *ALFilter; + + Context = GetContextRef(); + if(!Context) return; + + Device = Context->Device; + if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); + else + { + if(param == AL_FILTER_TYPE) + *value = ALFilter->type; + else + { + /* Call the appropriate handler */ + ALfilter_GetParami(ALFilter, Context, param, value); + } + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values) +{ + ALCcontext *Context; + ALCdevice *Device; + ALfilter *ALFilter; + + switch(param) + { + case AL_FILTER_TYPE: + alGetFilteri(filter, param, values); + return; + } + + Context = GetContextRef(); + if(!Context) return; + + Device = Context->Device; + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else + { + /* Call the appropriate handler */ + ALfilter_GetParamiv(ALFilter, Context, param, values); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value) +{ + ALCcontext *Context; + ALCdevice *Device; + ALfilter *ALFilter; + + Context = GetContextRef(); + if(!Context) return; + + Device = Context->Device; + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else + { + /* Call the appropriate handler */ + ALfilter_GetParamf(ALFilter, Context, param, value); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values) +{ + ALCcontext *Context; + ALCdevice *Device; + ALfilter *ALFilter; + + Context = GetContextRef(); + if(!Context) return; + + Device = Context->Device; + if((ALFilter=LookupFilter(Device, filter)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else + { + /* Call the appropriate handler */ + ALfilter_GetParamfv(ALFilter, Context, param, values); + } ALCcontext_DecRef(Context); } -ALfloat lpCoeffCalc(ALfloat g, ALfloat cw) +void ALfilterState_clear(ALfilterState *filter) { - ALfloat a = 0.0f; + filter->x[0] = 0.0f; + filter->x[1] = 0.0f; + filter->y[0] = 0.0f; + filter->y[1] = 0.0f; +} - /* Be careful with gains < 0.001, as that causes the coefficient head - * towards 1, which will flatten the signal */ - if(g < 0.9999f) /* 1-epsilon */ +void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth) +{ + ALfloat alpha; + ALfloat w0; + + // Limit gain to -100dB + gain = maxf(gain, 0.00001f); + + w0 = F_2PI * freq_scale; + + /* Calculate filter coefficients depending on filter type */ + switch(type) { - g = maxf(g, 0.001f); - a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / - (1 - g); + case ALfilterType_HighShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f/gain) * + (1.0f/0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = -2.0f * gain * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = 2.0f * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_LowShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = 2.0f * gain * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = -2.0f * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_Peaking: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = 1.0f + alpha * gain; + filter->b[1] = -2.0f * cosf(w0); + filter->b[2] = 1.0f - alpha * gain; + filter->a[0] = 1.0f + alpha / gain; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha / gain; + break; + + case ALfilterType_LowPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = (1.0f - cosf(w0)) / 2.0f; + filter->b[1] = 1.0f - cosf(w0); + filter->b[2] = (1.0f - cosf(w0)) / 2.0f; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; + case ALfilterType_HighPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = (1.0f + cosf(w0)) / 2.0f; + filter->b[1] = 1.0f + cosf(w0); + filter->b[2] = (1.0f + cosf(w0)) / 2.0f; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; + case ALfilterType_BandPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = alpha; + filter->b[1] = 0; + filter->b[2] = -alpha; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; } - return a; + filter->b[2] /= filter->a[0]; + filter->b[1] /= filter->a[0]; + filter->b[0] /= filter->a[0]; + filter->a[2] /= filter->a[0]; + filter->a[1] /= filter->a[0]; + filter->a[0] /= filter->a[0]; } -static void lp_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void lp_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void lp_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void lp_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } static void lp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_LOWPASS_GAIN: - if(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN) - filter->Gain = val; - else - alSetError(context, AL_INVALID_VALUE); + if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + filter->Gain = val; break; case AL_LOWPASS_GAINHF: - if(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF) - filter->GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); + if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + filter->GainHF = val; break; default: - alSetError(context, AL_INVALID_ENUM); - break; + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } } static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -393,10 +466,10 @@ static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, c lp_SetParamf(filter, context, param, vals[0]); } -static void lp_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void lp_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void lp_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void lp_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -410,8 +483,7 @@ static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, AL break; default: - alSetError(context, AL_INVALID_ENUM); - break; + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } } static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -420,23 +492,23 @@ static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, A } -static void null_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void null_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void null_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void null_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } ALvoid ReleaseALFilters(ALCdevice *device) @@ -448,7 +520,7 @@ ALvoid ReleaseALFilters(ALCdevice *device) device->FilterMap.array[i].value = NULL; // Release filter structure - FreeThunkEntry(temp->filter); + FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALfilter)); free(temp); } diff --git a/jni/openal-soft-android/OpenAL32/alFontsound.c b/jni/openal-soft-android/OpenAL32/alFontsound.c new file mode 100644 index 00000000..94cf3064 --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/alFontsound.c @@ -0,0 +1,972 @@ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" + +#include "midi/base.h" + + +extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id); +extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id); + +static void ALfontsound_Construct(ALfontsound *self); +void ALfontsound_Destruct(ALfontsound *self); +void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value); +static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage); +void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value); +static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values); + + +AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids) +{ + ALCcontext *context; + ALsizei cur = 0; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + for(cur = 0;cur < n;cur++) + { + ALfontsound *sound = NewFontsound(context); + if(!sound) + { + alDeleteFontsoundsSOFT(cur, ids); + break; + } + + ids[cur] = sound->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *inst; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid ID */ + if((inst=LookupFontsound(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(inst->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((inst=RemoveFontsound(device, ids[i])) == NULL) + continue; + + ALfontsound_Destruct(inst); + + memset(inst, 0, sizeof(*inst)); + free(inst); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE; + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + + ALfontsound_setPropi(sound, context, param, value); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + case AL_KEY_RANGE_SOFT: + if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + sound->MinKey = value1; + sound->MaxKey = value2; + break; + + case AL_VELOCITY_RANGE_SOFT: + if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + sound->MinVelocity = value1; + sound->MaxVelocity = value2; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + switch(param) + { + case AL_KEY_RANGE_SOFT: + case AL_VELOCITY_RANGE_SOFT: + alFontsound2iSOFT(id, param, values[0], values[1]); + return; + + case AL_MOD_LFO_TO_PITCH_SOFT: + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + case AL_MOD_ENV_TO_PITCH_SOFT: + case AL_FILTER_CUTOFF_SOFT: + case AL_FILTER_RESONANCE_SOFT: + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + case AL_MOD_LFO_TO_VOLUME_SOFT: + case AL_CHORUS_SEND_SOFT: + case AL_REVERB_SEND_SOFT: + case AL_PAN_SOFT: + case AL_MOD_LFO_DELAY_SOFT: + case AL_MOD_LFO_FREQUENCY_SOFT: + case AL_VIBRATO_LFO_DELAY_SOFT: + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + case AL_MOD_ENV_DELAYTIME_SOFT: + case AL_MOD_ENV_ATTACKTIME_SOFT: + case AL_MOD_ENV_HOLDTIME_SOFT: + case AL_MOD_ENV_DECAYTIME_SOFT: + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + case AL_MOD_ENV_RELEASETIME_SOFT: + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + case AL_VOLUME_ENV_DELAYTIME_SOFT: + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + case AL_VOLUME_ENV_HOLDTIME_SOFT: + case AL_VOLUME_ENV_DECAYTIME_SOFT: + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + case AL_VOLUME_ENV_RELEASETIME_SOFT: + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + case AL_ATTENUATION_SOFT: + case AL_TUNING_COARSE_SOFT: + case AL_TUNING_FINE_SOFT: + case AL_LOOP_MODE_SOFT: + case AL_TUNING_SCALE_SOFT: + case AL_EXCLUSIVE_CLASS_SOFT: + case AL_SAMPLE_START_SOFT: + case AL_SAMPLE_END_SOFT: + case AL_SAMPLE_LOOP_START_SOFT: + case AL_SAMPLE_LOOP_END_SOFT: + case AL_SAMPLE_RATE_SOFT: + case AL_BASE_KEY_SOFT: + case AL_KEY_CORRECTION_SOFT: + case AL_SAMPLE_TYPE_SOFT: + case AL_FONTSOUND_LINK_SOFT: + alFontsoundiSOFT(id, param, values[0]); + return; + } + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + const ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_MOD_LFO_TO_PITCH_SOFT: + values[0] = sound->ModLfoToPitch; + break; + + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + values[0] = sound->VibratoLfoToPitch; + break; + + case AL_MOD_ENV_TO_PITCH_SOFT: + values[0] = sound->ModEnvToPitch; + break; + + case AL_FILTER_CUTOFF_SOFT: + values[0] = sound->FilterCutoff; + break; + + case AL_FILTER_RESONANCE_SOFT: + values[0] = sound->FilterQ; + break; + + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + values[0] = sound->ModLfoToFilterCutoff; + break; + + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + values[0] = sound->ModEnvToFilterCutoff; + break; + + case AL_MOD_LFO_TO_VOLUME_SOFT: + values[0] = sound->ModLfoToVolume; + break; + + case AL_CHORUS_SEND_SOFT: + values[0] = sound->ChorusSend; + break; + + case AL_REVERB_SEND_SOFT: + values[0] = sound->ReverbSend; + break; + + case AL_PAN_SOFT: + values[0] = sound->Pan; + break; + + case AL_MOD_LFO_DELAY_SOFT: + values[0] = sound->ModLfo.Delay; + break; + case AL_MOD_LFO_FREQUENCY_SOFT: + values[0] = sound->ModLfo.Frequency; + break; + + case AL_VIBRATO_LFO_DELAY_SOFT: + values[0] = sound->VibratoLfo.Delay; + break; + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + values[0] = sound->VibratoLfo.Frequency; + break; + + case AL_MOD_ENV_DELAYTIME_SOFT: + values[0] = sound->ModEnv.DelayTime; + break; + case AL_MOD_ENV_ATTACKTIME_SOFT: + values[0] = sound->ModEnv.AttackTime; + break; + case AL_MOD_ENV_HOLDTIME_SOFT: + values[0] = sound->ModEnv.HoldTime; + break; + case AL_MOD_ENV_DECAYTIME_SOFT: + values[0] = sound->ModEnv.DecayTime; + break; + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + values[0] = sound->ModEnv.SustainAttn; + break; + case AL_MOD_ENV_RELEASETIME_SOFT: + values[0] = sound->ModEnv.ReleaseTime; + break; + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + values[0] = sound->ModEnv.KeyToHoldTime; + break; + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + values[0] = sound->ModEnv.KeyToDecayTime; + break; + + case AL_VOLUME_ENV_DELAYTIME_SOFT: + values[0] = sound->VolEnv.DelayTime; + break; + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + values[0] = sound->VolEnv.AttackTime; + break; + case AL_VOLUME_ENV_HOLDTIME_SOFT: + values[0] = sound->VolEnv.HoldTime; + break; + case AL_VOLUME_ENV_DECAYTIME_SOFT: + values[0] = sound->VolEnv.DecayTime; + break; + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + values[0] = sound->VolEnv.SustainAttn; + break; + case AL_VOLUME_ENV_RELEASETIME_SOFT: + values[0] = sound->VolEnv.ReleaseTime; + break; + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + values[0] = sound->VolEnv.KeyToHoldTime; + break; + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + values[0] = sound->VolEnv.KeyToDecayTime; + break; + + case AL_KEY_RANGE_SOFT: + values[0] = sound->MinKey; + values[1] = sound->MaxKey; + break; + + case AL_VELOCITY_RANGE_SOFT: + values[0] = sound->MinVelocity; + values[1] = sound->MaxVelocity; + break; + + case AL_ATTENUATION_SOFT: + values[0] = sound->Attenuation; + break; + + case AL_TUNING_COARSE_SOFT: + values[0] = sound->CoarseTuning; + break; + case AL_TUNING_FINE_SOFT: + values[0] = sound->FineTuning; + break; + + case AL_LOOP_MODE_SOFT: + values[0] = sound->LoopMode; + break; + + case AL_TUNING_SCALE_SOFT: + values[0] = sound->TuningScale; + break; + + case AL_EXCLUSIVE_CLASS_SOFT: + values[0] = sound->ExclusiveClass; + break; + + case AL_SAMPLE_START_SOFT: + values[0] = sound->Start; + break; + + case AL_SAMPLE_END_SOFT: + values[0] = sound->End; + break; + + case AL_SAMPLE_LOOP_START_SOFT: + values[0] = sound->LoopStart; + break; + + case AL_SAMPLE_LOOP_END_SOFT: + values[0] = sound->LoopEnd; + break; + + case AL_SAMPLE_RATE_SOFT: + values[0] = sound->SampleRate; + break; + + case AL_BASE_KEY_SOFT: + values[0] = sound->PitchKey; + break; + + case AL_KEY_CORRECTION_SOFT: + values[0] = sound->PitchCorrection; + break; + + case AL_SAMPLE_TYPE_SOFT: + values[0] = sound->SampleType; + break; + + case AL_FONTSOUND_LINK_SOFT: + values[0] = (sound->Link ? sound->Link->id : 0); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + ALfontsound_setModStagei(sound, context, stage, param, value); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + ALfontsound_getModStagei(sound, context, stage, param, values); + +done: + ALCcontext_DecRef(context); +} + + +ALfontsound *NewFontsound(ALCcontext *context) +{ + ALCdevice *device = context->Device; + ALfontsound *sound; + ALenum err; + + sound = calloc(1, sizeof(*sound)); + if(!sound) + SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); + ALfontsound_Construct(sound); + + err = NewThunkEntry(&sound->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->FontsoundMap, sound->id, sound); + if(err != AL_NO_ERROR) + { + ALfontsound_Destruct(sound); + memset(sound, 0, sizeof(*sound)); + free(sound); + + SET_ERROR_AND_RETURN_VALUE(context, err, NULL); + } + + return sound; +} + + +static void ALfontsound_Construct(ALfontsound *self) +{ + self->ref = 0; + + self->MinKey = 0; + self->MaxKey = 127; + self->MinVelocity = 0; + self->MaxVelocity = 127; + + self->ModLfoToPitch = 0; + self->VibratoLfoToPitch = 0; + self->ModEnvToPitch = 0; + + self->FilterCutoff = 13500; + self->FilterQ = 0; + self->ModLfoToFilterCutoff = 0; + self->ModEnvToFilterCutoff = 0; + self->ModLfoToVolume = 0; + + self->ChorusSend = 0; + self->ReverbSend = 0; + + self->Pan = 0; + + self->ModLfo.Delay = 0; + self->ModLfo.Frequency = 0; + + self->VibratoLfo.Delay = 0; + self->VibratoLfo.Frequency = 0; + + self->ModEnv.DelayTime = -12000; + self->ModEnv.AttackTime = -12000; + self->ModEnv.HoldTime = -12000; + self->ModEnv.DecayTime = -12000; + self->ModEnv.SustainAttn = 0; + self->ModEnv.ReleaseTime = -12000; + self->ModEnv.KeyToHoldTime = 0; + self->ModEnv.KeyToDecayTime = 0; + + self->VolEnv.DelayTime = -12000; + self->VolEnv.AttackTime = -12000; + self->VolEnv.HoldTime = -12000; + self->VolEnv.DecayTime = -12000; + self->VolEnv.SustainAttn = 0; + self->VolEnv.ReleaseTime = -12000; + self->VolEnv.KeyToHoldTime = 0; + self->VolEnv.KeyToDecayTime = 0; + + self->Attenuation = 0; + + self->CoarseTuning = 0; + self->FineTuning = 0; + + self->LoopMode = AL_NONE; + + self->TuningScale = 100; + + self->ExclusiveClass = 0; + + self->Start = 0; + self->End = 0; + self->LoopStart = 0; + self->LoopEnd = 0; + self->SampleRate = 0; + self->PitchKey = 0; + self->PitchCorrection = 0; + self->SampleType = AL_MONO_SOFT; + self->Link = NULL; + + InitUIntMap(&self->ModulatorMap, ~0); + + self->id = 0; +} + +void ALfontsound_Destruct(ALfontsound *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + if(self->Link) + DecrementRef(&self->Link->ref); + self->Link = NULL; + + for(i = 0;i < self->ModulatorMap.size;i++) + { + free(self->ModulatorMap.array[i].value); + self->ModulatorMap.array[i].value = NULL; + } + ResetUIntMap(&self->ModulatorMap); +} + +void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value) +{ + ALfontsound *link; + + switch(param) + { + case AL_MOD_LFO_TO_PITCH_SOFT: + self->ModLfoToPitch = value; + break; + + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + self->VibratoLfoToPitch = value; + break; + + case AL_MOD_ENV_TO_PITCH_SOFT: + self->ModEnvToPitch = value; + break; + + case AL_FILTER_CUTOFF_SOFT: + self->FilterCutoff = value; + break; + + case AL_FILTER_RESONANCE_SOFT: + if(!(value >= 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->FilterQ = value; + break; + + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + self->ModLfoToFilterCutoff = value; + break; + + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + self->ModEnvToFilterCutoff = value; + break; + + case AL_MOD_LFO_TO_VOLUME_SOFT: + self->ModLfoToVolume = value; + break; + + case AL_CHORUS_SEND_SOFT: + if(!(value >= 0 && value <= 1000)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->ChorusSend = value; + break; + case AL_REVERB_SEND_SOFT: + if(!(value >= 0 && value <= 1000)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->ReverbSend = value; + break; + + case AL_PAN_SOFT: + self->Pan = value; + break; + + case AL_MOD_LFO_DELAY_SOFT: + self->ModLfo.Delay = value; + break; + case AL_MOD_LFO_FREQUENCY_SOFT: + self->ModLfo.Frequency = value; + break; + + case AL_VIBRATO_LFO_DELAY_SOFT: + self->VibratoLfo.Delay = value; + break; + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + self->VibratoLfo.Frequency = value; + break; + + case AL_MOD_ENV_DELAYTIME_SOFT: + self->ModEnv.DelayTime = value; + break; + case AL_MOD_ENV_ATTACKTIME_SOFT: + self->ModEnv.AttackTime = value; + break; + case AL_MOD_ENV_HOLDTIME_SOFT: + self->ModEnv.HoldTime = value; + break; + case AL_MOD_ENV_DECAYTIME_SOFT: + self->ModEnv.DecayTime = value; + break; + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + self->ModEnv.SustainAttn = value; + break; + case AL_MOD_ENV_RELEASETIME_SOFT: + self->ModEnv.ReleaseTime = value; + break; + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + self->ModEnv.KeyToHoldTime = value; + break; + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + self->ModEnv.KeyToDecayTime = value; + break; + + case AL_VOLUME_ENV_DELAYTIME_SOFT: + self->VolEnv.DelayTime = value; + break; + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + self->VolEnv.AttackTime = value; + break; + case AL_VOLUME_ENV_HOLDTIME_SOFT: + self->VolEnv.HoldTime = value; + break; + case AL_VOLUME_ENV_DECAYTIME_SOFT: + self->VolEnv.DecayTime = value; + break; + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + self->VolEnv.SustainAttn = value; + break; + case AL_VOLUME_ENV_RELEASETIME_SOFT: + self->VolEnv.ReleaseTime = value; + break; + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + self->VolEnv.KeyToHoldTime = value; + break; + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + self->VolEnv.KeyToDecayTime = value; + break; + + case AL_ATTENUATION_SOFT: + if(!(value >= 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->Attenuation = value; + break; + + case AL_TUNING_COARSE_SOFT: + self->CoarseTuning = value; + break; + case AL_TUNING_FINE_SOFT: + self->FineTuning = value; + break; + + case AL_LOOP_MODE_SOFT: + if(!(value == AL_NONE || value == AL_LOOP_CONTINUOUS_SOFT || + value == AL_LOOP_UNTIL_RELEASE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->LoopMode = value; + break; + + case AL_TUNING_SCALE_SOFT: + self->TuningScale = value; + break; + + case AL_EXCLUSIVE_CLASS_SOFT: + self->ExclusiveClass = value; + break; + + case AL_SAMPLE_START_SOFT: + self->Start = value; + break; + + case AL_SAMPLE_END_SOFT: + self->End = value; + break; + + case AL_SAMPLE_LOOP_START_SOFT: + self->LoopStart = value; + break; + + case AL_SAMPLE_LOOP_END_SOFT: + self->LoopEnd = value; + break; + + case AL_SAMPLE_RATE_SOFT: + if(!(value > 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->SampleRate = value; + break; + + case AL_BASE_KEY_SOFT: + if(!((value >= 0 && value <= 127) || value == 255)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->PitchKey = value; + break; + + case AL_KEY_CORRECTION_SOFT: + if(!(value >= -99 && value <= 99)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->PitchCorrection = value; + break; + + case AL_SAMPLE_TYPE_SOFT: + if(!(value == AL_MONO_SOFT || value == AL_RIGHT_SOFT || value == AL_LEFT_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->SampleType = value; + break; + + case AL_FONTSOUND_LINK_SOFT: + if(!value) + link = NULL; + else + { + link = LookupFontsound(context->Device, value); + if(!link) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + } + if(link) IncrementRef(&link->ref); + link = ExchangePtr((XchgPtr*)&self->Link, link); + if(link) DecrementRef(&link->ref); + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage) +{ + ALsfmodulator *ret = LookupModulator(self, stage); + if(!ret) + { + static const ALsfmodulator moddef = { + { { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT }, + { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT } + }, + 0, + AL_LINEAR_SOFT, + AL_NONE + }; + ret = malloc(sizeof(*ret)); + *ret = moddef; + InsertUIntMapEntry(&self->ModulatorMap, stage, ret); + } + return ret; +} + +void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value) +{ + ALint srcidx = 0; + + if(self->ref != 0) + SET_ERROR_AND_RETURN(context, AL_INVALID_OPERATION); + switch(param) + { + case AL_SOURCE1_INPUT_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_INPUT_SOFT: + if(!(value == AL_ONE_SOFT || value == AL_NOTEON_VELOCITY_SOFT || + value == AL_NOTEON_KEY_SOFT || value == AL_KEYPRESSURE_SOFT || + value == AL_CHANNELPRESSURE_SOFT || value == AL_PITCHBEND_SOFT || + value == AL_PITCHBEND_SENSITIVITY_SOFT || + (value > 0 && value < 120 && !(value == 6 || (value >= 32 && value <= 63) || + (value >= 98 && value <= 101)) + ) + )) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Input = value; + break; + + case AL_SOURCE1_TYPE_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_TYPE_SOFT: + if(!(value == AL_UNORM_SOFT || value == AL_UNORM_REV_SOFT || + value == AL_SNORM_SOFT || value == AL_SNORM_REV_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Type = value; + break; + + case AL_SOURCE1_FORM_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_FORM_SOFT: + if(!(value == AL_LINEAR_SOFT || value == AL_CONCAVE_SOFT || + value == AL_CONVEX_SOFT || value == AL_SWITCH_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Form = value; + break; + + case AL_AMOUNT_SOFT: + ALfontsound_getModStage(self, stage)->Amount = value; + break; + + case AL_TRANSFORM_OP_SOFT: + if(!(value == AL_LINEAR_SOFT || value == AL_ABSOLUTE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->TransformOp = value; + break; + + case AL_DESTINATION_SOFT: + if(!(value == AL_MOD_LFO_TO_PITCH_SOFT || value == AL_VIBRATO_LFO_TO_PITCH_SOFT || + value == AL_MOD_ENV_TO_PITCH_SOFT || value == AL_FILTER_CUTOFF_SOFT || + value == AL_FILTER_RESONANCE_SOFT || value == AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT || + value == AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT || value == AL_MOD_LFO_TO_VOLUME_SOFT || + value == AL_CHORUS_SEND_SOFT || value == AL_REVERB_SEND_SOFT || value == AL_PAN_SOFT || + value == AL_MOD_LFO_DELAY_SOFT || value == AL_MOD_LFO_FREQUENCY_SOFT || + value == AL_VIBRATO_LFO_DELAY_SOFT || value == AL_VIBRATO_LFO_FREQUENCY_SOFT || + value == AL_MOD_ENV_DELAYTIME_SOFT || value == AL_MOD_ENV_ATTACKTIME_SOFT || + value == AL_MOD_ENV_HOLDTIME_SOFT || value == AL_MOD_ENV_DECAYTIME_SOFT || + value == AL_MOD_ENV_SUSTAINVOLUME_SOFT || value == AL_MOD_ENV_RELEASETIME_SOFT || + value == AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT || + value == AL_VOLUME_ENV_DELAYTIME_SOFT || value == AL_VOLUME_ENV_ATTACKTIME_SOFT || + value == AL_VOLUME_ENV_HOLDTIME_SOFT || value == AL_VOLUME_ENV_DECAYTIME_SOFT || + value == AL_VOLUME_ENV_SUSTAINVOLUME_SOFT || value == AL_VOLUME_ENV_RELEASETIME_SOFT || + value == AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT || + value == AL_ATTENUATION_SOFT || value == AL_TUNING_COARSE_SOFT || + value == AL_TUNING_FINE_SOFT || value == AL_TUNING_SCALE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Dest = value; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values) +{ + ALsfmodulator *mod = LookupModulator(self, stage); + ALint srcidx = 0; + + switch(param) + { + case AL_SOURCE1_INPUT_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_INPUT_SOFT: + values[0] = mod ? mod->Source[srcidx].Input : AL_ONE_SOFT; + break; + + case AL_SOURCE1_TYPE_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_TYPE_SOFT: + values[0] = mod ? mod->Source[srcidx].Type : AL_UNORM_SOFT; + break; + + case AL_SOURCE1_FORM_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_FORM_SOFT: + values[0] = mod ? mod->Source[srcidx].Form : AL_LINEAR_SOFT; + break; + + case AL_AMOUNT_SOFT: + values[0] = mod ? mod->Amount : 0; + break; + + case AL_TRANSFORM_OP_SOFT: + values[0] = mod ? mod->TransformOp : AL_LINEAR_SOFT; + break; + + case AL_DESTINATION_SOFT: + values[0] = mod ? mod->Dest : AL_NONE; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + + +/* ReleaseALFontsounds + * + * Called to destroy any fontsounds that still exist on the device + */ +void ReleaseALFontsounds(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->FontsoundMap.size;i++) + { + ALfontsound *temp = device->FontsoundMap.array[i].value; + device->FontsoundMap.array[i].value = NULL; + + ALfontsound_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/jni/openal-soft-android/OpenAL32/alListener.c b/jni/openal-soft-android/OpenAL32/alListener.c index 37982b5c..87cd3c61 100644 --- a/jni/openal-soft-android/OpenAL32/alListener.c +++ b/jni/openal-soft-android/OpenAL32/alListener.c @@ -26,458 +26,421 @@ #include "alListener.h" #include "alSource.h" -AL_API ALvoid AL_APIENTRY alListenerf(ALenum eParam, ALfloat flValue) +AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - switch(eParam) + switch(param) { - case AL_GAIN: - if(flValue >= 0.0f && isfinite(flValue)) - { - Context->Listener.Gain = flValue; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + case AL_GAIN: + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - case AL_METERS_PER_UNIT: - if(flValue > 0.0f && isfinite(flValue)) - { - Context->Listener.MetersPerUnit = flValue; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + context->Listener->Gain = value; + context->UpdateSources = AL_TRUE; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_METERS_PER_UNIT: + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + context->Listener->MetersPerUnit = value; + context->UpdateSources = AL_TRUE; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3) +AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - switch(eParam) + switch(param) { - case AL_POSITION: - if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3)) - { - LockContext(Context); - Context->Listener.Position[0] = flValue1; - Context->Listener.Position[1] = flValue2; - Context->Listener.Position[2] = flValue3; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + case AL_POSITION: + if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - case AL_VELOCITY: - if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3)) - { - LockContext(Context); - Context->Listener.Velocity[0] = flValue1; - Context->Listener.Velocity[1] = flValue2; - Context->Listener.Velocity[2] = flValue3; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - } - else - alSetError(Context, AL_INVALID_VALUE); - break; + LockContext(context); + context->Listener->Position[0] = value1; + context->Listener->Position[1] = value2; + context->Listener->Position[2] = value3; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_VELOCITY: + if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + LockContext(context); + context->Listener->Velocity[0] = value1; + context->Listener->Velocity[1] = value2; + context->Listener->Velocity[2] = value3; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues) +AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; - if(pflValues) + if(values) { - switch(eParam) + switch(param) { - case AL_GAIN: - case AL_METERS_PER_UNIT: - alListenerf(eParam, pflValues[0]); - return; - - case AL_POSITION: - case AL_VELOCITY: - alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]); - return; - } - } - - Context = GetContextRef(); - if(!Context) return; - - if(pflValues) - { - switch(eParam) - { - case AL_ORIENTATION: - if(isfinite(pflValues[0]) && isfinite(pflValues[1]) && - isfinite(pflValues[2]) && isfinite(pflValues[3]) && - isfinite(pflValues[4]) && isfinite(pflValues[5])) - { - LockContext(Context); - // AT then UP - Context->Listener.Forward[0] = pflValues[0]; - Context->Listener.Forward[1] = pflValues[1]; - Context->Listener.Forward[2] = pflValues[2]; - Context->Listener.Up[0] = pflValues[3]; - Context->Listener.Up[1] = pflValues[4]; - Context->Listener.Up[2] = pflValues[5]; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - } - else - alSetError(Context, AL_INVALID_VALUE); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - alSetError(Context, AL_INVALID_VALUE); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alListeneri(ALenum eParam, ALint lValue) -{ - ALCcontext *Context; - - (void)lValue; - - Context = GetContextRef(); - if(!Context) return; - - switch(eParam) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3) -{ - ALCcontext *Context; - - switch(eParam) - { - case AL_POSITION: - case AL_VELOCITY: - alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3); - return; - } - - Context = GetContextRef(); - if(!Context) return; - - switch(eParam) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alListeneriv( ALenum eParam, const ALint* plValues ) -{ - ALCcontext *Context; - ALfloat flValues[6]; - - if(plValues) - { - switch(eParam) - { - case AL_POSITION: - case AL_VELOCITY: - alListener3f(eParam, (ALfloat)plValues[0], (ALfloat)plValues[1], (ALfloat)plValues[2]); - return; - - case AL_ORIENTATION: - flValues[0] = (ALfloat)plValues[0]; - flValues[1] = (ALfloat)plValues[1]; - flValues[2] = (ALfloat)plValues[2]; - flValues[3] = (ALfloat)plValues[3]; - flValues[4] = (ALfloat)plValues[4]; - flValues[5] = (ALfloat)plValues[5]; - alListenerfv(eParam, flValues); - return; - } - } - - Context = GetContextRef(); - if(!Context) return; - - if(plValues) - { - switch(eParam) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - alSetError(Context, AL_INVALID_VALUE); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue) -{ - ALCcontext *Context; - - Context = GetContextRef(); - if(!Context) return; - - if(pflValue) - { - switch(eParam) - { - case AL_GAIN: - *pflValue = Context->Listener.Gain; - break; - - case AL_METERS_PER_UNIT: - *pflValue = Context->Listener.MetersPerUnit; - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - alSetError(Context, AL_INVALID_VALUE); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3) -{ - ALCcontext *Context; - - Context = GetContextRef(); - if(!Context) return; - - if(pflValue1 && pflValue2 && pflValue3) - { - switch(eParam) - { - case AL_POSITION: - LockContext(Context); - *pflValue1 = Context->Listener.Position[0]; - *pflValue2 = Context->Listener.Position[1]; - *pflValue3 = Context->Listener.Position[2]; - UnlockContext(Context); - break; - - case AL_VELOCITY: - LockContext(Context); - *pflValue1 = Context->Listener.Velocity[0]; - *pflValue2 = Context->Listener.Velocity[1]; - *pflValue3 = Context->Listener.Velocity[2]; - UnlockContext(Context); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - alSetError(Context, AL_INVALID_VALUE); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues) -{ - ALCcontext *Context; - - switch(eParam) - { case AL_GAIN: case AL_METERS_PER_UNIT: - alGetListenerf(eParam, pflValues); + alListenerf(param, values[0]); return; case AL_POSITION: case AL_VELOCITY: - alGetListener3f(eParam, pflValues+0, pflValues+1, pflValues+2); + alListener3f(param, values[0], values[1], values[2]); return; - } - - Context = GetContextRef(); - if(!Context) return; - - if(pflValues) - { - switch(eParam) - { - case AL_ORIENTATION: - LockContext(Context); - // AT then UP - pflValues[0] = Context->Listener.Forward[0]; - pflValues[1] = Context->Listener.Forward[1]; - pflValues[2] = Context->Listener.Forward[2]; - pflValues[3] = Context->Listener.Up[0]; - pflValues[4] = Context->Listener.Up[1]; - pflValues[5] = Context->Listener.Up[2]; - UnlockContext(Context); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; } } - else - alSetError(Context, AL_INVALID_VALUE); - ALCcontext_DecRef(Context); + context = GetContextRef(); + if(!context) return; + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_ORIENTATION: + if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && + isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + LockContext(context); + /* AT then UP */ + context->Listener->Forward[0] = values[0]; + context->Listener->Forward[1] = values[1]; + context->Listener->Forward[2] = values[2]; + context->Listener->Up[0] = values[3]; + context->Listener->Up[1] = values[4]; + context->Listener->Up[2] = values[5]; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum eParam, ALint *plValue) +AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(plValue) + switch(param) { - switch(eParam) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - else - alSetError(Context, AL_INVALID_VALUE); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3) +AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; - - if(plValue1 && plValue2 && plValue3) + switch(param) { - switch (eParam) - { - case AL_POSITION: - LockContext(Context); - *plValue1 = (ALint)Context->Listener.Position[0]; - *plValue2 = (ALint)Context->Listener.Position[1]; - *plValue3 = (ALint)Context->Listener.Position[2]; - UnlockContext(Context); - break; - - case AL_VELOCITY: - LockContext(Context); - *plValue1 = (ALint)Context->Listener.Velocity[0]; - *plValue2 = (ALint)Context->Listener.Velocity[1]; - *plValue3 = (ALint)Context->Listener.Velocity[2]; - UnlockContext(Context); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } + case AL_POSITION: + case AL_VELOCITY: + alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3); + return; } - else - alSetError(Context, AL_INVALID_VALUE); - ALCcontext_DecRef(Context); + context = GetContextRef(); + if(!context) return; + + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alGetListeneriv(ALenum eParam, ALint* plValues) +AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) { - ALCcontext *Context; + ALCcontext *context; - switch(eParam) + if(values) { + ALfloat fvals[6]; + switch(param) + { case AL_POSITION: case AL_VELOCITY: - alGetListener3i(eParam, plValues+0, plValues+1, plValues+2); + alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]); return; - } - Context = GetContextRef(); - if(!Context) return; - - if(plValues) - { - switch(eParam) - { - case AL_ORIENTATION: - LockContext(Context); - // AT then UP - plValues[0] = (ALint)Context->Listener.Forward[0]; - plValues[1] = (ALint)Context->Listener.Forward[1]; - plValues[2] = (ALint)Context->Listener.Forward[2]; - plValues[3] = (ALint)Context->Listener.Up[0]; - plValues[4] = (ALint)Context->Listener.Up[1]; - plValues[5] = (ALint)Context->Listener.Up[2]; - UnlockContext(Context); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_ORIENTATION: + fvals[0] = (ALfloat)values[0]; + fvals[1] = (ALfloat)values[1]; + fvals[2] = (ALfloat)values[2]; + fvals[3] = (ALfloat)values[3]; + fvals[4] = (ALfloat)values[4]; + fvals[5] = (ALfloat)values[5]; + alListenerfv(param, fvals); + return; } } - else - alSetError(Context, AL_INVALID_VALUE); - ALCcontext_DecRef(Context); + context = GetContextRef(); + if(!context) return; + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) +{ + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_GAIN: + *value = context->Listener->Gain; + break; + + case AL_METERS_PER_UNIT: + *value = context->Listener->MetersPerUnit; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) +{ + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_POSITION: + LockContext(context); + *value1 = context->Listener->Position[0]; + *value2 = context->Listener->Position[1]; + *value3 = context->Listener->Position[2]; + UnlockContext(context); + break; + + case AL_VELOCITY: + LockContext(context); + *value1 = context->Listener->Velocity[0]; + *value2 = context->Listener->Velocity[1]; + *value3 = context->Listener->Velocity[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) +{ + ALCcontext *context; + + switch(param) + { + case AL_GAIN: + case AL_METERS_PER_UNIT: + alGetListenerf(param, values); + return; + + case AL_POSITION: + case AL_VELOCITY: + alGetListener3f(param, values+0, values+1, values+2); + return; + } + + context = GetContextRef(); + if(!context) return; + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_ORIENTATION: + LockContext(context); + // AT then UP + values[0] = context->Listener->Forward[0]; + values[1] = context->Listener->Forward[1]; + values[2] = context->Listener->Forward[2]; + values[3] = context->Listener->Up[0]; + values[4] = context->Listener->Up[1]; + values[5] = context->Listener->Up[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) +{ + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3) +{ + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch (param) + { + case AL_POSITION: + LockContext(context); + *value1 = (ALint)context->Listener->Position[0]; + *value2 = (ALint)context->Listener->Position[1]; + *value3 = (ALint)context->Listener->Position[2]; + UnlockContext(context); + break; + + case AL_VELOCITY: + LockContext(context); + *value1 = (ALint)context->Listener->Velocity[0]; + *value2 = (ALint)context->Listener->Velocity[1]; + *value3 = (ALint)context->Listener->Velocity[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) +{ + ALCcontext *context; + + switch(param) + { + case AL_POSITION: + case AL_VELOCITY: + alGetListener3i(param, values+0, values+1, values+2); + return; + } + + context = GetContextRef(); + if(!context) return; + + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_ORIENTATION: + LockContext(context); + // AT then UP + values[0] = (ALint)context->Listener->Forward[0]; + values[1] = (ALint)context->Listener->Forward[1]; + values[2] = (ALint)context->Listener->Forward[2]; + values[3] = (ALint)context->Listener->Up[0]; + values[4] = (ALint)context->Listener->Up[1]; + values[5] = (ALint)context->Listener->Up[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); } diff --git a/jni/openal-soft-android/OpenAL32/alMidi.c b/jni/openal-soft-android/OpenAL32/alMidi.c new file mode 100644 index 00000000..0679b64c --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/alMidi.c @@ -0,0 +1,221 @@ + +#include "config.h" + +#include +#include +#include +#include + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" +#include "evtqueue.h" +#include "rwlock.h" +#include "alu.h" + +#include "midi/base.h" + + +MidiSynth *SynthCreate(ALCdevice *device) +{ + MidiSynth *synth = FSynth_create(device); + if(!synth) synth = DSynth_create(device); + return synth; +} + + +AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id) +{ + alMidiSoundfontvSOFT(1, &id); +} + +AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) + alSetError(context, AL_INVALID_OPERATION); + else + { + err = V(synth,selectSoundfonts)(context, count, ids); + if(err != AL_NO_ERROR) + alSetError(context, err); + } + WriteUnlock(&synth->Lock); + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(event == AL_NOTEOFF_SOFT || event == AL_NOTEON_SOFT || + event == AL_KEYPRESSURE_SOFT || event == AL_CONTROLLERCHANGE_SOFT || + event == AL_PROGRAMCHANGE_SOFT || event == AL_CHANNELPRESSURE_SOFT || + event == AL_PITCHBEND_SOFT)) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + if(!(channel >= 0 && channel <= 15)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!(param1 >= 0 && param1 <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!(param2 >= 0 && param2 <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + ALCdevice_Lock(device); + err = MidiSynth_insertEvent(device->Synth, time, event|channel, param1, param2); + ALCdevice_Unlock(device); + if(err != AL_NO_ERROR) + alSetError(context, err); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!data || size < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < size;i++) + { + if((data[i]&0x80)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + + device = context->Device; + ALCdevice_Lock(device); + err = MidiSynth_insertSysExEvent(device->Synth, time, data, size); + ALCdevice_Unlock(device); + if(err != AL_NO_ERROR) + alSetError(context, err); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiPlaySOFT(void) +{ + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + synth = context->Device->Synth; + WriteLock(&synth->Lock); + V(synth,setState)(AL_PLAYING); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiPauseSOFT(void) +{ + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + synth = context->Device->Synth; + WriteLock(&synth->Lock); + V(synth,setState)(AL_PAUSED); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiStopSOFT(void) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + V(synth,setState)(AL_STOPPED); + + ALCdevice_Lock(device); + V0(synth,stop)(); + ALCdevice_Unlock(device); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiResetSOFT(void) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + V(synth,setState)(AL_INITIAL); + + ALCdevice_Lock(device); + V0(synth,reset)(); + ALCdevice_Unlock(device); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value) +{ + ALCdevice *device; + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + V(device->Synth,setGain)(value); + +done: + ALCcontext_DecRef(context); +} diff --git a/jni/openal-soft-android/OpenAL32/alPreset.c b/jni/openal-soft-android/OpenAL32/alPreset.c new file mode 100644 index 00000000..d34772a4 --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/alPreset.c @@ -0,0 +1,340 @@ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" + +#include "midi/base.h" + + +extern inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id); +extern inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id); + +static void ALsfpreset_Construct(ALsfpreset *self); +void ALsfpreset_Destruct(ALsfpreset *self); + + +AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids) +{ + ALCcontext *context; + ALsizei cur = 0; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + for(cur = 0;cur < n;cur++) + { + ALsfpreset *preset = NewPreset(context); + if(!preset) + { + alDeletePresetsSOFT(cur, ids); + break; + } + + ids[cur] = preset->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid ID */ + if((preset=LookupPreset(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((preset=LookupPreset(device, ids[i])) == NULL) + continue; + DeletePreset(preset, device); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = LookupPreset(context->Device, id) ? AL_TRUE : AL_FALSE; + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + case AL_MIDI_PRESET_SOFT: + if(!(value >= 0 && value <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + preset->Preset = value; + break; + + case AL_MIDI_BANK_SOFT: + if(!(value >= 0 && value <= 128)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + preset->Bank = value; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + + switch(param) + { + case AL_MIDI_PRESET_SOFT: + case AL_MIDI_BANK_SOFT: + alPresetiSOFT(id, param, values[0]); + return; + } + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_MIDI_PRESET_SOFT: + values[0] = preset->Preset; + break; + + case AL_MIDI_BANK_SOFT: + values[0] = preset->Bank; + break; + + case AL_FONTSOUNDS_SIZE_SOFT: + values[0] = preset->NumSounds; + break; + + case AL_FONTSOUNDS_SOFT: + for(i = 0;i < preset->NumSounds;i++) + values[i] = preset->Sounds[i]->id; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALfontsound **sounds; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(preset=LookupPreset(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + + if(count == 0) + sounds = NULL; + else + { + sounds = calloc(count, sizeof(sounds[0])); + if(!sounds) + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + + for(i = 0;i < count;i++) + { + if(!(sounds[i]=LookupFontsound(device, fsids[i]))) + { + free(sounds); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + } + } + + for(i = 0;i < count;i++) + IncrementRef(&sounds[i]->ref); + + sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds); + count = ExchangeInt(&preset->NumSounds, count); + + for(i = 0;i < count;i++) + DecrementRef(&sounds[i]->ref); + free(sounds); + +done: + ALCcontext_DecRef(context); +} + + +ALsfpreset *NewPreset(ALCcontext *context) +{ + ALCdevice *device = context->Device; + ALsfpreset *preset; + ALenum err; + + preset = calloc(1, sizeof(*preset)); + if(!preset) + SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); + ALsfpreset_Construct(preset); + + err = NewThunkEntry(&preset->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->PresetMap, preset->id, preset); + if(err != AL_NO_ERROR) + { + ALsfpreset_Destruct(preset); + memset(preset, 0, sizeof(*preset)); + free(preset); + + SET_ERROR_AND_RETURN_VALUE(context, err, NULL); + } + + return preset; +} + +void DeletePreset(ALsfpreset *preset, ALCdevice *device) +{ + RemovePreset(device, preset->id); + + ALsfpreset_Destruct(preset); + memset(preset, 0, sizeof(*preset)); + free(preset); +} + + +static void ALsfpreset_Construct(ALsfpreset *self) +{ + self->ref = 0; + + self->Preset = 0; + self->Bank = 0; + + self->Sounds = NULL; + self->NumSounds = 0; + + self->id = 0; +} + +void ALsfpreset_Destruct(ALsfpreset *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + for(i = 0;i < self->NumSounds;i++) + DecrementRef(&self->Sounds[i]->ref); + free(self->Sounds); + self->Sounds = NULL; + self->NumSounds = 0; +} + + +/* ReleaseALPresets + * + * Called to destroy any presets that still exist on the device + */ +void ReleaseALPresets(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->PresetMap.size;i++) + { + ALsfpreset *temp = device->PresetMap.array[i].value; + device->PresetMap.array[i].value = NULL; + + ALsfpreset_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/jni/openal-soft-android/OpenAL32/alSoundfont.c b/jni/openal-soft-android/OpenAL32/alSoundfont.c new file mode 100644 index 00000000..355c5b41 --- /dev/null +++ b/jni/openal-soft-android/OpenAL32/alSoundfont.c @@ -0,0 +1,563 @@ + +#include "config.h" + +#include +#include +#include + +#include "alMain.h" +#include "alMidi.h" +#include "alThunk.h" +#include "alError.h" + +#include "midi/base.h" + + +extern inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id); +extern inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id); + +void ALsoundfont_Construct(ALsoundfont *self); +void ALsoundfont_Destruct(ALsoundfont *self); +void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device); +ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context); +static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr); + + +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALsoundfont *sfont = calloc(1, sizeof(ALsoundfont)); + if(!sfont) + { + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + ALsoundfont_Construct(sfont); + + err = NewThunkEntry(&sfont->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->SfontMap, sfont->id, sfont); + if(err != AL_NO_ERROR) + { + ALsoundfont_Destruct(sfont); + memset(sfont, 0, sizeof(ALsoundfont)); + free(sfont); + + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, err, done); + } + + ids[cur] = sfont->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid soundfont ID */ + if(ids[i] == 0) + { + if(!(sfont=device->DefaultSfont)) + continue; + } + else if((sfont=LookupSfont(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sfont->Mapped != AL_FALSE || sfont->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if(ids[i] == 0) + { + MidiSynth *synth = device->Synth; + WriteLock(&synth->Lock); + if(device->DefaultSfont != NULL) + ALsoundfont_deleteSoundfont(device->DefaultSfont, device); + device->DefaultSfont = NULL; + WriteUnlock(&synth->Lock); + continue; + } + else if((sfont=RemoveSfont(device, ids[i])) == NULL) + continue; + + ALsoundfont_Destruct(sfont); + + memset(sfont, 0, sizeof(*sfont)); + free(sfont); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = ((!id || LookupSfont(context->Device, id)) ? + AL_TRUE : AL_FALSE); + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API ALvoid AL_APIENTRY alSoundfontSamplesSOFT(ALuint id, ALenum type, ALsizei count, const ALvoid *samples) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + void *ptr; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(type != AL_SHORT_SOFT) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(count <= 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + alSetError(context, AL_INVALID_OPERATION); + else if(sfont->Mapped) + alSetError(context, AL_INVALID_OPERATION); + else if(!(ptr=realloc(sfont->Samples, count * sizeof(ALshort)))) + alSetError(context, AL_OUT_OF_MEMORY); + else + { + sfont->Samples = ptr; + sfont->NumSamples = count; + if(samples != NULL) + memcpy(sfont->Samples, samples, count * sizeof(ALshort)); + } + WriteUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + sfont = ALsoundfont_getDefSoundfont(context); + else if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(type != AL_SHORT_SOFT) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(offset < 0 || count <= 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + ReadLock(&sfont->Lock); + if(offset >= sfont->NumSamples || count > (sfont->NumSamples-offset)) + alSetError(context, AL_INVALID_VALUE); + else if(sfont->Mapped) + alSetError(context, AL_INVALID_OPERATION); + else + { + /* TODO: Allow conversion. */ + memcpy(samples, sfont->Samples + offset*sizeof(ALshort), count * sizeof(ALshort)); + } + ReadUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint id, ALsizei offset, ALsizei length) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALvoid *ptr = NULL; + + context = GetContextRef(); + if(!context) return NULL; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(offset < 0 || (ALuint)offset > sfont->NumSamples*sizeof(ALshort)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(length <= 0 || (ALuint)length > (sfont->NumSamples*sizeof(ALshort) - offset)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + ReadLock(&sfont->Lock); + if(sfont->ref != 0) + alSetError(context, AL_INVALID_OPERATION); + else if(ExchangeInt(&sfont->Mapped, AL_TRUE) == AL_TRUE) + alSetError(context, AL_INVALID_OPERATION); + else + ptr = (ALbyte*)sfont->Samples + offset; + ReadUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); + + return ptr; +} + +AL_API ALvoid AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint id) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(ExchangeInt(&sfont->Mapped, AL_FALSE) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + sfont = ALsoundfont_getDefSoundfont(context); + else if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_PRESETS_SIZE_SOFT: + values[0] = sfont->NumPresets; + break; + + case AL_PRESETS_SOFT: + for(i = 0;i < sfont->NumPresets;i++) + values[i] = sfont->Presets[i]->id; + break; + + case AL_SAMPLE_LENGTH_SOFT: + values[0] = sfont->NumSamples; + break; + + case AL_FORMAT_TYPE_SOFT: + values[0] = AL_SHORT_SOFT; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsfpreset **presets; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + if(count == 0) + presets = NULL; + else + { + presets = calloc(count, sizeof(presets[0])); + if(!presets) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + + for(i = 0;i < count;i++) + { + if(!(presets[i]=LookupPreset(device, pids[i]))) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + } + } + + for(i = 0;i < count;i++) + IncrementRef(&presets[i]->ref); + + presets = ExchangePtr((XchgPtr*)&sfont->Presets, presets); + count = ExchangeInt(&sfont->NumPresets, count); + WriteUnlock(&sfont->Lock); + + for(i = 0;i < count;i++) + DecrementRef(&presets[i]->ref); + free(presets); + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + Reader reader; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + if(sfont->Mapped) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + if(sfont->NumPresets > 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + reader.cb = cb; + reader.ptr = user; + reader.error = 0; + loadSf2(&reader, sfont, context); + WriteUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + + +void ALsoundfont_Construct(ALsoundfont *self) +{ + self->ref = 0; + + self->Presets = NULL; + self->NumPresets = 0; + + self->Samples = NULL; + self->NumSamples = 0; + + RWLockInit(&self->Lock); + self->Mapped = AL_FALSE; + + self->id = 0; +} + +void ALsoundfont_Destruct(ALsoundfont *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + for(i = 0;i < self->NumPresets;i++) + { + DecrementRef(&self->Presets[i]->ref); + self->Presets[i] = NULL; + } + free(self->Presets); + self->Presets = NULL; + self->NumPresets = 0; + + free(self->Samples); + self->Samples = NULL; + self->NumSamples = 0; +} + +ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context) +{ + ALCdevice *device = context->Device; + const char *fname; + + if(device->DefaultSfont) + return device->DefaultSfont; + + device->DefaultSfont = calloc(1, sizeof(device->DefaultSfont[0])); + ALsoundfont_Construct(device->DefaultSfont); + + fname = getenv("ALSOFT_SOUNDFONT"); + if((fname && fname[0]) || ConfigValueStr("midi", "soundfont", &fname)) + { + FILE *f; + + f = fopen(fname, "rb"); + if(f == NULL) + ERR("Failed to open %s\n", fname); + else + { + Reader reader; + reader.cb = ALsoundfont_read; + reader.ptr = f; + reader.error = 0; + TRACE("Loading %s\n", fname); + loadSf2(&reader, device->DefaultSfont, context); + fclose(f); + } + } + + return device->DefaultSfont; +} + +void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device) +{ + ALsfpreset **presets; + ALsizei num_presets; + ALsizei i; + + presets = ExchangePtr((XchgPtr*)&self->Presets, NULL); + num_presets = ExchangeInt(&self->NumPresets, 0); + + for(i = 0;i < num_presets;i++) + { + ALsfpreset *preset = presets[i]; + ALfontsound **sounds; + ALsizei num_sounds; + ALboolean deleting; + ALsizei j; + + sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); + num_sounds = ExchangeInt(&preset->NumSounds, 0); + DeletePreset(preset, device); + preset = NULL; + + for(j = 0;j < num_sounds;j++) + DecrementRef(&sounds[j]->ref); + /* Some fontsounds may not be immediately deletable because they're + * linked to another fontsound. When those fontsounds are deleted + * they should become deletable, so use a loop until all fontsounds + * are deleted. */ + do { + deleting = AL_FALSE; + for(j = 0;j < num_sounds;j++) + { + if(sounds[j] && sounds[j]->ref == 0) + { + deleting = AL_TRUE; + RemoveFontsound(device, sounds[j]->id); + ALfontsound_Destruct(sounds[j]); + free(sounds[j]); + sounds[j] = NULL; + } + } + } while(deleting); + free(sounds); + } + + ALsoundfont_Destruct(self); + free(self); +} + + +static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr) +{ + return fread(buf, 1, bytes, (FILE*)ptr); +} + + +/* ReleaseALSoundfonts + * + * Called to destroy any soundfonts that still exist on the device + */ +void ReleaseALSoundfonts(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->SfontMap.size;i++) + { + ALsoundfont *temp = device->SfontMap.array[i].value; + device->SfontMap.array[i].value = NULL; + + ALsoundfont_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/jni/openal-soft-android/OpenAL32/alSource.c b/jni/openal-soft-android/OpenAL32/alSource.c index 7d0aa978..543910db 100644 --- a/jni/openal-soft-android/OpenAL32/alSource.c +++ b/jni/openal-soft-android/OpenAL32/alSource.c @@ -23,9 +23,10 @@ #include #include #include -#include "alMain.h" + #include "AL/al.h" #include "AL/alc.h" +#include "alMain.h" #include "alError.h" #include "alSource.h" #include "alBuffer.h" @@ -33,1333 +34,1848 @@ #include "alAuxEffectSlot.h" -enum Resampler DefaultResampler = RESAMPLER_DEFAULT; -const ALsizei ResamplerPadding[RESAMPLER_MAX] = { +enum Resampler DefaultResampler = LinearResampler; +const ALsizei ResamplerPadding[ResamplerMax] = { 0, /* Point */ 1, /* Linear */ 2, /* Cubic */ }; -const ALsizei ResamplerPrePadding[RESAMPLER_MAX] = { +const ALsizei ResamplerPrePadding[ResamplerMax] = { 0, /* Point */ 0, /* Linear */ 1, /* Cubic */ }; +extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); +extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); + static ALvoid InitSourceParams(ALsource *Source); -static ALvoid GetSourceOffset(ALsource *Source, ALenum eName, ALdouble *Offsets, ALdouble updateLen); +static ALint64 GetSourceOffset(const ALsource *Source); +static ALdouble GetSourceSecOffset(const ALsource *Source); +static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offsets, ALdouble updateLen); static ALint GetSampleOffset(ALsource *Source); +typedef enum SrcFloatProp { + sfPitch = AL_PITCH, + sfGain = AL_GAIN, + sfMinGain = AL_MIN_GAIN, + sfMaxGain = AL_MAX_GAIN, + sfMaxDistance = AL_MAX_DISTANCE, + sfRolloffFactor = AL_ROLLOFF_FACTOR, + sfDopplerFactor = AL_DOPPLER_FACTOR, + sfConeOuterGain = AL_CONE_OUTER_GAIN, + sfSecOffset = AL_SEC_OFFSET, + sfSampleOffset = AL_SAMPLE_OFFSET, + sfByteOffset = AL_BYTE_OFFSET, + sfConeInnerAngle = AL_CONE_INNER_ANGLE, + sfConeOuterAngle = AL_CONE_OUTER_ANGLE, + sfRefDistance = AL_REFERENCE_DISTANCE, -AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n,ALuint *sources) + sfPosition = AL_POSITION, + sfVelocity = AL_VELOCITY, + sfDirection = AL_DIRECTION, + + sfSourceRelative = AL_SOURCE_RELATIVE, + sfLooping = AL_LOOPING, + sfBuffer = AL_BUFFER, + sfSourceState = AL_SOURCE_STATE, + sfBuffersQueued = AL_BUFFERS_QUEUED, + sfBuffersProcessed = AL_BUFFERS_PROCESSED, + sfSourceType = AL_SOURCE_TYPE, + + /* ALC_EXT_EFX */ + sfConeOuterGainHF = AL_CONE_OUTER_GAINHF, + sfAirAbsorptionFactor = AL_AIR_ABSORPTION_FACTOR, + sfRoomRolloffFactor = AL_ROOM_ROLLOFF_FACTOR, + sfDirectFilterGainHFAuto = AL_DIRECT_FILTER_GAINHF_AUTO, + sfAuxSendFilterGainAuto = AL_AUXILIARY_SEND_FILTER_GAIN_AUTO, + sfAuxSendFilterGainHFAuto = AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO, + + /* AL_SOFT_direct_channels */ + sfDirectChannelsSOFT = AL_DIRECT_CHANNELS_SOFT, + + /* AL_EXT_source_distance_model */ + sfDistanceModel = AL_DISTANCE_MODEL, + + /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */ + sfSampleRWOffsetsSOFT = AL_SAMPLE_RW_OFFSETS_SOFT, + sfByteRWOffsetsSOFT = AL_BYTE_RW_OFFSETS_SOFT, + + /* AL_SOFT_source_latency */ + sfSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT, +} SrcFloatProp; + +typedef enum SrcIntProp { + siMaxDistance = AL_MAX_DISTANCE, + siRolloffFactor = AL_ROLLOFF_FACTOR, + siRefDistance = AL_REFERENCE_DISTANCE, + siSourceRelative = AL_SOURCE_RELATIVE, + siConeInnerAngle = AL_CONE_INNER_ANGLE, + siConeOuterAngle = AL_CONE_OUTER_ANGLE, + siLooping = AL_LOOPING, + siBuffer = AL_BUFFER, + siSourceState = AL_SOURCE_STATE, + siBuffersQueued = AL_BUFFERS_QUEUED, + siBuffersProcessed = AL_BUFFERS_PROCESSED, + siSourceType = AL_SOURCE_TYPE, + siSecOffset = AL_SEC_OFFSET, + siSampleOffset = AL_SAMPLE_OFFSET, + siByteOffset = AL_BYTE_OFFSET, + siDopplerFactor = AL_DOPPLER_FACTOR, + siPosition = AL_POSITION, + siVelocity = AL_VELOCITY, + siDirection = AL_DIRECTION, + + /* ALC_EXT_EFX */ + siDirectFilterGainHFAuto = AL_DIRECT_FILTER_GAINHF_AUTO, + siAuxSendFilterGainAutio = AL_AUXILIARY_SEND_FILTER_GAIN_AUTO, + siAuxSendFilterGainHFAuto = AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO, + siDirectFilter = AL_DIRECT_FILTER, + siAuxSendFilter = AL_AUXILIARY_SEND_FILTER, + + /* AL_SOFT_direct_channels */ + siDirectChannelsSOFT = AL_DIRECT_CHANNELS_SOFT, + + /* AL_EXT_source_distance_model */ + siDistanceModel = AL_DISTANCE_MODEL, + + /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */ + siSampleRWOffsetsSOFT = AL_SAMPLE_RW_OFFSETS_SOFT, + siByteRWOffsetsSOFT = AL_BYTE_RW_OFFSETS_SOFT, + + /* AL_SOFT_source_latency */ + siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT, +} SrcIntProp; + +static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values); +static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values); +static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values); + +static ALboolean GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values); +static ALboolean GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values); +static ALboolean GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values); + +static ALint FloatValsByProp(ALenum prop) { - ALCcontext *Context; - ALCdevice *Device; - - Context = GetContextRef(); - if(!Context) return; - - Device = Context->Device; - if(n < 0 || IsBadWritePtr((void*)sources, n * sizeof(ALuint))) - alSetError(Context, AL_INVALID_VALUE); - else + if(prop != (ALenum)((SrcFloatProp)prop)) + return 0; + switch((SrcFloatProp)prop) { - ALenum err; - ALsizei i; + case sfPitch: + case sfGain: + case sfMinGain: + case sfMaxGain: + case sfMaxDistance: + case sfRolloffFactor: + case sfDopplerFactor: + case sfConeOuterGain: + case sfSecOffset: + case sfSampleOffset: + case sfByteOffset: + case sfConeInnerAngle: + case sfConeOuterAngle: + case sfRefDistance: + case sfConeOuterGainHF: + case sfAirAbsorptionFactor: + case sfRoomRolloffFactor: + case sfDirectFilterGainHFAuto: + case sfAuxSendFilterGainAuto: + case sfAuxSendFilterGainHFAuto: + case sfDirectChannelsSOFT: + case sfDistanceModel: + case sfSourceRelative: + case sfLooping: + case sfBuffer: + case sfSourceState: + case sfBuffersQueued: + case sfBuffersProcessed: + case sfSourceType: + return 1; - // Add additional sources to the list - i = 0; - while(i < n) - { - ALsource *source = calloc(1, sizeof(ALsource)); - if(!source) - { - alSetError(Context, AL_OUT_OF_MEMORY); - alDeleteSources(i, sources); - break; - } - InitSourceParams(source); + case sfSampleRWOffsetsSOFT: + case sfByteRWOffsetsSOFT: + return 2; - err = NewThunkEntry(&source->source); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&Context->SourceMap, source->source, source); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(source->source); - memset(source, 0, sizeof(ALsource)); - free(source); + case sfPosition: + case sfVelocity: + case sfDirection: + return 3; - alSetError(Context, err); - alDeleteSources(i, sources); - break; - } - - sources[i++] = source->source; - } + case sfSecOffsetLatencySOFT: + break; /* Double only */ } + return 0; +} +static ALint DoubleValsByProp(ALenum prop) +{ + if(prop != (ALenum)((SrcFloatProp)prop)) + return 0; + switch((SrcFloatProp)prop) + { + case sfPitch: + case sfGain: + case sfMinGain: + case sfMaxGain: + case sfMaxDistance: + case sfRolloffFactor: + case sfDopplerFactor: + case sfConeOuterGain: + case sfSecOffset: + case sfSampleOffset: + case sfByteOffset: + case sfConeInnerAngle: + case sfConeOuterAngle: + case sfRefDistance: + case sfConeOuterGainHF: + case sfAirAbsorptionFactor: + case sfRoomRolloffFactor: + case sfDirectFilterGainHFAuto: + case sfAuxSendFilterGainAuto: + case sfAuxSendFilterGainHFAuto: + case sfDirectChannelsSOFT: + case sfDistanceModel: + case sfSourceRelative: + case sfLooping: + case sfBuffer: + case sfSourceState: + case sfBuffersQueued: + case sfBuffersProcessed: + case sfSourceType: + return 1; - ALCcontext_DecRef(Context); + case sfSampleRWOffsetsSOFT: + case sfByteRWOffsetsSOFT: + case sfSecOffsetLatencySOFT: + return 2; + + case sfPosition: + case sfVelocity: + case sfDirection: + return 3; + } + return 0; +} + +static ALint IntValsByProp(ALenum prop) +{ + if(prop != (ALenum)((SrcIntProp)prop)) + return 0; + switch((SrcIntProp)prop) + { + case siMaxDistance: + case siRolloffFactor: + case siRefDistance: + case siSourceRelative: + case siConeInnerAngle: + case siConeOuterAngle: + case siLooping: + case siBuffer: + case siSourceState: + case siBuffersQueued: + case siBuffersProcessed: + case siSourceType: + case siSecOffset: + case siSampleOffset: + case siByteOffset: + case siDopplerFactor: + case siDirectFilterGainHFAuto: + case siAuxSendFilterGainAutio: + case siAuxSendFilterGainHFAuto: + case siDirectFilter: + case siDirectChannelsSOFT: + case siDistanceModel: + return 1; + + case siSampleRWOffsetsSOFT: + case siByteRWOffsetsSOFT: + return 2; + + case siPosition: + case siVelocity: + case siDirection: + case siAuxSendFilter: + return 3; + + case siSampleOffsetLatencySOFT: + break; /* i64 only */ + } + return 0; +} +static ALint Int64ValsByProp(ALenum prop) +{ + if(prop != (ALenum)((SrcIntProp)prop)) + return 0; + switch((SrcIntProp)prop) + { + case siMaxDistance: + case siRolloffFactor: + case siRefDistance: + case siSourceRelative: + case siConeInnerAngle: + case siConeOuterAngle: + case siLooping: + case siBuffer: + case siSourceState: + case siBuffersQueued: + case siBuffersProcessed: + case siSourceType: + case siSecOffset: + case siSampleOffset: + case siByteOffset: + case siDopplerFactor: + case siDirectFilterGainHFAuto: + case siAuxSendFilterGainAutio: + case siAuxSendFilterGainHFAuto: + case siDirectFilter: + case siDirectChannelsSOFT: + case siDistanceModel: + return 1; + + case siSampleRWOffsetsSOFT: + case siByteRWOffsetsSOFT: + case siSampleOffsetLatencySOFT: + return 2; + + case siPosition: + case siVelocity: + case siDirection: + case siAuxSendFilter: + return 3; + } + return 0; } -AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) +#define CHECKVAL(x) do { \ + if(!(x)) \ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ +} while(0) + +static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values) { - ALCcontext *Context; - ALsource *Source; - ALsizei i, j; - ALbufferlistitem *BufferList; + ALint ival; - Context = GetContextRef(); - if(!Context) return; - - if(n < 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - // Check that all Sources are valid (and can therefore be deleted) - for(i = 0;i < n;i++) - { - if(LookupSource(Context, sources[i]) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - n = 0; - break; - } - } - - // All Sources are valid, and can be deleted - for(i = 0;i < n;i++) - { - ALsource **srclist, **srclistend; - - // Remove Source from list of Sources - if((Source=RemoveSource(Context, sources[i])) == NULL) - continue; - - FreeThunkEntry(Source->source); - - LockContext(Context); - srclist = Context->ActiveSources; - srclistend = srclist + Context->ActiveSourceCount; - while(srclist != srclistend) - { - if(*srclist == Source) - { - Context->ActiveSourceCount--; - *srclist = *(--srclistend); - break; - } - srclist++; - } - UnlockContext(Context); - - // For each buffer in the source's queue... - while(Source->queue != NULL) - { - BufferList = Source->queue; - Source->queue = BufferList->next; - - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(Source->Send[j].Slot) - DecrementRef(&Source->Send[j].Slot->ref); - Source->Send[j].Slot = NULL; - } - - memset(Source,0,sizeof(ALsource)); - free(Source); - } - } - - ALCcontext_DecRef(Context); -} - - -AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) -{ - ALCcontext *Context; - ALboolean result; - - Context = GetContextRef(); - if(!Context) return AL_FALSE; - - result = (LookupSource(Context, source) ? AL_TRUE : AL_FALSE); - - ALCcontext_DecRef(Context); - - return result; -} - - -AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum eParam, ALfloat flValue) -{ - ALCcontext *pContext; - ALsource *Source; - - pContext = GetContextRef(); - if(!pContext) return; - - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_PITCH: - if(flValue >= 0.0f) - { - Source->flPitch = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_CONE_INNER_ANGLE: - if(flValue >= 0.0f && flValue <= 360.0f) - { - Source->flInnerAngle = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_CONE_OUTER_ANGLE: - if(flValue >= 0.0f && flValue <= 360.0f) - { - Source->flOuterAngle = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_GAIN: - if(flValue >= 0.0f) - { - Source->flGain = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_MAX_DISTANCE: - if(flValue >= 0.0f) - { - Source->flMaxDistance = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_ROLLOFF_FACTOR: - if(flValue >= 0.0f) - { - Source->flRollOffFactor = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_REFERENCE_DISTANCE: - if(flValue >= 0.0f) - { - Source->flRefDistance = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_MIN_GAIN: - if(flValue >= 0.0f && flValue <= 1.0f) - { - Source->flMinGain = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_MAX_GAIN: - if(flValue >= 0.0f && flValue <= 1.0f) - { - Source->flMaxGain = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_CONE_OUTER_GAIN: - if(flValue >= 0.0f && flValue <= 1.0f) - { - Source->flOuterGain = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_CONE_OUTER_GAINHF: - if(flValue >= 0.0f && flValue <= 1.0f) - { - Source->OuterGainHF = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_AIR_ABSORPTION_FACTOR: - if(flValue >= 0.0f && flValue <= 10.0f) - { - Source->AirAbsorptionFactor = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_ROOM_ROLLOFF_FACTOR: - if(flValue >= 0.0f && flValue <= 10.0f) - { - Source->RoomRolloffFactor = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_DOPPLER_FACTOR: - if(flValue >= 0.0f && flValue <= 1.0f) - { - Source->DopplerFactor = flValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - if(flValue >= 0.0f) - { - LockContext(pContext); - Source->lOffsetType = eParam; - - // Store Offset (convert Seconds into Milliseconds) - if(eParam == AL_SEC_OFFSET) - Source->lOffset = (ALint)(flValue * 1000.0f); - else - Source->lOffset = (ALint)flValue; - - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !pContext->DeferUpdates) - { - if(ApplyOffset(Source) == AL_FALSE) - alSetError(pContext, AL_INVALID_VALUE); - } - UnlockContext(pContext); - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - { - // Invalid Source Name - alSetError(pContext, AL_INVALID_NAME); - } - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum eParam, ALfloat flValue1,ALfloat flValue2,ALfloat flValue3) -{ - ALCcontext *pContext; - ALsource *Source; - - pContext = GetContextRef(); - if(!pContext) return; - - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_POSITION: - if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3)) - { - LockContext(pContext); - Source->vPosition[0] = flValue1; - Source->vPosition[1] = flValue2; - Source->vPosition[2] = flValue3; - UnlockContext(pContext); - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_VELOCITY: - if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3)) - { - LockContext(pContext); - Source->vVelocity[0] = flValue1; - Source->vVelocity[1] = flValue2; - Source->vVelocity[2] = flValue3; - UnlockContext(pContext); - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_DIRECTION: - if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3)) - { - LockContext(pContext); - Source->vOrientation[0] = flValue1; - Source->vOrientation[1] = flValue2; - Source->vOrientation[2] = flValue3; - UnlockContext(pContext); - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum eParam, const ALfloat *pflValues) -{ - ALCcontext *pContext; - - if(pflValues) - { - switch(eParam) - { - case AL_PITCH: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_GAIN: - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_REFERENCE_DISTANCE: - case AL_MIN_GAIN: - case AL_MAX_GAIN: - case AL_CONE_OUTER_GAIN: - case AL_CONE_OUTER_GAINHF: - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - case AL_AIR_ABSORPTION_FACTOR: - case AL_ROOM_ROLLOFF_FACTOR: - alSourcef(source, eParam, pflValues[0]); - return; - - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - alSource3f(source, eParam, pflValues[0], pflValues[1], pflValues[2]); - return; - } - } - - pContext = GetContextRef(); - if(!pContext) return; - - if(pflValues) - { - if(LookupSource(pContext, source) != NULL) - { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue) -{ - ALCcontext *pContext; - ALsource *Source; - ALbufferlistitem *BufferListItem; - - switch(eParam) - { - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_REFERENCE_DISTANCE: - alSourcef(source, eParam, (ALfloat)lValue); - return; - } - - pContext = GetContextRef(); - if(!pContext) return; - - if((Source=LookupSource(pContext, source)) != NULL) - { - ALCdevice *device = pContext->Device; - - switch(eParam) - { - case AL_SOURCE_RELATIVE: - if(lValue == AL_FALSE || lValue == AL_TRUE) - { - Source->bHeadRelative = (ALboolean)lValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_LOOPING: - if(lValue == AL_FALSE || lValue == AL_TRUE) - Source->bLooping = (ALboolean)lValue; - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_BUFFER: - LockContext(pContext); - if(Source->state == AL_STOPPED || Source->state == AL_INITIAL) - { - ALbufferlistitem *oldlist; - ALbuffer *buffer = NULL; - - if(lValue == 0 || (buffer=LookupBuffer(device, lValue)) != NULL) - { - Source->BuffersInQueue = 0; - Source->BuffersPlayed = 0; - - // Add the buffer to the queue (as long as it is NOT the NULL buffer) - if(buffer != NULL) - { - // Source is now in STATIC mode - Source->lSourceType = AL_STATIC; - - // Add the selected buffer to the queue - BufferListItem = malloc(sizeof(ALbufferlistitem)); - BufferListItem->buffer = buffer; - BufferListItem->next = NULL; - BufferListItem->prev = NULL; - // Increment reference counter for buffer - IncrementRef(&buffer->ref); - - oldlist = ExchangePtr((void**)&Source->queue, BufferListItem); - Source->BuffersInQueue = 1; - - ReadLock(&buffer->lock); - Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - Source->SampleSize = BytesFromFmt(buffer->FmtType); - ReadUnlock(&buffer->lock); - if(buffer->FmtChannels == FmtMono) - Source->Update = CalcSourceParams; - else - Source->Update = CalcNonAttnSourceParams; - Source->NeedsUpdate = AL_TRUE; - } - else - { - // Source is now in UNDETERMINED mode - Source->lSourceType = AL_UNDETERMINED; - oldlist = ExchangePtr((void**)&Source->queue, NULL); - } - - // Delete all previous elements in the queue - while(oldlist != NULL) - { - BufferListItem = oldlist; - oldlist = BufferListItem->next; - - if(BufferListItem->buffer) - DecrementRef(&BufferListItem->buffer->ref); - free(BufferListItem); - } - } - else - alSetError(pContext, AL_INVALID_VALUE); - } - else - alSetError(pContext, AL_INVALID_OPERATION); - UnlockContext(pContext); - break; - - case AL_SOURCE_STATE: - // Query only - alSetError(pContext, AL_INVALID_OPERATION); - break; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - if(lValue >= 0) - { - LockContext(pContext); - Source->lOffsetType = eParam; - - // Store Offset (convert Seconds into Milliseconds) - if(eParam == AL_SEC_OFFSET) - Source->lOffset = lValue * 1000; - else - Source->lOffset = lValue; - - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !pContext->DeferUpdates) - { - if(ApplyOffset(Source) == AL_FALSE) - alSetError(pContext, AL_INVALID_VALUE); - } - UnlockContext(pContext); - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_DIRECT_FILTER: { - ALfilter *filter = NULL; - - if(lValue == 0 || (filter=LookupFilter(pContext->Device, lValue)) != NULL) - { - LockContext(pContext); - if(!filter) - { - Source->DirectGain = 1.0f; - Source->DirectGainHF = 1.0f; - } - else - { - Source->DirectGain = filter->Gain; - Source->DirectGainHF = filter->GainHF; - } - UnlockContext(pContext); - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - } break; - - case AL_DIRECT_FILTER_GAINHF_AUTO: - if(lValue == AL_TRUE || lValue == AL_FALSE) - { - Source->DryGainHFAuto = lValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - if(lValue == AL_TRUE || lValue == AL_FALSE) - { - Source->WetGainAuto = lValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - if(lValue == AL_TRUE || lValue == AL_FALSE) - { - Source->WetGainHFAuto = lValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_VIRTUAL_CHANNELS_SOFT: - if(lValue == AL_TRUE || lValue == AL_FALSE) - { - Source->VirtualChannels = lValue; - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - case AL_DISTANCE_MODEL: - if(lValue == AL_NONE || - lValue == AL_INVERSE_DISTANCE || - lValue == AL_INVERSE_DISTANCE_CLAMPED || - lValue == AL_LINEAR_DISTANCE || - lValue == AL_LINEAR_DISTANCE_CLAMPED || - lValue == AL_EXPONENT_DISTANCE || - lValue == AL_EXPONENT_DISTANCE_CLAMPED) - { - Source->DistanceModel = lValue; - if(pContext->SourceDistanceModel) - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - - ALCcontext_DecRef(pContext); -} - - -AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3) -{ - ALCcontext *pContext; - ALsource *Source; - - switch(eParam) - { - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - alSource3f(source, eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3); - return; - } - - pContext = GetContextRef(); - if(!pContext) return; - - if((Source=LookupSource(pContext, source)) != NULL) - { - ALCdevice *device = pContext->Device; - - switch(eParam) - { - case AL_AUXILIARY_SEND_FILTER: { - ALeffectslot *ALEffectSlot = NULL; - ALfilter *ALFilter = NULL; - - LockContext(pContext); - if((ALuint)lValue2 < device->NumAuxSends && - (lValue1 == 0 || (ALEffectSlot=LookupEffectSlot(pContext, lValue1)) != NULL) && - (lValue3 == 0 || (ALFilter=LookupFilter(device, lValue3)) != NULL)) - { - /* Release refcount on the previous slot, and add one for - * the new slot */ - if(ALEffectSlot) IncrementRef(&ALEffectSlot->ref); - ALEffectSlot = ExchangePtr((void**)&Source->Send[lValue2].Slot, ALEffectSlot); - if(ALEffectSlot) DecrementRef(&ALEffectSlot->ref); - - if(!ALFilter) - { - /* Disable filter */ - Source->Send[lValue2].WetGain = 1.0f; - Source->Send[lValue2].WetGainHF = 1.0f; - } - else - { - Source->Send[lValue2].WetGain = ALFilter->Gain; - Source->Send[lValue2].WetGainHF = ALFilter->GainHF; - } - Source->NeedsUpdate = AL_TRUE; - } - else - alSetError(pContext, AL_INVALID_VALUE); - UnlockContext(pContext); - } break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - - ALCcontext_DecRef(pContext); -} - - -AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum eParam, const ALint* plValues) -{ - ALCcontext *pContext; - - if(plValues) - { - switch(eParam) - { - case AL_SOURCE_RELATIVE: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_LOOPING: - case AL_BUFFER: - case AL_SOURCE_STATE: - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_REFERENCE_DISTANCE: - case AL_DIRECT_FILTER: - case AL_DIRECT_FILTER_GAINHF_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - case AL_DISTANCE_MODEL: - case AL_VIRTUAL_CHANNELS_SOFT: - alSourcei(source, eParam, plValues[0]); - return; - - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - case AL_AUXILIARY_SEND_FILTER: - alSource3i(source, eParam, plValues[0], plValues[1], plValues[2]); - return; - } - } - - pContext = GetContextRef(); - if(!pContext) return; - - if(plValues) - { - if(LookupSource(pContext, source) != NULL) - { - switch(eParam) - { - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum eParam, ALfloat *pflValue) -{ - ALCcontext *pContext; - ALsource *Source; - ALdouble Offsets[2]; - ALdouble updateLen; - - pContext = GetContextRef(); - if(!pContext) return; - - if(pflValue) - { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_PITCH: - *pflValue = Source->flPitch; - break; - - case AL_GAIN: - *pflValue = Source->flGain; - break; - - case AL_MIN_GAIN: - *pflValue = Source->flMinGain; - break; - - case AL_MAX_GAIN: - *pflValue = Source->flMaxGain; - break; - - case AL_MAX_DISTANCE: - *pflValue = Source->flMaxDistance; - break; - - case AL_ROLLOFF_FACTOR: - *pflValue = Source->flRollOffFactor; - break; - - case AL_CONE_OUTER_GAIN: - *pflValue = Source->flOuterGain; - break; - - case AL_CONE_OUTER_GAINHF: - *pflValue = Source->OuterGainHF; - break; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - LockContext(pContext); - updateLen = (ALdouble)pContext->Device->UpdateSize / - pContext->Device->Frequency; - GetSourceOffset(Source, eParam, Offsets, updateLen); - UnlockContext(pContext); - *pflValue = (ALfloat)Offsets[0]; - break; - - case AL_CONE_INNER_ANGLE: - *pflValue = Source->flInnerAngle; - break; - - case AL_CONE_OUTER_ANGLE: - *pflValue = Source->flOuterAngle; - break; - - case AL_REFERENCE_DISTANCE: - *pflValue = Source->flRefDistance; - break; - - case AL_AIR_ABSORPTION_FACTOR: - *pflValue = Source->AirAbsorptionFactor; - break; - - case AL_ROOM_ROLLOFF_FACTOR: - *pflValue = Source->RoomRolloffFactor; - break; - - case AL_DOPPLER_FACTOR: - *pflValue = Source->DopplerFactor; - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3) -{ - ALCcontext *pContext; - ALsource *Source; - - pContext = GetContextRef(); - if(!pContext) return; - - if(pflValue1 && pflValue2 && pflValue3) - { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_POSITION: - LockContext(pContext); - *pflValue1 = Source->vPosition[0]; - *pflValue2 = Source->vPosition[1]; - *pflValue3 = Source->vPosition[2]; - UnlockContext(pContext); - break; - - case AL_VELOCITY: - LockContext(pContext); - *pflValue1 = Source->vVelocity[0]; - *pflValue2 = Source->vVelocity[1]; - *pflValue3 = Source->vVelocity[2]; - UnlockContext(pContext); - break; - - case AL_DIRECTION: - LockContext(pContext); - *pflValue1 = Source->vOrientation[0]; - *pflValue2 = Source->vOrientation[1]; - *pflValue3 = Source->vOrientation[2]; - UnlockContext(pContext); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} - - -AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum eParam, ALfloat *pflValues) -{ - ALCcontext *pContext; - ALsource *Source; - ALdouble Offsets[2]; - ALdouble updateLen; - - switch(eParam) + switch(prop) { case AL_PITCH: + CHECKVAL(*values >= 0.0f); + + Source->Pitch = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_CONE_INNER_ANGLE: + CHECKVAL(*values >= 0.0f && *values <= 360.0f); + + Source->InnerAngle = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_CONE_OUTER_ANGLE: + CHECKVAL(*values >= 0.0f && *values <= 360.0f); + + Source->OuterAngle = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + case AL_GAIN: - case AL_MIN_GAIN: - case AL_MAX_GAIN: + CHECKVAL(*values >= 0.0f); + + Source->Gain = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + case AL_MAX_DISTANCE: + CHECKVAL(*values >= 0.0f); + + Source->MaxDistance = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + case AL_ROLLOFF_FACTOR: - case AL_DOPPLER_FACTOR: + CHECKVAL(*values >= 0.0f); + + Source->RollOffFactor = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_REFERENCE_DISTANCE: + CHECKVAL(*values >= 0.0f); + + Source->RefDistance = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_MIN_GAIN: + CHECKVAL(*values >= 0.0f && *values <= 1.0f); + + Source->MinGain = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_MAX_GAIN: + CHECKVAL(*values >= 0.0f && *values <= 1.0f); + + Source->MaxGain = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + case AL_CONE_OUTER_GAIN: + CHECKVAL(*values >= 0.0f && *values <= 1.0f); + + Source->OuterGain = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_CONE_OUTER_GAINHF: + CHECKVAL(*values >= 0.0f && *values <= 1.0f); + + Source->OuterGainHF = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_AIR_ABSORPTION_FACTOR: + CHECKVAL(*values >= 0.0f && *values <= 10.0f); + + Source->AirAbsorptionFactor = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_ROOM_ROLLOFF_FACTOR: + CHECKVAL(*values >= 0.0f && *values <= 10.0f); + + Source->RoomRolloffFactor = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_DOPPLER_FACTOR: + CHECKVAL(*values >= 0.0f && *values <= 1.0f); + + Source->DopplerFactor = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: + CHECKVAL(*values >= 0.0f); + + LockContext(Context); + Source->OffsetType = prop; + Source->Offset = *values; + + if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && + !Context->DeferUpdates) + { + if(ApplyOffset(Source) == AL_FALSE) + { + UnlockContext(Context); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } + } + UnlockContext(Context); + return AL_TRUE; + + + case AL_SEC_OFFSET_LATENCY_SOFT: + /* Query only */ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + + + case AL_POSITION: + CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); + + LockContext(Context); + Source->Position[0] = values[0]; + Source->Position[1] = values[1]; + Source->Position[2] = values[2]; + UnlockContext(Context); + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_VELOCITY: + CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); + + LockContext(Context); + Source->Velocity[0] = values[0]; + Source->Velocity[1] = values[1]; + Source->Velocity[2] = values[2]; + UnlockContext(Context); + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_DIRECTION: + CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); + + LockContext(Context); + Source->Orientation[0] = values[0]; + Source->Orientation[1] = values[1]; + Source->Orientation[2] = values[2]; + UnlockContext(Context); + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + + case sfSampleRWOffsetsSOFT: + case sfByteRWOffsetsSOFT: + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + + + case sfSourceRelative: + case sfLooping: + case sfSourceState: + case sfSourceType: + case sfDistanceModel: + case sfDirectFilterGainHFAuto: + case sfAuxSendFilterGainAuto: + case sfAuxSendFilterGainHFAuto: + case sfDirectChannelsSOFT: + ival = (ALint)values[0]; + return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); + + case sfBuffer: + case sfBuffersQueued: + case sfBuffersProcessed: + ival = (ALint)((ALuint)values[0]); + return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); + } + + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); +} + +static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values) +{ + ALCdevice *device = Context->Device; + ALbuffer *buffer = NULL; + ALfilter *filter = NULL; + ALeffectslot *slot = NULL; + ALbufferlistitem *oldlist; + ALfloat fvals[3]; + + switch(prop) + { + case AL_SOURCE_RELATIVE: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->HeadRelative = (ALboolean)*values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_LOOPING: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->Looping = (ALboolean)*values; + return AL_TRUE; + + case AL_BUFFER: + CHECKVAL(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL); + + LockContext(Context); + if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL)) + { + UnlockContext(Context); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + } + + Source->BuffersInQueue = 0; + Source->BuffersPlayed = 0; + + if(buffer != NULL) + { + ALbufferlistitem *BufferListItem; + + /* Source is now Static */ + Source->SourceType = AL_STATIC; + + /* Add the selected buffer to a one-item queue */ + BufferListItem = malloc(sizeof(ALbufferlistitem)); + BufferListItem->buffer = buffer; + BufferListItem->next = NULL; + BufferListItem->prev = NULL; + IncrementRef(&buffer->ref); + + oldlist = ExchangePtr((XchgPtr*)&Source->queue, BufferListItem); + Source->BuffersInQueue = 1; + + ReadLock(&buffer->lock); + Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); + Source->SampleSize = BytesFromFmt(buffer->FmtType); + ReadUnlock(&buffer->lock); + if(buffer->FmtChannels == FmtMono) + Source->Update = CalcSourceParams; + else + Source->Update = CalcNonAttnSourceParams; + Source->NeedsUpdate = AL_TRUE; + } + else + { + /* Source is now Undetermined */ + Source->SourceType = AL_UNDETERMINED; + oldlist = ExchangePtr((XchgPtr*)&Source->queue, NULL); + } + + /* Delete all elements in the previous queue */ + while(oldlist != NULL) + { + ALbufferlistitem *temp = oldlist; + oldlist = temp->next; + + if(temp->buffer) + DecrementRef(&temp->buffer->ref); + free(temp); + } + UnlockContext(Context); + return AL_TRUE; + + case siSourceState: + case siSourceType: + case siBuffersQueued: + case siBuffersProcessed: + /* Query only */ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + + case AL_SEC_OFFSET: + case AL_SAMPLE_OFFSET: + case AL_BYTE_OFFSET: + CHECKVAL(*values >= 0); + + LockContext(Context); + Source->OffsetType = prop; + Source->Offset = *values; + + if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && + !Context->DeferUpdates) + { + if(ApplyOffset(Source) == AL_FALSE) + { + UnlockContext(Context); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } + } + UnlockContext(Context); + return AL_TRUE; + + + case siSampleRWOffsetsSOFT: + case siByteRWOffsetsSOFT: + /* Query only */ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + + + case AL_DIRECT_FILTER: + CHECKVAL(*values == 0 || (filter=LookupFilter(device, *values)) != NULL); + + LockContext(Context); + if(!filter) + { + Source->DirectGain = 1.0f; + Source->DirectGainHF = 1.0f; + } + else + { + Source->DirectGain = filter->Gain; + Source->DirectGainHF = filter->GainHF; + } + UnlockContext(Context); + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_DIRECT_FILTER_GAINHF_AUTO: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->DryGainHFAuto = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->WetGainAuto = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->WetGainHFAuto = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_DIRECT_CHANNELS_SOFT: + CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); + + Source->DirectChannels = *values; + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + case AL_DISTANCE_MODEL: + CHECKVAL(*values == AL_NONE || + *values == AL_INVERSE_DISTANCE || + *values == AL_INVERSE_DISTANCE_CLAMPED || + *values == AL_LINEAR_DISTANCE || + *values == AL_LINEAR_DISTANCE_CLAMPED || + *values == AL_EXPONENT_DISTANCE || + *values == AL_EXPONENT_DISTANCE_CLAMPED); + + Source->DistanceModel = *values; + if(Context->SourceDistanceModel) + Source->NeedsUpdate = AL_TRUE; + return AL_TRUE; + + + case AL_AUXILIARY_SEND_FILTER: + LockContext(Context); + if(!((ALuint)values[1] < device->NumAuxSends && + (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && + (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) + { + UnlockContext(Context); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } + + /* Add refcount on the new slot, and release the previous slot */ + if(slot) IncrementRef(&slot->ref); + slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); + if(slot) DecrementRef(&slot->ref); + + if(!filter) + { + /* Disable filter */ + Source->Send[values[1]].Gain = 1.0f; + Source->Send[values[1]].GainHF = 1.0f; + } + else + { + Source->Send[values[1]].Gain = filter->Gain; + Source->Send[values[1]].GainHF = filter->GainHF; + } + Source->NeedsUpdate = AL_TRUE; + UnlockContext(Context); + return AL_TRUE; + + + case AL_MAX_DISTANCE: + case AL_ROLLOFF_FACTOR: case AL_CONE_INNER_ANGLE: case AL_CONE_OUTER_ANGLE: case AL_REFERENCE_DISTANCE: - case AL_CONE_OUTER_GAINHF: - case AL_AIR_ABSORPTION_FACTOR: - case AL_ROOM_ROLLOFF_FACTOR: - alGetSourcef(source, eParam, pflValues); - return; + case siDopplerFactor: + fvals[0] = (ALfloat)*values; + return SetSourcefv(Source, Context, (int)prop, fvals); case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: - alGetSource3f(source, eParam, pflValues+0, pflValues+1, pflValues+2); - return; + fvals[0] = (ALfloat)values[0]; + fvals[1] = (ALfloat)values[1]; + fvals[2] = (ALfloat)values[2]; + return SetSourcefv(Source, Context, (int)prop, fvals); + + case siSampleOffsetLatencySOFT: + /* i64 only */ + break; } - pContext = GetContextRef(); - if(!pContext) return; - - if(pflValues) - { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_SAMPLE_RW_OFFSETS_SOFT: - case AL_BYTE_RW_OFFSETS_SOFT: - LockContext(pContext); - updateLen = (ALdouble)pContext->Device->UpdateSize / - pContext->Device->Frequency; - GetSourceOffset(Source, eParam, Offsets, updateLen); - UnlockContext(pContext); - pflValues[0] = (ALfloat)Offsets[0]; - pflValues[1] = (ALfloat)Offsets[1]; - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } - -AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum eParam, ALint *plValue) +static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values) { - ALbufferlistitem *BufferList; - ALCcontext *pContext; - ALsource *Source; - ALdouble Offsets[2]; - ALdouble updateLen; + ALfloat fvals[3]; + ALint ivals[3]; - pContext = GetContextRef(); - if(!pContext) return; - - if(plValue) + switch(prop) { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_MAX_DISTANCE: - *plValue = (ALint)Source->flMaxDistance; - break; - - case AL_ROLLOFF_FACTOR: - *plValue = (ALint)Source->flRollOffFactor; - break; - - case AL_REFERENCE_DISTANCE: - *plValue = (ALint)Source->flRefDistance; - break; - - case AL_SOURCE_RELATIVE: - *plValue = Source->bHeadRelative; - break; - - case AL_CONE_INNER_ANGLE: - *plValue = (ALint)Source->flInnerAngle; - break; - - case AL_CONE_OUTER_ANGLE: - *plValue = (ALint)Source->flOuterAngle; - break; - - case AL_LOOPING: - *plValue = Source->bLooping; - break; - - case AL_BUFFER: - LockContext(pContext); - BufferList = Source->queue; - if(Source->lSourceType != AL_STATIC) - { - ALuint i = Source->BuffersPlayed; - while(i > 0) - { - BufferList = BufferList->next; - i--; - } - } - *plValue = ((BufferList && BufferList->buffer) ? - BufferList->buffer->buffer : 0); - UnlockContext(pContext); - break; - - case AL_SOURCE_STATE: - *plValue = Source->state; - break; - - case AL_BUFFERS_QUEUED: - *plValue = Source->BuffersInQueue; - break; - - case AL_BUFFERS_PROCESSED: - LockContext(pContext); - if(Source->bLooping || Source->lSourceType != AL_STREAMING) - { - /* Buffers on a looping source are in a perpetual state - * of PENDING, so don't report any as PROCESSED */ - *plValue = 0; - } - else - *plValue = Source->BuffersPlayed; - UnlockContext(pContext); - break; - - case AL_SOURCE_TYPE: - *plValue = Source->lSourceType; - break; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - LockContext(pContext); - updateLen = (ALdouble)pContext->Device->UpdateSize / - pContext->Device->Frequency; - GetSourceOffset(Source, eParam, Offsets, updateLen); - UnlockContext(pContext); - *plValue = (ALint)Offsets[0]; - break; - - case AL_DIRECT_FILTER_GAINHF_AUTO: - *plValue = Source->DryGainHFAuto; - break; - - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - *plValue = Source->WetGainAuto; - break; - - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - *plValue = Source->WetGainHFAuto; - break; - - case AL_DOPPLER_FACTOR: - *plValue = (ALint)Source->DopplerFactor; - break; - - case AL_VIRTUAL_CHANNELS_SOFT: - *plValue = Source->VirtualChannels; - break; - - case AL_DISTANCE_MODEL: - *plValue = Source->DistanceModel; - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} + case siSampleRWOffsetsSOFT: + case siByteRWOffsetsSOFT: + case siSampleOffsetLatencySOFT: + /* Query only */ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); -AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3) -{ - ALCcontext *pContext; - ALsource *Source; - - pContext = GetContextRef(); - if(!pContext) return; - - if(plValue1 && plValue2 && plValue3) - { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) - { - case AL_POSITION: - LockContext(pContext); - *plValue1 = (ALint)Source->vPosition[0]; - *plValue2 = (ALint)Source->vPosition[1]; - *plValue3 = (ALint)Source->vPosition[2]; - UnlockContext(pContext); - break; - - case AL_VELOCITY: - LockContext(pContext); - *plValue1 = (ALint)Source->vVelocity[0]; - *plValue2 = (ALint)Source->vVelocity[1]; - *plValue3 = (ALint)Source->vVelocity[2]; - UnlockContext(pContext); - break; - - case AL_DIRECTION: - LockContext(pContext); - *plValue1 = (ALint)Source->vOrientation[0]; - *plValue2 = (ALint)Source->vOrientation[1]; - *plValue3 = (ALint)Source->vOrientation[2]; - UnlockContext(pContext); - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; - } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); - - ALCcontext_DecRef(pContext); -} - - -AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum eParam, ALint* plValues) -{ - ALCcontext *pContext; - ALsource *Source; - ALdouble Offsets[2]; - ALdouble updateLen; - - switch(eParam) - { + /* 1x int */ case AL_SOURCE_RELATIVE: + case AL_LOOPING: + case AL_SOURCE_STATE: + case AL_BYTE_OFFSET: + case AL_SAMPLE_OFFSET: + case siSourceType: + case siBuffersQueued: + case siBuffersProcessed: + case AL_DIRECT_FILTER_GAINHF_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + case AL_DIRECT_CHANNELS_SOFT: + case AL_DISTANCE_MODEL: + CHECKVAL(*values <= INT_MAX && *values >= INT_MIN); + + ivals[0] = (ALint)*values; + return SetSourceiv(Source, Context, (int)prop, ivals); + + /* 1x uint */ + case AL_BUFFER: + case AL_DIRECT_FILTER: + CHECKVAL(*values <= UINT_MAX && *values >= 0); + + ivals[0] = (ALuint)*values; + return SetSourceiv(Source, Context, (int)prop, ivals); + + /* 3x uint */ + case AL_AUXILIARY_SEND_FILTER: + CHECKVAL(values[0] <= UINT_MAX && values[0] >= 0 && + values[1] <= UINT_MAX && values[1] >= 0 && + values[2] <= UINT_MAX && values[2] >= 0); + + ivals[0] = (ALuint)values[0]; + ivals[1] = (ALuint)values[1]; + ivals[2] = (ALuint)values[2]; + return SetSourceiv(Source, Context, (int)prop, ivals); + + /* 1x float */ + case AL_MAX_DISTANCE: + case AL_ROLLOFF_FACTOR: case AL_CONE_INNER_ANGLE: case AL_CONE_OUTER_ANGLE: + case AL_REFERENCE_DISTANCE: + case AL_SEC_OFFSET: + case siDopplerFactor: + fvals[0] = (ALfloat)*values; + return SetSourcefv(Source, Context, (int)prop, fvals); + + /* 3x float */ + case AL_POSITION: + case AL_VELOCITY: + case AL_DIRECTION: + fvals[0] = (ALfloat)values[0]; + fvals[1] = (ALfloat)values[1]; + fvals[2] = (ALfloat)values[2]; + return SetSourcefv(Source, Context, (int)prop, fvals); + } + + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); +} + +#undef CHECKVAL + + +static ALboolean GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values) +{ + ALdouble offsets[2]; + ALdouble updateLen; + ALint ivals[3]; + ALboolean err; + + switch(prop) + { + case AL_GAIN: + *values = Source->Gain; + return AL_TRUE; + + case AL_PITCH: + *values = Source->Pitch; + return AL_TRUE; + + case AL_MAX_DISTANCE: + *values = Source->MaxDistance; + return AL_TRUE; + + case AL_ROLLOFF_FACTOR: + *values = Source->RollOffFactor; + return AL_TRUE; + + case AL_REFERENCE_DISTANCE: + *values = Source->RefDistance; + return AL_TRUE; + + case AL_CONE_INNER_ANGLE: + *values = Source->InnerAngle; + return AL_TRUE; + + case AL_CONE_OUTER_ANGLE: + *values = Source->OuterAngle; + return AL_TRUE; + + case AL_MIN_GAIN: + *values = Source->MinGain; + return AL_TRUE; + + case AL_MAX_GAIN: + *values = Source->MaxGain; + return AL_TRUE; + + case AL_CONE_OUTER_GAIN: + *values = Source->OuterGain; + return AL_TRUE; + + case AL_SEC_OFFSET: + case AL_SAMPLE_OFFSET: + case AL_BYTE_OFFSET: + LockContext(Context); + updateLen = (ALdouble)Context->Device->UpdateSize / + Context->Device->Frequency; + GetSourceOffsets(Source, prop, offsets, updateLen); + UnlockContext(Context); + *values = offsets[0]; + return AL_TRUE; + + case AL_CONE_OUTER_GAINHF: + *values = Source->OuterGainHF; + return AL_TRUE; + + case AL_AIR_ABSORPTION_FACTOR: + *values = Source->AirAbsorptionFactor; + return AL_TRUE; + + case AL_ROOM_ROLLOFF_FACTOR: + *values = Source->RoomRolloffFactor; + return AL_TRUE; + + case AL_DOPPLER_FACTOR: + *values = Source->DopplerFactor; + return AL_TRUE; + + case AL_SAMPLE_RW_OFFSETS_SOFT: + case AL_BYTE_RW_OFFSETS_SOFT: + LockContext(Context); + updateLen = (ALdouble)Context->Device->UpdateSize / + Context->Device->Frequency; + GetSourceOffsets(Source, prop, values, updateLen); + UnlockContext(Context); + return AL_TRUE; + + case AL_SEC_OFFSET_LATENCY_SOFT: + LockContext(Context); + values[0] = GetSourceSecOffset(Source); + values[1] = (ALdouble)ALCdevice_GetLatency(Context->Device) / + 1000000000.0; + UnlockContext(Context); + return AL_TRUE; + + case AL_POSITION: + LockContext(Context); + values[0] = Source->Position[0]; + values[1] = Source->Position[1]; + values[2] = Source->Position[2]; + UnlockContext(Context); + return AL_TRUE; + + case AL_VELOCITY: + LockContext(Context); + values[0] = Source->Velocity[0]; + values[1] = Source->Velocity[1]; + values[2] = Source->Velocity[2]; + UnlockContext(Context); + return AL_TRUE; + + case AL_DIRECTION: + LockContext(Context); + values[0] = Source->Orientation[0]; + values[1] = Source->Orientation[1]; + values[2] = Source->Orientation[2]; + UnlockContext(Context); + return AL_TRUE; + + case AL_SOURCE_RELATIVE: case AL_LOOPING: case AL_BUFFER: case AL_SOURCE_STATE: case AL_BUFFERS_QUEUED: case AL_BUFFERS_PROCESSED: - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_DOPPLER_FACTOR: - case AL_REFERENCE_DISTANCE: case AL_SOURCE_TYPE: - case AL_DIRECT_FILTER: case AL_DIRECT_FILTER_GAINHF_AUTO: case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + case AL_DIRECT_CHANNELS_SOFT: case AL_DISTANCE_MODEL: - case AL_VIRTUAL_CHANNELS_SOFT: - alGetSourcei(source, eParam, plValues); - return; + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) + *values = (ALdouble)ivals[0]; + return err; + } + + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); +} + +static ALboolean GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values) +{ + ALbufferlistitem *BufferList; + ALdouble dvals[3]; + ALboolean err; + + switch(prop) + { + case AL_SOURCE_RELATIVE: + *values = Source->HeadRelative; + return AL_TRUE; + + case AL_LOOPING: + *values = Source->Looping; + return AL_TRUE; + + case AL_BUFFER: + LockContext(Context); + BufferList = Source->queue; + if(Source->SourceType != AL_STATIC) + { + ALuint i = Source->BuffersPlayed; + while(i > 0) + { + BufferList = BufferList->next; + i--; + } + } + *values = ((BufferList && BufferList->buffer) ? + BufferList->buffer->id : 0); + UnlockContext(Context); + return AL_TRUE; + + case AL_SOURCE_STATE: + *values = Source->state; + return AL_TRUE; + + case AL_BUFFERS_QUEUED: + *values = Source->BuffersInQueue; + return AL_TRUE; + + case AL_BUFFERS_PROCESSED: + LockContext(Context); + if(Source->Looping || Source->SourceType != AL_STREAMING) + { + /* Buffers on a looping source are in a perpetual state of + * PENDING, so don't report any as PROCESSED */ + *values = 0; + } + else + *values = Source->BuffersPlayed; + UnlockContext(Context); + return AL_TRUE; + + case AL_SOURCE_TYPE: + *values = Source->SourceType; + return AL_TRUE; + + case AL_DIRECT_FILTER_GAINHF_AUTO: + *values = Source->DryGainHFAuto; + return AL_TRUE; + + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + *values = Source->WetGainAuto; + return AL_TRUE; + + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + *values = Source->WetGainHFAuto; + return AL_TRUE; + + case AL_DIRECT_CHANNELS_SOFT: + *values = Source->DirectChannels; + return AL_TRUE; + + case AL_DISTANCE_MODEL: + *values = Source->DistanceModel; + return AL_TRUE; + + case AL_MAX_DISTANCE: + case AL_ROLLOFF_FACTOR: + case AL_REFERENCE_DISTANCE: + case AL_CONE_INNER_ANGLE: + case AL_CONE_OUTER_ANGLE: + case AL_SEC_OFFSET: + case AL_SAMPLE_OFFSET: + case AL_BYTE_OFFSET: + case AL_DOPPLER_FACTOR: + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) + *values = (ALint)dvals[0]; + return err; + + case AL_SAMPLE_RW_OFFSETS_SOFT: + case AL_BYTE_RW_OFFSETS_SOFT: + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) + { + values[0] = (ALint)dvals[0]; + values[1] = (ALint)dvals[1]; + } + return err; case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: - alGetSource3i(source, eParam, plValues+0, plValues+1, plValues+2); - return; - } - - pContext = GetContextRef(); - if(!pContext) return; - - if(plValues) - { - if((Source=LookupSource(pContext, source)) != NULL) - { - switch(eParam) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) { - case AL_SAMPLE_RW_OFFSETS_SOFT: - case AL_BYTE_RW_OFFSETS_SOFT: - LockContext(pContext); - updateLen = (ALdouble)pContext->Device->UpdateSize / - pContext->Device->Frequency; - GetSourceOffset(Source, eParam, Offsets, updateLen); - UnlockContext(pContext); - plValues[0] = (ALint)Offsets[0]; - plValues[1] = (ALint)Offsets[1]; - break; - - default: - alSetError(pContext, AL_INVALID_ENUM); - break; + values[0] = (ALint)dvals[0]; + values[1] = (ALint)dvals[1]; + values[2] = (ALint)dvals[2]; } - } - else - alSetError(pContext, AL_INVALID_NAME); - } - else - alSetError(pContext, AL_INVALID_VALUE); + return err; - ALCcontext_DecRef(pContext); + case siSampleOffsetLatencySOFT: + /* i64 only */ + break; + + case siDirectFilter: + case siAuxSendFilter: + /* ??? */ + break; + } + + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); +} + +static ALboolean GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values) +{ + ALdouble dvals[3]; + ALint ivals[3]; + ALboolean err; + + switch(prop) + { + case AL_SAMPLE_OFFSET_LATENCY_SOFT: + LockContext(Context); + values[0] = GetSourceOffset(Source); + values[1] = ALCdevice_GetLatency(Context->Device); + UnlockContext(Context); + return AL_TRUE; + + case AL_MAX_DISTANCE: + case AL_ROLLOFF_FACTOR: + case AL_REFERENCE_DISTANCE: + case AL_CONE_INNER_ANGLE: + case AL_CONE_OUTER_ANGLE: + case AL_SEC_OFFSET: + case AL_SAMPLE_OFFSET: + case AL_BYTE_OFFSET: + case AL_DOPPLER_FACTOR: + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) + *values = (ALint64)dvals[0]; + return err; + + case AL_SAMPLE_RW_OFFSETS_SOFT: + case AL_BYTE_RW_OFFSETS_SOFT: + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) + { + values[0] = (ALint64)dvals[0]; + values[1] = (ALint64)dvals[1]; + } + return err; + + case AL_POSITION: + case AL_VELOCITY: + case AL_DIRECTION: + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) + { + values[0] = (ALint64)dvals[0]; + values[1] = (ALint64)dvals[1]; + values[2] = (ALint64)dvals[2]; + } + return err; + + case AL_SOURCE_RELATIVE: + case AL_LOOPING: + case AL_SOURCE_STATE: + case AL_BUFFERS_QUEUED: + case AL_BUFFERS_PROCESSED: + case AL_SOURCE_TYPE: + case AL_DIRECT_FILTER_GAINHF_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + case AL_DIRECT_CHANNELS_SOFT: + case AL_DISTANCE_MODEL: + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) + *values = ivals[0]; + return err; + + case siBuffer: + case siDirectFilter: + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) + *values = ((ALuint*)ivals)[0]; + return err; + + case siAuxSendFilter: + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) + { + values[0] = ((ALuint*)ivals)[0]; + values[1] = ((ALuint*)ivals)[1]; + values[2] = ((ALuint*)ivals)[2]; + } + return err; + } + + ERR("Unexpected property: 0x%04x\n", prop); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); +} + + +AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) +{ + ALCcontext *context; + ALsizei cur = 0; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(cur = 0;cur < n;cur++) + { + ALsource *source = al_calloc(16, sizeof(ALsource)); + if(!source) + { + alDeleteSources(cur, sources); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + InitSourceParams(source); + + err = NewThunkEntry(&source->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&context->SourceMap, source->id, source); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(source->id); + memset(source, 0, sizeof(ALsource)); + al_free(source); + + alDeleteSources(cur, sources); + SET_ERROR_AND_GOTO(context, err, done); + } + + sources[cur] = source->id; + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) +{ + ALCcontext *context; + ALbufferlistitem *BufferList; + ALsource *Source; + ALsizei i, j; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + /* Check that all Sources are valid */ + for(i = 0;i < n;i++) + { + if(LookupSource(context, sources[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + ALsource **srclist, **srclistend; + + if((Source=RemoveSource(context, sources[i])) == NULL) + continue; + FreeThunkEntry(Source->id); + + LockContext(context); + srclist = context->ActiveSources; + srclistend = srclist + context->ActiveSourceCount; + while(srclist != srclistend) + { + if(*srclist == Source) + { + context->ActiveSourceCount--; + *srclist = *(--srclistend); + break; + } + srclist++; + } + UnlockContext(context); + + while(Source->queue != NULL) + { + BufferList = Source->queue; + Source->queue = BufferList->next; + + if(BufferList->buffer != NULL) + DecrementRef(&BufferList->buffer->ref); + free(BufferList); + } + + for(j = 0;j < MAX_SENDS;++j) + { + if(Source->Send[j].Slot) + DecrementRef(&Source->Send[j].Slot->ref); + Source->Send[j].Slot = NULL; + } + + memset(Source, 0, sizeof(*Source)); + al_free(Source); + } + +done: + ALCcontext_DecRef(context); +} + + +AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = (LookupSource(context, source) ? AL_TRUE : AL_FALSE); + + ALCcontext_DecRef(context); + + return ret; +} + + +AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(FloatValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourcefv(Source, Context, param, &value); + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(FloatValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALfloat fvals[3] = { value1, value2, value3 }; + SetSourcefv(Source, Context, param, fvals); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(FloatValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourcefv(Source, Context, param, values); + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(DoubleValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALfloat fval = (ALfloat)value; + SetSourcefv(Source, Context, param, &fval); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(DoubleValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALfloat fvals[3] = { (ALfloat)value1, (ALfloat)value2, (ALfloat)value3 }; + SetSourcefv(Source, Context, param, fvals); + } + + ALCcontext_DecRef(Context); +} + +AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values) +{ + ALCcontext *Context; + ALsource *Source; + ALint count; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!((count=DoubleValsByProp(param)) > 0 && count <= 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALfloat fvals[3]; + ALint i; + + for(i = 0;i < count;i++) + fvals[i] = (ALfloat)values[i]; + SetSourcefv(Source, Context, param, fvals); + } + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(IntValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourceiv(Source, Context, param, &value); + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(IntValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALint ivals[3] = { value1, value2, value3 }; + SetSourceiv(Source, Context, param, ivals); + } + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(IntValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourceiv(Source, Context, param, values); + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(Int64ValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourcei64v(Source, Context, param, &value); + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(Int64ValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALint64SOFT i64vals[3] = { value1, value2, value3 }; + SetSourcei64v(Source, Context, param, i64vals); + } + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(Int64ValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + SetSourcei64v(Source, Context, param, values); + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!value) + alSetError(Context, AL_INVALID_VALUE); + else if(!(FloatValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALdouble dval; + if(GetSourcedv(Source, Context, param, &dval)) + *value = (ALfloat)dval; + } + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(value1 && value2 && value3)) + alSetError(Context, AL_INVALID_VALUE); + else if(!(FloatValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALdouble dvals[3]; + if(GetSourcedv(Source, Context, param, dvals)) + { + *value1 = (ALfloat)dvals[0]; + *value2 = (ALfloat)dvals[1]; + *value3 = (ALfloat)dvals[2]; + } + } + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values) +{ + ALCcontext *Context; + ALsource *Source; + ALint count; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!((count=FloatValsByProp(param)) > 0 && count <= 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALdouble dvals[3]; + if(GetSourcedv(Source, Context, param, dvals)) + { + ALint i; + for(i = 0;i < count;i++) + values[i] = (ALfloat)dvals[i]; + } + } + + ALCcontext_DecRef(Context); +} + + +AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!value) + alSetError(Context, AL_INVALID_VALUE); + else if(!(DoubleValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourcedv(Source, Context, param, value); + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(value1 && value2 && value3)) + alSetError(Context, AL_INVALID_VALUE); + else if(!(DoubleValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALdouble dvals[3]; + if(GetSourcedv(Source, Context, param, dvals)) + { + *value1 = dvals[0]; + *value2 = dvals[1]; + *value3 = dvals[2]; + } + } + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(DoubleValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourcedv(Source, Context, param, values); + + ALCcontext_DecRef(Context); +} + + +AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!value) + alSetError(Context, AL_INVALID_VALUE); + else if(!(IntValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourceiv(Source, Context, param, value); + + ALCcontext_DecRef(Context); +} + + +AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(value1 && value2 && value3)) + alSetError(Context, AL_INVALID_VALUE); + else if(!(IntValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALint ivals[3]; + if(GetSourceiv(Source, Context, param, ivals)) + { + *value1 = ivals[0]; + *value2 = ivals[1]; + *value3 = ivals[2]; + } + } + + ALCcontext_DecRef(Context); +} + + +AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(IntValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourceiv(Source, Context, param, values); + + ALCcontext_DecRef(Context); +} + + +AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!value) + alSetError(Context, AL_INVALID_VALUE); + else if(!(Int64ValsByProp(param) == 1)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourcei64v(Source, Context, param, value); + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!(value1 && value2 && value3)) + alSetError(Context, AL_INVALID_VALUE); + else if(!(Int64ValsByProp(param) == 3)) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALint64 i64vals[3]; + if(GetSourcei64v(Source, Context, param, i64vals)) + { + *value1 = i64vals[0]; + *value2 = i64vals[1]; + *value3 = i64vals[2]; + } + } + + ALCcontext_DecRef(Context); +} + +AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values) +{ + ALCcontext *Context; + ALsource *Source; + + Context = GetContextRef(); + if(!Context) return; + + if((Source=LookupSource(Context, source)) == NULL) + alSetError(Context, AL_INVALID_NAME); + else if(!values) + alSetError(Context, AL_INVALID_VALUE); + else if(!(Int64ValsByProp(param) > 0)) + alSetError(Context, AL_INVALID_ENUM); + else + GetSourcei64v(Source, Context, param, values); + + ALCcontext_DecRef(Context); } @@ -1367,262 +1883,191 @@ AL_API ALvoid AL_APIENTRY alSourcePlay(ALuint source) { alSourcePlayv(1, &source); } - AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - if(n > 0 && !sources) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - - // Check that all the Sources are valid + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) { - if(!LookupSource(Context, sources[i])) - { - alSetError(Context, AL_INVALID_NAME); - goto done; - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } - LockContext(Context); - while(Context->MaxActiveSources-Context->ActiveSourceCount < n) + LockContext(context); + while(n > context->MaxActiveSources-context->ActiveSourceCount) { void *temp = NULL; ALsizei newcount; - newcount = Context->MaxActiveSources << 1; + newcount = context->MaxActiveSources << 1; if(newcount > 0) - temp = realloc(Context->ActiveSources, - sizeof(*Context->ActiveSources) * newcount); + temp = realloc(context->ActiveSources, + sizeof(*context->ActiveSources) * newcount); if(!temp) { - UnlockContext(Context); - alSetError(Context, AL_OUT_OF_MEMORY); - goto done; + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } - Context->ActiveSources = temp; - Context->MaxActiveSources = newcount; + context->ActiveSources = temp; + context->MaxActiveSources = newcount; } for(i = 0;i < n;i++) { - Source = LookupSource(Context, sources[i]); - if(Context->DeferUpdates) Source->new_state = AL_PLAYING; - else SetSourceState(Source, Context, AL_PLAYING); + source = LookupSource(context, sources[i]); + if(context->DeferUpdates) source->new_state = AL_PLAYING; + else SetSourceState(source, context, AL_PLAYING); } - UnlockContext(Context); + UnlockContext(context); done: - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source) { alSourcePausev(1, &source); } - AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; + ALCcontext *context; + ALsource *source; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - if(n > 0 && !sources) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - - // Check all the Sources are valid + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) { - if(!LookupSource(Context, sources[i])) - { - alSetError(Context, AL_INVALID_NAME); - goto done; - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } - LockContext(Context); + LockContext(context); for(i = 0;i < n;i++) { - Source = LookupSource(Context, sources[i]); - if(Context->DeferUpdates) Source->new_state = AL_PAUSED; - else SetSourceState(Source, Context, AL_PAUSED); + source = LookupSource(context, sources[i]); + if(context->DeferUpdates) source->new_state = AL_PAUSED; + else SetSourceState(source, context, AL_PAUSED); } - UnlockContext(Context); + UnlockContext(context); done: - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source) { alSourceStopv(1, &source); } - AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; + ALCcontext *context; + ALsource *source; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - if(n > 0 && !sources) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - - // Check all the Sources are valid + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) { - if(!LookupSource(Context, sources[i])) - { - alSetError(Context, AL_INVALID_NAME); - goto done; - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } - LockContext(Context); + LockContext(context); for(i = 0;i < n;i++) { - Source = LookupSource(Context, sources[i]); - Source->new_state = AL_NONE; - SetSourceState(Source, Context, AL_STOPPED); + source = LookupSource(context, sources[i]); + source->new_state = AL_NONE; + SetSourceState(source, context, AL_STOPPED); } - UnlockContext(Context); + UnlockContext(context); done: - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source) { alSourceRewindv(1, &source); } - AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; + ALCcontext *context; + ALsource *source; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - if(n > 0 && !sources) - { - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - - // Check all the Sources are valid + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) { - if(!LookupSource(Context, sources[i])) - { - alSetError(Context, AL_INVALID_NAME); - goto done; - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } - LockContext(Context); + LockContext(context); for(i = 0;i < n;i++) { - Source = LookupSource(Context, sources[i]); - Source->new_state = AL_NONE; - SetSourceState(Source, Context, AL_INITIAL); + source = LookupSource(context, sources[i]); + source->new_state = AL_NONE; + SetSourceState(source, context, AL_INITIAL); } - UnlockContext(Context); + UnlockContext(context); done: - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei n, const ALuint *buffers) +AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALuint *buffers) { - ALCcontext *Context; ALCdevice *device; - ALsource *Source; + ALCcontext *context; + ALsource *source; ALsizei i; ALbufferlistitem *BufferListStart = NULL; ALbufferlistitem *BufferList; - ALbuffer *BufferFmt; + ALbuffer *BufferFmt = NULL; - if(n == 0) + if(nb == 0) return; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) + device = context->Device; + + if(!(nb >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if((source=LookupSource(context, src)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + LockContext(context); + if(source->SourceType == AL_STATIC) { - alSetError(Context, AL_INVALID_VALUE); - goto error; + UnlockContext(context); + /* Can't queue on a Static Source */ + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } - // Check that all buffers are valid or zero and that the source is valid - - // Check that this is a valid source - if((Source=LookupSource(Context, source)) == NULL) - { - alSetError(Context, AL_INVALID_NAME); - goto error; - } - - LockContext(Context); - // Check that this is not a STATIC Source - if(Source->lSourceType == AL_STATIC) - { - UnlockContext(Context); - // Invalid Source Type (can't queue on a Static Source) - alSetError(Context, AL_INVALID_OPERATION); - goto error; - } - - device = Context->Device; - - BufferFmt = NULL; - - // Check existing Queue (if any) for a valid Buffers and get its frequency and format - BufferList = Source->queue; + /* Check for a valid Buffer, for its frequency and format */ + BufferList = source->queue; while(BufferList) { if(BufferList->buffer) @@ -1633,14 +2078,13 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei n, const A BufferList = BufferList->next; } - for(i = 0;i < n;i++) + for(i = 0;i < nb;i++) { ALbuffer *buffer = NULL; if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) { - UnlockContext(Context); - alSetError(Context, AL_INVALID_NAME); - goto error; + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } if(!BufferListStart) @@ -1660,59 +2104,55 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei n, const A BufferList = BufferList->next; } if(!buffer) continue; - - // Increment reference counter for buffer IncrementRef(&buffer->ref); + ReadLock(&buffer->lock); if(BufferFmt == NULL) { BufferFmt = buffer; - Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - Source->SampleSize = BytesFromFmt(buffer->FmtType); + source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); + source->SampleSize = BytesFromFmt(buffer->FmtType); if(buffer->FmtChannels == FmtMono) - Source->Update = CalcSourceParams; + source->Update = CalcSourceParams; else - Source->Update = CalcNonAttnSourceParams; + source->Update = CalcNonAttnSourceParams; - Source->NeedsUpdate = AL_TRUE; + source->NeedsUpdate = AL_TRUE; } else if(BufferFmt->Frequency != buffer->Frequency || BufferFmt->OriginalChannels != buffer->OriginalChannels || BufferFmt->OriginalType != buffer->OriginalType) { ReadUnlock(&buffer->lock); - UnlockContext(Context); - alSetError(Context, AL_INVALID_OPERATION); - goto error; + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } ReadUnlock(&buffer->lock); } - // Change Source Type - Source->lSourceType = AL_STREAMING; + /* Source is now streaming */ + source->SourceType = AL_STREAMING; - if(Source->queue == NULL) - Source->queue = BufferListStart; + if(source->queue == NULL) + source->queue = BufferListStart; else { - // Find end of queue - BufferList = Source->queue; + /* Append to the end of the queue */ + BufferList = source->queue; while(BufferList->next != NULL) BufferList = BufferList->next; BufferListStart->prev = BufferList; BufferList->next = BufferListStart; } + BufferListStart = NULL; - // Update number of buffers in queue - Source->BuffersInQueue += n; + source->BuffersInQueue += nb; - UnlockContext(Context); - ALCcontext_DecRef(Context); - return; + UnlockContext(context); -error: +done: while(BufferListStart) { BufferList = BufferListStart; @@ -1722,73 +2162,61 @@ error: DecrementRef(&BufferList->buffer->ref); free(BufferList); } - ALCcontext_DecRef(Context); + + ALCcontext_DecRef(context); } - -// Implementation assumes that n is the number of buffers to be removed from the queue and buffers is -// an array of buffer IDs that are to be filled with the names of the buffers removed -AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers( ALuint source, ALsizei n, ALuint* buffers ) +AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint *buffers) { - ALCcontext *Context; - ALsource *Source; + ALCcontext *context; + ALsource *source; ALsizei i; ALbufferlistitem *BufferList; - if(n == 0) + if(nb == 0) return; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(n < 0) + if(!(nb >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + if((source=LookupSource(context, src)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + LockContext(context); + if(source->Looping || source->SourceType != AL_STREAMING || + (ALuint)nb > source->BuffersPlayed) { - alSetError(Context, AL_INVALID_VALUE); - goto done; + UnlockContext(context); + /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - if((Source=LookupSource(Context, source)) == NULL) + for(i = 0;i < nb;i++) { - alSetError(Context, AL_INVALID_NAME); - goto done; - } - - LockContext(Context); - if(Source->bLooping || Source->lSourceType != AL_STREAMING || - (ALuint)n > Source->BuffersPlayed) - { - UnlockContext(Context); - // Some buffers can't be unqueue because they have not been processed - alSetError(Context, AL_INVALID_VALUE); - goto done; - } - - for(i = 0;i < n;i++) - { - BufferList = Source->queue; - Source->queue = BufferList->next; - Source->BuffersInQueue--; - Source->BuffersPlayed--; + BufferList = source->queue; + source->queue = BufferList->next; + source->BuffersInQueue--; + source->BuffersPlayed--; if(BufferList->buffer) { - // Record name of buffer - buffers[i] = BufferList->buffer->buffer; - // Decrement buffer reference counter + buffers[i] = BufferList->buffer->id; DecrementRef(&BufferList->buffer->ref); } else buffers[i] = 0; - // Release memory for buffer list item free(BufferList); } - if(Source->queue) - Source->queue->prev = NULL; - UnlockContext(Context); + if(source->queue) + source->queue->prev = NULL; + UnlockContext(context); done: - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } @@ -1796,26 +2224,26 @@ static ALvoid InitSourceParams(ALsource *Source) { ALuint i; - Source->flInnerAngle = 360.0f; - Source->flOuterAngle = 360.0f; - Source->flPitch = 1.0f; - Source->vPosition[0] = 0.0f; - Source->vPosition[1] = 0.0f; - Source->vPosition[2] = 0.0f; - Source->vOrientation[0] = 0.0f; - Source->vOrientation[1] = 0.0f; - Source->vOrientation[2] = 0.0f; - Source->vVelocity[0] = 0.0f; - Source->vVelocity[1] = 0.0f; - Source->vVelocity[2] = 0.0f; - Source->flRefDistance = 1.0f; - Source->flMaxDistance = FLT_MAX; - Source->flRollOffFactor = 1.0f; - Source->bLooping = AL_FALSE; - Source->flGain = 1.0f; - Source->flMinGain = 0.0f; - Source->flMaxGain = 1.0f; - Source->flOuterGain = 0.0f; + Source->InnerAngle = 360.0f; + Source->OuterAngle = 360.0f; + Source->Pitch = 1.0f; + Source->Position[0] = 0.0f; + Source->Position[1] = 0.0f; + Source->Position[2] = 0.0f; + Source->Orientation[0] = 0.0f; + Source->Orientation[1] = 0.0f; + Source->Orientation[2] = 0.0f; + Source->Velocity[0] = 0.0f; + Source->Velocity[1] = 0.0f; + Source->Velocity[2] = 0.0f; + Source->RefDistance = 1.0f; + Source->MaxDistance = FLT_MAX; + Source->RollOffFactor = 1.0f; + Source->Looping = AL_FALSE; + Source->Gain = 1.0f; + Source->MinGain = 0.0f; + Source->MaxGain = 1.0f; + Source->OuterGain = 0.0f; Source->OuterGainHF = 1.0f; Source->DryGainHFAuto = AL_TRUE; @@ -1824,36 +2252,35 @@ static ALvoid InitSourceParams(ALsource *Source) Source->AirAbsorptionFactor = 0.0f; Source->RoomRolloffFactor = 0.0f; Source->DopplerFactor = 1.0f; - Source->VirtualChannels = AL_TRUE; + Source->DirectChannels = AL_FALSE; - Source->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED; + Source->DistanceModel = DefaultDistanceModel; Source->Resampler = DefaultResampler; Source->state = AL_INITIAL; Source->new_state = AL_NONE; - Source->lSourceType = AL_UNDETERMINED; - Source->lOffset = -1; + Source->SourceType = AL_UNDETERMINED; + Source->Offset = -1.0; Source->DirectGain = 1.0f; Source->DirectGainHF = 1.0f; for(i = 0;i < MAX_SENDS;i++) { - Source->Send[i].WetGain = 1.0f; - Source->Send[i].WetGainHF = 1.0f; + Source->Send[i].Gain = 1.0f; + Source->Send[i].GainHF = 1.0f; } Source->NeedsUpdate = AL_TRUE; - Source->HrtfMoving = AL_FALSE; - Source->HrtfCounter = 0; + Source->Hrtf.Moving = AL_FALSE; + Source->Hrtf.Counter = 0; } -/* - * SetSourceState +/* SetSourceState * - * Sets the source's new play state given its current state + * Sets the source's new play state given its current state. */ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { @@ -1862,7 +2289,8 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) ALbufferlistitem *BufferList; ALsizei j, k; - /* Check that there is a queue containing at least one non-null, non zero length AL Buffer */ + /* Check that there is a queue containing at least one valid, non zero + * length Buffer. */ BufferList = Source->queue; while(BufferList) { @@ -1873,14 +2301,14 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_PLAYING) { - for(j = 0;j < MAXCHANNELS;j++) + for(j = 0;j < MAX_INPUT_CHANNELS;j++) { for(k = 0;k < SRC_HISTORY_LENGTH;k++) - Source->HrtfHistory[j][k] = 0.0f; + Source->Hrtf.History[j][k] = 0.0f; for(k = 0;k < HRIR_LENGTH;k++) { - Source->HrtfValues[j][k][0] = 0.0f; - Source->HrtfValues[j][k][1] = 0.0f; + Source->Hrtf.Values[j][k][0] = 0.0f; + Source->Hrtf.Values[j][k][1] = 0.0f; } } } @@ -1896,7 +2324,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) Source->state = AL_PLAYING; // Check if an Offset has been set - if(Source->lOffset != -1) + if(Source->Offset >= 0.0) ApplyOffset(Source); /* If there's nothing to play, or device is disconnected, go right to @@ -1920,8 +2348,8 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state == AL_PLAYING) { Source->state = AL_PAUSED; - Source->HrtfMoving = AL_FALSE; - Source->HrtfCounter = 0; + Source->Hrtf.Moving = AL_FALSE; + Source->Hrtf.Counter = 0; } } else if(state == AL_STOPPED) @@ -1930,10 +2358,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { Source->state = AL_STOPPED; Source->BuffersPlayed = Source->BuffersInQueue; - Source->HrtfMoving = AL_FALSE; - Source->HrtfCounter = 0; + Source->Hrtf.Moving = AL_FALSE; + Source->Hrtf.Counter = 0; } - Source->lOffset = -1; + Source->Offset = -1.0; } else if(state == AL_INITIAL) { @@ -1943,36 +2371,105 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) Source->position = 0; Source->position_fraction = 0; Source->BuffersPlayed = 0; - Source->HrtfMoving = AL_FALSE; - Source->HrtfCounter = 0; + Source->Hrtf.Moving = AL_FALSE; + Source->Hrtf.Counter = 0; } - Source->lOffset = -1; + Source->Offset = -1.0; } } -/* - GetSourceOffset - - Gets the current playback position in the given Source, in the appropriate format (Bytes, Samples or MilliSeconds) - The offset is relative to the start of the queue (not the start of the current buffer) -*/ -static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, ALdouble updateLen) +/* GetSourceOffset + * + * Gets the current read offset for the given Source, in 32.32 fixed-point + * samples. The offset is relative to the start of the queue (not the start of + * the current buffer). + */ +static ALint64 GetSourceOffset(const ALsource *Source) { const ALbufferlistitem *BufferList; - const ALbuffer *Buffer = NULL; - ALuint BufferFreq = 0; - ALuint readPos, writePos; - ALuint totalBufferLen; - ALuint i; + ALuint64 readPos; + ALuint i; + + if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) + return 0; + + /* NOTE: This is the offset into the *current* buffer, so add the length of + * any played buffers */ + readPos = (ALuint64)Source->position << 32; + readPos |= (ALuint64)Source->position_fraction << (32-FRACTIONBITS); + BufferList = Source->queue; + for(i = 0;i < Source->BuffersPlayed && BufferList;i++) + { + if(BufferList->buffer) + readPos += (ALuint64)BufferList->buffer->SampleLen << 32; + BufferList = BufferList->next; + } + + return (ALint64)minu64(readPos, U64(0x7fffffffffffffff)); +} + +/* GetSourceSecOffset + * + * Gets the current read offset for the given Source, in seconds. The offset is + * relative to the start of the queue (not the start of the current buffer). + */ +static ALdouble GetSourceSecOffset(const ALsource *Source) +{ + const ALbufferlistitem *BufferList; + const ALbuffer *Buffer = NULL; + ALuint64 readPos; + ALuint i; - // Find the first non-NULL Buffer in the Queue BufferList = Source->queue; while(BufferList) { if(BufferList->buffer) { Buffer = BufferList->buffer; - BufferFreq = Buffer->Frequency; + break; + } + BufferList = BufferList->next; + } + + if((Source->state != AL_PLAYING && Source->state != AL_PAUSED) || !Buffer) + return 0.0; + + /* NOTE: This is the offset into the *current* buffer, so add the length of + * any played buffers */ + readPos = (ALuint64)Source->position << FRACTIONBITS; + readPos |= (ALuint64)Source->position_fraction; + BufferList = Source->queue; + for(i = 0;i < Source->BuffersPlayed && BufferList;i++) + { + if(BufferList->buffer) + readPos += (ALuint64)BufferList->buffer->SampleLen << FRACTIONBITS; + BufferList = BufferList->next; + } + + return (ALdouble)readPos / (ALdouble)FRACTIONONE / (ALdouble)Buffer->Frequency; +} + +/* GetSourceOffsets + * + * Gets the current read and write offsets for the given Source, in the + * appropriate format (Bytes, Samples or Seconds). The offsets are relative to + * the start of the queue (not the start of the current buffer). + */ +static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offset, ALdouble updateLen) +{ + const ALbufferlistitem *BufferList; + const ALbuffer *Buffer = NULL; + ALuint readPos, writePos; + ALuint totalBufferLen; + ALuint i; + + // Find the first valid Buffer in the Queue + BufferList = Source->queue; + while(BufferList) + { + if(BufferList->buffer) + { + Buffer = BufferList->buffer; break; } BufferList = BufferList->next; @@ -1985,9 +2482,12 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A return; } - // Get Current SamplesPlayed (NOTE : This is the offset into the *current* buffer) + if(updateLen > 0.0 && updateLen < 0.015) + updateLen = 0.015; + + /* NOTE: This is the offset into the *current* buffer, so add the length of + * any played buffers */ readPos = Source->position; - // Add length of any processed buffers in the queue totalBufferLen = 0; BufferList = Source->queue; for(i = 0;BufferList;i++) @@ -2001,18 +2501,18 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A BufferList = BufferList->next; } if(Source->state == AL_PLAYING) - writePos = readPos + (ALuint)(updateLen*BufferFreq); + writePos = readPos + (ALuint)(updateLen*Buffer->Frequency); else writePos = readPos; - if(Source->bLooping) + if(Source->Looping) { readPos %= totalBufferLen; writePos %= totalBufferLen; } else { - // Wrap positions back to 0 + /* Wrap positions back to 0 */ if(readPos >= totalBufferLen) readPos = 0; if(writePos >= totalBufferLen) @@ -2025,26 +2525,27 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A offset[0] = (ALdouble)readPos / Buffer->Frequency; offset[1] = (ALdouble)writePos / Buffer->Frequency; break; + case AL_SAMPLE_OFFSET: case AL_SAMPLE_RW_OFFSETS_SOFT: offset[0] = (ALdouble)readPos; offset[1] = (ALdouble)writePos; break; + case AL_BYTE_OFFSET: case AL_BYTE_RW_OFFSETS_SOFT: - // Take into account the original format of the Buffer if(Buffer->OriginalType == UserFmtIMA4) { ALuint BlockSize = 36 * ChannelsFromFmt(Buffer->FmtChannels); ALuint FrameBlockSize = 65; - // Round down to nearest ADPCM block + /* Round down to nearest ADPCM block */ offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize); if(Source->state != AL_PLAYING) offset[1] = offset[0]; else { - // Round up to nearest ADPCM block + /* Round up to nearest ADPCM block */ offset[1] = (ALdouble)((writePos+FrameBlockSize-1) / FrameBlockSize * BlockSize); } @@ -2060,12 +2561,11 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A } -/* - ApplyOffset - - Apply a playback offset to the Source. This function will update the queue (to correctly - mark buffers as 'pending' or 'processed' depending upon the new offset. -*/ +/* ApplyOffset + * + * Apply the stored playback offset to the Source. This function will update + * the number of buffers "played" given the stored offset. + */ ALboolean ApplyOffset(ALsource *Source) { const ALbufferlistitem *BufferList; @@ -2074,18 +2574,15 @@ ALboolean ApplyOffset(ALsource *Source) ALint buffersPlayed; ALint offset; - // Get true byte offset + /* Get sample frame offset */ offset = GetSampleOffset(Source); - - // If the offset is invalid, don't apply it if(offset == -1) return AL_FALSE; - // Sort out the queue (pending and processed states) - BufferList = Source->queue; - totalBufferLen = 0; buffersPlayed = 0; + totalBufferLen = 0; + BufferList = Source->queue; while(BufferList) { Buffer = BufferList->buffer; @@ -2093,44 +2590,42 @@ ALboolean ApplyOffset(ALsource *Source) if(bufferLen <= offset-totalBufferLen) { - // Offset is past this buffer so increment BuffersPlayed + /* Offset is past this buffer so increment to the next buffer */ buffersPlayed++; } else if(totalBufferLen <= offset) { - // Offset is within this buffer + /* Offset is in this buffer */ Source->BuffersPlayed = buffersPlayed; - // SW Mixer Positions are in Samples Source->position = offset - totalBufferLen; + Source->position_fraction = 0; return AL_TRUE; } - // Increment the TotalBufferSize totalBufferLen += bufferLen; - // Move on to next buffer in the Queue BufferList = BufferList->next; } - // Offset is out of range of the buffer queue + + /* Offset is out of range of the queue */ return AL_FALSE; } -/* - GetSampleOffset - - Returns the sample offset into the Source's queue (from the Sample, Byte or Millisecond offset - supplied by the application). This takes into account the fact that the buffer format may have - been modifed by AL -*/ +/* GetSampleOffset + * + * Returns the sample offset into the Source's queue (from the Sample, Byte or + * Second offset supplied by the application). This takes into account the fact + * that the buffer format may have been modifed since. + */ static ALint GetSampleOffset(ALsource *Source) { const ALbuffer *Buffer = NULL; const ALbufferlistitem *BufferList; ALint Offset = -1; - // Find the first non-NULL Buffer in the Queue + /* Find the first valid Buffer in the Queue */ BufferList = Source->queue; while(BufferList) { @@ -2144,21 +2639,18 @@ static ALint GetSampleOffset(ALsource *Source) if(!Buffer) { - Source->lOffset = -1; + Source->Offset = -1.0; return -1; } - // Determine the ByteOffset (and ensure it is block aligned) - switch(Source->lOffsetType) + switch(Source->OffsetType) { case AL_BYTE_OFFSET: - // Take into consideration the original format - Offset = Source->lOffset; + /* Determine the ByteOffset (and ensure it is block aligned) */ + Offset = (ALint)Source->Offset; if(Buffer->OriginalType == UserFmtIMA4) { - // Round down to nearest ADPCM block Offset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels); - // Multiply by compression rate (65 sample frames per block) Offset *= 65; } else @@ -2166,21 +2658,23 @@ static ALint GetSampleOffset(ALsource *Source) break; case AL_SAMPLE_OFFSET: - Offset = Source->lOffset; + Offset = (ALint)Source->Offset; break; case AL_SEC_OFFSET: - // Note - lOffset is internally stored as Milliseconds - Offset = (ALint)(Source->lOffset / 1000.0 * Buffer->Frequency); + Offset = (ALint)(Source->Offset * Buffer->Frequency); break; } - // Clear Offset - Source->lOffset = -1; + Source->Offset = -1.0; return Offset; } +/* ReleaseALSources + * + * Destroys all sources in the source map. + */ ALvoid ReleaseALSources(ALCcontext *Context) { ALsizei pos; @@ -2190,7 +2684,6 @@ ALvoid ReleaseALSources(ALCcontext *Context) ALsource *temp = Context->SourceMap.array[pos].value; Context->SourceMap.array[pos].value = NULL; - // For each buffer in the source's queue, decrement its reference counter and remove it while(temp->queue != NULL) { ALbufferlistitem *BufferList = temp->queue; @@ -2208,9 +2701,8 @@ ALvoid ReleaseALSources(ALCcontext *Context) temp->Send[j].Slot = NULL; } - // Release source structure - FreeThunkEntry(temp->source); - memset(temp, 0, sizeof(ALsource)); - free(temp); + FreeThunkEntry(temp->id); + memset(temp, 0, sizeof(*temp)); + al_free(temp); } } diff --git a/jni/openal-soft-android/OpenAL32/alState.c b/jni/openal-soft-android/OpenAL32/alState.c index c50df9e6..280dd896 100644 --- a/jni/openal-soft-android/OpenAL32/alState.c +++ b/jni/openal-soft-android/OpenAL32/alState.c @@ -23,11 +23,15 @@ #include #include "alMain.h" #include "AL/alc.h" +#include "AL/al.h" #include "AL/alext.h" #include "alError.h" #include "alSource.h" #include "alAuxEffectSlot.h" -#include "alState.h" +#include "alMidi.h" + +#include "midi/base.h" + static const ALchar alVendor[] = "OpenAL Community"; static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION; @@ -43,280 +47,336 @@ static const ALchar alErrOutOfMemory[] = "Out of Memory"; AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; switch(capability) { - case AL_SOURCE_DISTANCE_MODEL: - Context->SourceDistanceModel = AL_TRUE; - Context->UpdateSources = AL_TRUE; - break; + case AL_SOURCE_DISTANCE_MODEL: + context->SourceDistanceModel = AL_TRUE; + context->UpdateSources = AL_TRUE; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; switch(capability) { - case AL_SOURCE_DISTANCE_MODEL: - Context->SourceDistanceModel = AL_FALSE; - Context->UpdateSources = AL_TRUE; - break; + case AL_SOURCE_DISTANCE_MODEL: + context->SourceDistanceModel = AL_FALSE; + context->UpdateSources = AL_TRUE; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; ALboolean value=AL_FALSE; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; switch(capability) { - case AL_SOURCE_DISTANCE_MODEL: - value = Context->SourceDistanceModel; - break; + case AL_SOURCE_DISTANCE_MODEL: + value = context->SourceDistanceModel; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) { - ALCcontext *Context; + ALCcontext *context; ALboolean value=AL_FALSE; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; switch(pname) { - case AL_DOPPLER_FACTOR: - if(Context->DopplerFactor != 0.0f) - value = AL_TRUE; - break; + case AL_DOPPLER_FACTOR: + if(context->DopplerFactor != 0.0f) + value = AL_TRUE; + break; - case AL_DOPPLER_VELOCITY: - if(Context->DopplerVelocity != 0.0f) - value = AL_TRUE; - break; + case AL_DOPPLER_VELOCITY: + if(context->DopplerVelocity != 0.0f) + value = AL_TRUE; + break; - case AL_DISTANCE_MODEL: - if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) - value = AL_TRUE; - break; + case AL_DISTANCE_MODEL: + if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) + value = AL_TRUE; + break; - case AL_SPEED_OF_SOUND: - if(Context->flSpeedOfSound != 0.0f) - value = AL_TRUE; - break; + case AL_SPEED_OF_SOUND: + if(context->SpeedOfSound != 0.0f) + value = AL_TRUE; + break; - case AL_DEFERRED_UPDATES_SOFT: - value = Context->DeferUpdates; - break; + case AL_DEFERRED_UPDATES_SOFT: + value = context->DeferUpdates; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; ALdouble value = 0.0; - Context = GetContextRef(); - if(!Context) return 0.0; + context = GetContextRef(); + if(!context) return 0.0; switch(pname) { - case AL_DOPPLER_FACTOR: - value = (double)Context->DopplerFactor; - break; + case AL_DOPPLER_FACTOR: + value = (ALdouble)context->DopplerFactor; + break; - case AL_DOPPLER_VELOCITY: - value = (double)Context->DopplerVelocity; - break; + case AL_DOPPLER_VELOCITY: + value = (ALdouble)context->DopplerVelocity; + break; - case AL_DISTANCE_MODEL: - value = (double)Context->DistanceModel; - break; + case AL_DISTANCE_MODEL: + value = (ALdouble)context->DistanceModel; + break; - case AL_SPEED_OF_SOUND: - value = (double)Context->flSpeedOfSound; - break; + case AL_SPEED_OF_SOUND: + value = (ALdouble)context->SpeedOfSound; + break; - case AL_DEFERRED_UPDATES_SOFT: - value = (ALdouble)Context->DeferUpdates; - break; + case AL_DEFERRED_UPDATES_SOFT: + value = (ALdouble)context->DeferUpdates; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_MIDI_GAIN_SOFT: + device = context->Device; + value = (ALdouble)MidiSynth_getGain(device->Synth); + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALdouble)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; ALfloat value = 0.0f; - Context = GetContextRef(); - if(!Context) return 0.0f; + context = GetContextRef(); + if(!context) return 0.0f; switch(pname) { - case AL_DOPPLER_FACTOR: - value = Context->DopplerFactor; - break; + case AL_DOPPLER_FACTOR: + value = context->DopplerFactor; + break; - case AL_DOPPLER_VELOCITY: - value = Context->DopplerVelocity; - break; + case AL_DOPPLER_VELOCITY: + value = context->DopplerVelocity; + break; - case AL_DISTANCE_MODEL: - value = (float)Context->DistanceModel; - break; + case AL_DISTANCE_MODEL: + value = (ALfloat)context->DistanceModel; + break; - case AL_SPEED_OF_SOUND: - value = Context->flSpeedOfSound; - break; + case AL_SPEED_OF_SOUND: + value = context->SpeedOfSound; + break; - case AL_DEFERRED_UPDATES_SOFT: - value = (ALfloat)Context->DeferUpdates; - break; + case AL_DEFERRED_UPDATES_SOFT: + value = (ALfloat)context->DeferUpdates; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_MIDI_GAIN_SOFT: + device = context->Device; + value = MidiSynth_getGain(device->Synth); + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALfloat)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) { - ALCcontext *Context; + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; ALint value = 0; - Context = GetContextRef(); - if(!Context) return 0; + context = GetContextRef(); + if(!context) return 0; switch(pname) { - case AL_DOPPLER_FACTOR: - value = (ALint)Context->DopplerFactor; - break; + case AL_DOPPLER_FACTOR: + value = (ALint)context->DopplerFactor; + break; - case AL_DOPPLER_VELOCITY: - value = (ALint)Context->DopplerVelocity; - break; + case AL_DOPPLER_VELOCITY: + value = (ALint)context->DopplerVelocity; + break; - case AL_DISTANCE_MODEL: - value = (ALint)Context->DistanceModel; - break; + case AL_DISTANCE_MODEL: + value = (ALint)context->DistanceModel; + break; - case AL_SPEED_OF_SOUND: - value = (ALint)Context->flSpeedOfSound; - break; + case AL_SPEED_OF_SOUND: + value = (ALint)context->SpeedOfSound; + break; - case AL_DEFERRED_UPDATES_SOFT: - value = (ALint)Context->DeferUpdates; - break; + case AL_DEFERRED_UPDATES_SOFT: + value = (ALint)context->DeferUpdates; + break; - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = synth->NumSoundfonts; + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } -AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data) +AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) { - ALCcontext *Context; + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALint64SOFT value = 0; - if(data) + context = GetContextRef(); + if(!context) return 0; + + switch(pname) { - switch(pname) - { - case AL_DOPPLER_FACTOR: - case AL_DOPPLER_VELOCITY: - case AL_DISTANCE_MODEL: - case AL_SPEED_OF_SOUND: - case AL_DEFERRED_UPDATES_SOFT: - *data = alGetBoolean(pname); - return; - } + case AL_DOPPLER_FACTOR: + value = (ALint64SOFT)context->DopplerFactor; + break; + + case AL_DOPPLER_VELOCITY: + value = (ALint64SOFT)context->DopplerVelocity; + break; + + case AL_DISTANCE_MODEL: + value = (ALint64SOFT)context->DistanceModel; + break; + + case AL_SPEED_OF_SOUND: + value = (ALint64SOFT)context->SpeedOfSound; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = (ALint64SOFT)context->DeferUpdates; + break; + + case AL_MIDI_CLOCK_SOFT: + device = context->Device; + ALCdevice_Lock(device); + value = MidiSynth_getTime(device->Synth); + ALCdevice_Unlock(device); + break; + + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = (ALint64SOFT)synth->NumSoundfonts; + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALint64SOFT)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - Context = GetContextRef(); - if(!Context) return; +done: + ALCcontext_DecRef(context); - if(data) - { - switch(pname) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - { - // data is a NULL pointer - alSetError(Context, AL_INVALID_VALUE); - } - - ALCcontext_DecRef(Context); + return value; } -AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data) +AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values) { - ALCcontext *Context; + ALCcontext *context; - if(data) + if(values) { switch(pname) { @@ -325,37 +385,31 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: - *data = alGetDouble(pname); + values[0] = alGetBoolean(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(data) + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) { - switch(pname) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - { - // data is a NULL pointer - alSetError(Context, AL_INVALID_VALUE); + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data) +AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values) { - ALCcontext *Context; + ALCcontext *context; - if(data) + if(values) { switch(pname) { @@ -364,37 +418,33 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: - *data = alGetFloat(pname); + case AL_MIDI_GAIN_SOFT: + case AL_MIDI_STATE_SOFT: + values[0] = alGetDouble(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(data) + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) { - switch(pname) - { - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } - else - { - // data is a NULL pointer - alSetError(Context, AL_INVALID_VALUE); + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data) +AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; - if(data) + if(values) { switch(pname) { @@ -403,260 +453,342 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: - *data = alGetInteger(pname); + case AL_MIDI_GAIN_SOFT: + case AL_MIDI_STATE_SOFT: + values[0] = alGetFloat(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(data) + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) +{ + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; + + if(values) { switch(pname) { - default: - alSetError(Context, AL_INVALID_ENUM); - break; + case AL_DOPPLER_FACTOR: + case AL_DOPPLER_VELOCITY: + case AL_DISTANCE_MODEL: + case AL_SPEED_OF_SOUND: + case AL_DEFERRED_UPDATES_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: + case AL_MIDI_STATE_SOFT: + values[0] = alGetInteger(pname); + return; } } - else + + context = GetContextRef(); + if(!context) return; + + switch(pname) { - // data is a NULL pointer - alSetError(Context, AL_INVALID_VALUE); + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = synth->Soundfonts[i]->id; + } + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) +{ + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; + + if(values) + { + switch(pname) + { + case AL_DOPPLER_FACTOR: + case AL_DOPPLER_VELOCITY: + case AL_DISTANCE_MODEL: + case AL_SPEED_OF_SOUND: + case AL_DEFERRED_UPDATES_SOFT: + case AL_MIDI_CLOCK_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: + case AL_MIDI_STATE_SOFT: + values[0] = alGetInteger64SOFT(pname); + return; + } + } + + context = GetContextRef(); + if(!context) return; + + switch(pname) + { + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = (ALint64SOFT)synth->Soundfonts[i]->id; + } + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); } AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname) { - const ALchar *value; - ALCcontext *Context; + const ALchar *value = NULL; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return NULL; + context = GetContextRef(); + if(!context) return NULL; switch(pname) { - case AL_VENDOR: - value=alVendor; - break; + case AL_VENDOR: + value = alVendor; + break; - case AL_VERSION: - value=alVersion; - break; + case AL_VERSION: + value = alVersion; + break; - case AL_RENDERER: - value=alRenderer; - break; + case AL_RENDERER: + value = alRenderer; + break; - case AL_EXTENSIONS: - value=Context->ExtensionList; - break; + case AL_EXTENSIONS: + value = context->ExtensionList; + break; - case AL_NO_ERROR: - value=alNoError; - break; + case AL_NO_ERROR: + value = alNoError; + break; - case AL_INVALID_NAME: - value=alErrInvalidName; - break; + case AL_INVALID_NAME: + value = alErrInvalidName; + break; - case AL_INVALID_ENUM: - value=alErrInvalidEnum; - break; + case AL_INVALID_ENUM: + value = alErrInvalidEnum; + break; - case AL_INVALID_VALUE: - value=alErrInvalidValue; - break; + case AL_INVALID_VALUE: + value = alErrInvalidValue; + break; - case AL_INVALID_OPERATION: - value=alErrInvalidOp; - break; + case AL_INVALID_OPERATION: + value = alErrInvalidOp; + break; - case AL_OUT_OF_MEMORY: - value=alErrOutOfMemory; - break; + case AL_OUT_OF_MEMORY: + value = alErrOutOfMemory; + break; - default: - value=NULL; - alSetError(Context, AL_INVALID_ENUM); - break; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(value >= 0.0f && isfinite(value)) - { - Context->DopplerFactor = value; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ALCcontext_DecRef(Context); + context->DopplerFactor = value; + context->UpdateSources = AL_TRUE; + +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(value > 0.0f && isfinite(value)) - { - Context->DopplerVelocity=value; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ALCcontext_DecRef(Context); + context->DopplerVelocity = value; + context->UpdateSources = AL_TRUE; + +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat flSpeedOfSound) +AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(flSpeedOfSound > 0.0f && isfinite(flSpeedOfSound)) - { - Context->flSpeedOfSound = flSpeedOfSound; - Context->UpdateSources = AL_TRUE; - } - else - alSetError(Context, AL_INVALID_VALUE); + if(!(value > 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ALCcontext_DecRef(Context); + context->SpeedOfSound = value; + context->UpdateSources = AL_TRUE; + +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - switch(value) - { - case AL_NONE: - case AL_INVERSE_DISTANCE: - case AL_INVERSE_DISTANCE_CLAMPED: - case AL_LINEAR_DISTANCE: - case AL_LINEAR_DISTANCE_CLAMPED: - case AL_EXPONENT_DISTANCE: - case AL_EXPONENT_DISTANCE_CLAMPED: - Context->DistanceModel = value; - Context->UpdateSources = AL_TRUE; - break; + if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED || + value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED || + value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED || + value == AL_NONE)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - default: - alSetError(Context, AL_INVALID_VALUE); - break; - } + context->DistanceModel = value; + if(!context->SourceDistanceModel) + context->UpdateSources = AL_TRUE; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(!Context->DeferUpdates) + if(!context->DeferUpdates) { ALboolean UpdateSources; ALsource **src, **src_end; ALeffectslot **slot, **slot_end; - int fpuState; + FPUCtl oldMode; - fpuState = SetMixerFPUMode(); + SetMixerFPUMode(&oldMode); - LockContext(Context); - Context->DeferUpdates = AL_TRUE; + LockContext(context); + context->DeferUpdates = AL_TRUE; /* Make sure all pending updates are performed */ - UpdateSources = ExchangeInt(&Context->UpdateSources, AL_FALSE); + UpdateSources = ExchangeInt(&context->UpdateSources, AL_FALSE); - src = Context->ActiveSources; - src_end = src + Context->ActiveSourceCount; + src = context->ActiveSources; + src_end = src + context->ActiveSourceCount; while(src != src_end) { if((*src)->state != AL_PLAYING) { - Context->ActiveSourceCount--; + context->ActiveSourceCount--; *src = *(--src_end); continue; } if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources) - ALsource_Update(*src, Context); + ALsource_Update(*src, context); src++; } - slot = Context->ActiveEffectSlots; - slot_end = slot + Context->ActiveEffectSlotCount; + slot = context->ActiveEffectSlots; + slot_end = slot + context->ActiveEffectSlotCount; while(slot != slot_end) { if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE)) - ALeffectState_Update((*slot)->EffectState, Context, *slot); + V((*slot)->EffectState,update)(context->Device, *slot); slot++; } - UnlockContext(Context); - RestoreFPUMode(fpuState); + UnlockContext(context); + RestoreFPUMode(&oldMode); } - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(ExchangeInt(&Context->DeferUpdates, AL_FALSE)) + if(ExchangeInt(&context->DeferUpdates, AL_FALSE)) { ALsizei pos; - LockContext(Context); - LockUIntMapRead(&Context->SourceMap); - for(pos = 0;pos < Context->SourceMap.size;pos++) + LockContext(context); + LockUIntMapRead(&context->SourceMap); + for(pos = 0;pos < context->SourceMap.size;pos++) { - ALsource *Source = Context->SourceMap.array[pos].value; + ALsource *Source = context->SourceMap.array[pos].value; ALenum new_state; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - Source->lOffset != -1) + Source->Offset >= 0.0) ApplyOffset(Source); new_state = ExchangeInt(&Source->new_state, AL_NONE); if(new_state) - SetSourceState(Source, Context, new_state); + SetSourceState(Source, context, new_state); } - UnlockUIntMapRead(&Context->SourceMap); - UnlockContext(Context); + UnlockUIntMapRead(&context->SourceMap); + UnlockContext(context); } - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } diff --git a/jni/openal-soft-android/OpenAL32/alThunk.c b/jni/openal-soft-android/OpenAL32/alThunk.c index 7cd83c23..c4b3b92b 100644 --- a/jni/openal-soft-android/OpenAL32/alThunk.c +++ b/jni/openal-soft-android/OpenAL32/alThunk.c @@ -66,7 +66,7 @@ ALenum NewThunkEntry(ALuint *index) if(!NewList) { WriteUnlock(&ThunkLock); - ERR("Realloc failed to increase to %u enties!\n", ThunkArraySize*2); + ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2); return AL_OUT_OF_MEMORY; } memset(&NewList[ThunkArraySize], 0, ThunkArraySize*sizeof(*ThunkArray)); diff --git a/jni/openal-soft-android/OpenAL32/config.h b/jni/openal-soft-android/OpenAL32/config.h deleted file mode 100644 index dc045303..00000000 --- a/jni/openal-soft-android/OpenAL32/config.h +++ /dev/null @@ -1,150 +0,0 @@ -/* API declaration export attribute */ -#define AL_API __attribute__((visibility("protected"))) -#define ALC_API __attribute__((visibility("protected"))) - -/* Define to the library version */ -#define ALSOFT_VERSION "1.13" - -/* Define if we have the ALSA backend */ -/* #undef HAVE_ALSA */ - -/* Define if we have the OSS backend */ -/* #undef HAVE_OSS */ - -/* Define if we have the Solaris backend */ -/* #undef HAVE_SOLARIS */ - -/* Define if we have the SndIO backend */ -/* #undef HAVE_SNDIO */ - -/* Define if we have the MMDevApi backend */ -/* #undef HAVE_MMDEVAPI */ - -/* Define if we have the DSound backend */ -/* #undef HAVE_DSOUND */ - -/* Define if we have the Windows Multimedia backend */ -/* #undef HAVE_WINMM */ - -/* Define if we have the PortAudio backend */ -/* #undef HAVE_PORTAUDIO */ - -/* Define if we have the PulseAudio backend */ -/* #undef HAVE_PULSEAUDIO */ - -/* Define if we have the CoreAudio backend */ -/* #undef HAVE_COREAUDIO */ - -/* Define if we have the OpenSL backend */ -/* #undef HAVE_OPENSL */ - -/* Define if we have the OpenSL 1.1 backend */ -/* #undef HAVE_OPENSL_1_1 */ - -/* Define if we have the Android backend */ -#define HAVE_ANDROID - -/* Define if we want to use the low latency Android backend */ -/* #undef HAVE_ANDROID_LOW_LATENCY */ - -/* Define if we have the Wave Writer backend */ -#define HAVE_WAVE - -/* Define if we have dlfcn.h */ -#define HAVE_DLFCN_H - -/* Define if we have the stat function */ -#define HAVE_STAT - -/* Define if we have the powf function */ -#define HAVE_POWF - -/* Define if we have the sqrtf function */ -#define HAVE_SQRTF - -/* Define if we have the cosf function */ -#define HAVE_COSF - -/* Define if we have the sinf function */ -#define HAVE_SINF - -/* Define if we have the acosf function */ -#define HAVE_ACOSF - -/* Define if we have the asinf function */ -#define HAVE_ASINF - -/* Define if we have the atanf function */ -#define HAVE_ATANF - -/* Define if we have the atan2f function */ -#define HAVE_ATAN2F - -/* Define if we have the fabsf function */ -#define HAVE_FABSF - -/* Define if we have the log10f function */ -#define HAVE_LOG10F - -/* Define if we have the floorf function */ -#define HAVE_FLOORF - -/* Define if we have the strtof function */ -/* #undef HAVE_STRTOF */ - -/* Define if we have stdint.h */ -#define HAVE_STDINT_H - -/* Define if we have the __int64 type */ -/* #undef HAVE___INT64 */ - -/* Define to the size of a long int type */ -#define SIZEOF_LONG 4 - -/* Define to the size of a long long int type */ -#define SIZEOF_LONG_LONG 8 - -/* Define if we have GCC's destructor attribute */ -#define HAVE_GCC_DESTRUCTOR - -/* Define if we have GCC's format attribute */ -#define HAVE_GCC_FORMAT - -/* Define if we have pthread_np.h */ -/* #undef HAVE_PTHREAD_NP_H */ - -/* Define if we have arm_neon.h */ -/* #undef HAVE_ARM_NEON_H */ - -/* Define if we have guiddef.h */ -/* #undef HAVE_GUIDDEF_H */ - -/* Define if we have guiddef.h */ -/* #undef HAVE_INITGUID_H */ - -/* Define if we have ieeefp.h */ -/* #undef HAVE_IEEEFP_H */ - -/* Define if we have float.h */ -#define HAVE_FLOAT_H - -/* Define if we have fpu_control.h */ -/* #undef HAVE_FPU_CONTROL_H */ - -/* Define if we have fenv.h */ -/* #undef HAVE_FENV_H */ - -/* Define if we have fesetround() */ -/* #undef HAVE_FESETROUND */ - -/* Define if we have _controlfp() */ -/* #undef HAVE__CONTROLFP */ - -/* Define if we have pthread_setschedparam() */ -/* #undef HAVE_PTHREAD_SETSCHEDPARAM */ - -/* Define if we have the restrict keyword */ -/* #undef HAVE_RESTRICT */ - -/* Define if we have the __restrict keyword */ -#define HAVE___RESTRICT diff --git a/jni/openal-soft-android/README b/jni/openal-soft-android/README index ed1ac262..ebca8f91 100644 --- a/jni/openal-soft-android/README +++ b/jni/openal-soft-android/README @@ -1,24 +1,3 @@ -Android -======= -https://github.com/AerialX/openal-soft-android - -Build with cmake using a toolchain file made for the Android NDK. -For example, this one works: -https://github.com/AerialX/libbricks/blob/master/cmake/toolchain.android.cmake -Use its NDK_CPU_X86, NDK_CPU_ARM, and NDK_CPU_ARM_V7A/NDK_CPU_ARM_VFPV3 -options as needed to build for the various configurations. - -The OpenSL backend will be built if configured for API Level 9 (2.3) or later, -otherwise the JNI backend will be used. It's recommended that you compile -OpenAL Soft as a shared library (the default) when using the JNI backend. - -You may also try setting ANDROID_LOW_LATENCY to build the untested JNI -backend performance patch. - -Precompiled binaries are offered in the downloads tab of this repo. Not -necessarily up to date or configured to your liking. -https://github.com/AerialX/openal-soft-android/downloads - Source Install ============== diff --git a/jni/openal-soft-android/alsoftrc.sample b/jni/openal-soft-android/alsoftrc.sample index abaa628c..64590357 100644 --- a/jni/openal-soft-android/alsoftrc.sample +++ b/jni/openal-soft-android/alsoftrc.sample @@ -5,35 +5,36 @@ # The system-wide settings can be put in /etc/openal/alsoft.conf and user- # specific override settings in ~/.alsoftrc. # For Windows, these settings should go into %AppData%\alsoft.ini -# The environment variable ALSOFT_CONF can be used to specify another config -# override # Option and block names are case-insenstive. The supplied values are only # hints and may not be honored (though generally it'll try to get as close as # possible). Note: options that are left unset may default to app- or system- # specified values. These are the current available settings: -## format: -# Sets the output format. Can be one of: -# AL_FORMAT_MONO8 (8-bit mono) -# AL_FORMAT_STEREO8 (8-bit stereo) -# AL_FORMAT_QUAD8 (8-bit 4-channel) -# AL_FORMAT_51CHN8 (8-bit 5.1 output) -# AL_FORMAT_61CHN8 (8-bit 6.1 output) -# AL_FORMAT_71CHN8 (8-bit 7.1 output) -# AL_FORMAT_MONO16 (16-bit mono) -# AL_FORMAT_STEREO16 (16-bit stereo) -# AL_FORMAT_QUAD16 (16-bit 4-channel) -# AL_FORMAT_51CHN16 (16-bit 5.1 output) -# AL_FORMAT_61CHN16 (16-bit 6.1 output) -# AL_FORMAT_71CHN16 (16-bit 7.1 output) -# AL_FORMAT_MONO32 (32-bit float mono) -# AL_FORMAT_STEREO32 (32-bit float stereo) -# AL_FORMAT_QUAD32 (32-bit float 4-channel) -# AL_FORMAT_51CHN32 (32-bit float 5.1 output) -# AL_FORMAT_61CHN32 (32-bit float 6.1 output) -# AL_FORMAT_71CHN32 (32-bit float 7.1 output) -#format = AL_FORMAT_STEREO16 +## disable-cpu-exts: +# Disables use of the listed CPU extensions. Certain methods may utilize CPU +# extensions when detected, and this option is useful for preventing those +# extensions from being used. The available extensions are: sse, sse2, neon. +# Specifying 'all' disables use of all extensions. +#disable-cpu-exts = + +## channels: +# Sets the output channel configuration. If left unspecified, one will try to +# be detected from the system, and defaulting to stereo. The available values +# are: mono, stereo, quad, surround51, surround61, surround71 +#channels = stereo + +## sample-type: +# Sets the output sample type. Currently, all mixing is done with 32-bit float +# and converted to the output sample type as needed. Available values are: +# int8 - signed 8-bit int +# uint8 - unsigned 8-bit int +# int16 - signed 16-bit int +# uint16 - unsigned 16-bit int +# int32 - signed 32-bit int +# uint32 - unsigned 32-bit int +# float32 - 32-bit float +#sample-type = float32 ## hrtf: # Enables HRTF filters. These filters provide for better sound spatialization @@ -42,6 +43,18 @@ # Default is disabled since stereo speaker output quality may suffer. #hrtf = false +## hrtf_tables +# Specifies a comma-separated list of files containing HRTF data sets. The +# listed data sets can be used in place of or in addiiton to the the built-in +# set. The format of the files are described in hrtf.txt. The filenames may +# contain these markers, which will be replaced as needed: +# %r - Device sampling rate +# %% - Percent sign (%) +# So if this is set to "kemar-%r-diffuse.mhr", it will try to open +# "kemar-44100-diffuse.mhr" if the device is using 44100hz output, or +# "kemar-48000-diffuse.mhr" if the device is using 48000hz output, etc. +#hrtf_tables = + ## cf_level: # Sets the crossfeed level for stereo output. Valid values are: # 0 - No crossfeed @@ -55,17 +68,25 @@ # stereo modes. #cf_level = 0 +## wide-stereo: +# Specifies that stereo sources are given a width of about 120 degrees on each +# channel, centering on -90 (left) and +90 (right), as opposed to being points +# placed at -30 (left) and +30 (right). This can be useful for surround-sound +# to give stereo sources a more encompassing sound. Note that the sound's +# overall volume will be slightly reduced to account for the extra output. +#wide-stereo = false + ## frequency: # Sets the output frequency. #frequency = 44100 ## resampler: # Selects the resampler used when mixing sources. Valid values are: -# 0 - None (nearest sample, no interpolation) -# 1 - Linear (extrapolates samples using a linear slope between samples) -# 2 - Cubic (extrapolates samples using a Catmull-Rom spline) +# point - nearest sample, no interpolation +# linear - extrapolates samples using a linear slope between samples +# cubic - extrapolates samples using a Catmull-Rom spline # Specifying other values will result in using the default (linear). -#resampler = 1 +#resampler = linear ## rt-prio: # Sets real-time priority for the mixing thread. Not all drivers may use this @@ -78,13 +99,14 @@ ## period_size: # Sets the update period size, in frames. This is the number of frames needed -# for each mixing update. +# for each mixing update. Acceptable values range between 64 and 8192. #period_size = 1024 ## periods: # Sets the number of update periods. Higher values create a larger mix ahead, # which helps protect against skips when the CPU is under load, but increases -# the delay between a sound getting mixed and being heard. +# the delay between a sound getting mixed and being heard. Acceptable values +# range between 2 and 16. #periods = 4 ## sources: @@ -92,16 +114,6 @@ # systems with apps that try to play more sounds than the CPU can handle. #sources = 256 -## stereodup: -# Sets whether to duplicate stereo sounds behind the listener for 4+ channel -# output. This provides a "fuller" playback quality for surround sound output -# modes, although each individual speaker will have a slight reduction in -# volume to compensate for the extra output speakers. True, yes, on, and non-0 -# values will duplicate stereo sources. 0 and anything else will cause stereo -# sounds to only play in front. This only has an effect when a suitable output -# format is used (ie. those that contain side and/or rear speakers). -#stereodup = true - ## drivers: # Sets the backend driver list order, comma-seperated. Unknown backends and # duplicated names are ignored. Unlisted backends won't be considered for use @@ -109,13 +121,13 @@ # followed by all other available backends, while 'oss' will list OSS only). # Backends prepended with - won't be available for use (eg. '-oss,' will allow # all available backends except OSS). An empty list means the default. -#drivers = pulse,alsa,core,oss,solaris,sndio,mmdevapi,dsound,winmm,port,opensl,null,wave +#drivers = pulse,alsa,core,oss,solaris,sndio,qsa,mmdevapi,dsound,winmm,port,opensl,null,wave ## excludefx: # Sets which effects to exclude, preventing apps from using them. This can # help for apps that try to use effects which are too CPU intensive for the -# system to handle. Available effects are: eaxreverb,reverb,echo,modulator, -# dedicated +# system to handle. Available effects are: eaxreverb,reverb,autowah,chorus, +# compressor,distortion,echo,equalizer,flanger,modulator,dedicated #excludefx = ## slots: @@ -144,28 +156,50 @@ # Channel-specific layouts may be specified to override the layout option. The # same speakers as the layout option are available, and the default settings # are shown below. -#layout_STEREO = fl=-90, fr=90 -#layout_QUAD = fl=-45, fr=45, bl=-135, br=135 -#layout_51CHN = fl=-30, fr=30, fc=0, bl=-110, br=110 -#layout_61CHN = fl=-30, fr=30, fc=0, sl=-90, sr=90, bc=180 -#layout_71CHN = fl=-30, fr=30, fc=0, sl=-90, sr=90, bl=-150, br=150 +#layout_stereo = fl=-90, fr=90 +#layout_quad = fl=-45, fr=45, bl=-135, br=135 +#layout_surround51 = fl=-30, fr=30, fc=0, bl=-110, br=110 +#layout_surround61 = fl=-30, fr=30, fc=0, sl=-90, sr=90, bc=180 +#layout_surround71 = fl=-30, fr=30, fc=0, sl=-90, sr=90, bl=-150, br=150 + +## default-reverb: +# A reverb preset that applies by default to all sources on send 0 +# (applications that set their own slots on send 0 will override this). +# Available presets are: None, Generic, PaddedCell, Room, Bathroom, +# Livingroom, Stoneroom, Auditorium, ConcertHall, Cave, Arena, Hangar, +# CarpetedHallway, Hallway, StoneCorridor, Alley, Forest, City, Moutains, +# Quarry, Plain, ParkingLot, SewerPipe, Underwater, Drugged, Dizzy, Psychotic. +#default-reverb = ## trap-alc-error: # Generates a SIGTRAP signal when an ALC device error is generated, on systems # that support it. This helps when debugging, while trying to find the cause # of a device error. On Windows, a breakpoint exception is generated. -# Optionally, the __ALSOFT_TRAP_ALC_ERROR env var may be set before running -# the app instead. #trap-alc-error = false ## trap-al-error: # Generates a SIGTRAP signal when an AL context error is generated, on systems # that support it. This helps when debugging, while trying to find the cause # of a context error. On Windows, a breakpoint exception is generated. -# Optionally, the __ALSOFT_TRAP_AL_ERROR env var may be set before running the -# app instead. #trap-al-error = false +## +## MIDI stuff (EXPERIMENTAL) +## +[midi] + +## soundfont: +# A default soundfont (sf2 format). Used when an app requests the system +# default. +#soundfont = + +## volume: +# Additional attenuation applied to MIDI output, expressed in decibels. This +# is used to help keep the mix from clipping, and so must be 0 or less. The +# value is logarithmic, so -6 will be about half amplitude, and -12 about +# 1/4th. The default is roughly -13.9794 (0.2, or 1/5th). +#volume = + ## ## Reverb effect stuff (includes EAX reverb) ## @@ -184,6 +218,24 @@ # allows a simpler effect to be used at the loss of some quality. #emulate-eax = false +## +## PulseAudio backend stuff +## +[pulse] + +## spawn-server: +# Attempts to autospawn a PulseAudio server whenever needed (initializing the +# backend, enumerating devices, etc). Setting autospawn to false in Pulse's +# client.conf will still prevent autospawning even if this is set to true. +#spawn-server = true + +## allow-moves: +# Allows PulseAudio to move active streams to different devices. Note that the +# device specifier (seen by applications) will not be updated when this +# occurs, and neither will the AL device configuration (sample rate, format, +# etc). +#allow-moves = false + ## ## ALSA backend stuff ## @@ -199,16 +251,30 @@ # device index for the requested device name. #device-prefix = plughw: +## device-prefix-*: +# Card- and device-specific prefixes may be used to override the device-prefix +# option. The option may specify the card id (eg, device-prefix-NVidia), or +# the card id and device index (eg, device-prefix-NVidia-0). The card id is +# case-sensitive. +#device-prefix- = + ## capture: # Sets the device name for the default capture device. #capture = default ## capture-prefix: # Sets the prefix used by the discovered (non-default) capture devices. This -# will be appended with "CARD=c,DEV=d", where c is the card number and d is -# the device number for the requested device name. +# will be appended with "CARD=c,DEV=d", where c is the card id and d is the +# device number for the requested device name. #capture-prefix = plughw: +## capture-prefix-*: +# Card- and device-specific prefixes may be used to override the +# capture-prefix option. The option may specify the card id (eg, +# capture-prefix-NVidia), or the card id and device index (eg, +# capture-prefix-NVidia-0). The card id is case-sensitive. +#capture-prefix- = + ## mmap: # Sets whether to try using mmap mode (helps reduce latencies and CPU # consumption). If mmap isn't available, it will automatically fall back to @@ -238,6 +304,19 @@ # Sets the device name for Solaris output. #device = /dev/audio +## +## QSA backend stuff +## +[qsa] + +## device: +# Sets the device name for the default playback device. +#device = default + +## capture: +# Sets the device name for the default capture device. +#capture = default + ## ## MMDevApi backend stuff ## @@ -268,19 +347,6 @@ # given by PortAudio itself. #capture = -1 -## -## PulseAudio backend stuff -## -[pulse] - -## spawn-server: -# Attempts to spawn a PulseAudio server when requesting to open a PulseAudio -# device. Note that some apps may open and probe all enumerated devices on -# startup, causing a server to spawn even if a PulseAudio device is not -# actually selected. Setting autospawn to false in Pulse's client.conf will -# still prevent autospawning even if this is set to true. -#spawn-server = false - ## ## Wave File Writer stuff ## diff --git a/jni/openal-soft-android/cmake/CheckCCompilerFlag.cmake b/jni/openal-soft-android/cmake/CheckCCompilerFlag.cmake deleted file mode 100644 index 8b2361aa..00000000 --- a/jni/openal-soft-android/cmake/CheckCCompilerFlag.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# - Check if the C source code provided in the SOURCE argument compiles. -# CHECK_C_SOURCE_COMPILES(SOURCE VAR) -# -# FLAG - compiler flag to check -# VAR - variable to store whether the source code compiled -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# CMAKE_REQUIRED_LIBRARIES = list of libraries to link - -MACRO(CHECK_C_COMPILER_FLAG FLAG VAR) - IF("${VAR}" MATCHES "^${VAR}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS - "${FLAG} ${CMAKE_REQUIRED_FLAGS}") - IF(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_C_COMPILER_FLAG_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") - ELSE(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_C_COMPILER_FLAG_ADD_LIBRARIES) - ENDIF(CMAKE_REQUIRED_LIBRARIES) - IF(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_C_COMPILER_FLAG_ADD_INCLUDES - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") - ELSE(CMAKE_REQUIRED_INCLUDES) - SET(CHECK_C_COMPILER_FLAG_ADD_INCLUDES) - ENDIF(CMAKE_REQUIRED_INCLUDES) - FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c" - "int main() {return 0;}\n") - - MESSAGE(STATUS "Checking if C compiler supports ${FLAG}") - TRY_COMPILE(${VAR} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} - "${CHECK_C_COMPILER_FLAG_ADD_LIBRARIES}" - "${CHECK_C_COMPILER_FLAG_ADD_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) - IF(${VAR}) - SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") - MESSAGE(STATUS "Checking if C compiler supports ${FLAG} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${SOURCE}\n") - ELSE(${VAR}) - MESSAGE(STATUS "Checking if C compiler supports ${FLAG} - Failed") - SET(${VAR} "" CACHE INTERNAL "Test ${VAR}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${SOURCE}\n") - ENDIF(${VAR}) - ENDIF("${VAR}" MATCHES "^${VAR}$") -ENDMACRO(CHECK_C_COMPILER_FLAG) diff --git a/jni/openal-soft-android/cmake/FindFluidSynth.cmake b/jni/openal-soft-android/cmake/FindFluidSynth.cmake new file mode 100644 index 00000000..7d5cb6a8 --- /dev/null +++ b/jni/openal-soft-android/cmake/FindFluidSynth.cmake @@ -0,0 +1,23 @@ +# - Find fluidsynth +# Find the native fluidsynth includes and library +# +# FLUIDSYNTH_INCLUDE_DIR - where to find fluidsynth.h +# FLUIDSYNTH_LIBRARIES - List of libraries when using fluidsynth. +# FLUIDSYNTH_FOUND - True if fluidsynth found. + + +IF (FLUIDSYNTH_INCLUDE_DIR AND FLUIDSYNTH_LIBRARIES) + # Already in cache, be silent + SET(FluidSynth_FIND_QUIETLY TRUE) +ENDIF (FLUIDSYNTH_INCLUDE_DIR AND FLUIDSYNTH_LIBRARIES) + +FIND_PATH(FLUIDSYNTH_INCLUDE_DIR fluidsynth.h) + +FIND_LIBRARY(FLUIDSYNTH_LIBRARIES NAMES fluidsynth ) +MARK_AS_ADVANCED( FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR ) + +# handle the QUIETLY and REQUIRED arguments and set FLUIDSYNTH_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(FluidSynth DEFAULT_MSG FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR) + diff --git a/jni/openal-soft-android/cmake/FindSDL_sound.cmake b/jni/openal-soft-android/cmake/FindSDL_sound.cmake new file mode 100644 index 00000000..97d2a84c --- /dev/null +++ b/jni/openal-soft-android/cmake/FindSDL_sound.cmake @@ -0,0 +1,382 @@ +# - Locates the SDL_sound library +# +# This module depends on SDL being found and +# must be called AFTER FindSDL.cmake is called. +# +# This module defines +# SDL_SOUND_INCLUDE_DIR, where to find SDL_sound.h +# SDL_SOUND_FOUND, if false, do not try to link to SDL_sound +# SDL_SOUND_LIBRARIES, this contains the list of libraries that you need +# to link against. This is a read-only variable and is marked INTERNAL. +# SDL_SOUND_EXTRAS, this is an optional variable for you to add your own +# flags to SDL_SOUND_LIBRARIES. This is prepended to SDL_SOUND_LIBRARIES. +# This is available mostly for cases this module failed to anticipate for +# and you must add additional flags. This is marked as ADVANCED. +# SDL_SOUND_VERSION_STRING, human-readable string containing the version of SDL_sound +# +# This module also defines (but you shouldn't need to use directly) +# SDL_SOUND_LIBRARY, the name of just the SDL_sound library you would link +# against. Use SDL_SOUND_LIBRARIES for you link instructions and not this one. +# And might define the following as needed +# MIKMOD_LIBRARY +# MODPLUG_LIBRARY +# OGG_LIBRARY +# VORBIS_LIBRARY +# SMPEG_LIBRARY +# FLAC_LIBRARY +# SPEEX_LIBRARY +# +# Typically, you should not use these variables directly, and you should use +# SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other audio libraries +# (if needed) to successfully compile on your system. +# +# Created by Eric Wing. +# This module is a bit more complicated than the other FindSDL* family modules. +# The reason is that SDL_sound can be compiled in a large variety of different ways +# which are independent of platform. SDL_sound may dynamically link against other 3rd +# party libraries to get additional codec support, such as Ogg Vorbis, SMPEG, ModPlug, +# MikMod, FLAC, Speex, and potentially others. +# Under some circumstances which I don't fully understand, +# there seems to be a requirement +# that dependent libraries of libraries you use must also be explicitly +# linked against in order to successfully compile. SDL_sound does not currently +# have any system in place to know how it was compiled. +# So this CMake module does the hard work in trying to discover which 3rd party +# libraries are required for building (if any). +# This module uses a brute force approach to create a test program that uses SDL_sound, +# and then tries to build it. If the build fails, it parses the error output for +# known symbol names to figure out which libraries are needed. +# +# Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that would +# correspond to the ./configure --prefix=$SDLDIR used in building SDL. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL_LIBRARY to override this selectionor set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. + +#============================================================================= +# Copyright 2005-2009 Kitware, Inc. +# Copyright 2012 Benjamin Eikel +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +set(SDL_SOUND_EXTRAS "" CACHE STRING "SDL_sound extra flags") +mark_as_advanced(SDL_SOUND_EXTRAS) + +# Find SDL_sound.h +find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h + HINTS + ENV SDLSOUNDDIR + ENV SDLDIR + PATH_SUFFIXES SDL SDL12 SDL11 + ) + +find_library(SDL_SOUND_LIBRARY + NAMES SDL_sound + HINTS + ENV SDLSOUNDDIR + ENV SDLDIR + ) + +if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) + + # CMake is giving me problems using TRY_COMPILE with the CMAKE_FLAGS + # for the :STRING syntax if I have multiple values contained in a + # single variable. This is a problem for the SDL_LIBRARY variable + # because it does just that. When I feed this variable to the command, + # only the first value gets the appropriate modifier (e.g. -I) and + # the rest get dropped. + # To get multiple single variables to work, I must separate them with a "\;" + # I could go back and modify the FindSDL.cmake module, but that's kind of painful. + # The solution would be to try something like: + # set(SDL_TRY_COMPILE_LIBRARY_LIST "${SDL_TRY_COMPILE_LIBRARY_LIST}\;${CMAKE_THREAD_LIBS_INIT}") + # Instead, it was suggested on the mailing list to write a temporary CMakeLists.txt + # with a temporary test project and invoke that with TRY_COMPILE. + # See message thread "Figuring out dependencies for a library in order to build" + # 2005-07-16 + # try_compile( + # MY_RESULT + # ${CMAKE_BINARY_DIR} + # ${PROJECT_SOURCE_DIR}/DetermineSoundLibs.c + # CMAKE_FLAGS + # -DINCLUDE_DIRECTORIES:STRING=${SDL_INCLUDE_DIR}\;${SDL_SOUND_INCLUDE_DIR} + # -DLINK_LIBRARIES:STRING=${SDL_SOUND_LIBRARY}\;${SDL_LIBRARY} + # OUTPUT_VARIABLE MY_OUTPUT + # ) + + # To minimize external dependencies, create a sdlsound test program + # which will be used to figure out if additional link dependencies are + # required for the link phase. + file(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/DetermineSoundLibs.c + "#include \"SDL_sound.h\" + #include \"SDL.h\" + int main(int argc, char* argv[]) + { + Sound_AudioInfo desired; + Sound_Sample* sample; + + SDL_Init(0); + Sound_Init(); + + /* This doesn't actually have to work, but Init() is a no-op + * for some of the decoders, so this should force more symbols + * to be pulled in. + */ + sample = Sound_NewSampleFromFile(argv[1], &desired, 4096); + + Sound_Quit(); + SDL_Quit(); + return 0; + }" + ) + + # Calling + # target_link_libraries(DetermineSoundLibs "${SDL_SOUND_LIBRARY} ${SDL_LIBRARY}) + # causes problems when SDL_LIBRARY looks like + # /Library/Frameworks/SDL.framework;-framework Cocoa + # The ;-framework Cocoa seems to be confusing CMake once the OS X + # framework support was added. I was told that breaking up the list + # would fix the problem. + set(TMP_TRY_LIBS) + foreach(lib ${SDL_SOUND_LIBRARY} ${SDL_LIBRARY}) + set(TMP_TRY_LIBS "${TMP_TRY_LIBS} \"${lib}\"") + endforeach() + + # message("TMP_TRY_LIBS ${TMP_TRY_LIBS}") + + # Write the CMakeLists.txt and test project + # Weird, this is still sketchy. If I don't quote the variables + # in the TARGET_LINK_LIBRARIES, I seem to loose everything + # in the SDL_LIBRARY string after the "-framework". + # But if I quote the stuff in INCLUDE_DIRECTORIES, it doesn't work. + file(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/CMakeLists.txt + "cmake_minimum_required(VERSION 2.8) + project(DetermineSoundLibs C) + include_directories(${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR}) + add_executable(DetermineSoundLibs DetermineSoundLibs.c) + target_link_libraries(DetermineSoundLibs ${TMP_TRY_LIBS})" + ) + + try_compile( + MY_RESULT + ${PROJECT_BINARY_DIR}/CMakeTmp + ${PROJECT_BINARY_DIR}/CMakeTmp + DetermineSoundLibs + OUTPUT_VARIABLE MY_OUTPUT + ) + + # message("${MY_RESULT}") + # message(${MY_OUTPUT}) + + if(NOT MY_RESULT) + + # I expect that MPGLIB, VOC, WAV, AIFF, and SHN are compiled in statically. + # I think Timidity is also compiled in statically. + # I've never had to explcitly link against Quicktime, so I'll skip that for now. + + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARY}) + + # Find MikMod + if("${MY_OUTPUT}" MATCHES "MikMod_") + find_library(MIKMOD_LIBRARY + NAMES libmikmod-coreaudio mikmod + PATHS + ENV MIKMODDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(MIKMOD_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MIKMOD_LIBRARY}) + endif(MIKMOD_LIBRARY) + endif("${MY_OUTPUT}" MATCHES "MikMod_") + + # Find ModPlug + if("${MY_OUTPUT}" MATCHES "MODPLUG_") + find_library(MODPLUG_LIBRARY + NAMES modplug + PATHS + ENV MODPLUGDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(MODPLUG_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MODPLUG_LIBRARY}) + endif() + endif() + + + # Find Ogg and Vorbis + if("${MY_OUTPUT}" MATCHES "ov_") + find_library(VORBIS_LIBRARY + NAMES vorbis Vorbis VORBIS + PATHS + ENV VORBISDIR + ENV OGGDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(VORBIS_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${VORBIS_LIBRARY}) + endif() + + find_library(OGG_LIBRARY + NAMES ogg Ogg OGG + PATHS + ENV OGGDIR + ENV VORBISDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(OGG_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY}) + endif() + endif() + + + # Find SMPEG + if("${MY_OUTPUT}" MATCHES "SMPEG_") + find_library(SMPEG_LIBRARY + NAMES smpeg SMPEG Smpeg SMpeg + PATHS + ENV SMPEGDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(SMPEG_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SMPEG_LIBRARY}) + endif() + endif() + + + # Find FLAC + if("${MY_OUTPUT}" MATCHES "FLAC_") + find_library(FLAC_LIBRARY + NAMES flac FLAC + PATHS + ENV FLACDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(FLAC_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${FLAC_LIBRARY}) + endif() + endif() + + + # Hmmm...Speex seems to depend on Ogg. This might be a problem if + # the TRY_COMPILE attempt gets blocked at SPEEX before it can pull + # in the Ogg symbols. I'm not sure if I should duplicate the ogg stuff + # above for here or if two ogg entries will screw up things. + if("${MY_OUTPUT}" MATCHES "speex_") + find_library(SPEEX_LIBRARY + NAMES speex SPEEX + PATHS + ENV SPEEXDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES + lib + ) + if(SPEEX_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SPEEX_LIBRARY}) + endif() + + # Find OGG (needed for Speex) + # We might have already found Ogg for Vorbis, so skip it if so. + if(NOT OGG_LIBRARY) + find_library(OGG_LIBRARY + NAMES ogg Ogg OGG + PATHS + ENV OGGDIR + ENV VORBISDIR + ENV SPEEXDIR + ENV SDLSOUNDDIR + ENV SDLDIR + /sw + /opt/local + /opt/csw + /opt + PATH_SUFFIXES lib + ) + if(OGG_LIBRARY) + set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY}) + endif() + endif() + endif() + + set(SDL_SOUND_LIBRARIES ${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARIES_TMP} CACHE INTERNAL "SDL_sound and dependent libraries") + else() + set(SDL_SOUND_LIBRARIES ${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARY} CACHE INTERNAL "SDL_sound and dependent libraries") + endif() +endif() + +if(SDL_SOUND_INCLUDE_DIR AND EXISTS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h") + file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SOUND_VER_MAJOR[ \t]+[0-9]+$") + file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_MINOR_LINE REGEX "^#define[ \t]+SOUND_VER_MINOR[ \t]+[0-9]+$") + file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_PATCH_LINE REGEX "^#define[ \t]+SOUND_VER_PATCH[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MAJOR "${SDL_SOUND_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MINOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MINOR "${SDL_SOUND_VERSION_MINOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SOUND_VER_PATCH[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_PATCH "${SDL_SOUND_VERSION_PATCH_LINE}") + set(SDL_SOUND_VERSION_STRING ${SDL_SOUND_VERSION_MAJOR}.${SDL_SOUND_VERSION_MINOR}.${SDL_SOUND_VERSION_PATCH}) + unset(SDL_SOUND_VERSION_MAJOR_LINE) + unset(SDL_SOUND_VERSION_MINOR_LINE) + unset(SDL_SOUND_VERSION_PATCH_LINE) + unset(SDL_SOUND_VERSION_MAJOR) + unset(SDL_SOUND_VERSION_MINOR) + unset(SDL_SOUND_VERSION_PATCH) +endif() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_sound + REQUIRED_VARS SDL_SOUND_LIBRARY SDL_SOUND_INCLUDE_DIR + VERSION_VAR SDL_SOUND_VERSION_STRING) diff --git a/jni/openal-soft-android/toolchain.android.cmake b/jni/openal-soft-android/cmake/toolchain.android.cmake similarity index 55% rename from jni/openal-soft-android/toolchain.android.cmake rename to jni/openal-soft-android/cmake/toolchain.android.cmake index 255c9417..1751e1bf 100644 --- a/jni/openal-soft-android/toolchain.android.cmake +++ b/jni/openal-soft-android/cmake/toolchain.android.cmake @@ -4,7 +4,7 @@ set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_VERSION 1) if(APPLE) - set(HOST_APPLE true) + set(HOST_APPLE true) elseif(UNIX) set(HOST_UNIX true) endif() @@ -13,29 +13,10 @@ set(APPLE false) set(UNIX true) set(ANDROID_NDK_DEFAULT_SEARCH_PATH /opt/android-ndk) -set(ANDROID_NDK_SUPPORTED_VERSIONS -r6 -r5c -r5b -r5 "") +set(ANDROID_NDK_SUPPORTED_VERSIONS -r8d -r8 -r7 -r6 -r5c -r5b -r5 "") set(ANDROID_NDK_TOOLCHAIN_DEFAULT_SEARCH_PATH /opt/android-toolchain) set(TOOL_OS_SUFFIX "") -macro(__TOOLCHAIN_DETECT_API_LEVEL _path) - SET(_expected ${ARGV1}) - if(NOT EXISTS ${_path}) - message(FATAL_ERROR "Could not verify Android API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken.") - endif() - SET(API_LEVEL_REGEX "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*$") - FILE(STRINGS ${_path} API_FILE_CONTENT REGEX "${API_LEVEL_REGEX}") - if(NOT API_FILE_CONTENT) - message(FATAL_ERROR "Could not verify Android API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken.") - endif() - string(REGEX REPLACE "${API_LEVEL_REGEX}" "\\1" ANDROID_LEVEL_FOUND "${API_FILE_CONTENT}") - if(DEFINED _expected) - if(NOT ${ANDROID_LEVEL_FOUND} EQUAL ${_expected}) - message(FATAL_ERROR "Specified Android API level does not match level found. Probably your copy of NDK/toolchain is broken.") - endif() - endif() - set(ANDROID_API_LEVEL ${ANDROID_LEVEL_FOUND} CACHE STRING "android API level" FORCE) -endmacro() - if(NOT DEFINED ANDROID_NDK) set(ANDROID_NDK "$ENV{ANDROID_NDK}") endif() @@ -57,12 +38,12 @@ endif() if(EXISTS "${ANDROID_NDK}") if(APPLE) - set(NDKSYSTEM "darwin-x86") + set(ANDROID_TOOLCHAIN_SYSTEM "darwin-x86") elseif(WIN32) - set(NDKSYSTEM "windows") + set(ANDROID_TOOLCHAIN_SYSTEM "windows") set(TOOL_OS_SUFFIX ".exe") elseif(UNIX) - set(NDKSYSTEM "linux-x86") + set(ANDROID_TOOLCHAIN_SYSTEM "linux-x86_64") else() message(FATAL_ERROR "Your platform is not supported") endif() @@ -77,38 +58,49 @@ if(EXISTS "${ANDROID_NDK}") message(STATUS " If you prefer to use a different API level, please define the variable: ANDROID_API_LEVEL") endif() - if(NDK_CPU_X86) - set(ANDROID_NDK_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/x86-4.4.3/prebuilt/${NDKSYSTEM}") - set(ANDROID_NDK_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-x86") + if (NDK_CPU_X86) + set(ANDROID_TOOLCHAIN_PREFIX "i686-android-linux") + set(ANDROID_TOOLCHAIN_NAME "x86") + set(ANDROID_TOOLCHAIN_PLATFORM_NAME "x86") else() - set(ANDROID_NDK_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/${NDKSYSTEM}") - set(ANDROID_NDK_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-arm") + set(ANDROID_TOOLCHAIN_PREFIX "arm-linux-androideabi") + set(ANDROID_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_PREFIX}") + set(ANDROID_TOOLCHAIN_PLATFORM_NAME "arm") endif() - __TOOLCHAIN_DETECT_API_LEVEL("${ANDROID_NDK_SYSROOT}/usr/include/android/api-level.h" ${ANDROID_API_LEVEL}) + if (NOT DEFINED ANDROID_TOOLCHAIN_VERSION) + set(SUPPORTED_TOOLCHAIN_VERSIONS 4.4.0 4.4.3 4.6.0 4.6.1 4.6.2 4.6.3 4.7) + foreach(gcc_version ${SUPPORTED_TOOLCHAIN_VERSIONS}) + if (EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}-${gcc_version}") + set(ANDROID_TOOLCHAIN_VERSION ${gcc_version}) + endif() + endforeach() + if(NOT DEFINED ANDROID_TOOLCHAIN_VERSION) + message(FATAL_ERROR "Unable to find toolchain") + else() + message(STATUS "Using auto-detected toolchain ${ANDROID_TOOLCHAIN_NAME}-${ANDROID_TOOLCHAIN_VERSION}") + endif() + endif() + if (EXISTS "${ANDROID_NDK}/toolchains/clang-android-${ANDROID_TOOLCHAIN_VERSION}") + set (ANDROID_TOOLCHAIN_NAME "clang-android") + message(STATUS "Found clang toolchain ${ANDROID_TOOLCHAIN_NAME}-${ANDROID_TOOLCHAIN_VERSION}") + endif() + + set(ANDROID_NDK_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-${ANDROID_TOOLCHAIN_PLATFORM_NAME}") + set(ANDROID_NDK_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}-${ANDROID_TOOLCHAIN_VERSION}/prebuilt/${ANDROID_TOOLCHAIN_SYSTEM}") endif() +set(CMAKE_C_COMPILER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" FORCE) +set(CMAKE_CXX_COMPILER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" FORCE) +set(CMAKE_AR "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" FORCE) +set(CMAKE_LINKER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" FORCE) +set(CMAKE_NM "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" FORCE) +set(CMAKE_OBJCOPY "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" FORCE) +set(CMAKE_OBJDUMP "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" FORCE) +set(CMAKE_STRIP "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" FORCE) +set(CMAKE_RANLIB "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_PREFIX}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" FORCE) + if(NDK_CPU_X86) - set(ARM_PREFIX "i686-android-linux") -else() - set(ARM_PREFIX "arm-linux-androideabi") -endif() - -set(CMAKE_C_COMPILER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" FORCE) -set(CMAKE_CXX_COMPILER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" FORCE) -set(CMAKE_AR "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" FORCE) -set(CMAKE_LINKER "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" FORCE) -set(CMAKE_NM "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" FORCE) -set(CMAKE_OBJCOPY "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" FORCE) -set(CMAKE_OBJDUMP "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" FORCE) -set(CMAKE_STRIP "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" FORCE) -set(CMAKE_RANLIB "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin/${ARM_PREFIX}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" FORCE) - -if(NDK_CPU_ARM) - set(ANDROID_NDK_CPU_NAME "armeabi") - set(NDK_CPU_ARM_NEON false) - set(CMAKE_SYSTEM_PROCESSOR "armv5te") -elseif(NDK_CPU_X86) set(ANDROID_NDK_CPU_NAME "x86") set(CMAKE_SYSTEM_PROCESSOR "x86") elseif(NDK_CPU_ARM_V7A) @@ -117,9 +109,14 @@ elseif(NDK_CPU_ARM_V7A) set(NDK_CPU_ARM true) set(ANDROID_NDK_CPU_NAME "armeabi-v7a") set(CMAKE_SYSTEM_PROCESSOR "armv7-a") +else() + set(NDK_CPU_ARM true) + set(ANDROID_NDK_CPU_NAME "armeabi") + set(NDK_CPU_ARM_NEON false) + set(CMAKE_SYSTEM_PROCESSOR "armv5te") endif() -set(CMAKE_FIND_ROOT_PATH "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin" "${ANDROID_NDK_TOOLCHAIN_ROOT}/${ARM_PREFIX}" "${ANDROID_NDK_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share") +set(CMAKE_FIND_ROOT_PATH "${ANDROID_NDK_TOOLCHAIN_ROOT}/bin" "${ANDROID_NDK_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_PREFIX}" "${ANDROID_NDK_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share") set(STL_PATH "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++") set(STL_LIBRARIES_PATH "${STL_PATH}/libs/${ANDROID_NDK_CPU_NAME}") @@ -158,7 +155,7 @@ endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c++ flags") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags") -set(LINKER_FLAGS "-L\"${STL_LIBRARIES_PATH}\" -L\"${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_CPU_NAME}\" -lstdc++ -lsupc++") +set(LINKER_FLAGS "-L\"${STL_LIBRARIES_PATH}\" -L\"${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_CPU_NAME}\"") if(NDK_CPU_ARM OR NDK_CPU_ARM_V7A) set(LINKER_FLAGS "-Wl,--fix-cortex-a8 ${LINKER_FLAGS}") endif() @@ -171,3 +168,4 @@ set(ANDROID true) set(BUILD_ANDROID true) MARK_AS_ADVANCED(FORCE_ARM NO_UNDEFINED) + diff --git a/jni/openal-soft-android/cmake_install.cmake b/jni/openal-soft-android/cmake_install.cmake deleted file mode 100644 index 2bbf8555..00000000 --- a/jni/openal-soft-android/cmake_install.cmake +++ /dev/null @@ -1,88 +0,0 @@ -# Install script for directory: /home/hagish/workspace/adt/love-native-android/jni/openal-soft-android - -# Set the install prefix -IF(NOT DEFINED CMAKE_INSTALL_PREFIX) - SET(CMAKE_INSTALL_PREFIX "/usr/local") -ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX) -STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") - -# Set the install configuration name. -IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) - IF(BUILD_TYPE) - STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" "" - CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") - ELSE(BUILD_TYPE) - SET(CMAKE_INSTALL_CONFIG_NAME "RelWithDebInfo") - ENDIF(BUILD_TYPE) - MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") -ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) - -# Set the component getting installed. -IF(NOT CMAKE_INSTALL_COMPONENT) - IF(COMPONENT) - MESSAGE(STATUS "Install component: \"${COMPONENT}\"") - SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}") - ELSE(COMPONENT) - SET(CMAKE_INSTALL_COMPONENT) - ENDIF(COMPONENT) -ENDIF(NOT CMAKE_INSTALL_COMPONENT) - -# Install shared libraries without execute permission? -IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) - SET(CMAKE_INSTALL_SO_NO_EXE "1") -ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) - -IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so.1.13.0" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so.1" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/libopenal.so" - ) - FOREACH(file - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libopenal.so.1.13.0" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libopenal.so.1" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libopenal.so" - ) - IF(EXISTS "${file}" AND - NOT IS_SYMLINK "${file}") - IF(CMAKE_INSTALL_DO_STRIP) - EXECUTE_PROCESS(COMMAND "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip" "${file}") - ENDIF(CMAKE_INSTALL_DO_STRIP) - ENDIF() - ENDFOREACH() -ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - -IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/AL" TYPE FILE FILES - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include/AL/al.h" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include/AL/alc.h" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include/AL/alext.h" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include/AL/efx.h" - "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/include/AL/efx-creative.h" - ) -ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - -IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" TYPE FILE FILES "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/openal.pc") -ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - -IF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - FILE(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/CMakeFiles/CMakeRelink.dir/openal-info") - IF(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/openal-info" AND - NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/openal-info") - IF(CMAKE_INSTALL_DO_STRIP) - EXECUTE_PROCESS(COMMAND "/opt/android-ndk-r6/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/openal-info") - ENDIF(CMAKE_INSTALL_DO_STRIP) - ENDIF() -ENDIF(NOT CMAKE_INSTALL_COMPONENT OR "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Unspecified") - -IF(CMAKE_INSTALL_COMPONENT) - SET(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") -ELSE(CMAKE_INSTALL_COMPONENT) - SET(CMAKE_INSTALL_MANIFEST "install_manifest.txt") -ENDIF(CMAKE_INSTALL_COMPONENT) - -FILE(WRITE "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/${CMAKE_INSTALL_MANIFEST}" "") -FOREACH(file ${CMAKE_INSTALL_MANIFEST_FILES}) - FILE(APPEND "/home/hagish/workspace/adt/love-native-android/jni/openal-soft-android/${CMAKE_INSTALL_MANIFEST}" "${file}\n") -ENDFOREACH(file) diff --git a/jni/openal-soft-android/config.h b/jni/openal-soft-android/config.h index dc045303..cc3c005b 100644 --- a/jni/openal-soft-android/config.h +++ b/jni/openal-soft-android/config.h @@ -3,7 +3,34 @@ #define ALC_API __attribute__((visibility("protected"))) /* Define to the library version */ -#define ALSOFT_VERSION "1.13" +#define ALSOFT_VERSION "1.15.1" + +#ifdef IN_IDE_PARSER +/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but + * recent versions (at least 4.5.1) do recognize GCC's __restrict. */ +#define restrict __restrict +#endif + +/* Define any available alignment declaration */ +#define ALIGN(x) __attribute__((aligned(x))) + +/* Define if we have the C11 aligned_alloc function */ +/* #undef HAVE_ALIGNED_ALLOC */ + +/* Define if we have the posix_memalign function */ +/* #undef HAVE_POSIX_MEMALIGN */ + +/* Define if we have the _aligned_malloc function */ +/* #undef HAVE__ALIGNED_MALLOC */ + +/* Define if we have SSE CPU extensions */ +/* #undef HAVE_SSE */ + +/* Define if we have ARM Neon CPU extensions */ +#undef HAVE_NEON + +/* Define if we have FluidSynth support */ +/* #undef HAVE_FLUIDSYNTH */ /* Define if we have the ALSA backend */ /* #undef HAVE_ALSA */ @@ -17,6 +44,9 @@ /* Define if we have the SndIO backend */ /* #undef HAVE_SNDIO */ +/* Define if we have the QSA backend */ +/* #undef HAVE_QSA */ + /* Define if we have the MMDevApi backend */ /* #undef HAVE_MMDEVAPI */ @@ -36,65 +66,20 @@ /* #undef HAVE_COREAUDIO */ /* Define if we have the OpenSL backend */ -/* #undef HAVE_OPENSL */ - -/* Define if we have the OpenSL 1.1 backend */ -/* #undef HAVE_OPENSL_1_1 */ - -/* Define if we have the Android backend */ -#define HAVE_ANDROID - -/* Define if we want to use the low latency Android backend */ -/* #undef HAVE_ANDROID_LOW_LATENCY */ +#define HAVE_OPENSL /* Define if we have the Wave Writer backend */ #define HAVE_WAVE -/* Define if we have dlfcn.h */ -#define HAVE_DLFCN_H - /* Define if we have the stat function */ #define HAVE_STAT -/* Define if we have the powf function */ -#define HAVE_POWF - -/* Define if we have the sqrtf function */ -#define HAVE_SQRTF - -/* Define if we have the cosf function */ -#define HAVE_COSF - -/* Define if we have the sinf function */ -#define HAVE_SINF - -/* Define if we have the acosf function */ -#define HAVE_ACOSF - -/* Define if we have the asinf function */ -#define HAVE_ASINF - -/* Define if we have the atanf function */ -#define HAVE_ATANF - -/* Define if we have the atan2f function */ -#define HAVE_ATAN2F - -/* Define if we have the fabsf function */ -#define HAVE_FABSF - -/* Define if we have the log10f function */ -#define HAVE_LOG10F - -/* Define if we have the floorf function */ -#define HAVE_FLOORF +/* Define if we have the lrintf function */ +#define HAVE_LRINTF /* Define if we have the strtof function */ /* #undef HAVE_STRTOF */ -/* Define if we have stdint.h */ -#define HAVE_STDINT_H - /* Define if we have the __int64 type */ /* #undef HAVE___INT64 */ @@ -110,16 +95,40 @@ /* Define if we have GCC's format attribute */ #define HAVE_GCC_FORMAT +/* Define if we have stdint.h */ +#define HAVE_STDINT_H + +/* Define if we have windows.h */ +/* #undef HAVE_WINDOWS_H */ + +/* Define if we have dlfcn.h */ +#define HAVE_DLFCN_H + /* Define if we have pthread_np.h */ /* #undef HAVE_PTHREAD_NP_H */ +/* Define if we have xmmintrin.h */ +/* #undef HAVE_XMMINTRIN_H */ + /* Define if we have arm_neon.h */ /* #undef HAVE_ARM_NEON_H */ +/* Define if we have malloc.h */ +#define HAVE_MALLOC_H + +/* Define if we have strings.h */ +#define HAVE_STRINGS_H + +/* Define if we have cpuid.h */ +/* #undef HAVE_CPUID_H */ + +/* Define if we have sys/sysconf.h */ +#define HAVE_SYS_SYSCONF_H + /* Define if we have guiddef.h */ /* #undef HAVE_GUIDDEF_H */ -/* Define if we have guiddef.h */ +/* Define if we have initguid.h */ /* #undef HAVE_INITGUID_H */ /* Define if we have ieeefp.h */ @@ -128,23 +137,20 @@ /* Define if we have float.h */ #define HAVE_FLOAT_H -/* Define if we have fpu_control.h */ -/* #undef HAVE_FPU_CONTROL_H */ - /* Define if we have fenv.h */ -/* #undef HAVE_FENV_H */ - -/* Define if we have fesetround() */ -/* #undef HAVE_FESETROUND */ +#define HAVE_FENV_H /* Define if we have _controlfp() */ /* #undef HAVE__CONTROLFP */ +/* Define if we have __control87_2() */ +/* #undef HAVE___CONTROL87_2 */ + /* Define if we have pthread_setschedparam() */ -/* #undef HAVE_PTHREAD_SETSCHEDPARAM */ +#define HAVE_PTHREAD_SETSCHEDPARAM -/* Define if we have the restrict keyword */ -/* #undef HAVE_RESTRICT */ +/* Define if we have pthread_setname_np() */ +/* #undef HAVE_PTHREAD_SETNAME_NP */ -/* Define if we have the __restrict keyword */ -#define HAVE___RESTRICT +/* Define if we have pthread_set_name_np() */ +/* #undef HAVE_PTHREAD_SET_NAME_NP */ diff --git a/jni/openal-soft-android/config.h.in b/jni/openal-soft-android/config.h.in index 7573ef07..d9582e74 100644 --- a/jni/openal-soft-android/config.h.in +++ b/jni/openal-soft-android/config.h.in @@ -5,6 +5,33 @@ /* Define to the library version */ #define ALSOFT_VERSION "${LIB_VERSION}" +#ifdef IN_IDE_PARSER +/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but + * recent versions (at least 4.5.1) do recognize GCC's __restrict. */ +#define restrict __restrict +#endif + +/* Define any available alignment declaration */ +#define ALIGN(x) ${ALIGN_DECL} + +/* Define if we have the C11 aligned_alloc function */ +#cmakedefine HAVE_ALIGNED_ALLOC + +/* Define if we have the posix_memalign function */ +#cmakedefine HAVE_POSIX_MEMALIGN + +/* Define if we have the _aligned_malloc function */ +#cmakedefine HAVE__ALIGNED_MALLOC + +/* Define if we have SSE CPU extensions */ +#cmakedefine HAVE_SSE + +/* Define if we have ARM Neon CPU extensions */ +#cmakedefine HAVE_NEON + +/* Define if we have FluidSynth support */ +#cmakedefine HAVE_FLUIDSYNTH + /* Define if we have the ALSA backend */ #cmakedefine HAVE_ALSA @@ -17,6 +44,9 @@ /* Define if we have the SndIO backend */ #cmakedefine HAVE_SNDIO +/* Define if we have the QSA backend */ +#cmakedefine HAVE_QSA + /* Define if we have the MMDevApi backend */ #cmakedefine HAVE_MMDEVAPI @@ -38,63 +68,18 @@ /* Define if we have the OpenSL backend */ #cmakedefine HAVE_OPENSL -/* Define if we have the OpenSL 1.1 backend */ -#cmakedefine HAVE_OPENSL_1_1 - -/* Define if we have the Android backend */ -#cmakedefine HAVE_ANDROID - -/* Define if we want to use the low latency Android backend */ -#cmakedefine HAVE_ANDROID_LOW_LATENCY - /* Define if we have the Wave Writer backend */ #cmakedefine HAVE_WAVE -/* Define if we have dlfcn.h */ -#cmakedefine HAVE_DLFCN_H - /* Define if we have the stat function */ #cmakedefine HAVE_STAT -/* Define if we have the powf function */ -#cmakedefine HAVE_POWF - -/* Define if we have the sqrtf function */ -#cmakedefine HAVE_SQRTF - -/* Define if we have the cosf function */ -#cmakedefine HAVE_COSF - -/* Define if we have the sinf function */ -#cmakedefine HAVE_SINF - -/* Define if we have the acosf function */ -#cmakedefine HAVE_ACOSF - -/* Define if we have the asinf function */ -#cmakedefine HAVE_ASINF - -/* Define if we have the atanf function */ -#cmakedefine HAVE_ATANF - -/* Define if we have the atan2f function */ -#cmakedefine HAVE_ATAN2F - -/* Define if we have the fabsf function */ -#cmakedefine HAVE_FABSF - -/* Define if we have the log10f function */ -#cmakedefine HAVE_LOG10F - -/* Define if we have the floorf function */ -#cmakedefine HAVE_FLOORF +/* Define if we have the lrintf function */ +#cmakedefine HAVE_LRINTF /* Define if we have the strtof function */ #cmakedefine HAVE_STRTOF -/* Define if we have stdint.h */ -#cmakedefine HAVE_STDINT_H - /* Define if we have the __int64 type */ #cmakedefine HAVE___INT64 @@ -110,16 +95,40 @@ /* Define if we have GCC's format attribute */ #cmakedefine HAVE_GCC_FORMAT +/* Define if we have stdint.h */ +#cmakedefine HAVE_STDINT_H + +/* Define if we have windows.h */ +#cmakedefine HAVE_WINDOWS_H + +/* Define if we have dlfcn.h */ +#cmakedefine HAVE_DLFCN_H + /* Define if we have pthread_np.h */ #cmakedefine HAVE_PTHREAD_NP_H +/* Define if we have xmmintrin.h */ +#cmakedefine HAVE_XMMINTRIN_H + /* Define if we have arm_neon.h */ #cmakedefine HAVE_ARM_NEON_H +/* Define if we have malloc.h */ +#cmakedefine HAVE_MALLOC_H + +/* Define if we have strings.h */ +#cmakedefine HAVE_STRINGS_H + +/* Define if we have cpuid.h */ +#cmakedefine HAVE_CPUID_H + +/* Define if we have sys/sysconf.h */ +#cmakedefine HAVE_SYS_SYSCONF_H + /* Define if we have guiddef.h */ #cmakedefine HAVE_GUIDDEF_H -/* Define if we have guiddef.h */ +/* Define if we have initguid.h */ #cmakedefine HAVE_INITGUID_H /* Define if we have ieeefp.h */ @@ -128,23 +137,20 @@ /* Define if we have float.h */ #cmakedefine HAVE_FLOAT_H -/* Define if we have fpu_control.h */ -#cmakedefine HAVE_FPU_CONTROL_H - /* Define if we have fenv.h */ #cmakedefine HAVE_FENV_H -/* Define if we have fesetround() */ -#cmakedefine HAVE_FESETROUND - /* Define if we have _controlfp() */ #cmakedefine HAVE__CONTROLFP +/* Define if we have __control87_2() */ +#cmakedefine HAVE___CONTROL87_2 + /* Define if we have pthread_setschedparam() */ #cmakedefine HAVE_PTHREAD_SETSCHEDPARAM -/* Define if we have the restrict keyword */ -#cmakedefine HAVE_RESTRICT +/* Define if we have pthread_setname_np() */ +#cmakedefine HAVE_PTHREAD_SETNAME_NP -/* Define if we have the __restrict keyword */ -#cmakedefine HAVE___RESTRICT +/* Define if we have pthread_set_name_np() */ +#cmakedefine HAVE_PTHREAD_SET_NAME_NP diff --git a/jni/openal-soft-android/env-vars.txt b/jni/openal-soft-android/env-vars.txt new file mode 100644 index 00000000..47dce032 --- /dev/null +++ b/jni/openal-soft-android/env-vars.txt @@ -0,0 +1,71 @@ +Useful Environment Variables + +Below is a list of environment variables that can be set to aid with running or +debugging apps that use OpenAL Soft. They should be set before the app is run. + +*** Logging *** + +ALSOFT_LOGLEVEL +Specifies the amount of logging OpenAL Soft will write out: +0 - Effectively disables all logging +1 - Prints out errors only +2 - Prints out warnings and errors +3 - Prints out additional information, as well as warnings and errors +4 - Same as 3, but also device and context reference count changes. This will + print out *a lot* of info, and is generally not useful unless you're trying + to track a reference leak within the library. + +ALSOFT_LOGFILE +Specifies a filename that logged output will be written to. Note that the file +will be first cleared when logging is initialized. + +*** Overrides *** + +ALSOFT_CONF +Specifies an additional configuration file to load settings from. These +settings will take precedence over the global and user configs, but not other +environment variable settings. + +ALSOFT_DRIVERS +Overrides the drivers config option. This specifies which backend drivers to +consider or not consider for use. Please see the drivers option in +alsoftrc.sample for a list of available drivers. + +ALSOFT_DEFAULT_REVERB +Specifies the default reverb preset to apply to sources. Please see the +default-reverb option in alsoftrc.sample for additional information and a list +of available presets. + +ALSOFT_TRAP_AL_ERROR +Set to "true" or "1" to force trapping AL errors. Like the trap-al-error config +option, this will raise a SIGTRAP signal (or a breakpoint exception under +Windows) when a context-level error is generated. Useful when run under a +debugger as it will break execution right when the error occurs, making it +easier to track the cause. + +ALSOFT_TRAP_ALC_ERROR +Set to "true" or "1" to force trapping ALC errors. Like the trap-alc-error +config option, this will raise a SIGTRAP signal (or a breakpoint exception +under Windows) when a device-level error is generated. Useful when run under a +debugger as it will break execution right when the error occurs, making it +easier to track the cause. + +ALSOFT_TRAP_ERROR +Set to "true" or "1" to force trapping both ALC and AL errors. + +*** Compatibility *** + +__ALSOFT_HALF_ANGLE_CONES +Older versions of OpenAL Soft incorrectly calculated the cone angles to range +between 0 and 180 degrees, instead of the expected range of 0 to 360 degrees. +Setting this to "true" or "1" restores the old buggy behavior, for apps that +were written to expect the incorrect range. + +__ALSOFT_REVERSE_Z +Applications that don't natively use OpenAL's coordinate system have to convert +to it before passing in 3D coordinates. Depending on how exactly this is done, +it can cause correct output for stereo but incorrect Z panning for surround +sound (i.e., sounds that are supposed to be behind you sound like they're in +front, and vice-versa). Setting this to "true" or "1" will negate the localized +Z coordinate to attempt to fix output for apps that have incorrect front/back +panning. diff --git a/jni/openal-soft-android/examples/allatency.c b/jni/openal-soft-android/examples/allatency.c new file mode 100644 index 00000000..deb13d3b --- /dev/null +++ b/jni/openal-soft-android/examples/allatency.c @@ -0,0 +1,204 @@ +/* + * OpenAL Source Latency Example + * + * Copyright (c) 2012 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains an example for checking the latency of a sound. */ + +#include +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" + +#include "common/alhelpers.h" +#include "common/sdl_sound.h" + + +static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples; +static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT; + +static LPALSOURCEDSOFT alSourcedSOFT; +static LPALSOURCE3DSOFT alSource3dSOFT; +static LPALSOURCEDVSOFT alSourcedvSOFT; +static LPALGETSOURCEDSOFT alGetSourcedSOFT; +static LPALGETSOURCE3DSOFT alGetSource3dSOFT; +static LPALGETSOURCEDVSOFT alGetSourcedvSOFT; +static LPALSOURCEI64SOFT alSourcei64SOFT; +static LPALSOURCE3I64SOFT alSource3i64SOFT; +static LPALSOURCEI64VSOFT alSourcei64vSOFT; +static LPALGETSOURCEI64SOFT alGetSourcei64SOFT; +static LPALGETSOURCE3I64SOFT alGetSource3i64SOFT; +static LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT; + +/* LoadBuffer loads the named audio file into an OpenAL buffer object, and + * returns the new buffer ID. */ +static ALuint LoadSound(const char *filename) +{ + ALenum err, format, type, channels; + ALuint rate, buffer; + size_t datalen; + void *data; + FilePtr sound; + + /* Open the audio file */ + sound = openAudioFile(filename, 1000); + if(!sound) + { + fprintf(stderr, "Could not open audio in %s\n", filename); + closeAudioFile(sound); + return 0; + } + + /* Get the sound format, and figure out the OpenAL format */ + if(getAudioInfo(sound, &rate, &channels, &type) != 0) + { + fprintf(stderr, "Error getting audio info for %s\n", filename); + closeAudioFile(sound); + return 0; + } + + format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT); + if(format == AL_NONE) + { + fprintf(stderr, "Unsupported format (%s, %s) for %s\n", + ChannelsName(channels), TypeName(type), filename); + closeAudioFile(sound); + return 0; + } + + /* Decode the whole audio stream to a buffer. */ + data = decodeAudioStream(sound, &datalen); + if(!data) + { + fprintf(stderr, "Failed to read audio from %s\n", filename); + closeAudioFile(sound); + return 0; + } + + /* Buffer the audio data into a new buffer object, then free the data and + * close the file. */ + buffer = 0; + alGenBuffers(1, &buffer); + alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type), + channels, type, data); + free(data); + closeAudioFile(sound); + + /* Check if an error occured, and clean up if so. */ + err = alGetError(); + if(err != AL_NO_ERROR) + { + fprintf(stderr, "OpenAL Error: %s\n", alGetString(err)); + if(alIsBuffer(buffer)) + alDeleteBuffers(1, &buffer); + return 0; + } + + return buffer; +} + + +int main(int argc, char **argv) +{ + ALuint source, buffer; + ALdouble offsets[2]; + ALenum state; + + /* Print out usage if no file was specified */ + if(argc < 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + /* Initialize OpenAL with the default device, and check for EFX support. */ + if(InitAL() != 0) + return 1; + + if(!alIsExtensionPresent("AL_SOFT_source_latency")) + { + fprintf(stderr, "Error: AL_SOFT_source_latency not supported\n"); + CloseAL(); + return 1; + } + + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(x) ((x) = alGetProcAddress(#x)) + LOAD_PROC(alSourcedSOFT); + LOAD_PROC(alSource3dSOFT); + LOAD_PROC(alSourcedvSOFT); + LOAD_PROC(alGetSourcedSOFT); + LOAD_PROC(alGetSource3dSOFT); + LOAD_PROC(alGetSourcedvSOFT); + LOAD_PROC(alSourcei64SOFT); + LOAD_PROC(alSource3i64SOFT); + LOAD_PROC(alSourcei64vSOFT); + LOAD_PROC(alGetSourcei64SOFT); + LOAD_PROC(alGetSource3i64SOFT); + LOAD_PROC(alGetSourcei64vSOFT); + + if(alIsExtensionPresent("AL_SOFT_buffer_samples")) + { + LOAD_PROC(alBufferSamplesSOFT); + LOAD_PROC(alIsBufferFormatSupportedSOFT); + } +#undef LOAD_PROC + + /* Load the sound into a buffer. */ + buffer = LoadSound(argv[1]); + if(!buffer) + { + CloseAL(); + return 1; + } + + /* Create the source to play the sound with. */ + source = 0; + alGenSources(1, &source); + alSourcei(source, AL_BUFFER, buffer); + assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source"); + + /* Play the sound until it finishes. */ + alSourcePlay(source); + do { + Sleep(10); + alGetSourcei(source, AL_SOURCE_STATE, &state); + + /* Get the source offset and latency. AL_SEC_OFFSET_LATENCY_SOFT will + * place the offset (in seconds) in offsets[0], and the time until that + * offset will be heard (in seconds) in offsets[1]. */ + alGetSourcedvSOFT(source, AL_SEC_OFFSET_LATENCY_SOFT, offsets); + printf("\rOffset: %f - Latency:%3u ms ", offsets[0], (ALuint)(offsets[1]*1000)); + fflush(stdout); + } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); + printf("\n"); + + /* All done. Delete resources, and close OpenAL. */ + alDeleteSources(1, &source); + alDeleteBuffers(1, &buffer); + + CloseAL(); + + return 0; +} diff --git a/jni/openal-soft-android/examples/alloopback.c b/jni/openal-soft-android/examples/alloopback.c new file mode 100644 index 00000000..649ef6ef --- /dev/null +++ b/jni/openal-soft-android/examples/alloopback.c @@ -0,0 +1,244 @@ +/* + * OpenAL Loopback Example + * + * Copyright (c) 2013 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains an example for using the loopback device for custom + * output handling. + */ + +#include +#include +#include + +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" + +#include "common/alhelpers.h" + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +typedef struct { + ALCdevice *Device; + ALCcontext *Context; + + ALCsizei FrameSize; +} PlaybackInfo; + +static LPALCLOOPBACKOPENDEVICESOFT alcLoopbackOpenDeviceSOFT; +static LPALCISRENDERFORMATSUPPORTEDSOFT alcIsRenderFormatSupportedSOFT; +static LPALCRENDERSAMPLESSOFT alcRenderSamplesSOFT; + + +void SDLCALL RenderSDLSamples(void *userdata, Uint8 *stream, int len) +{ + PlaybackInfo *playback = (PlaybackInfo*)userdata; + alcRenderSamplesSOFT(playback->Device, stream, len/playback->FrameSize); +} + + +/* Creates a one second buffer containing a sine wave, and returns the new + * buffer ID. */ +static ALuint CreateSineWave(void) +{ + ALshort data[44100]; + ALuint buffer; + ALenum err; + ALuint i; + + for(i = 0;i < 44100;i++) + data[i] = (ALshort)(sin(i * 441.0 / 44100.0 * 2.0*M_PI)*32767.0); + + /* Buffer the audio data into a new buffer object. */ + buffer = 0; + alGenBuffers(1, &buffer); + alBufferData(buffer, AL_FORMAT_MONO16, data, sizeof(data), 44100); + + /* Check if an error occured, and clean up if so. */ + err = alGetError(); + if(err != AL_NO_ERROR) + { + fprintf(stderr, "OpenAL Error: %s\n", alGetString(err)); + if(alIsBuffer(buffer)) + alDeleteBuffers(1, &buffer); + return 0; + } + + return buffer; +} + + +int main() +{ + PlaybackInfo playback = { NULL, NULL, 0 }; + SDL_AudioSpec desired, obtained; + ALuint source, buffer; + ALCint attrs[16]; + ALenum state; + + /* Print out error if extension is missing. */ + if(!alcIsExtensionPresent(NULL, "ALC_SOFT_loopback")) + { + fprintf(stderr, "Error: ALC_SOFT_loopback not supported!\n"); + return 1; + } + + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(x) ((x) = alcGetProcAddress(NULL, #x)) + LOAD_PROC(alcLoopbackOpenDeviceSOFT); + LOAD_PROC(alcIsRenderFormatSupportedSOFT); + LOAD_PROC(alcRenderSamplesSOFT); +#undef LOAD_PROC + + if(SDL_Init(SDL_INIT_AUDIO) == -1) + { + fprintf(stderr, "Failed to init SDL audio: %s\n", SDL_GetError()); + return 1; + } + + /* Set up SDL audio with our requested format and callback. */ + desired.channels = 2; + desired.format = AUDIO_S16SYS; + desired.freq = 44100; + desired.padding = 0; + desired.samples = 4096; + desired.callback = RenderSDLSamples; + desired.userdata = &playback; + if(SDL_OpenAudio(&desired, &obtained) != 0) + { + SDL_Quit(); + fprintf(stderr, "Failed to open SDL audio: %s\n", SDL_GetError()); + return 1; + } + + /* Set up our OpenAL attributes based on what we got from SDL. */ + attrs[0] = ALC_FORMAT_CHANNELS_SOFT; + if(obtained.channels == 1) + attrs[1] = ALC_MONO_SOFT; + else if(obtained.channels == 2) + attrs[1] = ALC_STEREO_SOFT; + else + { + fprintf(stderr, "Unhandled SDL channel count: %d\n", obtained.channels); + goto error; + } + + attrs[2] = ALC_FORMAT_TYPE_SOFT; + if(obtained.format == AUDIO_U8) + attrs[3] = ALC_UNSIGNED_BYTE_SOFT; + else if(obtained.format == AUDIO_S8) + attrs[3] = ALC_BYTE_SOFT; + else if(obtained.format == AUDIO_U16SYS) + attrs[3] = ALC_UNSIGNED_SHORT_SOFT; + else if(obtained.format == AUDIO_S16SYS) + attrs[3] = ALC_SHORT_SOFT; + else + { + fprintf(stderr, "Unhandled SDL format: 0x%04x\n", obtained.format); + goto error; + } + + attrs[4] = ALC_FREQUENCY; + attrs[5] = obtained.freq; + + attrs[6] = 0; /* end of list */ + + /* Initialize OpenAL loopback device, using our format attributes. */ + playback.Device = alcLoopbackOpenDeviceSOFT(NULL); + if(!playback.Device) + { + fprintf(stderr, "Failed to open loopback device!\n"); + goto error; + } + /* Make sure the format is supported before setting them on the device. */ + if(alcIsRenderFormatSupportedSOFT(playback.Device, attrs[5], attrs[1], attrs[3]) == ALC_FALSE) + { + fprintf(stderr, "Render format not supported: %s, %s, %dhz\n", + ChannelsName(attrs[1]), TypeName(attrs[3]), attrs[5]); + goto error; + } + playback.Context = alcCreateContext(playback.Device, attrs); + if(!playback.Context || alcMakeContextCurrent(playback.Context) == ALC_FALSE) + { + fprintf(stderr, "Failed to set an OpenAL audio context\n"); + goto error; + } + playback.FrameSize = FramesToBytes(1, attrs[1], attrs[3]); + + /* Start SDL playing. Our callback (thus alcRenderSamplesSOFT) will now + * start being called regularly to update the AL playback state. */ + SDL_PauseAudio(0); + + /* Load the sound into a buffer. */ + buffer = CreateSineWave(); + if(!buffer) + { + SDL_CloseAudio(); + alcDestroyContext(playback.Context); + alcCloseDevice(playback.Device); + SDL_Quit(); + return 1; + } + + /* Create the source to play the sound with. */ + source = 0; + alGenSources(1, &source); + alSourcei(source, AL_BUFFER, buffer); + assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source"); + + /* Play the sound until it finishes. */ + alSourcePlay(source); + do { + Sleep(10); + alGetSourcei(source, AL_SOURCE_STATE, &state); + } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); + + /* All done. Delete resources, and close OpenAL. */ + alDeleteSources(1, &source); + alDeleteBuffers(1, &buffer); + + /* Stop SDL playing. */ + SDL_PauseAudio(1); + + /* Close up OpenAL and SDL. */ + SDL_CloseAudio(); + alcDestroyContext(playback.Context); + alcCloseDevice(playback.Device); + SDL_Quit(); + + return 0; + +error: + SDL_CloseAudio(); + if(playback.Context) + alcDestroyContext(playback.Context); + if(playback.Device) + alcCloseDevice(playback.Device); + SDL_Quit(); + + return 1; +} diff --git a/jni/openal-soft-android/examples/alreverb.c b/jni/openal-soft-android/examples/alreverb.c new file mode 100644 index 00000000..420b1c55 --- /dev/null +++ b/jni/openal-soft-android/examples/alreverb.c @@ -0,0 +1,327 @@ +/* + * OpenAL Reverb Example + * + * Copyright (c) 2012 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains an example for applying reverb to a sound. */ + +#include +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" +#include "AL/efx-presets.h" + +#include "common/alhelpers.h" +#include "common/sdl_sound.h" + + +static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples; +static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT; + +/* Effect object functions */ +static LPALGENEFFECTS alGenEffects; +static LPALDELETEEFFECTS alDeleteEffects; +static LPALISEFFECT alIsEffect; +static LPALEFFECTI alEffecti; +static LPALEFFECTIV alEffectiv; +static LPALEFFECTF alEffectf; +static LPALEFFECTFV alEffectfv; +static LPALGETEFFECTI alGetEffecti; +static LPALGETEFFECTIV alGetEffectiv; +static LPALGETEFFECTF alGetEffectf; +static LPALGETEFFECTFV alGetEffectfv; + +/* Auxiliary Effect Slot object functions */ +static LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; +static LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; +static LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; +static LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; +static LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; +static LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; +static LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; +static LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; +static LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; +static LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; +static LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; + + +/* LoadEffect loads the given reverb properties into a new OpenAL effect + * object, and returns the new effect ID. */ +static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb) +{ + ALuint effect = 0; + ALenum err; + + /* Create the effect object and check if we can do EAX reverb. */ + alGenEffects(1, &effect); + if(alGetEnumValue("AL_EFFECT_EAXREVERB") != 0) + { + printf("Using EAX Reverb\n"); + + /* EAX Reverb is available. Set the EAX effect type then load the + * reverb properties. */ + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + + alEffectf(effect, AL_EAXREVERB_DENSITY, reverb->flDensity); + alEffectf(effect, AL_EAXREVERB_DIFFUSION, reverb->flDiffusion); + alEffectf(effect, AL_EAXREVERB_GAIN, reverb->flGain); + alEffectf(effect, AL_EAXREVERB_GAINHF, reverb->flGainHF); + alEffectf(effect, AL_EAXREVERB_GAINLF, reverb->flGainLF); + alEffectf(effect, AL_EAXREVERB_DECAY_TIME, reverb->flDecayTime); + alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, reverb->flDecayHFRatio); + alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, reverb->flDecayLFRatio); + alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain); + alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay); + alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, reverb->flReflectionsPan); + alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain); + alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay); + alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, reverb->flLateReverbPan); + alEffectf(effect, AL_EAXREVERB_ECHO_TIME, reverb->flEchoTime); + alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, reverb->flEchoDepth); + alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, reverb->flModulationTime); + alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, reverb->flModulationDepth); + alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF); + alEffectf(effect, AL_EAXREVERB_HFREFERENCE, reverb->flHFReference); + alEffectf(effect, AL_EAXREVERB_LFREFERENCE, reverb->flLFReference); + alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor); + alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit); + } + else + { + printf("Using Standard Reverb\n"); + + /* No EAX Reverb. Set the standard reverb effect type then load the + * available reverb properties. */ + alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + + alEffectf(effect, AL_REVERB_DENSITY, reverb->flDensity); + alEffectf(effect, AL_REVERB_DIFFUSION, reverb->flDiffusion); + alEffectf(effect, AL_REVERB_GAIN, reverb->flGain); + alEffectf(effect, AL_REVERB_GAINHF, reverb->flGainHF); + alEffectf(effect, AL_REVERB_DECAY_TIME, reverb->flDecayTime); + alEffectf(effect, AL_REVERB_DECAY_HFRATIO, reverb->flDecayHFRatio); + alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain); + alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay); + alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain); + alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay); + alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF); + alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit); + } + + /* Check if an error occured, and clean up if so. */ + err = alGetError(); + if(err != AL_NO_ERROR) + { + fprintf(stderr, "OpenAL error: %s\n", alGetString(err)); + if(alIsEffect(effect)) + alDeleteEffects(1, &effect); + return 0; + } + + return effect; +} + + +/* LoadBuffer loads the named audio file into an OpenAL buffer object, and + * returns the new buffer ID. */ +static ALuint LoadSound(const char *filename) +{ + ALenum err, format, type, channels; + ALuint rate, buffer; + size_t datalen; + void *data; + FilePtr sound; + + /* Open the file and get the first stream from it */ + sound = openAudioFile(filename, 1000); + if(!sound) + { + fprintf(stderr, "Could not open audio in %s\n", filename); + return 0; + } + + /* Get the sound format, and figure out the OpenAL format */ + if(getAudioInfo(sound, &rate, &channels, &type) != 0) + { + fprintf(stderr, "Error getting audio info for %s\n", filename); + closeAudioFile(sound); + return 0; + } + + format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT); + if(format == AL_NONE) + { + fprintf(stderr, "Unsupported format (%s, %s) for %s\n", + ChannelsName(channels), TypeName(type), filename); + closeAudioFile(sound); + return 0; + } + + /* Decode the whole audio stream to a buffer. */ + data = decodeAudioStream(sound, &datalen); + if(!data) + { + fprintf(stderr, "Failed to read audio from %s\n", filename); + closeAudioFile(sound); + return 0; + } + + /* Buffer the audio data into a new buffer object, then free the data and + * close the file. */ + buffer = 0; + alGenBuffers(1, &buffer); + alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type), + channels, type, data); + free(data); + closeAudioFile(sound); + + /* Check if an error occured, and clean up if so. */ + err = alGetError(); + if(err != AL_NO_ERROR) + { + fprintf(stderr, "OpenAL Error: %s\n", alGetString(err)); + if(alIsBuffer(buffer)) + alDeleteBuffers(1, &buffer); + return 0; + } + + return buffer; +} + + +int main(int argc, char **argv) +{ + EFXEAXREVERBPROPERTIES reverb = EFX_REVERB_PRESET_GENERIC; + ALuint source, buffer, effect, slot; + ALenum state; + + /* Print out usage if no file was specified */ + if(argc < 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + /* Initialize OpenAL with the default device, and check for EFX support. */ + if(InitAL() != 0) + return 1; + + if(!alcIsExtensionPresent(alcGetContextsDevice(alcGetCurrentContext()), "ALC_EXT_EFX")) + { + fprintf(stderr, "Error: EFX not supported\n"); + CloseAL(); + return 1; + } + + /* Define a macro to help load the function pointers. */ +#define LOAD_PROC(x) ((x) = alGetProcAddress(#x)) + LOAD_PROC(alGenEffects); + LOAD_PROC(alDeleteEffects); + LOAD_PROC(alIsEffect); + LOAD_PROC(alEffecti); + LOAD_PROC(alEffectiv); + LOAD_PROC(alEffectf); + LOAD_PROC(alEffectfv); + LOAD_PROC(alGetEffecti); + LOAD_PROC(alGetEffectiv); + LOAD_PROC(alGetEffectf); + LOAD_PROC(alGetEffectfv); + + LOAD_PROC(alGenAuxiliaryEffectSlots); + LOAD_PROC(alDeleteAuxiliaryEffectSlots); + LOAD_PROC(alIsAuxiliaryEffectSlot); + LOAD_PROC(alAuxiliaryEffectSloti); + LOAD_PROC(alAuxiliaryEffectSlotiv); + LOAD_PROC(alAuxiliaryEffectSlotf); + LOAD_PROC(alAuxiliaryEffectSlotfv); + LOAD_PROC(alGetAuxiliaryEffectSloti); + LOAD_PROC(alGetAuxiliaryEffectSlotiv); + LOAD_PROC(alGetAuxiliaryEffectSlotf); + LOAD_PROC(alGetAuxiliaryEffectSlotfv); + + if(alIsExtensionPresent("AL_SOFT_buffer_samples")) + { + LOAD_PROC(alBufferSamplesSOFT); + LOAD_PROC(alIsBufferFormatSupportedSOFT); + } +#undef LOAD_PROC + + /* Load the sound into a buffer. */ + buffer = LoadSound(argv[1]); + if(!buffer) + { + CloseAL(); + return 1; + } + + /* Load the reverb into an effect. */ + effect = LoadEffect(&reverb); + if(!effect) + { + alDeleteBuffers(1, &buffer); + CloseAL(); + return 1; + } + + /* Create the effect slot object. This is what "plays" an effect on sources + * that connect to it. */ + slot = 0; + alGenAuxiliaryEffectSlots(1, &slot); + + /* Tell the effect slot to use the loaded effect object. Note that the this + * effectively copies the effect properties. You can modify or delete the + * effect object afterward without affecting the effect slot. + */ + alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect); + assert(alGetError()==AL_NO_ERROR && "Failed to set effect slot"); + + /* Create the source to play the sound with. */ + source = 0; + alGenSources(1, &source); + alSourcei(source, AL_BUFFER, buffer); + + /* Connect the source to the effect slot. This tells the source to use the + * effect slot 'slot', on send #0 with the AL_FILTER_NULL filter object. + */ + alSource3i(source, AL_AUXILIARY_SEND_FILTER, slot, 0, AL_FILTER_NULL); + assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source"); + + /* Play the sound until it finishes. */ + alSourcePlay(source); + do { + Sleep(10); + alGetSourcei(source, AL_SOURCE_STATE, &state); + } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); + + /* All done. Delete resources, and close OpenAL. */ + alDeleteSources(1, &source); + alDeleteAuxiliaryEffectSlots(1, &slot); + alDeleteEffects(1, &effect); + alDeleteBuffers(1, &buffer); + + CloseAL(); + + return 0; +} diff --git a/jni/openal-soft-android/examples/alstream.c b/jni/openal-soft-android/examples/alstream.c new file mode 100644 index 00000000..2972d375 --- /dev/null +++ b/jni/openal-soft-android/examples/alstream.c @@ -0,0 +1,335 @@ +/* + * OpenAL Audio Stream Example + * + * Copyright (c) 2011 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains a relatively simple streaming audio player. */ + +#include +#include +#include +#include +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" + +#include "common/alhelpers.h" +#include "common/sdl_sound.h" + + +static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples; +static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT; + + +/* Define the number of buffers and buffer size (in milliseconds) to use. 4 + * buffers with 200ms each gives a nice per-chunk size, and lets the queue last + * for almost one second. */ +#define NUM_BUFFERS 4 +#define BUFFER_TIME_MS 200 + +typedef struct StreamPlayer { + /* These are the buffers and source to play out through OpenAL with */ + ALuint buffers[NUM_BUFFERS]; + ALuint source; + + /* Handle for the audio file */ + FilePtr file; + + /* The format of the output stream */ + ALenum format; + ALenum channels; + ALenum type; + ALuint rate; +} StreamPlayer; + +static StreamPlayer *NewPlayer(void); +static void DeletePlayer(StreamPlayer *player); +static int OpenPlayerFile(StreamPlayer *player, const char *filename); +static void ClosePlayerFile(StreamPlayer *player); +static int StartPlayer(StreamPlayer *player); +static int UpdatePlayer(StreamPlayer *player); + +/* Creates a new player object, and allocates the needed OpenAL source and + * buffer objects. Error checking is simplified for the purposes of this + * example, and will cause an abort if needed. */ +static StreamPlayer *NewPlayer(void) +{ + StreamPlayer *player; + + player = malloc(sizeof(*player)); + assert(player != NULL); + + memset(player, 0, sizeof(*player)); + + /* Generate the buffers and source */ + alGenBuffers(NUM_BUFFERS, player->buffers); + assert(alGetError() == AL_NO_ERROR && "Could not create buffers"); + + alGenSources(1, &player->source); + assert(alGetError() == AL_NO_ERROR && "Could not create source"); + + /* Set parameters so mono sources play out the front-center speaker and + * won't distance attenuate. */ + alSource3i(player->source, AL_POSITION, 0, 0, -1); + alSourcei(player->source, AL_SOURCE_RELATIVE, AL_TRUE); + alSourcei(player->source, AL_ROLLOFF_FACTOR, 0); + assert(alGetError() == AL_NO_ERROR && "Could not set source parameters"); + + return player; +} + +/* Destroys a player object, deleting the source and buffers. No error handling + * since these calls shouldn't fail with a properly-made player object. */ +static void DeletePlayer(StreamPlayer *player) +{ + ClosePlayerFile(player); + + alDeleteSources(1, &player->source); + alDeleteBuffers(NUM_BUFFERS, player->buffers); + if(alGetError() != AL_NO_ERROR) + fprintf(stderr, "Failed to delete object IDs\n"); + + memset(player, 0, sizeof(*player)); + free(player); +} + + +/* Opens the first audio stream of the named file. If a file is already open, + * it will be closed first. */ +static int OpenPlayerFile(StreamPlayer *player, const char *filename) +{ + ClosePlayerFile(player); + + /* Open the file and get the first stream from it */ + player->file = openAudioFile(filename, BUFFER_TIME_MS); + if(!player->file) + { + fprintf(stderr, "Could not open audio in %s\n", filename); + goto error; + } + + /* Get the stream format, and figure out the OpenAL format */ + if(getAudioInfo(player->file, &player->rate, &player->channels, &player->type) != 0) + { + fprintf(stderr, "Error getting audio info for %s\n", filename); + goto error; + } + + player->format = GetFormat(player->channels, player->type, alIsBufferFormatSupportedSOFT); + if(player->format == 0) + { + fprintf(stderr, "Unsupported format (%s, %s) for %s\n", + ChannelsName(player->channels), TypeName(player->type), + filename); + goto error; + } + + return 1; + +error: + closeAudioFile(player->file); + player->file = NULL; + + return 0; +} + +/* Closes the audio file stream */ +static void ClosePlayerFile(StreamPlayer *player) +{ + closeAudioFile(player->file); + player->file = NULL; +} + + +/* Prebuffers some audio from the file, and starts playing the source */ +static int StartPlayer(StreamPlayer *player) +{ + size_t i; + + /* Rewind the source position and clear the buffer queue */ + alSourceRewind(player->source); + alSourcei(player->source, AL_BUFFER, 0); + + /* Fill the buffer queue */ + for(i = 0;i < NUM_BUFFERS;i++) + { + uint8_t *data; + size_t got; + + /* Get some data to give it to the buffer */ + data = getAudioData(player->file, &got); + if(!data) break; + + alBufferSamplesSOFT(player->buffers[i], player->rate, player->format, + BytesToFrames(got, player->channels, player->type), + player->channels, player->type, data); + } + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "Error buffering for playback\n"); + return 0; + } + + /* Now queue and start playback! */ + alSourceQueueBuffers(player->source, i, player->buffers); + alSourcePlay(player->source); + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "Error starting playback\n"); + return 0; + } + + return 1; +} + +static int UpdatePlayer(StreamPlayer *player) +{ + ALint processed, state; + + /* Get relevant source info */ + alGetSourcei(player->source, AL_SOURCE_STATE, &state); + alGetSourcei(player->source, AL_BUFFERS_PROCESSED, &processed); + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "Error checking source state\n"); + return 0; + } + + /* Unqueue and handle each processed buffer */ + while(processed > 0) + { + ALuint bufid; + uint8_t *data; + size_t got; + + alSourceUnqueueBuffers(player->source, 1, &bufid); + processed--; + + /* Read the next chunk of data, refill the buffer, and queue it + * back on the source */ + data = getAudioData(player->file, &got); + if(data != NULL) + { + alBufferSamplesSOFT(bufid, player->rate, player->format, + BytesToFrames(got, player->channels, player->type), + player->channels, player->type, data); + alSourceQueueBuffers(player->source, 1, &bufid); + } + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "Error buffering data\n"); + return 0; + } + } + + /* Make sure the source hasn't underrun */ + if(state != AL_PLAYING && state != AL_PAUSED) + { + ALint queued; + + /* If no buffers are queued, playback is finished */ + alGetSourcei(player->source, AL_BUFFERS_QUEUED, &queued); + if(queued == 0) + return 0; + + alSourcePlay(player->source); + if(alGetError() != AL_NO_ERROR) + { + fprintf(stderr, "Error restarting playback\n"); + return 0; + } + } + + return 1; +} + + +int main(int argc, char **argv) +{ + StreamPlayer *player; + int i; + + /* Print out usage if no file was specified */ + if(argc < 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + if(InitAL() != 0) + return 1; + + if(alIsExtensionPresent("AL_SOFT_buffer_samples")) + { + printf("AL_SOFT_buffer_samples supported!\n"); + alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT"); + alIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT"); + } + else + printf("AL_SOFT_buffer_samples not supported\n"); + + player = NewPlayer(); + + /* Play each file listed on the command line */ + for(i = 1;i < argc;i++) + { + const char *namepart; + + if(!OpenPlayerFile(player, argv[i])) + continue; + + /* Get the name portion, without the path, for display. */ + namepart = strrchr(argv[i], '/'); + if(namepart || (namepart=strrchr(argv[i], '\\'))) + namepart++; + else + namepart = argv[i]; + + printf("Playing: %s (%s, %s, %dhz)\n", namepart, + TypeName(player->type), ChannelsName(player->channels), + player->rate); + fflush(stdout); + + if(!StartPlayer(player)) + { + ClosePlayerFile(player); + continue; + } + + while(UpdatePlayer(player)) + Sleep(10); + + /* All done with this file. Close it and go to the next */ + ClosePlayerFile(player); + } + printf("Done.\n"); + + /* All files done. Delete the player, and close OpenAL */ + DeletePlayer(player); + player = NULL; + + CloseAL(); + + return 0; +} diff --git a/jni/openal-soft-android/examples/common/alhelpers.c b/jni/openal-soft-android/examples/common/alhelpers.c new file mode 100644 index 00000000..4582321c --- /dev/null +++ b/jni/openal-soft-android/examples/common/alhelpers.c @@ -0,0 +1,327 @@ +/* + * OpenAL Helpers + * + * Copyright (c) 2011 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains routines to help with some menial OpenAL-related tasks, + * such as opening a device and setting up a context, closing the device and + * destroying its context, converting between frame counts and byte lengths, + * finding an appropriate buffer format, and getting readable strings for + * channel configs and sample types. */ + +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" + +#include "alhelpers.h" + + +/* InitAL opens the default device and sets up a context using default + * attributes, making the program ready to call OpenAL functions. */ +int InitAL(void) +{ + ALCdevice *device; + ALCcontext *ctx; + + /* Open and initialize a device with default settings */ + device = alcOpenDevice(NULL); + if(!device) + { + fprintf(stderr, "Could not open a device!\n"); + return 1; + } + + ctx = alcCreateContext(device, NULL); + if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE) + { + if(ctx != NULL) + alcDestroyContext(ctx); + alcCloseDevice(device); + fprintf(stderr, "Could not set a context!\n"); + return 1; + } + + printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER)); + return 0; +} + +/* CloseAL closes the device belonging to the current context, and destroys the + * context. */ +void CloseAL(void) +{ + ALCdevice *device; + ALCcontext *ctx; + + ctx = alcGetCurrentContext(); + if(ctx == NULL) + return; + + device = alcGetContextsDevice(ctx); + + alcMakeContextCurrent(NULL); + alcDestroyContext(ctx); + alcCloseDevice(device); +} + + +/* GetFormat retrieves a compatible buffer format given the channel config and + * sample type. If an alIsBufferFormatSupportedSOFT-compatible function is + * provided, it will be called to find the closest-matching format from + * AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be + * found. */ +ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT) +{ + ALenum format = AL_NONE; + + /* If using AL_SOFT_buffer_samples, try looking through its formats */ + if(palIsBufferFormatSupportedSOFT) + { + /* AL_SOFT_buffer_samples is more lenient with matching formats. The + * specified sample type does not need to match the returned format, + * but it is nice to try to get something close. */ + if(type == AL_UNSIGNED_BYTE_SOFT || type == AL_BYTE_SOFT) + { + if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT; + } + else if(type == AL_UNSIGNED_SHORT_SOFT || type == AL_SHORT_SOFT) + { + if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT; + } + else if(type == AL_UNSIGNED_BYTE3_SOFT || type == AL_BYTE3_SOFT || + type == AL_UNSIGNED_INT_SOFT || type == AL_INT_SOFT || + type == AL_FLOAT_SOFT || type == AL_DOUBLE_SOFT) + { + if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT; + } + + if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) + format = AL_NONE; + + /* A matching format was not found or supported. Try 32-bit float. */ + if(format == AL_NONE) + { + if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT; + + if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) + format = AL_NONE; + } + /* 32-bit float not supported. Try 16-bit int. */ + if(format == AL_NONE) + { + if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT; + + if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) + format = AL_NONE; + } + /* 16-bit int not supported. Try 8-bit int. */ + if(format == AL_NONE) + { + if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT; + else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT; + else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT; + else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT; + else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT; + else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT; + + if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) + format = AL_NONE; + } + + return format; + } + + /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1, + * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and + * AL_EXT_DOUBLE for 64-bit float samples. */ + if(type == AL_UNSIGNED_BYTE_SOFT) + { + if(channels == AL_MONO_SOFT) + format = AL_FORMAT_MONO8; + else if(channels == AL_STEREO_SOFT) + format = AL_FORMAT_STEREO8; + else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if(channels == AL_QUAD_SOFT) + format = alGetEnumValue("AL_FORMAT_QUAD8"); + else if(channels == AL_5POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_51CHN8"); + else if(channels == AL_6POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_61CHN8"); + else if(channels == AL_7POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_71CHN8"); + } + } + else if(type == AL_SHORT_SOFT) + { + if(channels == AL_MONO_SOFT) + format = AL_FORMAT_MONO16; + else if(channels == AL_STEREO_SOFT) + format = AL_FORMAT_STEREO16; + else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if(channels == AL_QUAD_SOFT) + format = alGetEnumValue("AL_FORMAT_QUAD16"); + else if(channels == AL_5POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_51CHN16"); + else if(channels == AL_6POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_61CHN16"); + else if(channels == AL_7POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_71CHN16"); + } + } + else if(type == AL_FLOAT_SOFT && alIsExtensionPresent("AL_EXT_FLOAT32")) + { + if(channels == AL_MONO_SOFT) + format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32"); + else if(channels == AL_STEREO_SOFT) + format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32"); + else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if(channels == AL_QUAD_SOFT) + format = alGetEnumValue("AL_FORMAT_QUAD32"); + else if(channels == AL_5POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_51CHN32"); + else if(channels == AL_6POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_61CHN32"); + else if(channels == AL_7POINT1_SOFT) + format = alGetEnumValue("AL_FORMAT_71CHN32"); + } + } + else if(type == AL_DOUBLE_SOFT && alIsExtensionPresent("AL_EXT_DOUBLE")) + { + if(channels == AL_MONO_SOFT) + format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE"); + else if(channels == AL_STEREO_SOFT) + format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE"); + } + + /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as + * opposed to 0. Correct it. */ + if(format == -1) + format = 0; + + return format; +} + + +void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate, + ALenum internalformat, ALsizei samples, + ALenum channels, ALenum type, + const ALvoid *data) +{ + alBufferData(buffer, internalformat, data, + FramesToBytes(samples, channels, type), + samplerate); +} + + +const char *ChannelsName(ALenum chans) +{ + switch(chans) + { + case AL_MONO_SOFT: return "Mono"; + case AL_STEREO_SOFT: return "Stereo"; + case AL_REAR_SOFT: return "Rear"; + case AL_QUAD_SOFT: return "Quadraphonic"; + case AL_5POINT1_SOFT: return "5.1 Surround"; + case AL_6POINT1_SOFT: return "6.1 Surround"; + case AL_7POINT1_SOFT: return "7.1 Surround"; + } + return "Unknown Channels"; +} + +const char *TypeName(ALenum type) +{ + switch(type) + { + case AL_BYTE_SOFT: return "S8"; + case AL_UNSIGNED_BYTE_SOFT: return "U8"; + case AL_SHORT_SOFT: return "S16"; + case AL_UNSIGNED_SHORT_SOFT: return "U16"; + case AL_INT_SOFT: return "S32"; + case AL_UNSIGNED_INT_SOFT: return "U32"; + case AL_FLOAT_SOFT: return "Float32"; + case AL_DOUBLE_SOFT: return "Float64"; + } + return "Unknown Type"; +} + + +ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type) +{ + switch(channels) + { + case AL_MONO_SOFT: size *= 1; break; + case AL_STEREO_SOFT: size *= 2; break; + case AL_REAR_SOFT: size *= 2; break; + case AL_QUAD_SOFT: size *= 4; break; + case AL_5POINT1_SOFT: size *= 6; break; + case AL_6POINT1_SOFT: size *= 7; break; + case AL_7POINT1_SOFT: size *= 8; break; + } + + switch(type) + { + case AL_BYTE_SOFT: size *= sizeof(ALbyte); break; + case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break; + case AL_SHORT_SOFT: size *= sizeof(ALshort); break; + case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break; + case AL_INT_SOFT: size *= sizeof(ALint); break; + case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break; + case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break; + case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break; + } + + return size; +} + +ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type) +{ + return size / FramesToBytes(1, channels, type); +} diff --git a/jni/openal-soft-android/examples/common/alhelpers.h b/jni/openal-soft-android/examples/common/alhelpers.h new file mode 100644 index 00000000..62ed5be2 --- /dev/null +++ b/jni/openal-soft-android/examples/common/alhelpers.h @@ -0,0 +1,51 @@ +#ifndef ALHELPERS_H +#define ALHELPERS_H + +#ifndef _WIN32 +#include +#define Sleep(x) usleep((x)*1000) +#else +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#include "AL/alc.h" +#include "AL/al.h" +#include "AL/alext.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Some helper functions to get the name from the channel and type enums. */ +const char *ChannelsName(ALenum chans); +const char *TypeName(ALenum type); + +/* Helpers to convert frame counts and byte lengths. */ +ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type); +ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type); + +/* Retrieves a compatible buffer format given the channel configuration and + * sample type. If an alIsBufferFormatSupportedSOFT-compatible function is + * provided, it will be called to find the closest-matching format from + * AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be + * found. */ +ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT); + +/* Loads samples into a buffer using the standard alBufferData call, but with a + * LPALBUFFERSAMPLESSOFT-compatible prototype. Assumes internalformat is valid + * for alBufferData, and that channels and type match it. */ +void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate, + ALenum internalformat, ALsizei samples, + ALenum channels, ALenum type, + const ALvoid *data); + +/* Easy device init/deinit functions. InitAL returns 0 on success. */ +int InitAL(void); +void CloseAL(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ALHELPERS_H */ diff --git a/jni/openal-soft-android/examples/common/sdl_sound.c b/jni/openal-soft-android/examples/common/sdl_sound.c new file mode 100644 index 00000000..79a5bf32 --- /dev/null +++ b/jni/openal-soft-android/examples/common/sdl_sound.c @@ -0,0 +1,164 @@ +/* + * SDL_sound Decoder Helpers + * + * Copyright (c) 2013 by Chris Robinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* This file contains routines for helping to decode audio using SDL_sound. + * There's very little OpenAL-specific code here. + */ +#include "sdl_sound.h" + +#include +#include +#include +#include +#include + +#include + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" + +#include "alhelpers.h" + + +static int done_init = 0; + +FilePtr openAudioFile(const char *fname, size_t buftime_ms) +{ + FilePtr file; + ALuint rate; + Uint32 bufsize; + ALenum chans, type; + + /* We need to make sure SDL_sound is initialized. */ + if(!done_init) + { + Sound_Init(); + done_init = 1; + } + + file = Sound_NewSampleFromFile(fname, NULL, 0); + if(!file) + { + fprintf(stderr, "Failed to open %s: %s\n", fname, Sound_GetError()); + return NULL; + } + + if(getAudioInfo(file, &rate, &chans, &type) != 0) + { + Sound_FreeSample(file); + return NULL; + } + + bufsize = FramesToBytes((ALsizei)(buftime_ms/1000.0*rate), chans, type); + if(Sound_SetBufferSize(file, bufsize) == 0) + { + fprintf(stderr, "Failed to set buffer size to %u bytes: %s\n", bufsize, Sound_GetError()); + Sound_FreeSample(file); + return NULL; + } + + return file; +} + +void closeAudioFile(FilePtr file) +{ + if(file) + Sound_FreeSample(file); +} + + +int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type) +{ + if(file->actual.channels == 1) + *channels = AL_MONO_SOFT; + else if(file->actual.channels == 2) + *channels = AL_STEREO_SOFT; + else + { + fprintf(stderr, "Unsupported channel count: %d\n", file->actual.channels); + return 1; + } + + if(file->actual.format == AUDIO_U8) + *type = AL_UNSIGNED_BYTE_SOFT; + else if(file->actual.format == AUDIO_S8) + *type = AL_BYTE_SOFT; + else if(file->actual.format == AUDIO_U16LSB || file->actual.format == AUDIO_U16MSB) + *type = AL_UNSIGNED_SHORT_SOFT; + else if(file->actual.format == AUDIO_S16LSB || file->actual.format == AUDIO_S16MSB) + *type = AL_SHORT_SOFT; + else + { + fprintf(stderr, "Unsupported sample format: 0x%04x\n", file->actual.format); + return 1; + } + + *rate = file->actual.rate; + + return 0; +} + + +uint8_t *getAudioData(FilePtr file, size_t *length) +{ + *length = Sound_Decode(file); + if(*length == 0) + return NULL; + if((file->actual.format == AUDIO_U16LSB && AUDIO_U16LSB != AUDIO_U16SYS) || + (file->actual.format == AUDIO_U16MSB && AUDIO_U16MSB != AUDIO_U16SYS) || + (file->actual.format == AUDIO_S16LSB && AUDIO_S16LSB != AUDIO_S16SYS) || + (file->actual.format == AUDIO_S16MSB && AUDIO_S16MSB != AUDIO_S16SYS)) + { + /* Swap bytes if the decoded endianness doesn't match the system. */ + char *buffer = file->buffer; + size_t i; + for(i = 0;i < *length;i+=2) + { + char b = buffer[i]; + buffer[i] = buffer[i+1]; + buffer[i+1] = b; + } + } + return file->buffer; +} + +void *decodeAudioStream(FilePtr file, size_t *length) +{ + Uint32 got; + char *mem; + + got = Sound_DecodeAll(file); + if(got == 0) + { + *length = 0; + return NULL; + } + + mem = malloc(got); + memcpy(mem, file->buffer, got); + + *length = got; + return mem; +} diff --git a/jni/openal-soft-android/examples/common/sdl_sound.h b/jni/openal-soft-android/examples/common/sdl_sound.h new file mode 100644 index 00000000..e93ab92b --- /dev/null +++ b/jni/openal-soft-android/examples/common/sdl_sound.h @@ -0,0 +1,43 @@ +#ifndef EXAMPLES_SDL_SOUND_H +#define EXAMPLES_SDL_SOUND_H + +#include "AL/al.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Opaque handles to files and streams. Apps don't need to concern themselves + * with the internals */ +typedef Sound_Sample *FilePtr; + +/* Opens a file with SDL_sound, and specifies the size of the sample buffer in + * milliseconds. */ +FilePtr openAudioFile(const char *fname, size_t buftime_ms); + +/* Closes/frees an opened file */ +void closeAudioFile(FilePtr file); + +/* Returns information about the given audio stream. Returns 0 on success. */ +int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type); + +/* Returns a pointer to the next available chunk of decoded audio. The size (in + * bytes) of the returned data buffer is stored in 'length', and the returned + * pointer is only valid until the next call to getAudioData. */ +uint8_t *getAudioData(FilePtr file, size_t *length); + +/* Decodes all remaining data from the stream and returns a buffer containing + * the audio data, with the size stored in 'length'. The returned pointer must + * be freed with a call to free(). Note that since this decodes the whole + * stream, using it on lengthy streams (eg, music) will use a lot of memory. + * Such streams are better handled using getAudioData to keep smaller chunks in + * memory at any given time. */ +void *decodeAudioStream(FilePtr, size_t *length); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* EXAMPLES_SDL_SOUND_H */ diff --git a/jni/openal-soft-android/hrtf.txt b/jni/openal-soft-android/hrtf.txt new file mode 100644 index 00000000..59a8b4ee --- /dev/null +++ b/jni/openal-soft-android/hrtf.txt @@ -0,0 +1,74 @@ +HRTF Support +============ + +Starting with OpenAL Soft 1.14, HRTFs can be used to enable enhanced +spatialization for both 3D (mono) and multi-channel sources, when used with +headphones/stereo output. This can be enabled using the 'hrtf' config option. + +For multi-channel sources this creates a virtual speaker effect, making it +sound as if speakers provide a discrete position for each channel around the +listener. For mono sources this provides much more versatility in the perceived +placement of sounds, making it seem as though they are coming from all around, +including above and below the listener, instead of just to the front, back, and +sides. + +The built-in data set is based on the KEMAR HRTF data provided by MIT, which +can be found at . It's only +available when using 44100hz playback. + + +External HRTF Data Sets +======================= + +OpenAL Soft also provides an option to use user-specified data sets, in +addition to or in place of the built-in set. This allows users to provide their +own data sets, which could be better suited for their heads, or to work with +stereo speakers instead of headphones, or to support more playback sample +rates, for example. + +The file format is specified below. It uses little-endian byte order. + +== +ALchar magic[8] = "MinPHR01"; +ALuint sampleRate; + +ALubyte hrirSize; /* Can be 8 to 128 in steps of 8. */ +ALubyte evCount; /* Can be 5 to 128. */ + +ALubyte azCount[evCount]; /* Each can be 1 to 128. */ + +/* NOTE: hrirCount is the sum of all azCounts */ +ALshort coefficients[hrirCount][hrirSize]; +ALubyte delays[hrirCount]; /* Each can be 0 to 63. */ +== + +The data is described as thus: + +The file first starts with the 8-byte marker, "MinPHR01", to identify it as an +HRTF data set. This is followed by an unsigned 32-bit integer, specifying the +sample rate the data set is designed for (OpenAL Soft will not use it if the +output device's playback rate doesn't match). + +Afterward, an unsigned 8-bit integer specifies how many sample points (or +finite impulse response filter coefficients) make up each HRIR. + +The following unsigned 8-bit integer specifies the number of elevations used +by the data set. The elevations start at the bottom (-90 degrees), and +increment upwards. Following this is an array of unsigned 8-bit integers, one +for each elevation which specifies the number of azimuths (and thus HRIRs) that +make up each elevation. Azimuths start clockwise from the front, constructing +a full circle for the left ear only. The right ear uses the same HRIRs but in +reverse (ie, left = angle, right = 360-angle). + +The actual coefficients follow. Each coefficient is a signed 16-bit sample, +with each HRIR being a consecutive number of sample points. The HRIRs must be +minimum-phase. This allows the use of a smaller filter length, reducing +computation. For reference, the built-in data set uses a 32-point filter while +even the smallest data set provided by MIT used a 128-sample filter (a 4x +reduction by applying minimum-phase reconstruction). Theoretically, one could +further reduce the minimum-phase version down to a 16-point filter with only a +small reduction in quality. + +After the coefficients is an array of unsigned 8-bit delay values, one for +each HRIR. This is the propagation delay (in samples) a signal must wait before +being convolved with the corresponding minimum-phase HRIR filter. diff --git a/jni/openal-soft-android/include/AL/al.h b/jni/openal-soft-android/include/AL/al.h index 95d33988..413b3833 100644 --- a/jni/openal-soft-android/include/AL/al.h +++ b/jni/openal-soft-android/include/AL/al.h @@ -21,26 +21,19 @@ extern "C" { #define AL_APIENTRY #endif -#if defined(TARGET_OS_MAC) && TARGET_OS_MAC - #pragma export on -#endif -/* - * The OPENAL, ALAPI, ALAPIENTRY, AL_INVALID, AL_ILLEGAL_ENUM, and - * AL_ILLEGAL_COMMAND macros are deprecated, but are included for - * applications porting code from AL 1.0 - */ +/** Deprecated macro. */ #define OPENAL -#define ALAPI AL_API -#define ALAPIENTRY AL_APIENTRY -#define AL_INVALID (-1) -#define AL_ILLEGAL_ENUM AL_INVALID_ENUM -#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION +#define ALAPI AL_API +#define ALAPIENTRY AL_APIENTRY +#define AL_INVALID (-1) +#define AL_ILLEGAL_ENUM AL_INVALID_ENUM +#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION +/** Supported AL version. */ #define AL_VERSION_1_0 #define AL_VERSION_1_1 - /** 8-bit boolean */ typedef char ALboolean; @@ -83,633 +76,578 @@ typedef void ALvoid; /* Enumerant values begin at column 50. No tabs. */ -/* "no distance model" or "no buffer" */ -#define AL_NONE 0 +/** "no distance model" or "no buffer" */ +#define AL_NONE 0 -/* Boolean False. */ -#define AL_FALSE 0 +/** Boolean False. */ +#define AL_FALSE 0 /** Boolean True. */ -#define AL_TRUE 1 - -/** Indicate Source has relative coordinates. */ -#define AL_SOURCE_RELATIVE 0x202 - +#define AL_TRUE 1 /** - * Directional source, inner cone angle, in degrees. - * Range: [0-360] - * Default: 360 - */ -#define AL_CONE_INNER_ANGLE 0x1001 - -/** - * Directional source, outer cone angle, in degrees. - * Range: [0-360] - * Default: 360 - */ -#define AL_CONE_OUTER_ANGLE 0x1002 - -/** - * Specify the pitch to be applied at source. - * Range: [0.5-2.0] - * Default: 1.0 - */ -#define AL_PITCH 0x1003 - -/** - * Specify the current location in three dimensional space. - * OpenAL, like OpenGL, uses a right handed coordinate system, - * where in a frontal default view X (thumb) points right, - * Y points up (index finger), and Z points towards the - * viewer/camera (middle finger). - * To switch from a left handed coordinate system, flip the - * sign on the Z coordinate. - * Listener position is always in the world coordinate system. - */ -#define AL_POSITION 0x1004 - -/** Specify the current direction. */ -#define AL_DIRECTION 0x1005 - -/** Specify the current velocity in three dimensional space. */ -#define AL_VELOCITY 0x1006 - -/** - * Indicate whether source is looping. - * Type: ALboolean? + * Relative source. + * Type: ALboolean * Range: [AL_TRUE, AL_FALSE] - * Default: FALSE. - */ -#define AL_LOOPING 0x1007 - -/** - * Indicate the buffer to provide sound samples. - * Type: ALuint. - * Range: any valid Buffer id. - */ -#define AL_BUFFER 0x1009 - -/** - * Indicate the gain (volume amplification) applied. - * Type: ALfloat. - * Range: ]0.0- ] - * A value of 1.0 means un-attenuated/unchanged. - * Each division by 2 equals an attenuation of -6dB. - * Each multiplicaton with 2 equals an amplification of +6dB. - * A value of 0.0 is meaningless with respect to a logarithmic - * scale; it is interpreted as zero volume - the channel - * is effectively disabled. - */ -#define AL_GAIN 0x100A - -/* - * Indicate minimum source attenuation - * Type: ALfloat - * Range: [0.0 - 1.0] + * Default: AL_FALSE * - * Logarthmic + * Specifies if the Source has relative coordinates. */ -#define AL_MIN_GAIN 0x100D +#define AL_SOURCE_RELATIVE 0x202 + /** - * Indicate maximum source attenuation - * Type: ALfloat - * Range: [0.0 - 1.0] + * Inner cone angle, in degrees. + * Type: ALint, ALfloat + * Range: [0 - 360] + * Default: 360 * - * Logarthmic + * The angle covered by the inner cone, where the source will not attenuate. */ -#define AL_MAX_GAIN 0x100E +#define AL_CONE_INNER_ANGLE 0x1001 /** - * Indicate listener orientation. + * Outer cone angle, in degrees. + * Range: [0 - 360] + * Default: 360 * - * at/up + * The angle covered by the outer cone, where the source will be fully + * attenuated. */ -#define AL_ORIENTATION 0x100F +#define AL_CONE_OUTER_ANGLE 0x1002 /** - * Source state information. - */ -#define AL_SOURCE_STATE 0x1010 -#define AL_INITIAL 0x1011 -#define AL_PLAYING 0x1012 -#define AL_PAUSED 0x1013 -#define AL_STOPPED 0x1014 - -/** - * Buffer Queue params - */ -#define AL_BUFFERS_QUEUED 0x1015 -#define AL_BUFFERS_PROCESSED 0x1016 - -/** - * Source buffer position information - */ -#define AL_SEC_OFFSET 0x1024 -#define AL_SAMPLE_OFFSET 0x1025 -#define AL_BYTE_OFFSET 0x1026 - -/* - * Source type (Static, Streaming or undetermined) - * Source is Static if a Buffer has been attached using AL_BUFFER - * Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers - * Source is undetermined when it has the NULL buffer attached - */ -#define AL_SOURCE_TYPE 0x1027 -#define AL_STATIC 0x1028 -#define AL_STREAMING 0x1029 -#define AL_UNDETERMINED 0x1030 - -/** Sound samples: format specifier. */ -#define AL_FORMAT_MONO8 0x1100 -#define AL_FORMAT_MONO16 0x1101 -#define AL_FORMAT_STEREO8 0x1102 -#define AL_FORMAT_STEREO16 0x1103 - -/** - * source specific reference distance - * Type: ALfloat - * Range: 0.0 - +inf + * Source pitch. + * Type: ALfloat + * Range: [0.5 - 2.0] + * Default: 1.0 * - * At 0.0, no distance attenuation occurs. Default is - * 1.0. + * A multiplier for the frequency (sample rate) of the source's buffer. */ -#define AL_REFERENCE_DISTANCE 0x1020 +#define AL_PITCH 0x1003 /** - * source specific rolloff factor - * Type: ALfloat - * Range: 0.0 - +inf + * Source or listener position. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} * + * The source or listener location in three dimensional space. + * + * OpenAL, like OpenGL, uses a right handed coordinate system, where in a + * frontal default view X (thumb) points right, Y points up (index finger), and + * Z points towards the viewer/camera (middle finger). + * + * To switch from a left handed coordinate system, flip the sign on the Z + * coordinate. */ -#define AL_ROLLOFF_FACTOR 0x1021 +#define AL_POSITION 0x1004 /** - * Directional source, outer cone gain. + * Source direction. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} * - * Default: 0.0 - * Range: [0.0 - 1.0] - * Logarithmic + * Specifies the current direction in local space. + * A zero-length vector specifies an omni-directional source (cone is ignored). */ -#define AL_CONE_OUTER_GAIN 0x1022 +#define AL_DIRECTION 0x1005 /** - * Indicate distance above which sources are not - * attenuated using the inverse clamped distance model. + * Source or listener velocity. + * Type: ALfloat[3], ALint[3] + * Default: {0, 0, 0} * + * Specifies the current velocity in local space. + */ +#define AL_VELOCITY 0x1006 + +/** + * Source looping. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + * + * Specifies whether source is looping. + */ +#define AL_LOOPING 0x1007 + +/** + * Source buffer. + * Type: ALuint + * Range: any valid Buffer. + * + * Specifies the buffer to provide sound samples. + */ +#define AL_BUFFER 0x1009 + +/** + * Source or listener gain. + * Type: ALfloat + * Range: [0.0 - ] + * + * A value of 1.0 means unattenuated. Each division by 2 equals an attenuation + * of about -6dB. Each multiplicaton by 2 equals an amplification of about + * +6dB. + * + * A value of 0.0 is meaningless with respect to a logarithmic scale; it is + * silent. + */ +#define AL_GAIN 0x100A + +/** + * Minimum source gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * The minimum gain allowed for a source, after distance and cone attenation is + * applied (if applicable). + */ +#define AL_MIN_GAIN 0x100D + +/** + * Maximum source gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * + * The maximum gain allowed for a source, after distance and cone attenation is + * applied (if applicable). + */ +#define AL_MAX_GAIN 0x100E + +/** + * Listener orientation. + * Type: ALfloat[6] + * Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0} + * + * Effectively two three dimensional vectors. The first vector is the front (or + * "at") and the second is the top (or "up"). + * + * Both vectors are in local space. + */ +#define AL_ORIENTATION 0x100F + +/** + * Source state (query only). + * Type: ALint + * Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED] + */ +#define AL_SOURCE_STATE 0x1010 + +/** Source state value. */ +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Source Buffer Queue size (query only). + * Type: ALint + * + * The number of buffers queued using alSourceQueueBuffers, minus the buffers + * removed with alSourceUnqueueBuffers. + */ +#define AL_BUFFERS_QUEUED 0x1015 + +/** + * Source Buffer Queue processed count (query only). + * Type: ALint + * + * The number of queued buffers that have been fully processed, and can be + * removed with alSourceUnqueueBuffers. + * + * Looping sources will never fully process buffers because they will be set to + * play again for when the source loops. + */ +#define AL_BUFFERS_PROCESSED 0x1016 + +/** + * Source reference distance. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + * + * The distance in units that no attenuation occurs. + * + * At 0.0, no distance attenuation ever occurs on non-linear attenuation models. + */ +#define AL_REFERENCE_DISTANCE 0x1020 + +/** + * Source rolloff factor. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + * + * Multiplier to exaggerate or diminish distance attenuation. + * + * At 0.0, no distance attenuation ever occurs. + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Outer cone gain. + * Type: ALfloat + * Range: [0.0 - 1.0] + * Default: 0.0 + * + * The gain attenuation applied when the listener is outside of the source's + * outer cone. + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Source maximum distance. + * Type: ALfloat + * Range: [0.0 - ] * Default: +inf - * Type: ALfloat - * Range: 0.0 - +inf + * + * The distance above which the source is not attenuated any further with a + * clamped distance model, or where attenuation reaches 0.0 gain for linear + * distance models with a default rolloff factor. */ -#define AL_MAX_DISTANCE 0x1023 +#define AL_MAX_DISTANCE 0x1023 -/** - * Sound samples: frequency, in units of Hertz [Hz]. - * This is the number of samples per second. Half of the - * sample frequency marks the maximum significant - * frequency component. +/** Source buffer position, in seconds */ +#define AL_SEC_OFFSET 0x1024 +/** Source buffer position, in sample frames */ +#define AL_SAMPLE_OFFSET 0x1025 +/** Source buffer position, in bytes */ +#define AL_BYTE_OFFSET 0x1026 + +/** + * Source type (query only). + * Type: ALint + * Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED] + * + * A Source is Static if a Buffer has been attached using AL_BUFFER. + * + * A Source is Streaming if one or more Buffers have been attached using + * alSourceQueueBuffers. + * + * A Source is Undetermined when it has the NULL buffer attached using + * AL_BUFFER. */ -#define AL_FREQUENCY 0x2001 -#define AL_BITS 0x2002 -#define AL_CHANNELS 0x2003 -#define AL_SIZE 0x2004 +#define AL_SOURCE_TYPE 0x1027 + +/** Source type value. */ +#define AL_STATIC 0x1028 +#define AL_STREAMING 0x1029 +#define AL_UNDETERMINED 0x1030 + +/** Buffer format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** Buffer frequency (query only). */ +#define AL_FREQUENCY 0x2001 +/** Buffer bits per sample (query only). */ +#define AL_BITS 0x2002 +/** Buffer channel count (query only). */ +#define AL_CHANNELS 0x2003 +/** Buffer data size (query only). */ +#define AL_SIZE 0x2004 /** * Buffer state. * - * Not supported for public use (yet). + * Not for public use. */ -#define AL_UNUSED 0x2010 -#define AL_PENDING 0x2011 -#define AL_PROCESSED 0x2012 +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 -/** Errors: No Error. */ -#define AL_NO_ERROR AL_FALSE +/** No error. */ +#define AL_NO_ERROR 0 -/** - * Invalid Name paramater passed to AL call. - */ -#define AL_INVALID_NAME 0xA001 +/** Invalid name paramater passed to AL call. */ +#define AL_INVALID_NAME 0xA001 -/** - * Invalid parameter passed to AL call. - */ -#define AL_INVALID_ENUM 0xA002 +/** Invalid enum parameter passed to AL call. */ +#define AL_INVALID_ENUM 0xA002 -/** - * Invalid enum parameter value. - */ -#define AL_INVALID_VALUE 0xA003 +/** Invalid value parameter passed to AL call. */ +#define AL_INVALID_VALUE 0xA003 -/** - * Illegal call. - */ -#define AL_INVALID_OPERATION 0xA004 +/** Illegal AL call. */ +#define AL_INVALID_OPERATION 0xA004 - -/** - * No mojo. - */ -#define AL_OUT_OF_MEMORY 0xA005 +/** Not enough memory. */ +#define AL_OUT_OF_MEMORY 0xA005 -/** Context strings: Vendor Name. */ -#define AL_VENDOR 0xB001 -#define AL_VERSION 0xB002 -#define AL_RENDERER 0xB003 -#define AL_EXTENSIONS 0xB004 +/** Context string: Vendor ID. */ +#define AL_VENDOR 0xB001 +/** Context string: Version. */ +#define AL_VERSION 0xB002 +/** Context string: Renderer ID. */ +#define AL_RENDERER 0xB003 +/** Context string: Space-separated extension list. */ +#define AL_EXTENSIONS 0xB004 -/** Global tweakage. */ /** - * Doppler scale. Default 1.0 - */ -#define AL_DOPPLER_FACTOR 0xC000 - -/** - * Tweaks speed of propagation. - */ -#define AL_DOPPLER_VELOCITY 0xC001 - -/** - * Speed of Sound in units per second - */ -#define AL_SPEED_OF_SOUND 0xC003 - -/** - * Distance models + * Doppler scale. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 * - * used in conjunction with DistanceModel + * Scale for source and listener velocities. + */ +#define AL_DOPPLER_FACTOR 0xC000 +AL_API void AL_APIENTRY alDopplerFactor(ALfloat value); + +/** + * Doppler velocity (deprecated). * - * implicit: NONE, which disances distance attenuation. + * A multiplier applied to the Speed of Sound. */ -#define AL_DISTANCE_MODEL 0xD000 -#define AL_INVERSE_DISTANCE 0xD001 -#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 -#define AL_LINEAR_DISTANCE 0xD003 -#define AL_LINEAR_DISTANCE_CLAMPED 0xD004 -#define AL_EXPONENT_DISTANCE 0xD005 -#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 +#define AL_DOPPLER_VELOCITY 0xC001 +AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value); -/* - * Renderer State management +/** + * Speed of Sound, in units per second. + * Type: ALfloat + * Range: [0.0001 - ] + * Default: 343.3 + * + * The speed at which sound waves are assumed to travel, when calculating the + * doppler effect. */ -AL_API void AL_APIENTRY alEnable( ALenum capability ); +#define AL_SPEED_OF_SOUND 0xC003 +AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value); -AL_API void AL_APIENTRY alDisable( ALenum capability ); - -AL_API ALboolean AL_APIENTRY alIsEnabled( ALenum capability ); - - -/* - * State retrieval +/** + * Distance attenuation model. + * Type: ALint + * Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED, + * AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED, + * AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED] + * Default: AL_INVERSE_DISTANCE_CLAMPED + * + * The model by which sources attenuate with distance. + * + * None - No distance attenuation. + * Inverse - Doubling the distance halves the source gain. + * Linear - Linear gain scaling between the reference and max distances. + * Exponent - Exponential gain dropoff. + * + * Clamped variations work like the non-clamped counterparts, except the + * distance calculated is clamped between the reference and max distances. */ -AL_API const ALchar* AL_APIENTRY alGetString( ALenum param ); +#define AL_DISTANCE_MODEL 0xD000 +AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel); -AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data ); +/** Distance model value. */ +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 +#define AL_LINEAR_DISTANCE 0xD003 +#define AL_LINEAR_DISTANCE_CLAMPED 0xD004 +#define AL_EXPONENT_DISTANCE 0xD005 +#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 -AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data ); +/** Renderer State management. */ +AL_API void AL_APIENTRY alEnable(ALenum capability); +AL_API void AL_APIENTRY alDisable(ALenum capability); +AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability); -AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data ); +/** State retrieval. */ +AL_API const ALchar* AL_APIENTRY alGetString(ALenum param); +AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values); +AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values); +AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values); +AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param); +AL_API ALint AL_APIENTRY alGetInteger(ALenum param); +AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param); +AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param); -AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data ); - -AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param ); - -AL_API ALint AL_APIENTRY alGetInteger( ALenum param ); - -AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param ); - -AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param ); - - -/* - * Error support. - * Obtain the most recent error generated in the AL state machine. +/** + * Error retrieval. + * + * Obtain the first error generated in the AL context since the last check. */ -AL_API ALenum AL_APIENTRY alGetError( void ); +AL_API ALenum AL_APIENTRY alGetError(void); - -/* +/** * Extension support. - * Query for the presence of an extension, and obtain any appropriate - * function pointers and enum values. - */ -AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname ); - -AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname ); - -AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename ); - - -/* - * LISTENER - * Listener represents the location and orientation of the - * 'user' in 3D-space. * - * Properties include: - - * - * Gain AL_GAIN ALfloat - * Position AL_POSITION ALfloat[3] - * Velocity AL_VELOCITY ALfloat[3] - * Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors) -*/ - -/* - * Set Listener parameters + * Query for the presence of an extension, and obtain any appropriate function + * pointers and enum values. */ -AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value ); - -AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); - -AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values ); - -AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value ); - -AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ); - -AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values ); - -/* - * Get Listener parameters - */ -AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value ); - -AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); - -AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values ); - -AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value ); - -AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); - -AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values ); - - -/** - * SOURCE - * Sources represent individual sound objects in 3D-space. - * Sources take the PCM data provided in the specified Buffer, - * apply Source-specific modifications, and then - * submit them to be mixed according to spatial arrangement etc. - * - * Properties include: - - * - * Gain AL_GAIN ALfloat - * Min Gain AL_MIN_GAIN ALfloat - * Max Gain AL_MAX_GAIN ALfloat - * Position AL_POSITION ALfloat[3] - * Velocity AL_VELOCITY ALfloat[3] - * Direction AL_DIRECTION ALfloat[3] - * Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE) - * Reference Distance AL_REFERENCE_DISTANCE ALfloat - * Max Distance AL_MAX_DISTANCE ALfloat - * RollOff Factor AL_ROLLOFF_FACTOR ALfloat - * Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat - * Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat - * Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat - * Pitch AL_PITCH ALfloat - * Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE) - * MS Offset AL_MSEC_OFFSET ALint or ALfloat - * Byte Offset AL_BYTE_OFFSET ALint or ALfloat - * Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat - * Attached Buffer AL_BUFFER ALint - * State (Query only) AL_SOURCE_STATE ALint - * Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint - * Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint - */ - -/* Create Source objects */ -AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources ); - -/* Delete Source objects */ -AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources ); - -/* Verify a handle is a valid Source */ -AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid ); - -/* - * Set Source parameters - */ -AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value ); - -AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); - -AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values ); - -AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value ); - -AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); - -AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values ); - -/* - * Get Source parameters - */ -AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value ); - -AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); - -AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values ); - -AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value ); - -AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); - -AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values ); - - -/* - * Source vector based playback calls - */ - -/* Play, replay, or resume (if paused) a list of Sources */ -AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids ); - -/* Stop a list of Sources */ -AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids ); - -/* Rewind a list of Sources */ -AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids ); - -/* Pause a list of Sources */ -AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids ); - -/* - * Source based playback calls - */ - -/* Play, replay, or resume a Source */ -AL_API void AL_APIENTRY alSourcePlay( ALuint sid ); - -/* Stop a Source */ -AL_API void AL_APIENTRY alSourceStop( ALuint sid ); - -/* Rewind a Source (set playback postiton to beginning) */ -AL_API void AL_APIENTRY alSourceRewind( ALuint sid ); - -/* Pause a Source */ -AL_API void AL_APIENTRY alSourcePause( ALuint sid ); - -/* - * Source Queuing - */ -AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ); - -AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ); - - -/** - * BUFFER - * Buffer objects are storage space for sample data. - * Buffers are referred to by Sources. One Buffer can be used - * by multiple Sources. - * - * Properties include: - - * - * Frequency (Query only) AL_FREQUENCY ALint - * Size (Query only) AL_SIZE ALint - * Bits (Query only) AL_BITS ALint - * Channels (Query only) AL_CHANNELS ALint - */ - -/* Create Buffer objects */ -AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers ); - -/* Delete Buffer objects */ -AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers ); - -/* Verify a handle is a valid Buffer */ -AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint bid ); - -/* Specify the data to be copied into a buffer */ -AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ); - -/* - * Set Buffer parameters - */ -AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value ); - -AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); - -AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values ); - -AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value ); - -AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); - -AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values ); - -/* - * Get Buffer parameters - */ -AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value ); - -AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); - -AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values ); - -AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value ); - -AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); - -AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values ); - - -/* - * Global Parameters - */ -AL_API void AL_APIENTRY alDopplerFactor( ALfloat value ); - -AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value ); - -AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value ); - -AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel ); - -/* - * Pointer-to-function types, useful for dynamically getting AL entry points. - */ -typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability ); -typedef void (AL_APIENTRY *LPALDISABLE)( ALenum capability ); -typedef ALboolean (AL_APIENTRY *LPALISENABLED)( ALenum capability ); -typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)( ALenum param ); -typedef void (AL_APIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data ); -typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data ); -typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data ); -typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data ); -typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)( ALenum param ); -typedef ALint (AL_APIENTRY *LPALGETINTEGER)( ALenum param ); -typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)( ALenum param ); -typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)( ALenum param ); -typedef ALenum (AL_APIENTRY *LPALGETERROR)( void ); -typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname ); -typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)( const ALchar* fname ); -typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)( const ALchar* ename ); -typedef void (AL_APIENTRY *LPALLISTENERF)( ALenum param, ALfloat value ); -typedef void (AL_APIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); -typedef void (AL_APIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values ); -typedef void (AL_APIENTRY *LPALLISTENERI)( ALenum param, ALint value ); -typedef void (AL_APIENTRY *LPALLISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 ); -typedef void (AL_APIENTRY *LPALLISTENERIV)( ALenum param, const ALint* values ); -typedef void (AL_APIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value ); -typedef void (AL_APIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ); -typedef void (AL_APIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values ); -typedef void (AL_APIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value ); -typedef void (AL_APIENTRY *LPALGETLISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 ); -typedef void (AL_APIENTRY *LPALGETLISTENERIV)( ALenum param, ALint* values ); -typedef void (AL_APIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources ); -typedef void (AL_APIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources ); -typedef ALboolean (AL_APIENTRY *LPALISSOURCE)( ALuint sid ); -typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value); -typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); -typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values ); -typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value); -typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ); -typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values ); -typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value ); -typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); -typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values ); -typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value ); -typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3); -typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values ); -typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids ); -typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids ); -typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids ); -typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids ); -typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid ); -typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid ); -typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid ); -typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid ); -typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids ); -typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids ); -typedef void (AL_APIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers ); -typedef void (AL_APIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers ); -typedef ALboolean (AL_APIENTRY *LPALISBUFFER)( ALuint bid ); -typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ); -typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value); -typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ); -typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values ); -typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value); -typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ); -typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values ); -typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value ); -typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3); -typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values ); -typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value ); -typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3); -typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, ALenum param, ALint* values ); -typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)( ALfloat value ); -typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)( ALfloat value ); -typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)( ALfloat value ); -typedef void (AL_APIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel ); - -#if defined(TARGET_OS_MAC) && TARGET_OS_MAC - #pragma export off -#endif +AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname); +AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname); +AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename); + + +/** Set Listener parameters */ +AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value); +AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value); +AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values); + +/** Get Listener parameters */ +AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values); + + +/** Create Source objects. */ +AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources); +/** Delete Source objects. */ +AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources); +/** Verify a handle is a valid Source. */ +AL_API ALboolean AL_APIENTRY alIsSource(ALuint source); + +/** Set Source parameters. */ +AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value); +AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value); +AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values); + +/** Get Source parameters. */ +AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values); + + +/** Play, replay, or resume (if paused) a list of Sources */ +AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources); +/** Stop a list of Sources */ +AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources); +/** Rewind a list of Sources */ +AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources); +/** Pause a list of Sources */ +AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources); + +/** Play, replay, or resume a Source */ +AL_API void AL_APIENTRY alSourcePlay(ALuint source); +/** Stop a Source */ +AL_API void AL_APIENTRY alSourceStop(ALuint source); +/** Rewind a Source (set playback postiton to beginning) */ +AL_API void AL_APIENTRY alSourceRewind(ALuint source); +/** Pause a Source */ +AL_API void AL_APIENTRY alSourcePause(ALuint source); + +/** Queue buffers onto a source */ +AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers); +/** Unqueue processed buffers from a source */ +AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers); + + +/** Create Buffer objects */ +AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers); +/** Delete Buffer objects */ +AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers); +/** Verify a handle is a valid Buffer */ +AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer); + +/** Specifies the data to be copied into a buffer */ +AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); + +/** Set Buffer parameters, */ +AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value); +AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values); +AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value); +AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); +AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values); + +/** Get Buffer parameters. */ +AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value); +AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values); +AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value); +AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); +AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values); + +/** Pointer-to-function type, useful for dynamically getting AL entry points. */ +typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability); +typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability); +typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability); +typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param); +typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values); +typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values); +typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param); +typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param); +typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param); +typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param); +typedef ALenum (AL_APIENTRY *LPALGETERROR)(void); +typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname); +typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname); +typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename); +typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources); +typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources); +typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources); +typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source); +typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers); +typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers); +typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers); +typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers); +typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer); +typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); +typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value); +typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); +typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values); +typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value); +typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); +typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values); +typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value); +typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); +typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values); +typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value); +typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); +typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values); +typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value); +typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value); +typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value); +typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel); #if defined(__cplusplus) } /* extern "C" */ diff --git a/jni/openal-soft-android/include/AL/alc.h b/jni/openal-soft-android/include/AL/alc.h index 4712055c..294e8b33 100644 --- a/jni/openal-soft-android/include/AL/alc.h +++ b/jni/openal-soft-android/include/AL/alc.h @@ -21,25 +21,20 @@ extern "C" { #define ALC_APIENTRY #endif -#if defined(TARGET_OS_MAC) && TARGET_OS_MAC - #pragma export on -#endif -/* - * The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are - * included for applications porting code from AL 1.0 - */ -#define ALCAPI ALC_API -#define ALCAPIENTRY ALC_APIENTRY -#define ALC_INVALID 0 +/** Deprecated macro. */ +#define ALCAPI ALC_API +#define ALCAPIENTRY ALC_APIENTRY +#define ALC_INVALID 0 +/** Supported ALC version? */ +#define ALC_VERSION_0_1 1 -#define ALC_VERSION_0_1 1 - +/** Opaque device handle */ typedef struct ALCdevice_struct ALCdevice; +/** Opaque context handle */ typedef struct ALCcontext_struct ALCcontext; - /** 8-bit boolean */ typedef char ALCboolean; @@ -82,196 +77,158 @@ typedef void ALCvoid; /* Enumerant values begin at column 50. No tabs. */ -/* Boolean False. */ +/** Boolean False. */ #define ALC_FALSE 0 -/* Boolean True. */ +/** Boolean True. */ #define ALC_TRUE 1 -/** - * followed by Hz - */ +/** Context attribute: Hz. */ #define ALC_FREQUENCY 0x1007 -/** - * followed by Hz - */ +/** Context attribute: Hz. */ #define ALC_REFRESH 0x1008 -/** - * followed by AL_TRUE, AL_FALSE - */ +/** Context attribute: AL_TRUE or AL_FALSE. */ #define ALC_SYNC 0x1009 -/** - * followed by Num of requested Mono (3D) Sources - */ +/** Context attribute: requested Mono (3D) Sources. */ #define ALC_MONO_SOURCES 0x1010 -/** - * followed by Num of requested Stereo Sources - */ +/** Context attribute: requested Stereo Sources. */ #define ALC_STEREO_SOURCES 0x1011 -/** - * errors - */ +/** No error. */ +#define ALC_NO_ERROR 0 -/** - * No error - */ -#define ALC_NO_ERROR ALC_FALSE - -/** - * No device - */ +/** Invalid device handle. */ #define ALC_INVALID_DEVICE 0xA001 -/** - * invalid context ID - */ +/** Invalid context handle. */ #define ALC_INVALID_CONTEXT 0xA002 -/** - * bad enum - */ +/** Invalid enum parameter passed to an ALC call. */ #define ALC_INVALID_ENUM 0xA003 -/** - * bad value - */ +/** Invalid value parameter passed to an ALC call. */ #define ALC_INVALID_VALUE 0xA004 -/** - * Out of memory. - */ +/** Out of memory. */ #define ALC_OUT_OF_MEMORY 0xA005 -/** - * The Specifier string for default device - */ -#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 -#define ALC_DEVICE_SPECIFIER 0x1005 -#define ALC_EXTENSIONS 0x1006 - +/** Runtime ALC version. */ #define ALC_MAJOR_VERSION 0x1000 #define ALC_MINOR_VERSION 0x1001 +/** Context attribute list properties. */ #define ALC_ATTRIBUTES_SIZE 0x1002 #define ALC_ALL_ATTRIBUTES 0x1003 - +/** String for the default device specifier. */ +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 /** - * Capture extension + * String for the given device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known device specifiers (list ends with an empty string). */ +#define ALC_DEVICE_SPECIFIER 0x1005 +/** String for space-separated list of ALC extensions. */ +#define ALC_EXTENSIONS 0x1006 + + +/** Capture extension */ #define ALC_EXT_CAPTURE 1 +/** + * String for the given capture device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known capture device specifiers (list ends with an empty string). + */ #define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 +/** String for the default capture device specifier. */ #define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311 +/** Number of sample frames available for capture. */ #define ALC_CAPTURE_SAMPLES 0x312 -/** - * ALC_ENUMERATE_ALL_EXT enums - */ +/** Enumerate All extension */ #define ALC_ENUMERATE_ALL_EXT 1 +/** String for the default extended device specifier. */ #define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 +/** + * String for the given extended device's specifier. + * + * If device handle is NULL, it is instead a null-char separated list of + * strings of known extended device specifiers (list ends with an empty string). + */ #define ALC_ALL_DEVICES_SPECIFIER 0x1013 -/* - * Context Management - */ -ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist ); +/** Context management. */ +ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist); +ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context); +ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context); +ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context); +ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context); +ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void); +ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context); -ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context ); - -ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context ); - -ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context ); - -ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context ); - -ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void ); - -ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context ); +/** Device management. */ +ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename); +ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device); -/* - * Device Management - */ -ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename ); - -ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device ); - - -/* +/** * Error support. - * Obtain the most recent Context error + * + * Obtain the most recent Device error. */ -ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device ); +ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device); - -/* +/** * Extension support. + * * Query for the presence of an extension, and obtain any appropriate * function pointers and enum values. */ -ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ); +ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname); +ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname); +ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname); -ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname ); +/** Query function. */ +ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param); +ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values); -ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname ); +/** Capture function. */ +ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize); +ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device); +ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); - -/* - * Query functions - */ -ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param ); - -ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ); - - -/* - * Capture functions - */ -ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); - -ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device ); - -ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device ); - -ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device ); - -ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); - -/* - * Pointer-to-function types, useful for dynamically getting ALC entry points. - */ -typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist); -typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context ); -typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context ); -typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context ); -typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context ); -typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void ); -typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context ); -typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename ); -typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device ); -typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device ); -typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname ); -typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname ); -typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname ); -typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param ); -typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest ); -typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ); -typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device ); -typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device ); -typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device ); -typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ); - -#if defined(TARGET_OS_MAC) && TARGET_OS_MAC - #pragma export off -#endif +/** Pointer-to-function type, useful for dynamically getting ALC entry points. */ +typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist); +typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context); +typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context); +typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void); +typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context); +typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename); +typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device); +typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device); +typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname); +typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname); +typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname); +typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param); +typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values); +typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize); +typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device); +typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); #if defined(__cplusplus) } diff --git a/jni/openal-soft-android/include/AL/alext.h b/jni/openal-soft-android/include/AL/alext.h index 745b7653..f15ba33f 100644 --- a/jni/openal-soft-android/include/AL/alext.h +++ b/jni/openal-soft-android/include/AL/alext.h @@ -22,6 +22,21 @@ #define AL_ALEXT_H #include +/* Define int64_t and uint64_t types */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif + +#include "alc.h" +#include "al.h" #ifdef __cplusplus extern "C" { @@ -188,6 +203,167 @@ AL_API void AL_APIENTRY alRequestFoldbackStop(void); #define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000 #endif +#ifndef AL_SOFT_buffer_samples +#define AL_SOFT_buffer_samples 1 +/* Channel configurations */ +#define AL_MONO_SOFT 0x1500 +#define AL_STEREO_SOFT 0x1501 +#define AL_REAR_SOFT 0x1502 +#define AL_QUAD_SOFT 0x1503 +#define AL_5POINT1_SOFT 0x1504 +#define AL_6POINT1_SOFT 0x1505 +#define AL_7POINT1_SOFT 0x1506 + +/* Sample types */ +#define AL_BYTE_SOFT 0x1400 +#define AL_UNSIGNED_BYTE_SOFT 0x1401 +#define AL_SHORT_SOFT 0x1402 +#define AL_UNSIGNED_SHORT_SOFT 0x1403 +#define AL_INT_SOFT 0x1404 +#define AL_UNSIGNED_INT_SOFT 0x1405 +#define AL_FLOAT_SOFT 0x1406 +#define AL_DOUBLE_SOFT 0x1407 +#define AL_BYTE3_SOFT 0x1408 +#define AL_UNSIGNED_BYTE3_SOFT 0x1409 + +/* Storage formats */ +#define AL_MONO8_SOFT 0x1100 +#define AL_MONO16_SOFT 0x1101 +#define AL_MONO32F_SOFT 0x10010 +#define AL_STEREO8_SOFT 0x1102 +#define AL_STEREO16_SOFT 0x1103 +#define AL_STEREO32F_SOFT 0x10011 +#define AL_QUAD8_SOFT 0x1204 +#define AL_QUAD16_SOFT 0x1205 +#define AL_QUAD32F_SOFT 0x1206 +#define AL_REAR8_SOFT 0x1207 +#define AL_REAR16_SOFT 0x1208 +#define AL_REAR32F_SOFT 0x1209 +#define AL_5POINT1_8_SOFT 0x120A +#define AL_5POINT1_16_SOFT 0x120B +#define AL_5POINT1_32F_SOFT 0x120C +#define AL_6POINT1_8_SOFT 0x120D +#define AL_6POINT1_16_SOFT 0x120E +#define AL_6POINT1_32F_SOFT 0x120F +#define AL_7POINT1_8_SOFT 0x1210 +#define AL_7POINT1_16_SOFT 0x1211 +#define AL_7POINT1_32F_SOFT 0x1212 + +/* Buffer attributes */ +#define AL_INTERNAL_FORMAT_SOFT 0x2008 +#define AL_BYTE_LENGTH_SOFT 0x2009 +#define AL_SAMPLE_LENGTH_SOFT 0x200A +#define AL_SEC_LENGTH_SOFT 0x200B + +typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); +typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); +typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*); +typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); +AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); +AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data); +AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); +#endif +#endif + +#ifndef AL_SOFT_direct_channels +#define AL_SOFT_direct_channels 1 +#define AL_DIRECT_CHANNELS_SOFT 0x1033 +#endif + +#ifndef ALC_SOFT_loopback +#define ALC_SOFT_loopback 1 +#define ALC_FORMAT_CHANNELS_SOFT 0x1990 +#define ALC_FORMAT_TYPE_SOFT 0x1991 + +/* Sample types */ +#define ALC_BYTE_SOFT 0x1400 +#define ALC_UNSIGNED_BYTE_SOFT 0x1401 +#define ALC_SHORT_SOFT 0x1402 +#define ALC_UNSIGNED_SHORT_SOFT 0x1403 +#define ALC_INT_SOFT 0x1404 +#define ALC_UNSIGNED_INT_SOFT 0x1405 +#define ALC_FLOAT_SOFT 0x1406 + +/* Channel configurations */ +#define ALC_MONO_SOFT 0x1500 +#define ALC_STEREO_SOFT 0x1501 +#define ALC_QUAD_SOFT 0x1503 +#define ALC_5POINT1_SOFT 0x1504 +#define ALC_6POINT1_SOFT 0x1505 +#define ALC_7POINT1_SOFT 0x1506 + +typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*); +typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum); +typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei); +#ifdef AL_ALEXT_PROTOTYPES +ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName); +ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); +ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); +#endif +#endif + +#ifndef AL_EXT_STEREO_ANGLES +#define AL_EXT_STEREO_ANGLES 1 +#define AL_STEREO_ANGLES 0x1030 +#endif + +#ifndef AL_EXT_SOURCE_RADIUS +#define AL_EXT_SOURCE_RADIUS 1 +#define AL_SOURCE_RADIUS 0x1031 +#endif + +#ifndef AL_SOFT_source_latency +#define AL_SOFT_source_latency 1 +#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 +#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 +typedef int64_t ALint64SOFT; +typedef uint64_t ALuint64SOFT; +typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble); +typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble); +typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*); +typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*); +typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT); +typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT); +typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*); +typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value); +AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3); +AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values); +AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value); +AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3); +AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values); +AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value); +AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3); +AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values); +AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value); +AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3); +AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values); +#endif +#endif + +#ifndef ALC_EXT_DEFAULT_FILTER_ORDER +#define ALC_EXT_DEFAULT_FILTER_ORDER 1 +#define ALC_DEFAULT_FILTER_ORDER 0x1100 +#endif + +#ifndef AL_SOFT_deferred_updates +#define AL_SOFT_deferred_updates 1 +#define AL_DEFERRED_UPDATES_SOFT 0xC002 +typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void); +typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void); +#ifdef AL_ALEXT_PROTOTYPES +AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void); +AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); +#endif +#endif + #ifdef __cplusplus } #endif diff --git a/jni/openal-soft-android/include/AL/efx-presets.h b/jni/openal-soft-android/include/AL/efx-presets.h new file mode 100644 index 00000000..86dcbda2 --- /dev/null +++ b/jni/openal-soft-android/include/AL/efx-presets.h @@ -0,0 +1,402 @@ +/* Reverb presets for EFX */ + +#ifndef EFX_PRESETS_H +#define EFX_PRESETS_H + +#ifndef EFXEAXREVERBPROPERTIES_DEFINED +#define EFXEAXREVERBPROPERTIES_DEFINED +typedef struct { + float flDensity; + float flDiffusion; + float flGain; + float flGainHF; + float flGainLF; + float flDecayTime; + float flDecayHFRatio; + float flDecayLFRatio; + float flReflectionsGain; + float flReflectionsDelay; + float flReflectionsPan[3]; + float flLateReverbGain; + float flLateReverbDelay; + float flLateReverbPan[3]; + float flEchoTime; + float flEchoDepth; + float flModulationTime; + float flModulationDepth; + float flAirAbsorptionGainHF; + float flHFReference; + float flLFReference; + float flRoomRolloffFactor; + int iDecayHFLimit; +} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES; +#endif + +/* Default Presets */ + +#define EFX_REVERB_PRESET_GENERIC \ + { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PADDEDCELL \ + { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ROOM \ + { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_BATHROOM \ + { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_LIVINGROOM \ + { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_STONEROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_AUDITORIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CONCERTHALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CAVE \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_ARENA \ + { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_HANGAR \ + { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CARPETEDHALLWAY \ + { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_HALLWAY \ + { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_STONECORRIDOR \ + { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ALLEY \ + { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FOREST \ + { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY \ + { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_MOUNTAINS \ + { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_QUARRY \ + { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PLAIN \ + { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PARKINGLOT \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SEWERPIPE \ + { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_UNDERWATER \ + { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRUGGED \ + { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DIZZY \ + { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PSYCHOTIC \ + { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Castle Presets */ + +#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \ + { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \ + { 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \ + { 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \ + { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \ + { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_HALL \ + { 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \ + { 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CASTLE_COURTYARD \ + { 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CASTLE_ALCOVE \ + { 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } + +/* Factory Presets */ + +#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \ + { 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \ + { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \ + { 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \ + { 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \ + { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_HALL \ + { 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \ + { 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_COURTYARD \ + { 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_FACTORY_ALCOVE \ + { 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } + +/* Ice Palace Presets */ + +#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \ + { 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \ + { 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \ + { 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \ + { 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_HALL \ + { 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \ + { 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \ + { 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } + +/* Space Station Presets */ + +#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \ + { 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \ + { 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \ + { 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \ + { 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \ + { 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_HALL \ + { 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \ + { 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \ + { 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } + +/* Wooden Galleon Presets */ + +#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \ + { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_HALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \ + { 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_COURTYARD \ + { 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_WOODEN_ALCOVE \ + { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } + +/* Sports Presets */ + +#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \ + { 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \ + { 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \ + { 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \ + { 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \ + { 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \ + { 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +/* Prefab Presets */ + +#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \ + { 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \ + { 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \ + { 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \ + { 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PREFAB_CARAVAN \ + { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Dome and Pipe Presets */ + +#define EFX_REVERB_PRESET_DOME_TOMB \ + { 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PIPE_SMALL \ + { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DOME_SAINTPAULS \ + { 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PIPE_LONGTHIN \ + { 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_PIPE_LARGE \ + { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_PIPE_RESONANT \ + { 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } + +/* Outdoors Presets */ + +#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \ + { 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \ + { 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \ + { 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_CREEK \ + { 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \ + { 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +/* Mood Presets */ + +#define EFX_REVERB_PRESET_MOOD_HEAVEN \ + { 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_MOOD_HELL \ + { 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_MOOD_MEMORY \ + { 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +/* Driving Presets */ + +#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \ + { 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \ + { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \ + { 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \ + { 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \ + { 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \ + { 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \ + { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_DRIVING_TUNNEL \ + { 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 } + +/* City Presets */ + +#define EFX_REVERB_PRESET_CITY_STREETS \ + { 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_SUBWAY \ + { 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_MUSEUM \ + { 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CITY_LIBRARY \ + { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } + +#define EFX_REVERB_PRESET_CITY_UNDERPASS \ + { 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CITY_ABANDONED \ + { 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +/* Misc. Presets */ + +#define EFX_REVERB_PRESET_DUSTYROOM \ + { 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_CHAPEL \ + { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } + +#define EFX_REVERB_PRESET_SMALLWATERROOM \ + { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } + +#endif /* EFX_PRESETS_H */ diff --git a/jni/openal-soft-android/include/AL/efx.h b/jni/openal-soft-android/include/AL/efx.h index 978f64a6..57766983 100644 --- a/jni/openal-soft-android/include/AL/efx.h +++ b/jni/openal-soft-android/include/AL/efx.h @@ -2,6 +2,9 @@ #define AL_EFX_H +#include "alc.h" +#include "al.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/jni/openal-soft-android/openal.pc b/jni/openal-soft-android/openal.pc deleted file mode 100644 index 0bd3e671..00000000 --- a/jni/openal-soft-android/openal.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include - -Name: OpenAL -Description: OpenAL is a cross-platform 3D audio API -Requires: -Version: 1.13 -Libs: -L${libdir} -lopenal -Cflags: -I${includedir} diff --git a/jni/openal-soft-android/openal.pc.in b/jni/openal-soft-android/openal.pc.in index eaa18e5e..8bdd4f3b 100644 --- a/jni/openal-soft-android/openal.pc.in +++ b/jni/openal-soft-android/openal.pc.in @@ -8,4 +8,4 @@ Description: OpenAL is a cross-platform 3D audio API Requires: @PKG_CONFIG_REQUIRES@ Version: @PACKAGE_VERSION@ Libs: -L${libdir} -l@LIBNAME@ @PKG_CONFIG_LIBS@ -Cflags: -I${includedir} @PKG_CONFIG_CFLAGS@ +Cflags: -I${includedir} -I${includedir}/AL @PKG_CONFIG_CFLAGS@ diff --git a/jni/openal-soft-android/utils/CIAIR.def b/jni/openal-soft-android/utils/CIAIR.def new file mode 100644 index 00000000..9589a694 --- /dev/null +++ b/jni/openal-soft-android/utils/CIAIR.def @@ -0,0 +1,2010 @@ +# This is a makehrtf HRIR definition file. It is used to define the layout +# and source data to be processed into an OpenAL Soft compatible HRTF. +# +# This definition is used to transform the left ear HRIRs from a data set +# used in several papers and articles by Fumitada Itakura, Kazuya Takeda, +# Mikio Ikeda, Shoji Kajita, and Takanori Nishino. +# +# The data (data02.tgz) can be obtained from The Database of Head Related +# Transfer Functions hosted by the Takeda Laboratory at Nagoya University: +# +# http://www.sp.m.is.nagoya-u.ac.jp/HRTF/database.html +# +# It is copyright 1999 by Itakura Laboratory and the Center for Integrated +# Acoustic Information Research (CIAIR) of Nagoya University and provided +# free of charge with no restrictions on use so long as the authors (above) +# are cited. + +rate = 44100 + +points = 512 + +# The CIAIR set is composed of a uniform number of azimuths for all but the +# poles (-90 and 90 degree elevation). +azimuths = 1, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 1 + +# No head radius was provided. Just use the average radius of 9 cm. +radius = 0.09 + +# The distance between the source and the listener is not known for this set, +# so 1.5 m is used. +distance = 1.5 + +# The CIAIR source azimuth is counter-clockwise, so it needs to be flipped. +# The extension of the source data may be misleading, they're ASCII text +# lists of floating point values (one per line). + +[ 9, 0 ] = ascii (fp) : "./hrtfs/elev-45/L-45e000a.dat" +[ 9, 1 ] = ascii (fp) : "./hrtfs/elev-45/L-45e355a.dat" +[ 9, 2 ] = ascii (fp) : "./hrtfs/elev-45/L-45e350a.dat" +[ 9, 3 ] = ascii (fp) : "./hrtfs/elev-45/L-45e345a.dat" +[ 9, 4 ] = ascii (fp) : "./hrtfs/elev-45/L-45e340a.dat" +[ 9, 5 ] = ascii (fp) : "./hrtfs/elev-45/L-45e335a.dat" +[ 9, 6 ] = ascii (fp) : "./hrtfs/elev-45/L-45e330a.dat" +[ 9, 7 ] = ascii (fp) : "./hrtfs/elev-45/L-45e325a.dat" +[ 9, 8 ] = ascii (fp) : "./hrtfs/elev-45/L-45e320a.dat" +[ 9, 9 ] = ascii (fp) : "./hrtfs/elev-45/L-45e315a.dat" +[ 9, 10 ] = ascii (fp) : "./hrtfs/elev-45/L-45e310a.dat" +[ 9, 11 ] = ascii (fp) : "./hrtfs/elev-45/L-45e305a.dat" +[ 9, 12 ] = ascii (fp) : "./hrtfs/elev-45/L-45e300a.dat" +[ 9, 13 ] = ascii (fp) : "./hrtfs/elev-45/L-45e295a.dat" +[ 9, 14 ] = ascii (fp) : "./hrtfs/elev-45/L-45e290a.dat" +[ 9, 15 ] = ascii (fp) : "./hrtfs/elev-45/L-45e285a.dat" +[ 9, 16 ] = ascii (fp) : "./hrtfs/elev-45/L-45e280a.dat" +[ 9, 17 ] = ascii (fp) : "./hrtfs/elev-45/L-45e275a.dat" +[ 9, 18 ] = ascii (fp) : "./hrtfs/elev-45/L-45e270a.dat" +[ 9, 19 ] = ascii (fp) : "./hrtfs/elev-45/L-45e265a.dat" +[ 9, 20 ] = ascii (fp) : "./hrtfs/elev-45/L-45e260a.dat" +[ 9, 21 ] = ascii (fp) : "./hrtfs/elev-45/L-45e255a.dat" +[ 9, 22 ] = ascii (fp) : "./hrtfs/elev-45/L-45e250a.dat" +[ 9, 23 ] = ascii (fp) : "./hrtfs/elev-45/L-45e245a.dat" +[ 9, 24 ] = ascii (fp) : "./hrtfs/elev-45/L-45e240a.dat" +[ 9, 25 ] = ascii (fp) : "./hrtfs/elev-45/L-45e235a.dat" +[ 9, 26 ] = ascii (fp) : "./hrtfs/elev-45/L-45e230a.dat" +[ 9, 27 ] = ascii (fp) : "./hrtfs/elev-45/L-45e225a.dat" +[ 9, 28 ] = ascii (fp) : "./hrtfs/elev-45/L-45e220a.dat" +[ 9, 29 ] = ascii (fp) : "./hrtfs/elev-45/L-45e215a.dat" +[ 9, 30 ] = ascii (fp) : "./hrtfs/elev-45/L-45e210a.dat" +[ 9, 31 ] = ascii (fp) : "./hrtfs/elev-45/L-45e205a.dat" +[ 9, 32 ] = ascii (fp) : "./hrtfs/elev-45/L-45e200a.dat" +[ 9, 33 ] = ascii (fp) : "./hrtfs/elev-45/L-45e195a.dat" +[ 9, 34 ] = ascii (fp) : "./hrtfs/elev-45/L-45e190a.dat" +[ 9, 35 ] = ascii (fp) : "./hrtfs/elev-45/L-45e185a.dat" +[ 9, 36 ] = ascii (fp) : "./hrtfs/elev-45/L-45e180a.dat" +[ 9, 37 ] = ascii (fp) : "./hrtfs/elev-45/L-45e175a.dat" +[ 9, 38 ] = ascii (fp) : "./hrtfs/elev-45/L-45e170a.dat" +[ 9, 39 ] = ascii (fp) : "./hrtfs/elev-45/L-45e165a.dat" +[ 9, 40 ] = ascii (fp) : "./hrtfs/elev-45/L-45e160a.dat" +[ 9, 41 ] = ascii (fp) : "./hrtfs/elev-45/L-45e155a.dat" +[ 9, 42 ] = ascii (fp) : "./hrtfs/elev-45/L-45e150a.dat" +[ 9, 43 ] = ascii (fp) : "./hrtfs/elev-45/L-45e145a.dat" +[ 9, 44 ] = ascii (fp) : "./hrtfs/elev-45/L-45e140a.dat" +[ 9, 45 ] = ascii (fp) : "./hrtfs/elev-45/L-45e135a.dat" +[ 9, 46 ] = ascii (fp) : "./hrtfs/elev-45/L-45e130a.dat" +[ 9, 47 ] = ascii (fp) : "./hrtfs/elev-45/L-45e125a.dat" +[ 9, 48 ] = ascii (fp) : "./hrtfs/elev-45/L-45e120a.dat" +[ 9, 49 ] = ascii (fp) : "./hrtfs/elev-45/L-45e115a.dat" +[ 9, 50 ] = ascii (fp) : "./hrtfs/elev-45/L-45e110a.dat" +[ 9, 51 ] = ascii (fp) : "./hrtfs/elev-45/L-45e105a.dat" +[ 9, 52 ] = ascii (fp) : "./hrtfs/elev-45/L-45e100a.dat" +[ 9, 53 ] = ascii (fp) : "./hrtfs/elev-45/L-45e095a.dat" +[ 9, 54 ] = ascii (fp) : "./hrtfs/elev-45/L-45e090a.dat" +[ 9, 55 ] = ascii (fp) : "./hrtfs/elev-45/L-45e085a.dat" +[ 9, 56 ] = ascii (fp) : "./hrtfs/elev-45/L-45e080a.dat" +[ 9, 57 ] = ascii (fp) : "./hrtfs/elev-45/L-45e075a.dat" +[ 9, 58 ] = ascii (fp) : "./hrtfs/elev-45/L-45e070a.dat" +[ 9, 59 ] = ascii (fp) : "./hrtfs/elev-45/L-45e065a.dat" +[ 9, 60 ] = ascii (fp) : "./hrtfs/elev-45/L-45e060a.dat" +[ 9, 61 ] = ascii (fp) : "./hrtfs/elev-45/L-45e055a.dat" +[ 9, 62 ] = ascii (fp) : "./hrtfs/elev-45/L-45e050a.dat" +[ 9, 63 ] = ascii (fp) : "./hrtfs/elev-45/L-45e045a.dat" +[ 9, 64 ] = ascii (fp) : "./hrtfs/elev-45/L-45e040a.dat" +[ 9, 65 ] = ascii (fp) : "./hrtfs/elev-45/L-45e035a.dat" +[ 9, 66 ] = ascii (fp) : "./hrtfs/elev-45/L-45e030a.dat" +[ 9, 67 ] = ascii (fp) : "./hrtfs/elev-45/L-45e025a.dat" +[ 9, 68 ] = ascii (fp) : "./hrtfs/elev-45/L-45e020a.dat" +[ 9, 69 ] = ascii (fp) : "./hrtfs/elev-45/L-45e015a.dat" +[ 9, 70 ] = ascii (fp) : "./hrtfs/elev-45/L-45e010a.dat" +[ 9, 71 ] = ascii (fp) : "./hrtfs/elev-45/L-45e005a.dat" + +[ 10, 0 ] = ascii (fp) : "./hrtfs/elev-40/L-40e000a.dat" +[ 10, 1 ] = ascii (fp) : "./hrtfs/elev-40/L-40e355a.dat" +[ 10, 2 ] = ascii (fp) : "./hrtfs/elev-40/L-40e350a.dat" +[ 10, 3 ] = ascii (fp) : "./hrtfs/elev-40/L-40e345a.dat" +[ 10, 4 ] = ascii (fp) : "./hrtfs/elev-40/L-40e340a.dat" +[ 10, 5 ] = ascii (fp) : "./hrtfs/elev-40/L-40e335a.dat" +[ 10, 6 ] = ascii (fp) : "./hrtfs/elev-40/L-40e330a.dat" +[ 10, 7 ] = ascii (fp) : "./hrtfs/elev-40/L-40e325a.dat" +[ 10, 8 ] = ascii (fp) : "./hrtfs/elev-40/L-40e320a.dat" +[ 10, 9 ] = ascii (fp) : "./hrtfs/elev-40/L-40e315a.dat" +[ 10, 10 ] = ascii (fp) : "./hrtfs/elev-40/L-40e310a.dat" +[ 10, 11 ] = ascii (fp) : "./hrtfs/elev-40/L-40e305a.dat" +[ 10, 12 ] = ascii (fp) : "./hrtfs/elev-40/L-40e300a.dat" +[ 10, 13 ] = ascii (fp) : "./hrtfs/elev-40/L-40e295a.dat" +[ 10, 14 ] = ascii (fp) : "./hrtfs/elev-40/L-40e290a.dat" +[ 10, 15 ] = ascii (fp) : "./hrtfs/elev-40/L-40e285a.dat" +[ 10, 16 ] = ascii (fp) : "./hrtfs/elev-40/L-40e280a.dat" +[ 10, 17 ] = ascii (fp) : "./hrtfs/elev-40/L-40e275a.dat" +[ 10, 18 ] = ascii (fp) : "./hrtfs/elev-40/L-40e270a.dat" +[ 10, 19 ] = ascii (fp) : "./hrtfs/elev-40/L-40e265a.dat" +[ 10, 20 ] = ascii (fp) : "./hrtfs/elev-40/L-40e260a.dat" +[ 10, 21 ] = ascii (fp) : "./hrtfs/elev-40/L-40e255a.dat" +[ 10, 22 ] = ascii (fp) : "./hrtfs/elev-40/L-40e250a.dat" +[ 10, 23 ] = ascii (fp) : "./hrtfs/elev-40/L-40e245a.dat" +[ 10, 24 ] = ascii (fp) : "./hrtfs/elev-40/L-40e240a.dat" +[ 10, 25 ] = ascii (fp) : "./hrtfs/elev-40/L-40e235a.dat" +[ 10, 26 ] = ascii (fp) : "./hrtfs/elev-40/L-40e230a.dat" +[ 10, 27 ] = ascii (fp) : "./hrtfs/elev-40/L-40e225a.dat" +[ 10, 28 ] = ascii (fp) : "./hrtfs/elev-40/L-40e220a.dat" +[ 10, 29 ] = ascii (fp) : "./hrtfs/elev-40/L-40e215a.dat" +[ 10, 30 ] = ascii (fp) : "./hrtfs/elev-40/L-40e210a.dat" +[ 10, 31 ] = ascii (fp) : "./hrtfs/elev-40/L-40e205a.dat" +[ 10, 32 ] = ascii (fp) : "./hrtfs/elev-40/L-40e200a.dat" +[ 10, 33 ] = ascii (fp) : "./hrtfs/elev-40/L-40e195a.dat" +[ 10, 34 ] = ascii (fp) : "./hrtfs/elev-40/L-40e190a.dat" +[ 10, 35 ] = ascii (fp) : "./hrtfs/elev-40/L-40e185a.dat" +[ 10, 36 ] = ascii (fp) : "./hrtfs/elev-40/L-40e180a.dat" +[ 10, 37 ] = ascii (fp) : "./hrtfs/elev-40/L-40e175a.dat" +[ 10, 38 ] = ascii (fp) : "./hrtfs/elev-40/L-40e170a.dat" +[ 10, 39 ] = ascii (fp) : "./hrtfs/elev-40/L-40e165a.dat" +[ 10, 40 ] = ascii (fp) : "./hrtfs/elev-40/L-40e160a.dat" +[ 10, 41 ] = ascii (fp) : "./hrtfs/elev-40/L-40e155a.dat" +[ 10, 42 ] = ascii (fp) : "./hrtfs/elev-40/L-40e150a.dat" +[ 10, 43 ] = ascii (fp) : "./hrtfs/elev-40/L-40e145a.dat" +[ 10, 44 ] = ascii (fp) : "./hrtfs/elev-40/L-40e140a.dat" +[ 10, 45 ] = ascii (fp) : "./hrtfs/elev-40/L-40e135a.dat" +[ 10, 46 ] = ascii (fp) : "./hrtfs/elev-40/L-40e130a.dat" +[ 10, 47 ] = ascii (fp) : "./hrtfs/elev-40/L-40e125a.dat" +[ 10, 48 ] = ascii (fp) : "./hrtfs/elev-40/L-40e120a.dat" +[ 10, 49 ] = ascii (fp) : "./hrtfs/elev-40/L-40e115a.dat" +[ 10, 50 ] = ascii (fp) : "./hrtfs/elev-40/L-40e110a.dat" +[ 10, 51 ] = ascii (fp) : "./hrtfs/elev-40/L-40e105a.dat" +[ 10, 52 ] = ascii (fp) : "./hrtfs/elev-40/L-40e100a.dat" +[ 10, 53 ] = ascii (fp) : "./hrtfs/elev-40/L-40e095a.dat" +[ 10, 54 ] = ascii (fp) : "./hrtfs/elev-40/L-40e090a.dat" +[ 10, 55 ] = ascii (fp) : "./hrtfs/elev-40/L-40e085a.dat" +[ 10, 56 ] = ascii (fp) : "./hrtfs/elev-40/L-40e080a.dat" +[ 10, 57 ] = ascii (fp) : "./hrtfs/elev-40/L-40e075a.dat" +[ 10, 58 ] = ascii (fp) : "./hrtfs/elev-40/L-40e070a.dat" +[ 10, 59 ] = ascii (fp) : "./hrtfs/elev-40/L-40e065a.dat" +[ 10, 60 ] = ascii (fp) : "./hrtfs/elev-40/L-40e060a.dat" +[ 10, 61 ] = ascii (fp) : "./hrtfs/elev-40/L-40e055a.dat" +[ 10, 62 ] = ascii (fp) : "./hrtfs/elev-40/L-40e050a.dat" +[ 10, 63 ] = ascii (fp) : "./hrtfs/elev-40/L-40e045a.dat" +[ 10, 64 ] = ascii (fp) : "./hrtfs/elev-40/L-40e040a.dat" +[ 10, 65 ] = ascii (fp) : "./hrtfs/elev-40/L-40e035a.dat" +[ 10, 66 ] = ascii (fp) : "./hrtfs/elev-40/L-40e030a.dat" +[ 10, 67 ] = ascii (fp) : "./hrtfs/elev-40/L-40e025a.dat" +[ 10, 68 ] = ascii (fp) : "./hrtfs/elev-40/L-40e020a.dat" +[ 10, 69 ] = ascii (fp) : "./hrtfs/elev-40/L-40e015a.dat" +[ 10, 70 ] = ascii (fp) : "./hrtfs/elev-40/L-40e010a.dat" +[ 10, 71 ] = ascii (fp) : "./hrtfs/elev-40/L-40e005a.dat" + +[ 11, 0 ] = ascii (fp) : "./hrtfs/elev-35/L-35e000a.dat" +[ 11, 1 ] = ascii (fp) : "./hrtfs/elev-35/L-35e355a.dat" +[ 11, 2 ] = ascii (fp) : "./hrtfs/elev-35/L-35e350a.dat" +[ 11, 3 ] = ascii (fp) : "./hrtfs/elev-35/L-35e345a.dat" +[ 11, 4 ] = ascii (fp) : "./hrtfs/elev-35/L-35e340a.dat" +[ 11, 5 ] = ascii (fp) : "./hrtfs/elev-35/L-35e335a.dat" +[ 11, 6 ] = ascii (fp) : "./hrtfs/elev-35/L-35e330a.dat" +[ 11, 7 ] = ascii (fp) : "./hrtfs/elev-35/L-35e325a.dat" +[ 11, 8 ] = ascii (fp) : "./hrtfs/elev-35/L-35e320a.dat" +[ 11, 9 ] = ascii (fp) : "./hrtfs/elev-35/L-35e315a.dat" +[ 11, 10 ] = ascii (fp) : "./hrtfs/elev-35/L-35e310a.dat" +[ 11, 11 ] = ascii (fp) : "./hrtfs/elev-35/L-35e305a.dat" +[ 11, 12 ] = ascii (fp) : "./hrtfs/elev-35/L-35e300a.dat" +[ 11, 13 ] = ascii (fp) : "./hrtfs/elev-35/L-35e295a.dat" +[ 11, 14 ] = ascii (fp) : "./hrtfs/elev-35/L-35e290a.dat" +[ 11, 15 ] = ascii (fp) : "./hrtfs/elev-35/L-35e285a.dat" +[ 11, 16 ] = ascii (fp) : "./hrtfs/elev-35/L-35e280a.dat" +[ 11, 17 ] = ascii (fp) : "./hrtfs/elev-35/L-35e275a.dat" +[ 11, 18 ] = ascii (fp) : "./hrtfs/elev-35/L-35e270a.dat" +[ 11, 19 ] = ascii (fp) : "./hrtfs/elev-35/L-35e265a.dat" +[ 11, 20 ] = ascii (fp) : "./hrtfs/elev-35/L-35e260a.dat" +[ 11, 21 ] = ascii (fp) : "./hrtfs/elev-35/L-35e255a.dat" +[ 11, 22 ] = ascii (fp) : "./hrtfs/elev-35/L-35e250a.dat" +[ 11, 23 ] = ascii (fp) : "./hrtfs/elev-35/L-35e245a.dat" +[ 11, 24 ] = ascii (fp) : "./hrtfs/elev-35/L-35e240a.dat" +[ 11, 25 ] = ascii (fp) : "./hrtfs/elev-35/L-35e235a.dat" +[ 11, 26 ] = ascii (fp) : "./hrtfs/elev-35/L-35e230a.dat" +[ 11, 27 ] = ascii (fp) : "./hrtfs/elev-35/L-35e225a.dat" +[ 11, 28 ] = ascii (fp) : "./hrtfs/elev-35/L-35e220a.dat" +[ 11, 29 ] = ascii (fp) : "./hrtfs/elev-35/L-35e215a.dat" +[ 11, 30 ] = ascii (fp) : "./hrtfs/elev-35/L-35e210a.dat" +[ 11, 31 ] = ascii (fp) : "./hrtfs/elev-35/L-35e205a.dat" +[ 11, 32 ] = ascii (fp) : "./hrtfs/elev-35/L-35e200a.dat" +[ 11, 33 ] = ascii (fp) : "./hrtfs/elev-35/L-35e195a.dat" +[ 11, 34 ] = ascii (fp) : "./hrtfs/elev-35/L-35e190a.dat" +[ 11, 35 ] = ascii (fp) : "./hrtfs/elev-35/L-35e185a.dat" +[ 11, 36 ] = ascii (fp) : "./hrtfs/elev-35/L-35e180a.dat" +[ 11, 37 ] = ascii (fp) : "./hrtfs/elev-35/L-35e175a.dat" +[ 11, 38 ] = ascii (fp) : "./hrtfs/elev-35/L-35e170a.dat" +[ 11, 39 ] = ascii (fp) : "./hrtfs/elev-35/L-35e165a.dat" +[ 11, 40 ] = ascii (fp) : "./hrtfs/elev-35/L-35e160a.dat" +[ 11, 41 ] = ascii (fp) : "./hrtfs/elev-35/L-35e155a.dat" +[ 11, 42 ] = ascii (fp) : "./hrtfs/elev-35/L-35e150a.dat" +[ 11, 43 ] = ascii (fp) : "./hrtfs/elev-35/L-35e145a.dat" +[ 11, 44 ] = ascii (fp) : "./hrtfs/elev-35/L-35e140a.dat" +[ 11, 45 ] = ascii (fp) : "./hrtfs/elev-35/L-35e135a.dat" +[ 11, 46 ] = ascii (fp) : "./hrtfs/elev-35/L-35e130a.dat" +[ 11, 47 ] = ascii (fp) : "./hrtfs/elev-35/L-35e125a.dat" +[ 11, 48 ] = ascii (fp) : "./hrtfs/elev-35/L-35e120a.dat" +[ 11, 49 ] = ascii (fp) : "./hrtfs/elev-35/L-35e115a.dat" +[ 11, 50 ] = ascii (fp) : "./hrtfs/elev-35/L-35e110a.dat" +[ 11, 51 ] = ascii (fp) : "./hrtfs/elev-35/L-35e105a.dat" +[ 11, 52 ] = ascii (fp) : "./hrtfs/elev-35/L-35e100a.dat" +[ 11, 53 ] = ascii (fp) : "./hrtfs/elev-35/L-35e095a.dat" +[ 11, 54 ] = ascii (fp) : "./hrtfs/elev-35/L-35e090a.dat" +[ 11, 55 ] = ascii (fp) : "./hrtfs/elev-35/L-35e085a.dat" +[ 11, 56 ] = ascii (fp) : "./hrtfs/elev-35/L-35e080a.dat" +[ 11, 57 ] = ascii (fp) : "./hrtfs/elev-35/L-35e075a.dat" +[ 11, 58 ] = ascii (fp) : "./hrtfs/elev-35/L-35e070a.dat" +[ 11, 59 ] = ascii (fp) : "./hrtfs/elev-35/L-35e065a.dat" +[ 11, 60 ] = ascii (fp) : "./hrtfs/elev-35/L-35e060a.dat" +[ 11, 61 ] = ascii (fp) : "./hrtfs/elev-35/L-35e055a.dat" +[ 11, 62 ] = ascii (fp) : "./hrtfs/elev-35/L-35e050a.dat" +[ 11, 63 ] = ascii (fp) : "./hrtfs/elev-35/L-35e045a.dat" +[ 11, 64 ] = ascii (fp) : "./hrtfs/elev-35/L-35e040a.dat" +[ 11, 65 ] = ascii (fp) : "./hrtfs/elev-35/L-35e035a.dat" +[ 11, 66 ] = ascii (fp) : "./hrtfs/elev-35/L-35e030a.dat" +[ 11, 67 ] = ascii (fp) : "./hrtfs/elev-35/L-35e025a.dat" +[ 11, 68 ] = ascii (fp) : "./hrtfs/elev-35/L-35e020a.dat" +[ 11, 69 ] = ascii (fp) : "./hrtfs/elev-35/L-35e015a.dat" +[ 11, 70 ] = ascii (fp) : "./hrtfs/elev-35/L-35e010a.dat" +[ 11, 71 ] = ascii (fp) : "./hrtfs/elev-35/L-35e005a.dat" + +[ 12, 0 ] = ascii (fp) : "./hrtfs/elev-30/L-30e000a.dat" +[ 12, 1 ] = ascii (fp) : "./hrtfs/elev-30/L-30e355a.dat" +[ 12, 2 ] = ascii (fp) : "./hrtfs/elev-30/L-30e350a.dat" +[ 12, 3 ] = ascii (fp) : "./hrtfs/elev-30/L-30e345a.dat" +[ 12, 4 ] = ascii (fp) : "./hrtfs/elev-30/L-30e340a.dat" +[ 12, 5 ] = ascii (fp) : "./hrtfs/elev-30/L-30e335a.dat" +[ 12, 6 ] = ascii (fp) : "./hrtfs/elev-30/L-30e330a.dat" +[ 12, 7 ] = ascii (fp) : "./hrtfs/elev-30/L-30e325a.dat" +[ 12, 8 ] = ascii (fp) : "./hrtfs/elev-30/L-30e320a.dat" +[ 12, 9 ] = ascii (fp) : "./hrtfs/elev-30/L-30e315a.dat" +[ 12, 10 ] = ascii (fp) : "./hrtfs/elev-30/L-30e310a.dat" +[ 12, 11 ] = ascii (fp) : "./hrtfs/elev-30/L-30e305a.dat" +[ 12, 12 ] = ascii (fp) : "./hrtfs/elev-30/L-30e300a.dat" +[ 12, 13 ] = ascii (fp) : "./hrtfs/elev-30/L-30e295a.dat" +[ 12, 14 ] = ascii (fp) : "./hrtfs/elev-30/L-30e290a.dat" +[ 12, 15 ] = ascii (fp) : "./hrtfs/elev-30/L-30e285a.dat" +[ 12, 16 ] = ascii (fp) : "./hrtfs/elev-30/L-30e280a.dat" +[ 12, 17 ] = ascii (fp) : "./hrtfs/elev-30/L-30e275a.dat" +[ 12, 18 ] = ascii (fp) : "./hrtfs/elev-30/L-30e270a.dat" +[ 12, 19 ] = ascii (fp) : "./hrtfs/elev-30/L-30e265a.dat" +[ 12, 20 ] = ascii (fp) : "./hrtfs/elev-30/L-30e260a.dat" +[ 12, 21 ] = ascii (fp) : "./hrtfs/elev-30/L-30e255a.dat" +[ 12, 22 ] = ascii (fp) : "./hrtfs/elev-30/L-30e250a.dat" +[ 12, 23 ] = ascii (fp) : "./hrtfs/elev-30/L-30e245a.dat" +[ 12, 24 ] = ascii (fp) : "./hrtfs/elev-30/L-30e240a.dat" +[ 12, 25 ] = ascii (fp) : "./hrtfs/elev-30/L-30e235a.dat" +[ 12, 26 ] = ascii (fp) : "./hrtfs/elev-30/L-30e230a.dat" +[ 12, 27 ] = ascii (fp) : "./hrtfs/elev-30/L-30e225a.dat" +[ 12, 28 ] = ascii (fp) : "./hrtfs/elev-30/L-30e220a.dat" +[ 12, 29 ] = ascii (fp) : "./hrtfs/elev-30/L-30e215a.dat" +[ 12, 30 ] = ascii (fp) : "./hrtfs/elev-30/L-30e210a.dat" +[ 12, 31 ] = ascii (fp) : "./hrtfs/elev-30/L-30e205a.dat" +[ 12, 32 ] = ascii (fp) : "./hrtfs/elev-30/L-30e200a.dat" +[ 12, 33 ] = ascii (fp) : "./hrtfs/elev-30/L-30e195a.dat" +[ 12, 34 ] = ascii (fp) : "./hrtfs/elev-30/L-30e190a.dat" +[ 12, 35 ] = ascii (fp) : "./hrtfs/elev-30/L-30e185a.dat" +[ 12, 36 ] = ascii (fp) : "./hrtfs/elev-30/L-30e180a.dat" +[ 12, 37 ] = ascii (fp) : "./hrtfs/elev-30/L-30e175a.dat" +[ 12, 38 ] = ascii (fp) : "./hrtfs/elev-30/L-30e170a.dat" +[ 12, 39 ] = ascii (fp) : "./hrtfs/elev-30/L-30e165a.dat" +[ 12, 40 ] = ascii (fp) : "./hrtfs/elev-30/L-30e160a.dat" +[ 12, 41 ] = ascii (fp) : "./hrtfs/elev-30/L-30e155a.dat" +[ 12, 42 ] = ascii (fp) : "./hrtfs/elev-30/L-30e150a.dat" +[ 12, 43 ] = ascii (fp) : "./hrtfs/elev-30/L-30e145a.dat" +[ 12, 44 ] = ascii (fp) : "./hrtfs/elev-30/L-30e140a.dat" +[ 12, 45 ] = ascii (fp) : "./hrtfs/elev-30/L-30e135a.dat" +[ 12, 46 ] = ascii (fp) : "./hrtfs/elev-30/L-30e130a.dat" +[ 12, 47 ] = ascii (fp) : "./hrtfs/elev-30/L-30e125a.dat" +[ 12, 48 ] = ascii (fp) : "./hrtfs/elev-30/L-30e120a.dat" +[ 12, 49 ] = ascii (fp) : "./hrtfs/elev-30/L-30e115a.dat" +[ 12, 50 ] = ascii (fp) : "./hrtfs/elev-30/L-30e110a.dat" +[ 12, 51 ] = ascii (fp) : "./hrtfs/elev-30/L-30e105a.dat" +[ 12, 52 ] = ascii (fp) : "./hrtfs/elev-30/L-30e100a.dat" +[ 12, 53 ] = ascii (fp) : "./hrtfs/elev-30/L-30e095a.dat" +[ 12, 54 ] = ascii (fp) : "./hrtfs/elev-30/L-30e090a.dat" +[ 12, 55 ] = ascii (fp) : "./hrtfs/elev-30/L-30e085a.dat" +[ 12, 56 ] = ascii (fp) : "./hrtfs/elev-30/L-30e080a.dat" +[ 12, 57 ] = ascii (fp) : "./hrtfs/elev-30/L-30e075a.dat" +[ 12, 58 ] = ascii (fp) : "./hrtfs/elev-30/L-30e070a.dat" +[ 12, 59 ] = ascii (fp) : "./hrtfs/elev-30/L-30e065a.dat" +[ 12, 60 ] = ascii (fp) : "./hrtfs/elev-30/L-30e060a.dat" +[ 12, 61 ] = ascii (fp) : "./hrtfs/elev-30/L-30e055a.dat" +[ 12, 62 ] = ascii (fp) : "./hrtfs/elev-30/L-30e050a.dat" +[ 12, 63 ] = ascii (fp) : "./hrtfs/elev-30/L-30e045a.dat" +[ 12, 64 ] = ascii (fp) : "./hrtfs/elev-30/L-30e040a.dat" +[ 12, 65 ] = ascii (fp) : "./hrtfs/elev-30/L-30e035a.dat" +[ 12, 66 ] = ascii (fp) : "./hrtfs/elev-30/L-30e030a.dat" +[ 12, 67 ] = ascii (fp) : "./hrtfs/elev-30/L-30e025a.dat" +[ 12, 68 ] = ascii (fp) : "./hrtfs/elev-30/L-30e020a.dat" +[ 12, 69 ] = ascii (fp) : "./hrtfs/elev-30/L-30e015a.dat" +[ 12, 70 ] = ascii (fp) : "./hrtfs/elev-30/L-30e010a.dat" +[ 12, 71 ] = ascii (fp) : "./hrtfs/elev-30/L-30e005a.dat" + +[ 13, 0 ] = ascii (fp) : "./hrtfs/elev-25/L-25e000a.dat" +[ 13, 1 ] = ascii (fp) : "./hrtfs/elev-25/L-25e355a.dat" +[ 13, 2 ] = ascii (fp) : "./hrtfs/elev-25/L-25e350a.dat" +[ 13, 3 ] = ascii (fp) : "./hrtfs/elev-25/L-25e345a.dat" +[ 13, 4 ] = ascii (fp) : "./hrtfs/elev-25/L-25e340a.dat" +[ 13, 5 ] = ascii (fp) : "./hrtfs/elev-25/L-25e335a.dat" +[ 13, 6 ] = ascii (fp) : "./hrtfs/elev-25/L-25e330a.dat" +[ 13, 7 ] = ascii (fp) : "./hrtfs/elev-25/L-25e325a.dat" +[ 13, 8 ] = ascii (fp) : "./hrtfs/elev-25/L-25e320a.dat" +[ 13, 9 ] = ascii (fp) : "./hrtfs/elev-25/L-25e315a.dat" +[ 13, 10 ] = ascii (fp) : "./hrtfs/elev-25/L-25e310a.dat" +[ 13, 11 ] = ascii (fp) : "./hrtfs/elev-25/L-25e305a.dat" +[ 13, 12 ] = ascii (fp) : "./hrtfs/elev-25/L-25e300a.dat" +[ 13, 13 ] = ascii (fp) : "./hrtfs/elev-25/L-25e295a.dat" +[ 13, 14 ] = ascii (fp) : "./hrtfs/elev-25/L-25e290a.dat" +[ 13, 15 ] = ascii (fp) : "./hrtfs/elev-25/L-25e285a.dat" +[ 13, 16 ] = ascii (fp) : "./hrtfs/elev-25/L-25e280a.dat" +[ 13, 17 ] = ascii (fp) : "./hrtfs/elev-25/L-25e275a.dat" +[ 13, 18 ] = ascii (fp) : "./hrtfs/elev-25/L-25e270a.dat" +[ 13, 19 ] = ascii (fp) : "./hrtfs/elev-25/L-25e265a.dat" +[ 13, 20 ] = ascii (fp) : "./hrtfs/elev-25/L-25e260a.dat" +[ 13, 21 ] = ascii (fp) : "./hrtfs/elev-25/L-25e255a.dat" +[ 13, 22 ] = ascii (fp) : "./hrtfs/elev-25/L-25e250a.dat" +[ 13, 23 ] = ascii (fp) : "./hrtfs/elev-25/L-25e245a.dat" +[ 13, 24 ] = ascii (fp) : "./hrtfs/elev-25/L-25e240a.dat" +[ 13, 25 ] = ascii (fp) : "./hrtfs/elev-25/L-25e235a.dat" +[ 13, 26 ] = ascii (fp) : "./hrtfs/elev-25/L-25e230a.dat" +[ 13, 27 ] = ascii (fp) : "./hrtfs/elev-25/L-25e225a.dat" +[ 13, 28 ] = ascii (fp) : "./hrtfs/elev-25/L-25e220a.dat" +[ 13, 29 ] = ascii (fp) : "./hrtfs/elev-25/L-25e215a.dat" +[ 13, 30 ] = ascii (fp) : "./hrtfs/elev-25/L-25e210a.dat" +[ 13, 31 ] = ascii (fp) : "./hrtfs/elev-25/L-25e205a.dat" +[ 13, 32 ] = ascii (fp) : "./hrtfs/elev-25/L-25e200a.dat" +[ 13, 33 ] = ascii (fp) : "./hrtfs/elev-25/L-25e195a.dat" +[ 13, 34 ] = ascii (fp) : "./hrtfs/elev-25/L-25e190a.dat" +[ 13, 35 ] = ascii (fp) : "./hrtfs/elev-25/L-25e185a.dat" +[ 13, 36 ] = ascii (fp) : "./hrtfs/elev-25/L-25e180a.dat" +[ 13, 37 ] = ascii (fp) : "./hrtfs/elev-25/L-25e175a.dat" +[ 13, 38 ] = ascii (fp) : "./hrtfs/elev-25/L-25e170a.dat" +[ 13, 39 ] = ascii (fp) : "./hrtfs/elev-25/L-25e165a.dat" +[ 13, 40 ] = ascii (fp) : "./hrtfs/elev-25/L-25e160a.dat" +[ 13, 41 ] = ascii (fp) : "./hrtfs/elev-25/L-25e155a.dat" +[ 13, 42 ] = ascii (fp) : "./hrtfs/elev-25/L-25e150a.dat" +[ 13, 43 ] = ascii (fp) : "./hrtfs/elev-25/L-25e145a.dat" +[ 13, 44 ] = ascii (fp) : "./hrtfs/elev-25/L-25e140a.dat" +[ 13, 45 ] = ascii (fp) : "./hrtfs/elev-25/L-25e135a.dat" +[ 13, 46 ] = ascii (fp) : "./hrtfs/elev-25/L-25e130a.dat" +[ 13, 47 ] = ascii (fp) : "./hrtfs/elev-25/L-25e125a.dat" +[ 13, 48 ] = ascii (fp) : "./hrtfs/elev-25/L-25e120a.dat" +[ 13, 49 ] = ascii (fp) : "./hrtfs/elev-25/L-25e115a.dat" +[ 13, 50 ] = ascii (fp) : "./hrtfs/elev-25/L-25e110a.dat" +[ 13, 51 ] = ascii (fp) : "./hrtfs/elev-25/L-25e105a.dat" +[ 13, 52 ] = ascii (fp) : "./hrtfs/elev-25/L-25e100a.dat" +[ 13, 53 ] = ascii (fp) : "./hrtfs/elev-25/L-25e095a.dat" +[ 13, 54 ] = ascii (fp) : "./hrtfs/elev-25/L-25e090a.dat" +[ 13, 55 ] = ascii (fp) : "./hrtfs/elev-25/L-25e085a.dat" +[ 13, 56 ] = ascii (fp) : "./hrtfs/elev-25/L-25e080a.dat" +[ 13, 57 ] = ascii (fp) : "./hrtfs/elev-25/L-25e075a.dat" +[ 13, 58 ] = ascii (fp) : "./hrtfs/elev-25/L-25e070a.dat" +[ 13, 59 ] = ascii (fp) : "./hrtfs/elev-25/L-25e065a.dat" +[ 13, 60 ] = ascii (fp) : "./hrtfs/elev-25/L-25e060a.dat" +[ 13, 61 ] = ascii (fp) : "./hrtfs/elev-25/L-25e055a.dat" +[ 13, 62 ] = ascii (fp) : "./hrtfs/elev-25/L-25e050a.dat" +[ 13, 63 ] = ascii (fp) : "./hrtfs/elev-25/L-25e045a.dat" +[ 13, 64 ] = ascii (fp) : "./hrtfs/elev-25/L-25e040a.dat" +[ 13, 65 ] = ascii (fp) : "./hrtfs/elev-25/L-25e035a.dat" +[ 13, 66 ] = ascii (fp) : "./hrtfs/elev-25/L-25e030a.dat" +[ 13, 67 ] = ascii (fp) : "./hrtfs/elev-25/L-25e025a.dat" +[ 13, 68 ] = ascii (fp) : "./hrtfs/elev-25/L-25e020a.dat" +[ 13, 69 ] = ascii (fp) : "./hrtfs/elev-25/L-25e015a.dat" +[ 13, 70 ] = ascii (fp) : "./hrtfs/elev-25/L-25e010a.dat" +[ 13, 71 ] = ascii (fp) : "./hrtfs/elev-25/L-25e005a.dat" + +[ 14, 0 ] = ascii (fp) : "./hrtfs/elev-20/L-20e000a.dat" +[ 14, 1 ] = ascii (fp) : "./hrtfs/elev-20/L-20e355a.dat" +[ 14, 2 ] = ascii (fp) : "./hrtfs/elev-20/L-20e350a.dat" +[ 14, 3 ] = ascii (fp) : "./hrtfs/elev-20/L-20e345a.dat" +[ 14, 4 ] = ascii (fp) : "./hrtfs/elev-20/L-20e340a.dat" +[ 14, 5 ] = ascii (fp) : "./hrtfs/elev-20/L-20e335a.dat" +[ 14, 6 ] = ascii (fp) : "./hrtfs/elev-20/L-20e330a.dat" +[ 14, 7 ] = ascii (fp) : "./hrtfs/elev-20/L-20e325a.dat" +[ 14, 8 ] = ascii (fp) : "./hrtfs/elev-20/L-20e320a.dat" +[ 14, 9 ] = ascii (fp) : "./hrtfs/elev-20/L-20e315a.dat" +[ 14, 10 ] = ascii (fp) : "./hrtfs/elev-20/L-20e310a.dat" +[ 14, 11 ] = ascii (fp) : "./hrtfs/elev-20/L-20e305a.dat" +[ 14, 12 ] = ascii (fp) : "./hrtfs/elev-20/L-20e300a.dat" +[ 14, 13 ] = ascii (fp) : "./hrtfs/elev-20/L-20e295a.dat" +[ 14, 14 ] = ascii (fp) : "./hrtfs/elev-20/L-20e290a.dat" +[ 14, 15 ] = ascii (fp) : "./hrtfs/elev-20/L-20e285a.dat" +[ 14, 16 ] = ascii (fp) : "./hrtfs/elev-20/L-20e280a.dat" +[ 14, 17 ] = ascii (fp) : "./hrtfs/elev-20/L-20e275a.dat" +[ 14, 18 ] = ascii (fp) : "./hrtfs/elev-20/L-20e270a.dat" +[ 14, 19 ] = ascii (fp) : "./hrtfs/elev-20/L-20e265a.dat" +[ 14, 20 ] = ascii (fp) : "./hrtfs/elev-20/L-20e260a.dat" +[ 14, 21 ] = ascii (fp) : "./hrtfs/elev-20/L-20e255a.dat" +[ 14, 22 ] = ascii (fp) : "./hrtfs/elev-20/L-20e250a.dat" +[ 14, 23 ] = ascii (fp) : "./hrtfs/elev-20/L-20e245a.dat" +[ 14, 24 ] = ascii (fp) : "./hrtfs/elev-20/L-20e240a.dat" +[ 14, 25 ] = ascii (fp) : "./hrtfs/elev-20/L-20e235a.dat" +[ 14, 26 ] = ascii (fp) : "./hrtfs/elev-20/L-20e230a.dat" +[ 14, 27 ] = ascii (fp) : "./hrtfs/elev-20/L-20e225a.dat" +[ 14, 28 ] = ascii (fp) : "./hrtfs/elev-20/L-20e220a.dat" +[ 14, 29 ] = ascii (fp) : "./hrtfs/elev-20/L-20e215a.dat" +[ 14, 30 ] = ascii (fp) : "./hrtfs/elev-20/L-20e210a.dat" +[ 14, 31 ] = ascii (fp) : "./hrtfs/elev-20/L-20e205a.dat" +[ 14, 32 ] = ascii (fp) : "./hrtfs/elev-20/L-20e200a.dat" +[ 14, 33 ] = ascii (fp) : "./hrtfs/elev-20/L-20e195a.dat" +[ 14, 34 ] = ascii (fp) : "./hrtfs/elev-20/L-20e190a.dat" +[ 14, 35 ] = ascii (fp) : "./hrtfs/elev-20/L-20e185a.dat" +[ 14, 36 ] = ascii (fp) : "./hrtfs/elev-20/L-20e180a.dat" +[ 14, 37 ] = ascii (fp) : "./hrtfs/elev-20/L-20e175a.dat" +[ 14, 38 ] = ascii (fp) : "./hrtfs/elev-20/L-20e170a.dat" +[ 14, 39 ] = ascii (fp) : "./hrtfs/elev-20/L-20e165a.dat" +[ 14, 40 ] = ascii (fp) : "./hrtfs/elev-20/L-20e160a.dat" +[ 14, 41 ] = ascii (fp) : "./hrtfs/elev-20/L-20e155a.dat" +[ 14, 42 ] = ascii (fp) : "./hrtfs/elev-20/L-20e150a.dat" +[ 14, 43 ] = ascii (fp) : "./hrtfs/elev-20/L-20e145a.dat" +[ 14, 44 ] = ascii (fp) : "./hrtfs/elev-20/L-20e140a.dat" +[ 14, 45 ] = ascii (fp) : "./hrtfs/elev-20/L-20e135a.dat" +[ 14, 46 ] = ascii (fp) : "./hrtfs/elev-20/L-20e130a.dat" +[ 14, 47 ] = ascii (fp) : "./hrtfs/elev-20/L-20e125a.dat" +[ 14, 48 ] = ascii (fp) : "./hrtfs/elev-20/L-20e120a.dat" +[ 14, 49 ] = ascii (fp) : "./hrtfs/elev-20/L-20e115a.dat" +[ 14, 50 ] = ascii (fp) : "./hrtfs/elev-20/L-20e110a.dat" +[ 14, 51 ] = ascii (fp) : "./hrtfs/elev-20/L-20e105a.dat" +[ 14, 52 ] = ascii (fp) : "./hrtfs/elev-20/L-20e100a.dat" +[ 14, 53 ] = ascii (fp) : "./hrtfs/elev-20/L-20e095a.dat" +[ 14, 54 ] = ascii (fp) : "./hrtfs/elev-20/L-20e090a.dat" +[ 14, 55 ] = ascii (fp) : "./hrtfs/elev-20/L-20e085a.dat" +[ 14, 56 ] = ascii (fp) : "./hrtfs/elev-20/L-20e080a.dat" +[ 14, 57 ] = ascii (fp) : "./hrtfs/elev-20/L-20e075a.dat" +[ 14, 58 ] = ascii (fp) : "./hrtfs/elev-20/L-20e070a.dat" +[ 14, 59 ] = ascii (fp) : "./hrtfs/elev-20/L-20e065a.dat" +[ 14, 60 ] = ascii (fp) : "./hrtfs/elev-20/L-20e060a.dat" +[ 14, 61 ] = ascii (fp) : "./hrtfs/elev-20/L-20e055a.dat" +[ 14, 62 ] = ascii (fp) : "./hrtfs/elev-20/L-20e050a.dat" +[ 14, 63 ] = ascii (fp) : "./hrtfs/elev-20/L-20e045a.dat" +[ 14, 64 ] = ascii (fp) : "./hrtfs/elev-20/L-20e040a.dat" +[ 14, 65 ] = ascii (fp) : "./hrtfs/elev-20/L-20e035a.dat" +[ 14, 66 ] = ascii (fp) : "./hrtfs/elev-20/L-20e030a.dat" +[ 14, 67 ] = ascii (fp) : "./hrtfs/elev-20/L-20e025a.dat" +[ 14, 68 ] = ascii (fp) : "./hrtfs/elev-20/L-20e020a.dat" +[ 14, 69 ] = ascii (fp) : "./hrtfs/elev-20/L-20e015a.dat" +[ 14, 70 ] = ascii (fp) : "./hrtfs/elev-20/L-20e010a.dat" +[ 14, 71 ] = ascii (fp) : "./hrtfs/elev-20/L-20e005a.dat" + +[ 15, 0 ] = ascii (fp) : "./hrtfs/elev-15/L-15e000a.dat" +[ 15, 1 ] = ascii (fp) : "./hrtfs/elev-15/L-15e355a.dat" +[ 15, 2 ] = ascii (fp) : "./hrtfs/elev-15/L-15e350a.dat" +[ 15, 3 ] = ascii (fp) : "./hrtfs/elev-15/L-15e345a.dat" +[ 15, 4 ] = ascii (fp) : "./hrtfs/elev-15/L-15e340a.dat" +[ 15, 5 ] = ascii (fp) : "./hrtfs/elev-15/L-15e335a.dat" +[ 15, 6 ] = ascii (fp) : "./hrtfs/elev-15/L-15e330a.dat" +[ 15, 7 ] = ascii (fp) : "./hrtfs/elev-15/L-15e325a.dat" +[ 15, 8 ] = ascii (fp) : "./hrtfs/elev-15/L-15e320a.dat" +[ 15, 9 ] = ascii (fp) : "./hrtfs/elev-15/L-15e315a.dat" +[ 15, 10 ] = ascii (fp) : "./hrtfs/elev-15/L-15e310a.dat" +[ 15, 11 ] = ascii (fp) : "./hrtfs/elev-15/L-15e305a.dat" +[ 15, 12 ] = ascii (fp) : "./hrtfs/elev-15/L-15e300a.dat" +[ 15, 13 ] = ascii (fp) : "./hrtfs/elev-15/L-15e295a.dat" +[ 15, 14 ] = ascii (fp) : "./hrtfs/elev-15/L-15e290a.dat" +[ 15, 15 ] = ascii (fp) : "./hrtfs/elev-15/L-15e285a.dat" +[ 15, 16 ] = ascii (fp) : "./hrtfs/elev-15/L-15e280a.dat" +[ 15, 17 ] = ascii (fp) : "./hrtfs/elev-15/L-15e275a.dat" +[ 15, 18 ] = ascii (fp) : "./hrtfs/elev-15/L-15e270a.dat" +[ 15, 19 ] = ascii (fp) : "./hrtfs/elev-15/L-15e265a.dat" +[ 15, 20 ] = ascii (fp) : "./hrtfs/elev-15/L-15e260a.dat" +[ 15, 21 ] = ascii (fp) : "./hrtfs/elev-15/L-15e255a.dat" +[ 15, 22 ] = ascii (fp) : "./hrtfs/elev-15/L-15e250a.dat" +[ 15, 23 ] = ascii (fp) : "./hrtfs/elev-15/L-15e245a.dat" +[ 15, 24 ] = ascii (fp) : "./hrtfs/elev-15/L-15e240a.dat" +[ 15, 25 ] = ascii (fp) : "./hrtfs/elev-15/L-15e235a.dat" +[ 15, 26 ] = ascii (fp) : "./hrtfs/elev-15/L-15e230a.dat" +[ 15, 27 ] = ascii (fp) : "./hrtfs/elev-15/L-15e225a.dat" +[ 15, 28 ] = ascii (fp) : "./hrtfs/elev-15/L-15e220a.dat" +[ 15, 29 ] = ascii (fp) : "./hrtfs/elev-15/L-15e215a.dat" +[ 15, 30 ] = ascii (fp) : "./hrtfs/elev-15/L-15e210a.dat" +[ 15, 31 ] = ascii (fp) : "./hrtfs/elev-15/L-15e205a.dat" +[ 15, 32 ] = ascii (fp) : "./hrtfs/elev-15/L-15e200a.dat" +[ 15, 33 ] = ascii (fp) : "./hrtfs/elev-15/L-15e195a.dat" +[ 15, 34 ] = ascii (fp) : "./hrtfs/elev-15/L-15e190a.dat" +[ 15, 35 ] = ascii (fp) : "./hrtfs/elev-15/L-15e185a.dat" +[ 15, 36 ] = ascii (fp) : "./hrtfs/elev-15/L-15e180a.dat" +[ 15, 37 ] = ascii (fp) : "./hrtfs/elev-15/L-15e175a.dat" +[ 15, 38 ] = ascii (fp) : "./hrtfs/elev-15/L-15e170a.dat" +[ 15, 39 ] = ascii (fp) : "./hrtfs/elev-15/L-15e165a.dat" +[ 15, 40 ] = ascii (fp) : "./hrtfs/elev-15/L-15e160a.dat" +[ 15, 41 ] = ascii (fp) : "./hrtfs/elev-15/L-15e155a.dat" +[ 15, 42 ] = ascii (fp) : "./hrtfs/elev-15/L-15e150a.dat" +[ 15, 43 ] = ascii (fp) : "./hrtfs/elev-15/L-15e145a.dat" +[ 15, 44 ] = ascii (fp) : "./hrtfs/elev-15/L-15e140a.dat" +[ 15, 45 ] = ascii (fp) : "./hrtfs/elev-15/L-15e135a.dat" +[ 15, 46 ] = ascii (fp) : "./hrtfs/elev-15/L-15e130a.dat" +[ 15, 47 ] = ascii (fp) : "./hrtfs/elev-15/L-15e125a.dat" +[ 15, 48 ] = ascii (fp) : "./hrtfs/elev-15/L-15e120a.dat" +[ 15, 49 ] = ascii (fp) : "./hrtfs/elev-15/L-15e115a.dat" +[ 15, 50 ] = ascii (fp) : "./hrtfs/elev-15/L-15e110a.dat" +[ 15, 51 ] = ascii (fp) : "./hrtfs/elev-15/L-15e105a.dat" +[ 15, 52 ] = ascii (fp) : "./hrtfs/elev-15/L-15e100a.dat" +[ 15, 53 ] = ascii (fp) : "./hrtfs/elev-15/L-15e095a.dat" +[ 15, 54 ] = ascii (fp) : "./hrtfs/elev-15/L-15e090a.dat" +[ 15, 55 ] = ascii (fp) : "./hrtfs/elev-15/L-15e085a.dat" +[ 15, 56 ] = ascii (fp) : "./hrtfs/elev-15/L-15e080a.dat" +[ 15, 57 ] = ascii (fp) : "./hrtfs/elev-15/L-15e075a.dat" +[ 15, 58 ] = ascii (fp) : "./hrtfs/elev-15/L-15e070a.dat" +[ 15, 59 ] = ascii (fp) : "./hrtfs/elev-15/L-15e065a.dat" +[ 15, 60 ] = ascii (fp) : "./hrtfs/elev-15/L-15e060a.dat" +[ 15, 61 ] = ascii (fp) : "./hrtfs/elev-15/L-15e055a.dat" +[ 15, 62 ] = ascii (fp) : "./hrtfs/elev-15/L-15e050a.dat" +[ 15, 63 ] = ascii (fp) : "./hrtfs/elev-15/L-15e045a.dat" +[ 15, 64 ] = ascii (fp) : "./hrtfs/elev-15/L-15e040a.dat" +[ 15, 65 ] = ascii (fp) : "./hrtfs/elev-15/L-15e035a.dat" +[ 15, 66 ] = ascii (fp) : "./hrtfs/elev-15/L-15e030a.dat" +[ 15, 67 ] = ascii (fp) : "./hrtfs/elev-15/L-15e025a.dat" +[ 15, 68 ] = ascii (fp) : "./hrtfs/elev-15/L-15e020a.dat" +[ 15, 69 ] = ascii (fp) : "./hrtfs/elev-15/L-15e015a.dat" +[ 15, 70 ] = ascii (fp) : "./hrtfs/elev-15/L-15e010a.dat" +[ 15, 71 ] = ascii (fp) : "./hrtfs/elev-15/L-15e005a.dat" + +[ 16, 0 ] = ascii (fp) : "./hrtfs/elev-10/L-10e000a.dat" +[ 16, 1 ] = ascii (fp) : "./hrtfs/elev-10/L-10e355a.dat" +[ 16, 2 ] = ascii (fp) : "./hrtfs/elev-10/L-10e350a.dat" +[ 16, 3 ] = ascii (fp) : "./hrtfs/elev-10/L-10e345a.dat" +[ 16, 4 ] = ascii (fp) : "./hrtfs/elev-10/L-10e340a.dat" +[ 16, 5 ] = ascii (fp) : "./hrtfs/elev-10/L-10e335a.dat" +[ 16, 6 ] = ascii (fp) : "./hrtfs/elev-10/L-10e330a.dat" +[ 16, 7 ] = ascii (fp) : "./hrtfs/elev-10/L-10e325a.dat" +[ 16, 8 ] = ascii (fp) : "./hrtfs/elev-10/L-10e320a.dat" +[ 16, 9 ] = ascii (fp) : "./hrtfs/elev-10/L-10e315a.dat" +[ 16, 10 ] = ascii (fp) : "./hrtfs/elev-10/L-10e310a.dat" +[ 16, 11 ] = ascii (fp) : "./hrtfs/elev-10/L-10e305a.dat" +[ 16, 12 ] = ascii (fp) : "./hrtfs/elev-10/L-10e300a.dat" +[ 16, 13 ] = ascii (fp) : "./hrtfs/elev-10/L-10e295a.dat" +[ 16, 14 ] = ascii (fp) : "./hrtfs/elev-10/L-10e290a.dat" +[ 16, 15 ] = ascii (fp) : "./hrtfs/elev-10/L-10e285a.dat" +[ 16, 16 ] = ascii (fp) : "./hrtfs/elev-10/L-10e280a.dat" +[ 16, 17 ] = ascii (fp) : "./hrtfs/elev-10/L-10e275a.dat" +[ 16, 18 ] = ascii (fp) : "./hrtfs/elev-10/L-10e270a.dat" +[ 16, 19 ] = ascii (fp) : "./hrtfs/elev-10/L-10e265a.dat" +[ 16, 20 ] = ascii (fp) : "./hrtfs/elev-10/L-10e260a.dat" +[ 16, 21 ] = ascii (fp) : "./hrtfs/elev-10/L-10e255a.dat" +[ 16, 22 ] = ascii (fp) : "./hrtfs/elev-10/L-10e250a.dat" +[ 16, 23 ] = ascii (fp) : "./hrtfs/elev-10/L-10e245a.dat" +[ 16, 24 ] = ascii (fp) : "./hrtfs/elev-10/L-10e240a.dat" +[ 16, 25 ] = ascii (fp) : "./hrtfs/elev-10/L-10e235a.dat" +[ 16, 26 ] = ascii (fp) : "./hrtfs/elev-10/L-10e230a.dat" +[ 16, 27 ] = ascii (fp) : "./hrtfs/elev-10/L-10e225a.dat" +[ 16, 28 ] = ascii (fp) : "./hrtfs/elev-10/L-10e220a.dat" +[ 16, 29 ] = ascii (fp) : "./hrtfs/elev-10/L-10e215a.dat" +[ 16, 30 ] = ascii (fp) : "./hrtfs/elev-10/L-10e210a.dat" +[ 16, 31 ] = ascii (fp) : "./hrtfs/elev-10/L-10e205a.dat" +[ 16, 32 ] = ascii (fp) : "./hrtfs/elev-10/L-10e200a.dat" +[ 16, 33 ] = ascii (fp) : "./hrtfs/elev-10/L-10e195a.dat" +[ 16, 34 ] = ascii (fp) : "./hrtfs/elev-10/L-10e190a.dat" +[ 16, 35 ] = ascii (fp) : "./hrtfs/elev-10/L-10e185a.dat" +[ 16, 36 ] = ascii (fp) : "./hrtfs/elev-10/L-10e180a.dat" +[ 16, 37 ] = ascii (fp) : "./hrtfs/elev-10/L-10e175a.dat" +[ 16, 38 ] = ascii (fp) : "./hrtfs/elev-10/L-10e170a.dat" +[ 16, 39 ] = ascii (fp) : "./hrtfs/elev-10/L-10e165a.dat" +[ 16, 40 ] = ascii (fp) : "./hrtfs/elev-10/L-10e160a.dat" +[ 16, 41 ] = ascii (fp) : "./hrtfs/elev-10/L-10e155a.dat" +[ 16, 42 ] = ascii (fp) : "./hrtfs/elev-10/L-10e150a.dat" +[ 16, 43 ] = ascii (fp) : "./hrtfs/elev-10/L-10e145a.dat" +[ 16, 44 ] = ascii (fp) : "./hrtfs/elev-10/L-10e140a.dat" +[ 16, 45 ] = ascii (fp) : "./hrtfs/elev-10/L-10e135a.dat" +[ 16, 46 ] = ascii (fp) : "./hrtfs/elev-10/L-10e130a.dat" +[ 16, 47 ] = ascii (fp) : "./hrtfs/elev-10/L-10e125a.dat" +[ 16, 48 ] = ascii (fp) : "./hrtfs/elev-10/L-10e120a.dat" +[ 16, 49 ] = ascii (fp) : "./hrtfs/elev-10/L-10e115a.dat" +[ 16, 50 ] = ascii (fp) : "./hrtfs/elev-10/L-10e110a.dat" +[ 16, 51 ] = ascii (fp) : "./hrtfs/elev-10/L-10e105a.dat" +[ 16, 52 ] = ascii (fp) : "./hrtfs/elev-10/L-10e100a.dat" +[ 16, 53 ] = ascii (fp) : "./hrtfs/elev-10/L-10e095a.dat" +[ 16, 54 ] = ascii (fp) : "./hrtfs/elev-10/L-10e090a.dat" +[ 16, 55 ] = ascii (fp) : "./hrtfs/elev-10/L-10e085a.dat" +[ 16, 56 ] = ascii (fp) : "./hrtfs/elev-10/L-10e080a.dat" +[ 16, 57 ] = ascii (fp) : "./hrtfs/elev-10/L-10e075a.dat" +[ 16, 58 ] = ascii (fp) : "./hrtfs/elev-10/L-10e070a.dat" +[ 16, 59 ] = ascii (fp) : "./hrtfs/elev-10/L-10e065a.dat" +[ 16, 60 ] = ascii (fp) : "./hrtfs/elev-10/L-10e060a.dat" +[ 16, 61 ] = ascii (fp) : "./hrtfs/elev-10/L-10e055a.dat" +[ 16, 62 ] = ascii (fp) : "./hrtfs/elev-10/L-10e050a.dat" +[ 16, 63 ] = ascii (fp) : "./hrtfs/elev-10/L-10e045a.dat" +[ 16, 64 ] = ascii (fp) : "./hrtfs/elev-10/L-10e040a.dat" +[ 16, 65 ] = ascii (fp) : "./hrtfs/elev-10/L-10e035a.dat" +[ 16, 66 ] = ascii (fp) : "./hrtfs/elev-10/L-10e030a.dat" +[ 16, 67 ] = ascii (fp) : "./hrtfs/elev-10/L-10e025a.dat" +[ 16, 68 ] = ascii (fp) : "./hrtfs/elev-10/L-10e020a.dat" +[ 16, 69 ] = ascii (fp) : "./hrtfs/elev-10/L-10e015a.dat" +[ 16, 70 ] = ascii (fp) : "./hrtfs/elev-10/L-10e010a.dat" +[ 16, 71 ] = ascii (fp) : "./hrtfs/elev-10/L-10e005a.dat" + +[ 17, 0 ] = ascii (fp) : "./hrtfs/elev-5/L-5e000a.dat" +[ 17, 1 ] = ascii (fp) : "./hrtfs/elev-5/L-5e355a.dat" +[ 17, 2 ] = ascii (fp) : "./hrtfs/elev-5/L-5e350a.dat" +[ 17, 3 ] = ascii (fp) : "./hrtfs/elev-5/L-5e345a.dat" +[ 17, 4 ] = ascii (fp) : "./hrtfs/elev-5/L-5e340a.dat" +[ 17, 5 ] = ascii (fp) : "./hrtfs/elev-5/L-5e335a.dat" +[ 17, 6 ] = ascii (fp) : "./hrtfs/elev-5/L-5e330a.dat" +[ 17, 7 ] = ascii (fp) : "./hrtfs/elev-5/L-5e325a.dat" +[ 17, 8 ] = ascii (fp) : "./hrtfs/elev-5/L-5e320a.dat" +[ 17, 9 ] = ascii (fp) : "./hrtfs/elev-5/L-5e315a.dat" +[ 17, 10 ] = ascii (fp) : "./hrtfs/elev-5/L-5e310a.dat" +[ 17, 11 ] = ascii (fp) : "./hrtfs/elev-5/L-5e305a.dat" +[ 17, 12 ] = ascii (fp) : "./hrtfs/elev-5/L-5e300a.dat" +[ 17, 13 ] = ascii (fp) : "./hrtfs/elev-5/L-5e295a.dat" +[ 17, 14 ] = ascii (fp) : "./hrtfs/elev-5/L-5e290a.dat" +[ 17, 15 ] = ascii (fp) : "./hrtfs/elev-5/L-5e285a.dat" +[ 17, 16 ] = ascii (fp) : "./hrtfs/elev-5/L-5e280a.dat" +[ 17, 17 ] = ascii (fp) : "./hrtfs/elev-5/L-5e275a.dat" +[ 17, 18 ] = ascii (fp) : "./hrtfs/elev-5/L-5e270a.dat" +[ 17, 19 ] = ascii (fp) : "./hrtfs/elev-5/L-5e265a.dat" +[ 17, 20 ] = ascii (fp) : "./hrtfs/elev-5/L-5e260a.dat" +[ 17, 21 ] = ascii (fp) : "./hrtfs/elev-5/L-5e255a.dat" +[ 17, 22 ] = ascii (fp) : "./hrtfs/elev-5/L-5e250a.dat" +[ 17, 23 ] = ascii (fp) : "./hrtfs/elev-5/L-5e245a.dat" +[ 17, 24 ] = ascii (fp) : "./hrtfs/elev-5/L-5e240a.dat" +[ 17, 25 ] = ascii (fp) : "./hrtfs/elev-5/L-5e235a.dat" +[ 17, 26 ] = ascii (fp) : "./hrtfs/elev-5/L-5e230a.dat" +[ 17, 27 ] = ascii (fp) : "./hrtfs/elev-5/L-5e225a.dat" +[ 17, 28 ] = ascii (fp) : "./hrtfs/elev-5/L-5e220a.dat" +[ 17, 29 ] = ascii (fp) : "./hrtfs/elev-5/L-5e215a.dat" +[ 17, 30 ] = ascii (fp) : "./hrtfs/elev-5/L-5e210a.dat" +[ 17, 31 ] = ascii (fp) : "./hrtfs/elev-5/L-5e205a.dat" +[ 17, 32 ] = ascii (fp) : "./hrtfs/elev-5/L-5e200a.dat" +[ 17, 33 ] = ascii (fp) : "./hrtfs/elev-5/L-5e195a.dat" +[ 17, 34 ] = ascii (fp) : "./hrtfs/elev-5/L-5e190a.dat" +[ 17, 35 ] = ascii (fp) : "./hrtfs/elev-5/L-5e185a.dat" +[ 17, 36 ] = ascii (fp) : "./hrtfs/elev-5/L-5e180a.dat" +[ 17, 37 ] = ascii (fp) : "./hrtfs/elev-5/L-5e175a.dat" +[ 17, 38 ] = ascii (fp) : "./hrtfs/elev-5/L-5e170a.dat" +[ 17, 39 ] = ascii (fp) : "./hrtfs/elev-5/L-5e165a.dat" +[ 17, 40 ] = ascii (fp) : "./hrtfs/elev-5/L-5e160a.dat" +[ 17, 41 ] = ascii (fp) : "./hrtfs/elev-5/L-5e155a.dat" +[ 17, 42 ] = ascii (fp) : "./hrtfs/elev-5/L-5e150a.dat" +[ 17, 43 ] = ascii (fp) : "./hrtfs/elev-5/L-5e145a.dat" +[ 17, 44 ] = ascii (fp) : "./hrtfs/elev-5/L-5e140a.dat" +[ 17, 45 ] = ascii (fp) : "./hrtfs/elev-5/L-5e135a.dat" +[ 17, 46 ] = ascii (fp) : "./hrtfs/elev-5/L-5e130a.dat" +[ 17, 47 ] = ascii (fp) : "./hrtfs/elev-5/L-5e125a.dat" +[ 17, 48 ] = ascii (fp) : "./hrtfs/elev-5/L-5e120a.dat" +[ 17, 49 ] = ascii (fp) : "./hrtfs/elev-5/L-5e115a.dat" +[ 17, 50 ] = ascii (fp) : "./hrtfs/elev-5/L-5e110a.dat" +[ 17, 51 ] = ascii (fp) : "./hrtfs/elev-5/L-5e105a.dat" +[ 17, 52 ] = ascii (fp) : "./hrtfs/elev-5/L-5e100a.dat" +[ 17, 53 ] = ascii (fp) : "./hrtfs/elev-5/L-5e095a.dat" +[ 17, 54 ] = ascii (fp) : "./hrtfs/elev-5/L-5e090a.dat" +[ 17, 55 ] = ascii (fp) : "./hrtfs/elev-5/L-5e085a.dat" +[ 17, 56 ] = ascii (fp) : "./hrtfs/elev-5/L-5e080a.dat" +[ 17, 57 ] = ascii (fp) : "./hrtfs/elev-5/L-5e075a.dat" +[ 17, 58 ] = ascii (fp) : "./hrtfs/elev-5/L-5e070a.dat" +[ 17, 59 ] = ascii (fp) : "./hrtfs/elev-5/L-5e065a.dat" +[ 17, 60 ] = ascii (fp) : "./hrtfs/elev-5/L-5e060a.dat" +[ 17, 61 ] = ascii (fp) : "./hrtfs/elev-5/L-5e055a.dat" +[ 17, 62 ] = ascii (fp) : "./hrtfs/elev-5/L-5e050a.dat" +[ 17, 63 ] = ascii (fp) : "./hrtfs/elev-5/L-5e045a.dat" +[ 17, 64 ] = ascii (fp) : "./hrtfs/elev-5/L-5e040a.dat" +[ 17, 65 ] = ascii (fp) : "./hrtfs/elev-5/L-5e035a.dat" +[ 17, 66 ] = ascii (fp) : "./hrtfs/elev-5/L-5e030a.dat" +[ 17, 67 ] = ascii (fp) : "./hrtfs/elev-5/L-5e025a.dat" +[ 17, 68 ] = ascii (fp) : "./hrtfs/elev-5/L-5e020a.dat" +[ 17, 69 ] = ascii (fp) : "./hrtfs/elev-5/L-5e015a.dat" +[ 17, 70 ] = ascii (fp) : "./hrtfs/elev-5/L-5e010a.dat" +[ 17, 71 ] = ascii (fp) : "./hrtfs/elev-5/L-5e005a.dat" + +[ 18, 0 ] = ascii (fp) : "./hrtfs/elev0/L0e000a.dat" +[ 18, 1 ] = ascii (fp) : "./hrtfs/elev0/L0e355a.dat" +[ 18, 2 ] = ascii (fp) : "./hrtfs/elev0/L0e350a.dat" +[ 18, 3 ] = ascii (fp) : "./hrtfs/elev0/L0e345a.dat" +[ 18, 4 ] = ascii (fp) : "./hrtfs/elev0/L0e340a.dat" +[ 18, 5 ] = ascii (fp) : "./hrtfs/elev0/L0e335a.dat" +[ 18, 6 ] = ascii (fp) : "./hrtfs/elev0/L0e330a.dat" +[ 18, 7 ] = ascii (fp) : "./hrtfs/elev0/L0e325a.dat" +[ 18, 8 ] = ascii (fp) : "./hrtfs/elev0/L0e320a.dat" +[ 18, 9 ] = ascii (fp) : "./hrtfs/elev0/L0e315a.dat" +[ 18, 10 ] = ascii (fp) : "./hrtfs/elev0/L0e310a.dat" +[ 18, 11 ] = ascii (fp) : "./hrtfs/elev0/L0e305a.dat" +[ 18, 12 ] = ascii (fp) : "./hrtfs/elev0/L0e300a.dat" +[ 18, 13 ] = ascii (fp) : "./hrtfs/elev0/L0e295a.dat" +[ 18, 14 ] = ascii (fp) : "./hrtfs/elev0/L0e290a.dat" +[ 18, 15 ] = ascii (fp) : "./hrtfs/elev0/L0e285a.dat" +[ 18, 16 ] = ascii (fp) : "./hrtfs/elev0/L0e280a.dat" +[ 18, 17 ] = ascii (fp) : "./hrtfs/elev0/L0e275a.dat" +[ 18, 18 ] = ascii (fp) : "./hrtfs/elev0/L0e270a.dat" +[ 18, 19 ] = ascii (fp) : "./hrtfs/elev0/L0e265a.dat" +[ 18, 20 ] = ascii (fp) : "./hrtfs/elev0/L0e260a.dat" +[ 18, 21 ] = ascii (fp) : "./hrtfs/elev0/L0e255a.dat" +[ 18, 22 ] = ascii (fp) : "./hrtfs/elev0/L0e250a.dat" +[ 18, 23 ] = ascii (fp) : "./hrtfs/elev0/L0e245a.dat" +[ 18, 24 ] = ascii (fp) : "./hrtfs/elev0/L0e240a.dat" +[ 18, 25 ] = ascii (fp) : "./hrtfs/elev0/L0e235a.dat" +[ 18, 26 ] = ascii (fp) : "./hrtfs/elev0/L0e230a.dat" +[ 18, 27 ] = ascii (fp) : "./hrtfs/elev0/L0e225a.dat" +[ 18, 28 ] = ascii (fp) : "./hrtfs/elev0/L0e220a.dat" +[ 18, 29 ] = ascii (fp) : "./hrtfs/elev0/L0e215a.dat" +[ 18, 30 ] = ascii (fp) : "./hrtfs/elev0/L0e210a.dat" +[ 18, 31 ] = ascii (fp) : "./hrtfs/elev0/L0e205a.dat" +[ 18, 32 ] = ascii (fp) : "./hrtfs/elev0/L0e200a.dat" +[ 18, 33 ] = ascii (fp) : "./hrtfs/elev0/L0e195a.dat" +[ 18, 34 ] = ascii (fp) : "./hrtfs/elev0/L0e190a.dat" +[ 18, 35 ] = ascii (fp) : "./hrtfs/elev0/L0e185a.dat" +[ 18, 36 ] = ascii (fp) : "./hrtfs/elev0/L0e180a.dat" +[ 18, 37 ] = ascii (fp) : "./hrtfs/elev0/L0e175a.dat" +[ 18, 38 ] = ascii (fp) : "./hrtfs/elev0/L0e170a.dat" +[ 18, 39 ] = ascii (fp) : "./hrtfs/elev0/L0e165a.dat" +[ 18, 40 ] = ascii (fp) : "./hrtfs/elev0/L0e160a.dat" +[ 18, 41 ] = ascii (fp) : "./hrtfs/elev0/L0e155a.dat" +[ 18, 42 ] = ascii (fp) : "./hrtfs/elev0/L0e150a.dat" +[ 18, 43 ] = ascii (fp) : "./hrtfs/elev0/L0e145a.dat" +[ 18, 44 ] = ascii (fp) : "./hrtfs/elev0/L0e140a.dat" +[ 18, 45 ] = ascii (fp) : "./hrtfs/elev0/L0e135a.dat" +[ 18, 46 ] = ascii (fp) : "./hrtfs/elev0/L0e130a.dat" +[ 18, 47 ] = ascii (fp) : "./hrtfs/elev0/L0e125a.dat" +[ 18, 48 ] = ascii (fp) : "./hrtfs/elev0/L0e120a.dat" +[ 18, 49 ] = ascii (fp) : "./hrtfs/elev0/L0e115a.dat" +[ 18, 50 ] = ascii (fp) : "./hrtfs/elev0/L0e110a.dat" +[ 18, 51 ] = ascii (fp) : "./hrtfs/elev0/L0e105a.dat" +[ 18, 52 ] = ascii (fp) : "./hrtfs/elev0/L0e100a.dat" +[ 18, 53 ] = ascii (fp) : "./hrtfs/elev0/L0e095a.dat" +[ 18, 54 ] = ascii (fp) : "./hrtfs/elev0/L0e090a.dat" +[ 18, 55 ] = ascii (fp) : "./hrtfs/elev0/L0e085a.dat" +[ 18, 56 ] = ascii (fp) : "./hrtfs/elev0/L0e080a.dat" +[ 18, 57 ] = ascii (fp) : "./hrtfs/elev0/L0e075a.dat" +[ 18, 58 ] = ascii (fp) : "./hrtfs/elev0/L0e070a.dat" +[ 18, 59 ] = ascii (fp) : "./hrtfs/elev0/L0e065a.dat" +[ 18, 60 ] = ascii (fp) : "./hrtfs/elev0/L0e060a.dat" +[ 18, 61 ] = ascii (fp) : "./hrtfs/elev0/L0e055a.dat" +[ 18, 62 ] = ascii (fp) : "./hrtfs/elev0/L0e050a.dat" +[ 18, 63 ] = ascii (fp) : "./hrtfs/elev0/L0e045a.dat" +[ 18, 64 ] = ascii (fp) : "./hrtfs/elev0/L0e040a.dat" +[ 18, 65 ] = ascii (fp) : "./hrtfs/elev0/L0e035a.dat" +[ 18, 66 ] = ascii (fp) : "./hrtfs/elev0/L0e030a.dat" +[ 18, 67 ] = ascii (fp) : "./hrtfs/elev0/L0e025a.dat" +[ 18, 68 ] = ascii (fp) : "./hrtfs/elev0/L0e020a.dat" +[ 18, 69 ] = ascii (fp) : "./hrtfs/elev0/L0e015a.dat" +[ 18, 70 ] = ascii (fp) : "./hrtfs/elev0/L0e010a.dat" +[ 18, 71 ] = ascii (fp) : "./hrtfs/elev0/L0e005a.dat" + +[ 19, 0 ] = ascii (fp) : "./hrtfs/elev5/L5e000a.dat" +[ 19, 1 ] = ascii (fp) : "./hrtfs/elev5/L5e355a.dat" +[ 19, 2 ] = ascii (fp) : "./hrtfs/elev5/L5e350a.dat" +[ 19, 3 ] = ascii (fp) : "./hrtfs/elev5/L5e345a.dat" +[ 19, 4 ] = ascii (fp) : "./hrtfs/elev5/L5e340a.dat" +[ 19, 5 ] = ascii (fp) : "./hrtfs/elev5/L5e335a.dat" +[ 19, 6 ] = ascii (fp) : "./hrtfs/elev5/L5e330a.dat" +[ 19, 7 ] = ascii (fp) : "./hrtfs/elev5/L5e325a.dat" +[ 19, 8 ] = ascii (fp) : "./hrtfs/elev5/L5e320a.dat" +[ 19, 9 ] = ascii (fp) : "./hrtfs/elev5/L5e315a.dat" +[ 19, 10 ] = ascii (fp) : "./hrtfs/elev5/L5e310a.dat" +[ 19, 11 ] = ascii (fp) : "./hrtfs/elev5/L5e305a.dat" +[ 19, 12 ] = ascii (fp) : "./hrtfs/elev5/L5e300a.dat" +[ 19, 13 ] = ascii (fp) : "./hrtfs/elev5/L5e295a.dat" +[ 19, 14 ] = ascii (fp) : "./hrtfs/elev5/L5e290a.dat" +[ 19, 15 ] = ascii (fp) : "./hrtfs/elev5/L5e285a.dat" +[ 19, 16 ] = ascii (fp) : "./hrtfs/elev5/L5e280a.dat" +[ 19, 17 ] = ascii (fp) : "./hrtfs/elev5/L5e275a.dat" +[ 19, 18 ] = ascii (fp) : "./hrtfs/elev5/L5e270a.dat" +[ 19, 19 ] = ascii (fp) : "./hrtfs/elev5/L5e265a.dat" +[ 19, 20 ] = ascii (fp) : "./hrtfs/elev5/L5e260a.dat" +[ 19, 21 ] = ascii (fp) : "./hrtfs/elev5/L5e255a.dat" +[ 19, 22 ] = ascii (fp) : "./hrtfs/elev5/L5e250a.dat" +[ 19, 23 ] = ascii (fp) : "./hrtfs/elev5/L5e245a.dat" +[ 19, 24 ] = ascii (fp) : "./hrtfs/elev5/L5e240a.dat" +[ 19, 25 ] = ascii (fp) : "./hrtfs/elev5/L5e235a.dat" +[ 19, 26 ] = ascii (fp) : "./hrtfs/elev5/L5e230a.dat" +[ 19, 27 ] = ascii (fp) : "./hrtfs/elev5/L5e225a.dat" +[ 19, 28 ] = ascii (fp) : "./hrtfs/elev5/L5e220a.dat" +[ 19, 29 ] = ascii (fp) : "./hrtfs/elev5/L5e215a.dat" +[ 19, 30 ] = ascii (fp) : "./hrtfs/elev5/L5e210a.dat" +[ 19, 31 ] = ascii (fp) : "./hrtfs/elev5/L5e205a.dat" +[ 19, 32 ] = ascii (fp) : "./hrtfs/elev5/L5e200a.dat" +[ 19, 33 ] = ascii (fp) : "./hrtfs/elev5/L5e195a.dat" +[ 19, 34 ] = ascii (fp) : "./hrtfs/elev5/L5e190a.dat" +[ 19, 35 ] = ascii (fp) : "./hrtfs/elev5/L5e185a.dat" +[ 19, 36 ] = ascii (fp) : "./hrtfs/elev5/L5e180a.dat" +[ 19, 37 ] = ascii (fp) : "./hrtfs/elev5/L5e175a.dat" +[ 19, 38 ] = ascii (fp) : "./hrtfs/elev5/L5e170a.dat" +[ 19, 39 ] = ascii (fp) : "./hrtfs/elev5/L5e165a.dat" +[ 19, 40 ] = ascii (fp) : "./hrtfs/elev5/L5e160a.dat" +[ 19, 41 ] = ascii (fp) : "./hrtfs/elev5/L5e155a.dat" +[ 19, 42 ] = ascii (fp) : "./hrtfs/elev5/L5e150a.dat" +[ 19, 43 ] = ascii (fp) : "./hrtfs/elev5/L5e145a.dat" +[ 19, 44 ] = ascii (fp) : "./hrtfs/elev5/L5e140a.dat" +[ 19, 45 ] = ascii (fp) : "./hrtfs/elev5/L5e135a.dat" +[ 19, 46 ] = ascii (fp) : "./hrtfs/elev5/L5e130a.dat" +[ 19, 47 ] = ascii (fp) : "./hrtfs/elev5/L5e125a.dat" +[ 19, 48 ] = ascii (fp) : "./hrtfs/elev5/L5e120a.dat" +[ 19, 49 ] = ascii (fp) : "./hrtfs/elev5/L5e115a.dat" +[ 19, 50 ] = ascii (fp) : "./hrtfs/elev5/L5e110a.dat" +[ 19, 51 ] = ascii (fp) : "./hrtfs/elev5/L5e105a.dat" +[ 19, 52 ] = ascii (fp) : "./hrtfs/elev5/L5e100a.dat" +[ 19, 53 ] = ascii (fp) : "./hrtfs/elev5/L5e095a.dat" +[ 19, 54 ] = ascii (fp) : "./hrtfs/elev5/L5e090a.dat" +[ 19, 55 ] = ascii (fp) : "./hrtfs/elev5/L5e085a.dat" +[ 19, 56 ] = ascii (fp) : "./hrtfs/elev5/L5e080a.dat" +[ 19, 57 ] = ascii (fp) : "./hrtfs/elev5/L5e075a.dat" +[ 19, 58 ] = ascii (fp) : "./hrtfs/elev5/L5e070a.dat" +[ 19, 59 ] = ascii (fp) : "./hrtfs/elev5/L5e065a.dat" +[ 19, 60 ] = ascii (fp) : "./hrtfs/elev5/L5e060a.dat" +[ 19, 61 ] = ascii (fp) : "./hrtfs/elev5/L5e055a.dat" +[ 19, 62 ] = ascii (fp) : "./hrtfs/elev5/L5e050a.dat" +[ 19, 63 ] = ascii (fp) : "./hrtfs/elev5/L5e045a.dat" +[ 19, 64 ] = ascii (fp) : "./hrtfs/elev5/L5e040a.dat" +[ 19, 65 ] = ascii (fp) : "./hrtfs/elev5/L5e035a.dat" +[ 19, 66 ] = ascii (fp) : "./hrtfs/elev5/L5e030a.dat" +[ 19, 67 ] = ascii (fp) : "./hrtfs/elev5/L5e025a.dat" +[ 19, 68 ] = ascii (fp) : "./hrtfs/elev5/L5e020a.dat" +[ 19, 69 ] = ascii (fp) : "./hrtfs/elev5/L5e015a.dat" +[ 19, 70 ] = ascii (fp) : "./hrtfs/elev5/L5e010a.dat" +[ 19, 71 ] = ascii (fp) : "./hrtfs/elev5/L5e005a.dat" + +[ 20, 0 ] = ascii (fp) : "./hrtfs/elev10/L10e000a.dat" +[ 20, 1 ] = ascii (fp) : "./hrtfs/elev10/L10e355a.dat" +[ 20, 2 ] = ascii (fp) : "./hrtfs/elev10/L10e350a.dat" +[ 20, 3 ] = ascii (fp) : "./hrtfs/elev10/L10e345a.dat" +[ 20, 4 ] = ascii (fp) : "./hrtfs/elev10/L10e340a.dat" +[ 20, 5 ] = ascii (fp) : "./hrtfs/elev10/L10e335a.dat" +[ 20, 6 ] = ascii (fp) : "./hrtfs/elev10/L10e330a.dat" +[ 20, 7 ] = ascii (fp) : "./hrtfs/elev10/L10e325a.dat" +[ 20, 8 ] = ascii (fp) : "./hrtfs/elev10/L10e320a.dat" +[ 20, 9 ] = ascii (fp) : "./hrtfs/elev10/L10e315a.dat" +[ 20, 10 ] = ascii (fp) : "./hrtfs/elev10/L10e310a.dat" +[ 20, 11 ] = ascii (fp) : "./hrtfs/elev10/L10e305a.dat" +[ 20, 12 ] = ascii (fp) : "./hrtfs/elev10/L10e300a.dat" +[ 20, 13 ] = ascii (fp) : "./hrtfs/elev10/L10e295a.dat" +[ 20, 14 ] = ascii (fp) : "./hrtfs/elev10/L10e290a.dat" +[ 20, 15 ] = ascii (fp) : "./hrtfs/elev10/L10e285a.dat" +[ 20, 16 ] = ascii (fp) : "./hrtfs/elev10/L10e280a.dat" +[ 20, 17 ] = ascii (fp) : "./hrtfs/elev10/L10e275a.dat" +[ 20, 18 ] = ascii (fp) : "./hrtfs/elev10/L10e270a.dat" +[ 20, 19 ] = ascii (fp) : "./hrtfs/elev10/L10e265a.dat" +[ 20, 20 ] = ascii (fp) : "./hrtfs/elev10/L10e260a.dat" +[ 20, 21 ] = ascii (fp) : "./hrtfs/elev10/L10e255a.dat" +[ 20, 22 ] = ascii (fp) : "./hrtfs/elev10/L10e250a.dat" +[ 20, 23 ] = ascii (fp) : "./hrtfs/elev10/L10e245a.dat" +[ 20, 24 ] = ascii (fp) : "./hrtfs/elev10/L10e240a.dat" +[ 20, 25 ] = ascii (fp) : "./hrtfs/elev10/L10e235a.dat" +[ 20, 26 ] = ascii (fp) : "./hrtfs/elev10/L10e230a.dat" +[ 20, 27 ] = ascii (fp) : "./hrtfs/elev10/L10e225a.dat" +[ 20, 28 ] = ascii (fp) : "./hrtfs/elev10/L10e220a.dat" +[ 20, 29 ] = ascii (fp) : "./hrtfs/elev10/L10e215a.dat" +[ 20, 30 ] = ascii (fp) : "./hrtfs/elev10/L10e210a.dat" +[ 20, 31 ] = ascii (fp) : "./hrtfs/elev10/L10e205a.dat" +[ 20, 32 ] = ascii (fp) : "./hrtfs/elev10/L10e200a.dat" +[ 20, 33 ] = ascii (fp) : "./hrtfs/elev10/L10e195a.dat" +[ 20, 34 ] = ascii (fp) : "./hrtfs/elev10/L10e190a.dat" +[ 20, 35 ] = ascii (fp) : "./hrtfs/elev10/L10e185a.dat" +[ 20, 36 ] = ascii (fp) : "./hrtfs/elev10/L10e180a.dat" +[ 20, 37 ] = ascii (fp) : "./hrtfs/elev10/L10e175a.dat" +[ 20, 38 ] = ascii (fp) : "./hrtfs/elev10/L10e170a.dat" +[ 20, 39 ] = ascii (fp) : "./hrtfs/elev10/L10e165a.dat" +[ 20, 40 ] = ascii (fp) : "./hrtfs/elev10/L10e160a.dat" +[ 20, 41 ] = ascii (fp) : "./hrtfs/elev10/L10e155a.dat" +[ 20, 42 ] = ascii (fp) : "./hrtfs/elev10/L10e150a.dat" +[ 20, 43 ] = ascii (fp) : "./hrtfs/elev10/L10e145a.dat" +[ 20, 44 ] = ascii (fp) : "./hrtfs/elev10/L10e140a.dat" +[ 20, 45 ] = ascii (fp) : "./hrtfs/elev10/L10e135a.dat" +[ 20, 46 ] = ascii (fp) : "./hrtfs/elev10/L10e130a.dat" +[ 20, 47 ] = ascii (fp) : "./hrtfs/elev10/L10e125a.dat" +[ 20, 48 ] = ascii (fp) : "./hrtfs/elev10/L10e120a.dat" +[ 20, 49 ] = ascii (fp) : "./hrtfs/elev10/L10e115a.dat" +[ 20, 50 ] = ascii (fp) : "./hrtfs/elev10/L10e110a.dat" +[ 20, 51 ] = ascii (fp) : "./hrtfs/elev10/L10e105a.dat" +[ 20, 52 ] = ascii (fp) : "./hrtfs/elev10/L10e100a.dat" +[ 20, 53 ] = ascii (fp) : "./hrtfs/elev10/L10e095a.dat" +[ 20, 54 ] = ascii (fp) : "./hrtfs/elev10/L10e090a.dat" +[ 20, 55 ] = ascii (fp) : "./hrtfs/elev10/L10e085a.dat" +[ 20, 56 ] = ascii (fp) : "./hrtfs/elev10/L10e080a.dat" +[ 20, 57 ] = ascii (fp) : "./hrtfs/elev10/L10e075a.dat" +[ 20, 58 ] = ascii (fp) : "./hrtfs/elev10/L10e070a.dat" +[ 20, 59 ] = ascii (fp) : "./hrtfs/elev10/L10e065a.dat" +[ 20, 60 ] = ascii (fp) : "./hrtfs/elev10/L10e060a.dat" +[ 20, 61 ] = ascii (fp) : "./hrtfs/elev10/L10e055a.dat" +[ 20, 62 ] = ascii (fp) : "./hrtfs/elev10/L10e050a.dat" +[ 20, 63 ] = ascii (fp) : "./hrtfs/elev10/L10e045a.dat" +[ 20, 64 ] = ascii (fp) : "./hrtfs/elev10/L10e040a.dat" +[ 20, 65 ] = ascii (fp) : "./hrtfs/elev10/L10e035a.dat" +[ 20, 66 ] = ascii (fp) : "./hrtfs/elev10/L10e030a.dat" +[ 20, 67 ] = ascii (fp) : "./hrtfs/elev10/L10e025a.dat" +[ 20, 68 ] = ascii (fp) : "./hrtfs/elev10/L10e020a.dat" +[ 20, 69 ] = ascii (fp) : "./hrtfs/elev10/L10e015a.dat" +[ 20, 70 ] = ascii (fp) : "./hrtfs/elev10/L10e010a.dat" +[ 20, 71 ] = ascii (fp) : "./hrtfs/elev10/L10e005a.dat" + +[ 21, 0 ] = ascii (fp) : "./hrtfs/elev15/L15e000a.dat" +[ 21, 1 ] = ascii (fp) : "./hrtfs/elev15/L15e355a.dat" +[ 21, 2 ] = ascii (fp) : "./hrtfs/elev15/L15e350a.dat" +[ 21, 3 ] = ascii (fp) : "./hrtfs/elev15/L15e345a.dat" +[ 21, 4 ] = ascii (fp) : "./hrtfs/elev15/L15e340a.dat" +[ 21, 5 ] = ascii (fp) : "./hrtfs/elev15/L15e335a.dat" +[ 21, 6 ] = ascii (fp) : "./hrtfs/elev15/L15e330a.dat" +[ 21, 7 ] = ascii (fp) : "./hrtfs/elev15/L15e325a.dat" +[ 21, 8 ] = ascii (fp) : "./hrtfs/elev15/L15e320a.dat" +[ 21, 9 ] = ascii (fp) : "./hrtfs/elev15/L15e315a.dat" +[ 21, 10 ] = ascii (fp) : "./hrtfs/elev15/L15e310a.dat" +[ 21, 11 ] = ascii (fp) : "./hrtfs/elev15/L15e305a.dat" +[ 21, 12 ] = ascii (fp) : "./hrtfs/elev15/L15e300a.dat" +[ 21, 13 ] = ascii (fp) : "./hrtfs/elev15/L15e295a.dat" +[ 21, 14 ] = ascii (fp) : "./hrtfs/elev15/L15e290a.dat" +[ 21, 15 ] = ascii (fp) : "./hrtfs/elev15/L15e285a.dat" +[ 21, 16 ] = ascii (fp) : "./hrtfs/elev15/L15e280a.dat" +[ 21, 17 ] = ascii (fp) : "./hrtfs/elev15/L15e275a.dat" +[ 21, 18 ] = ascii (fp) : "./hrtfs/elev15/L15e270a.dat" +[ 21, 19 ] = ascii (fp) : "./hrtfs/elev15/L15e265a.dat" +[ 21, 20 ] = ascii (fp) : "./hrtfs/elev15/L15e260a.dat" +[ 21, 21 ] = ascii (fp) : "./hrtfs/elev15/L15e255a.dat" +[ 21, 22 ] = ascii (fp) : "./hrtfs/elev15/L15e250a.dat" +[ 21, 23 ] = ascii (fp) : "./hrtfs/elev15/L15e245a.dat" +[ 21, 24 ] = ascii (fp) : "./hrtfs/elev15/L15e240a.dat" +[ 21, 25 ] = ascii (fp) : "./hrtfs/elev15/L15e235a.dat" +[ 21, 26 ] = ascii (fp) : "./hrtfs/elev15/L15e230a.dat" +[ 21, 27 ] = ascii (fp) : "./hrtfs/elev15/L15e225a.dat" +[ 21, 28 ] = ascii (fp) : "./hrtfs/elev15/L15e220a.dat" +[ 21, 29 ] = ascii (fp) : "./hrtfs/elev15/L15e215a.dat" +[ 21, 30 ] = ascii (fp) : "./hrtfs/elev15/L15e210a.dat" +[ 21, 31 ] = ascii (fp) : "./hrtfs/elev15/L15e205a.dat" +[ 21, 32 ] = ascii (fp) : "./hrtfs/elev15/L15e200a.dat" +[ 21, 33 ] = ascii (fp) : "./hrtfs/elev15/L15e195a.dat" +[ 21, 34 ] = ascii (fp) : "./hrtfs/elev15/L15e190a.dat" +[ 21, 35 ] = ascii (fp) : "./hrtfs/elev15/L15e185a.dat" +[ 21, 36 ] = ascii (fp) : "./hrtfs/elev15/L15e180a.dat" +[ 21, 37 ] = ascii (fp) : "./hrtfs/elev15/L15e175a.dat" +[ 21, 38 ] = ascii (fp) : "./hrtfs/elev15/L15e170a.dat" +[ 21, 39 ] = ascii (fp) : "./hrtfs/elev15/L15e165a.dat" +[ 21, 40 ] = ascii (fp) : "./hrtfs/elev15/L15e160a.dat" +[ 21, 41 ] = ascii (fp) : "./hrtfs/elev15/L15e155a.dat" +[ 21, 42 ] = ascii (fp) : "./hrtfs/elev15/L15e150a.dat" +[ 21, 43 ] = ascii (fp) : "./hrtfs/elev15/L15e145a.dat" +[ 21, 44 ] = ascii (fp) : "./hrtfs/elev15/L15e140a.dat" +[ 21, 45 ] = ascii (fp) : "./hrtfs/elev15/L15e135a.dat" +[ 21, 46 ] = ascii (fp) : "./hrtfs/elev15/L15e130a.dat" +[ 21, 47 ] = ascii (fp) : "./hrtfs/elev15/L15e125a.dat" +[ 21, 48 ] = ascii (fp) : "./hrtfs/elev15/L15e120a.dat" +[ 21, 49 ] = ascii (fp) : "./hrtfs/elev15/L15e115a.dat" +[ 21, 50 ] = ascii (fp) : "./hrtfs/elev15/L15e110a.dat" +[ 21, 51 ] = ascii (fp) : "./hrtfs/elev15/L15e105a.dat" +[ 21, 52 ] = ascii (fp) : "./hrtfs/elev15/L15e100a.dat" +[ 21, 53 ] = ascii (fp) : "./hrtfs/elev15/L15e095a.dat" +[ 21, 54 ] = ascii (fp) : "./hrtfs/elev15/L15e090a.dat" +[ 21, 55 ] = ascii (fp) : "./hrtfs/elev15/L15e085a.dat" +[ 21, 56 ] = ascii (fp) : "./hrtfs/elev15/L15e080a.dat" +[ 21, 57 ] = ascii (fp) : "./hrtfs/elev15/L15e075a.dat" +[ 21, 58 ] = ascii (fp) : "./hrtfs/elev15/L15e070a.dat" +[ 21, 59 ] = ascii (fp) : "./hrtfs/elev15/L15e065a.dat" +[ 21, 60 ] = ascii (fp) : "./hrtfs/elev15/L15e060a.dat" +[ 21, 61 ] = ascii (fp) : "./hrtfs/elev15/L15e055a.dat" +[ 21, 62 ] = ascii (fp) : "./hrtfs/elev15/L15e050a.dat" +[ 21, 63 ] = ascii (fp) : "./hrtfs/elev15/L15e045a.dat" +[ 21, 64 ] = ascii (fp) : "./hrtfs/elev15/L15e040a.dat" +[ 21, 65 ] = ascii (fp) : "./hrtfs/elev15/L15e035a.dat" +[ 21, 66 ] = ascii (fp) : "./hrtfs/elev15/L15e030a.dat" +[ 21, 67 ] = ascii (fp) : "./hrtfs/elev15/L15e025a.dat" +[ 21, 68 ] = ascii (fp) : "./hrtfs/elev15/L15e020a.dat" +[ 21, 69 ] = ascii (fp) : "./hrtfs/elev15/L15e015a.dat" +[ 21, 70 ] = ascii (fp) : "./hrtfs/elev15/L15e010a.dat" +[ 21, 71 ] = ascii (fp) : "./hrtfs/elev15/L15e005a.dat" + +[ 22, 0 ] = ascii (fp) : "./hrtfs/elev20/L20e000a.dat" +[ 22, 1 ] = ascii (fp) : "./hrtfs/elev20/L20e355a.dat" +[ 22, 2 ] = ascii (fp) : "./hrtfs/elev20/L20e350a.dat" +[ 22, 3 ] = ascii (fp) : "./hrtfs/elev20/L20e345a.dat" +[ 22, 4 ] = ascii (fp) : "./hrtfs/elev20/L20e340a.dat" +[ 22, 5 ] = ascii (fp) : "./hrtfs/elev20/L20e335a.dat" +[ 22, 6 ] = ascii (fp) : "./hrtfs/elev20/L20e330a.dat" +[ 22, 7 ] = ascii (fp) : "./hrtfs/elev20/L20e325a.dat" +[ 22, 8 ] = ascii (fp) : "./hrtfs/elev20/L20e320a.dat" +[ 22, 9 ] = ascii (fp) : "./hrtfs/elev20/L20e315a.dat" +[ 22, 10 ] = ascii (fp) : "./hrtfs/elev20/L20e310a.dat" +[ 22, 11 ] = ascii (fp) : "./hrtfs/elev20/L20e305a.dat" +[ 22, 12 ] = ascii (fp) : "./hrtfs/elev20/L20e300a.dat" +[ 22, 13 ] = ascii (fp) : "./hrtfs/elev20/L20e295a.dat" +[ 22, 14 ] = ascii (fp) : "./hrtfs/elev20/L20e290a.dat" +[ 22, 15 ] = ascii (fp) : "./hrtfs/elev20/L20e285a.dat" +[ 22, 16 ] = ascii (fp) : "./hrtfs/elev20/L20e280a.dat" +[ 22, 17 ] = ascii (fp) : "./hrtfs/elev20/L20e275a.dat" +[ 22, 18 ] = ascii (fp) : "./hrtfs/elev20/L20e270a.dat" +[ 22, 19 ] = ascii (fp) : "./hrtfs/elev20/L20e265a.dat" +[ 22, 20 ] = ascii (fp) : "./hrtfs/elev20/L20e260a.dat" +[ 22, 21 ] = ascii (fp) : "./hrtfs/elev20/L20e255a.dat" +[ 22, 22 ] = ascii (fp) : "./hrtfs/elev20/L20e250a.dat" +[ 22, 23 ] = ascii (fp) : "./hrtfs/elev20/L20e245a.dat" +[ 22, 24 ] = ascii (fp) : "./hrtfs/elev20/L20e240a.dat" +[ 22, 25 ] = ascii (fp) : "./hrtfs/elev20/L20e235a.dat" +[ 22, 26 ] = ascii (fp) : "./hrtfs/elev20/L20e230a.dat" +[ 22, 27 ] = ascii (fp) : "./hrtfs/elev20/L20e225a.dat" +[ 22, 28 ] = ascii (fp) : "./hrtfs/elev20/L20e220a.dat" +[ 22, 29 ] = ascii (fp) : "./hrtfs/elev20/L20e215a.dat" +[ 22, 30 ] = ascii (fp) : "./hrtfs/elev20/L20e210a.dat" +[ 22, 31 ] = ascii (fp) : "./hrtfs/elev20/L20e205a.dat" +[ 22, 32 ] = ascii (fp) : "./hrtfs/elev20/L20e200a.dat" +[ 22, 33 ] = ascii (fp) : "./hrtfs/elev20/L20e195a.dat" +[ 22, 34 ] = ascii (fp) : "./hrtfs/elev20/L20e190a.dat" +[ 22, 35 ] = ascii (fp) : "./hrtfs/elev20/L20e185a.dat" +[ 22, 36 ] = ascii (fp) : "./hrtfs/elev20/L20e180a.dat" +[ 22, 37 ] = ascii (fp) : "./hrtfs/elev20/L20e175a.dat" +[ 22, 38 ] = ascii (fp) : "./hrtfs/elev20/L20e170a.dat" +[ 22, 39 ] = ascii (fp) : "./hrtfs/elev20/L20e165a.dat" +[ 22, 40 ] = ascii (fp) : "./hrtfs/elev20/L20e160a.dat" +[ 22, 41 ] = ascii (fp) : "./hrtfs/elev20/L20e155a.dat" +[ 22, 42 ] = ascii (fp) : "./hrtfs/elev20/L20e150a.dat" +[ 22, 43 ] = ascii (fp) : "./hrtfs/elev20/L20e145a.dat" +[ 22, 44 ] = ascii (fp) : "./hrtfs/elev20/L20e140a.dat" +[ 22, 45 ] = ascii (fp) : "./hrtfs/elev20/L20e135a.dat" +[ 22, 46 ] = ascii (fp) : "./hrtfs/elev20/L20e130a.dat" +[ 22, 47 ] = ascii (fp) : "./hrtfs/elev20/L20e125a.dat" +[ 22, 48 ] = ascii (fp) : "./hrtfs/elev20/L20e120a.dat" +[ 22, 49 ] = ascii (fp) : "./hrtfs/elev20/L20e115a.dat" +[ 22, 50 ] = ascii (fp) : "./hrtfs/elev20/L20e110a.dat" +[ 22, 51 ] = ascii (fp) : "./hrtfs/elev20/L20e105a.dat" +[ 22, 52 ] = ascii (fp) : "./hrtfs/elev20/L20e100a.dat" +[ 22, 53 ] = ascii (fp) : "./hrtfs/elev20/L20e095a.dat" +[ 22, 54 ] = ascii (fp) : "./hrtfs/elev20/L20e090a.dat" +[ 22, 55 ] = ascii (fp) : "./hrtfs/elev20/L20e085a.dat" +[ 22, 56 ] = ascii (fp) : "./hrtfs/elev20/L20e080a.dat" +[ 22, 57 ] = ascii (fp) : "./hrtfs/elev20/L20e075a.dat" +[ 22, 58 ] = ascii (fp) : "./hrtfs/elev20/L20e070a.dat" +[ 22, 59 ] = ascii (fp) : "./hrtfs/elev20/L20e065a.dat" +[ 22, 60 ] = ascii (fp) : "./hrtfs/elev20/L20e060a.dat" +[ 22, 61 ] = ascii (fp) : "./hrtfs/elev20/L20e055a.dat" +[ 22, 62 ] = ascii (fp) : "./hrtfs/elev20/L20e050a.dat" +[ 22, 63 ] = ascii (fp) : "./hrtfs/elev20/L20e045a.dat" +[ 22, 64 ] = ascii (fp) : "./hrtfs/elev20/L20e040a.dat" +[ 22, 65 ] = ascii (fp) : "./hrtfs/elev20/L20e035a.dat" +[ 22, 66 ] = ascii (fp) : "./hrtfs/elev20/L20e030a.dat" +[ 22, 67 ] = ascii (fp) : "./hrtfs/elev20/L20e025a.dat" +[ 22, 68 ] = ascii (fp) : "./hrtfs/elev20/L20e020a.dat" +[ 22, 69 ] = ascii (fp) : "./hrtfs/elev20/L20e015a.dat" +[ 22, 70 ] = ascii (fp) : "./hrtfs/elev20/L20e010a.dat" +[ 22, 71 ] = ascii (fp) : "./hrtfs/elev20/L20e005a.dat" + +[ 23, 0 ] = ascii (fp) : "./hrtfs/elev25/L25e000a.dat" +[ 23, 1 ] = ascii (fp) : "./hrtfs/elev25/L25e355a.dat" +[ 23, 2 ] = ascii (fp) : "./hrtfs/elev25/L25e350a.dat" +[ 23, 3 ] = ascii (fp) : "./hrtfs/elev25/L25e345a.dat" +[ 23, 4 ] = ascii (fp) : "./hrtfs/elev25/L25e340a.dat" +[ 23, 5 ] = ascii (fp) : "./hrtfs/elev25/L25e335a.dat" +[ 23, 6 ] = ascii (fp) : "./hrtfs/elev25/L25e330a.dat" +[ 23, 7 ] = ascii (fp) : "./hrtfs/elev25/L25e325a.dat" +[ 23, 8 ] = ascii (fp) : "./hrtfs/elev25/L25e320a.dat" +[ 23, 9 ] = ascii (fp) : "./hrtfs/elev25/L25e315a.dat" +[ 23, 10 ] = ascii (fp) : "./hrtfs/elev25/L25e310a.dat" +[ 23, 11 ] = ascii (fp) : "./hrtfs/elev25/L25e305a.dat" +[ 23, 12 ] = ascii (fp) : "./hrtfs/elev25/L25e300a.dat" +[ 23, 13 ] = ascii (fp) : "./hrtfs/elev25/L25e295a.dat" +[ 23, 14 ] = ascii (fp) : "./hrtfs/elev25/L25e290a.dat" +[ 23, 15 ] = ascii (fp) : "./hrtfs/elev25/L25e285a.dat" +[ 23, 16 ] = ascii (fp) : "./hrtfs/elev25/L25e280a.dat" +[ 23, 17 ] = ascii (fp) : "./hrtfs/elev25/L25e275a.dat" +[ 23, 18 ] = ascii (fp) : "./hrtfs/elev25/L25e270a.dat" +[ 23, 19 ] = ascii (fp) : "./hrtfs/elev25/L25e265a.dat" +[ 23, 20 ] = ascii (fp) : "./hrtfs/elev25/L25e260a.dat" +[ 23, 21 ] = ascii (fp) : "./hrtfs/elev25/L25e255a.dat" +[ 23, 22 ] = ascii (fp) : "./hrtfs/elev25/L25e250a.dat" +[ 23, 23 ] = ascii (fp) : "./hrtfs/elev25/L25e245a.dat" +[ 23, 24 ] = ascii (fp) : "./hrtfs/elev25/L25e240a.dat" +[ 23, 25 ] = ascii (fp) : "./hrtfs/elev25/L25e235a.dat" +[ 23, 26 ] = ascii (fp) : "./hrtfs/elev25/L25e230a.dat" +[ 23, 27 ] = ascii (fp) : "./hrtfs/elev25/L25e225a.dat" +[ 23, 28 ] = ascii (fp) : "./hrtfs/elev25/L25e220a.dat" +[ 23, 29 ] = ascii (fp) : "./hrtfs/elev25/L25e215a.dat" +[ 23, 30 ] = ascii (fp) : "./hrtfs/elev25/L25e210a.dat" +[ 23, 31 ] = ascii (fp) : "./hrtfs/elev25/L25e205a.dat" +[ 23, 32 ] = ascii (fp) : "./hrtfs/elev25/L25e200a.dat" +[ 23, 33 ] = ascii (fp) : "./hrtfs/elev25/L25e195a.dat" +[ 23, 34 ] = ascii (fp) : "./hrtfs/elev25/L25e190a.dat" +[ 23, 35 ] = ascii (fp) : "./hrtfs/elev25/L25e185a.dat" +[ 23, 36 ] = ascii (fp) : "./hrtfs/elev25/L25e180a.dat" +[ 23, 37 ] = ascii (fp) : "./hrtfs/elev25/L25e175a.dat" +[ 23, 38 ] = ascii (fp) : "./hrtfs/elev25/L25e170a.dat" +[ 23, 39 ] = ascii (fp) : "./hrtfs/elev25/L25e165a.dat" +[ 23, 40 ] = ascii (fp) : "./hrtfs/elev25/L25e160a.dat" +[ 23, 41 ] = ascii (fp) : "./hrtfs/elev25/L25e155a.dat" +[ 23, 42 ] = ascii (fp) : "./hrtfs/elev25/L25e150a.dat" +[ 23, 43 ] = ascii (fp) : "./hrtfs/elev25/L25e145a.dat" +[ 23, 44 ] = ascii (fp) : "./hrtfs/elev25/L25e140a.dat" +[ 23, 45 ] = ascii (fp) : "./hrtfs/elev25/L25e135a.dat" +[ 23, 46 ] = ascii (fp) : "./hrtfs/elev25/L25e130a.dat" +[ 23, 47 ] = ascii (fp) : "./hrtfs/elev25/L25e125a.dat" +[ 23, 48 ] = ascii (fp) : "./hrtfs/elev25/L25e120a.dat" +[ 23, 49 ] = ascii (fp) : "./hrtfs/elev25/L25e115a.dat" +[ 23, 50 ] = ascii (fp) : "./hrtfs/elev25/L25e110a.dat" +[ 23, 51 ] = ascii (fp) : "./hrtfs/elev25/L25e105a.dat" +[ 23, 52 ] = ascii (fp) : "./hrtfs/elev25/L25e100a.dat" +[ 23, 53 ] = ascii (fp) : "./hrtfs/elev25/L25e095a.dat" +[ 23, 54 ] = ascii (fp) : "./hrtfs/elev25/L25e090a.dat" +[ 23, 55 ] = ascii (fp) : "./hrtfs/elev25/L25e085a.dat" +[ 23, 56 ] = ascii (fp) : "./hrtfs/elev25/L25e080a.dat" +[ 23, 57 ] = ascii (fp) : "./hrtfs/elev25/L25e075a.dat" +[ 23, 58 ] = ascii (fp) : "./hrtfs/elev25/L25e070a.dat" +[ 23, 59 ] = ascii (fp) : "./hrtfs/elev25/L25e065a.dat" +[ 23, 60 ] = ascii (fp) : "./hrtfs/elev25/L25e060a.dat" +[ 23, 61 ] = ascii (fp) : "./hrtfs/elev25/L25e055a.dat" +[ 23, 62 ] = ascii (fp) : "./hrtfs/elev25/L25e050a.dat" +[ 23, 63 ] = ascii (fp) : "./hrtfs/elev25/L25e045a.dat" +[ 23, 64 ] = ascii (fp) : "./hrtfs/elev25/L25e040a.dat" +[ 23, 65 ] = ascii (fp) : "./hrtfs/elev25/L25e035a.dat" +[ 23, 66 ] = ascii (fp) : "./hrtfs/elev25/L25e030a.dat" +[ 23, 67 ] = ascii (fp) : "./hrtfs/elev25/L25e025a.dat" +[ 23, 68 ] = ascii (fp) : "./hrtfs/elev25/L25e020a.dat" +[ 23, 69 ] = ascii (fp) : "./hrtfs/elev25/L25e015a.dat" +[ 23, 70 ] = ascii (fp) : "./hrtfs/elev25/L25e010a.dat" +[ 23, 71 ] = ascii (fp) : "./hrtfs/elev25/L25e005a.dat" + +[ 24, 0 ] = ascii (fp) : "./hrtfs/elev30/L30e000a.dat" +[ 24, 1 ] = ascii (fp) : "./hrtfs/elev30/L30e355a.dat" +[ 24, 2 ] = ascii (fp) : "./hrtfs/elev30/L30e350a.dat" +[ 24, 3 ] = ascii (fp) : "./hrtfs/elev30/L30e345a.dat" +[ 24, 4 ] = ascii (fp) : "./hrtfs/elev30/L30e340a.dat" +[ 24, 5 ] = ascii (fp) : "./hrtfs/elev30/L30e335a.dat" +[ 24, 6 ] = ascii (fp) : "./hrtfs/elev30/L30e330a.dat" +[ 24, 7 ] = ascii (fp) : "./hrtfs/elev30/L30e325a.dat" +[ 24, 8 ] = ascii (fp) : "./hrtfs/elev30/L30e320a.dat" +[ 24, 9 ] = ascii (fp) : "./hrtfs/elev30/L30e315a.dat" +[ 24, 10 ] = ascii (fp) : "./hrtfs/elev30/L30e310a.dat" +[ 24, 11 ] = ascii (fp) : "./hrtfs/elev30/L30e305a.dat" +[ 24, 12 ] = ascii (fp) : "./hrtfs/elev30/L30e300a.dat" +[ 24, 13 ] = ascii (fp) : "./hrtfs/elev30/L30e295a.dat" +[ 24, 14 ] = ascii (fp) : "./hrtfs/elev30/L30e290a.dat" +[ 24, 15 ] = ascii (fp) : "./hrtfs/elev30/L30e285a.dat" +[ 24, 16 ] = ascii (fp) : "./hrtfs/elev30/L30e280a.dat" +[ 24, 17 ] = ascii (fp) : "./hrtfs/elev30/L30e275a.dat" +[ 24, 18 ] = ascii (fp) : "./hrtfs/elev30/L30e270a.dat" +[ 24, 19 ] = ascii (fp) : "./hrtfs/elev30/L30e265a.dat" +[ 24, 20 ] = ascii (fp) : "./hrtfs/elev30/L30e260a.dat" +[ 24, 21 ] = ascii (fp) : "./hrtfs/elev30/L30e255a.dat" +[ 24, 22 ] = ascii (fp) : "./hrtfs/elev30/L30e250a.dat" +[ 24, 23 ] = ascii (fp) : "./hrtfs/elev30/L30e245a.dat" +[ 24, 24 ] = ascii (fp) : "./hrtfs/elev30/L30e240a.dat" +[ 24, 25 ] = ascii (fp) : "./hrtfs/elev30/L30e235a.dat" +[ 24, 26 ] = ascii (fp) : "./hrtfs/elev30/L30e230a.dat" +[ 24, 27 ] = ascii (fp) : "./hrtfs/elev30/L30e225a.dat" +[ 24, 28 ] = ascii (fp) : "./hrtfs/elev30/L30e220a.dat" +[ 24, 29 ] = ascii (fp) : "./hrtfs/elev30/L30e215a.dat" +[ 24, 30 ] = ascii (fp) : "./hrtfs/elev30/L30e210a.dat" +[ 24, 31 ] = ascii (fp) : "./hrtfs/elev30/L30e205a.dat" +[ 24, 32 ] = ascii (fp) : "./hrtfs/elev30/L30e200a.dat" +[ 24, 33 ] = ascii (fp) : "./hrtfs/elev30/L30e195a.dat" +[ 24, 34 ] = ascii (fp) : "./hrtfs/elev30/L30e190a.dat" +[ 24, 35 ] = ascii (fp) : "./hrtfs/elev30/L30e185a.dat" +[ 24, 36 ] = ascii (fp) : "./hrtfs/elev30/L30e180a.dat" +[ 24, 37 ] = ascii (fp) : "./hrtfs/elev30/L30e175a.dat" +[ 24, 38 ] = ascii (fp) : "./hrtfs/elev30/L30e170a.dat" +[ 24, 39 ] = ascii (fp) : "./hrtfs/elev30/L30e165a.dat" +[ 24, 40 ] = ascii (fp) : "./hrtfs/elev30/L30e160a.dat" +[ 24, 41 ] = ascii (fp) : "./hrtfs/elev30/L30e155a.dat" +[ 24, 42 ] = ascii (fp) : "./hrtfs/elev30/L30e150a.dat" +[ 24, 43 ] = ascii (fp) : "./hrtfs/elev30/L30e145a.dat" +[ 24, 44 ] = ascii (fp) : "./hrtfs/elev30/L30e140a.dat" +[ 24, 45 ] = ascii (fp) : "./hrtfs/elev30/L30e135a.dat" +[ 24, 46 ] = ascii (fp) : "./hrtfs/elev30/L30e130a.dat" +[ 24, 47 ] = ascii (fp) : "./hrtfs/elev30/L30e125a.dat" +[ 24, 48 ] = ascii (fp) : "./hrtfs/elev30/L30e120a.dat" +[ 24, 49 ] = ascii (fp) : "./hrtfs/elev30/L30e115a.dat" +[ 24, 50 ] = ascii (fp) : "./hrtfs/elev30/L30e110a.dat" +[ 24, 51 ] = ascii (fp) : "./hrtfs/elev30/L30e105a.dat" +[ 24, 52 ] = ascii (fp) : "./hrtfs/elev30/L30e100a.dat" +[ 24, 53 ] = ascii (fp) : "./hrtfs/elev30/L30e095a.dat" +[ 24, 54 ] = ascii (fp) : "./hrtfs/elev30/L30e090a.dat" +[ 24, 55 ] = ascii (fp) : "./hrtfs/elev30/L30e085a.dat" +[ 24, 56 ] = ascii (fp) : "./hrtfs/elev30/L30e080a.dat" +[ 24, 57 ] = ascii (fp) : "./hrtfs/elev30/L30e075a.dat" +[ 24, 58 ] = ascii (fp) : "./hrtfs/elev30/L30e070a.dat" +[ 24, 59 ] = ascii (fp) : "./hrtfs/elev30/L30e065a.dat" +[ 24, 60 ] = ascii (fp) : "./hrtfs/elev30/L30e060a.dat" +[ 24, 61 ] = ascii (fp) : "./hrtfs/elev30/L30e055a.dat" +[ 24, 62 ] = ascii (fp) : "./hrtfs/elev30/L30e050a.dat" +[ 24, 63 ] = ascii (fp) : "./hrtfs/elev30/L30e045a.dat" +[ 24, 64 ] = ascii (fp) : "./hrtfs/elev30/L30e040a.dat" +[ 24, 65 ] = ascii (fp) : "./hrtfs/elev30/L30e035a.dat" +[ 24, 66 ] = ascii (fp) : "./hrtfs/elev30/L30e030a.dat" +[ 24, 67 ] = ascii (fp) : "./hrtfs/elev30/L30e025a.dat" +[ 24, 68 ] = ascii (fp) : "./hrtfs/elev30/L30e020a.dat" +[ 24, 69 ] = ascii (fp) : "./hrtfs/elev30/L30e015a.dat" +[ 24, 70 ] = ascii (fp) : "./hrtfs/elev30/L30e010a.dat" +[ 24, 71 ] = ascii (fp) : "./hrtfs/elev30/L30e005a.dat" + +[ 25, 0 ] = ascii (fp) : "./hrtfs/elev35/L35e000a.dat" +[ 25, 1 ] = ascii (fp) : "./hrtfs/elev35/L35e355a.dat" +[ 25, 2 ] = ascii (fp) : "./hrtfs/elev35/L35e350a.dat" +[ 25, 3 ] = ascii (fp) : "./hrtfs/elev35/L35e345a.dat" +[ 25, 4 ] = ascii (fp) : "./hrtfs/elev35/L35e340a.dat" +[ 25, 5 ] = ascii (fp) : "./hrtfs/elev35/L35e335a.dat" +[ 25, 6 ] = ascii (fp) : "./hrtfs/elev35/L35e330a.dat" +[ 25, 7 ] = ascii (fp) : "./hrtfs/elev35/L35e325a.dat" +[ 25, 8 ] = ascii (fp) : "./hrtfs/elev35/L35e320a.dat" +[ 25, 9 ] = ascii (fp) : "./hrtfs/elev35/L35e315a.dat" +[ 25, 10 ] = ascii (fp) : "./hrtfs/elev35/L35e310a.dat" +[ 25, 11 ] = ascii (fp) : "./hrtfs/elev35/L35e305a.dat" +[ 25, 12 ] = ascii (fp) : "./hrtfs/elev35/L35e300a.dat" +[ 25, 13 ] = ascii (fp) : "./hrtfs/elev35/L35e295a.dat" +[ 25, 14 ] = ascii (fp) : "./hrtfs/elev35/L35e290a.dat" +[ 25, 15 ] = ascii (fp) : "./hrtfs/elev35/L35e285a.dat" +[ 25, 16 ] = ascii (fp) : "./hrtfs/elev35/L35e280a.dat" +[ 25, 17 ] = ascii (fp) : "./hrtfs/elev35/L35e275a.dat" +[ 25, 18 ] = ascii (fp) : "./hrtfs/elev35/L35e270a.dat" +[ 25, 19 ] = ascii (fp) : "./hrtfs/elev35/L35e265a.dat" +[ 25, 20 ] = ascii (fp) : "./hrtfs/elev35/L35e260a.dat" +[ 25, 21 ] = ascii (fp) : "./hrtfs/elev35/L35e255a.dat" +[ 25, 22 ] = ascii (fp) : "./hrtfs/elev35/L35e250a.dat" +[ 25, 23 ] = ascii (fp) : "./hrtfs/elev35/L35e245a.dat" +[ 25, 24 ] = ascii (fp) : "./hrtfs/elev35/L35e240a.dat" +[ 25, 25 ] = ascii (fp) : "./hrtfs/elev35/L35e235a.dat" +[ 25, 26 ] = ascii (fp) : "./hrtfs/elev35/L35e230a.dat" +[ 25, 27 ] = ascii (fp) : "./hrtfs/elev35/L35e225a.dat" +[ 25, 28 ] = ascii (fp) : "./hrtfs/elev35/L35e220a.dat" +[ 25, 29 ] = ascii (fp) : "./hrtfs/elev35/L35e215a.dat" +[ 25, 30 ] = ascii (fp) : "./hrtfs/elev35/L35e210a.dat" +[ 25, 31 ] = ascii (fp) : "./hrtfs/elev35/L35e205a.dat" +[ 25, 32 ] = ascii (fp) : "./hrtfs/elev35/L35e200a.dat" +[ 25, 33 ] = ascii (fp) : "./hrtfs/elev35/L35e195a.dat" +[ 25, 34 ] = ascii (fp) : "./hrtfs/elev35/L35e190a.dat" +[ 25, 35 ] = ascii (fp) : "./hrtfs/elev35/L35e185a.dat" +[ 25, 36 ] = ascii (fp) : "./hrtfs/elev35/L35e180a.dat" +[ 25, 37 ] = ascii (fp) : "./hrtfs/elev35/L35e175a.dat" +[ 25, 38 ] = ascii (fp) : "./hrtfs/elev35/L35e170a.dat" +[ 25, 39 ] = ascii (fp) : "./hrtfs/elev35/L35e165a.dat" +[ 25, 40 ] = ascii (fp) : "./hrtfs/elev35/L35e160a.dat" +[ 25, 41 ] = ascii (fp) : "./hrtfs/elev35/L35e155a.dat" +[ 25, 42 ] = ascii (fp) : "./hrtfs/elev35/L35e150a.dat" +[ 25, 43 ] = ascii (fp) : "./hrtfs/elev35/L35e145a.dat" +[ 25, 44 ] = ascii (fp) : "./hrtfs/elev35/L35e140a.dat" +[ 25, 45 ] = ascii (fp) : "./hrtfs/elev35/L35e135a.dat" +[ 25, 46 ] = ascii (fp) : "./hrtfs/elev35/L35e130a.dat" +[ 25, 47 ] = ascii (fp) : "./hrtfs/elev35/L35e125a.dat" +[ 25, 48 ] = ascii (fp) : "./hrtfs/elev35/L35e120a.dat" +[ 25, 49 ] = ascii (fp) : "./hrtfs/elev35/L35e115a.dat" +[ 25, 50 ] = ascii (fp) : "./hrtfs/elev35/L35e110a.dat" +[ 25, 51 ] = ascii (fp) : "./hrtfs/elev35/L35e105a.dat" +[ 25, 52 ] = ascii (fp) : "./hrtfs/elev35/L35e100a.dat" +[ 25, 53 ] = ascii (fp) : "./hrtfs/elev35/L35e095a.dat" +[ 25, 54 ] = ascii (fp) : "./hrtfs/elev35/L35e090a.dat" +[ 25, 55 ] = ascii (fp) : "./hrtfs/elev35/L35e085a.dat" +[ 25, 56 ] = ascii (fp) : "./hrtfs/elev35/L35e080a.dat" +[ 25, 57 ] = ascii (fp) : "./hrtfs/elev35/L35e075a.dat" +[ 25, 58 ] = ascii (fp) : "./hrtfs/elev35/L35e070a.dat" +[ 25, 59 ] = ascii (fp) : "./hrtfs/elev35/L35e065a.dat" +[ 25, 60 ] = ascii (fp) : "./hrtfs/elev35/L35e060a.dat" +[ 25, 61 ] = ascii (fp) : "./hrtfs/elev35/L35e055a.dat" +[ 25, 62 ] = ascii (fp) : "./hrtfs/elev35/L35e050a.dat" +[ 25, 63 ] = ascii (fp) : "./hrtfs/elev35/L35e045a.dat" +[ 25, 64 ] = ascii (fp) : "./hrtfs/elev35/L35e040a.dat" +[ 25, 65 ] = ascii (fp) : "./hrtfs/elev35/L35e035a.dat" +[ 25, 66 ] = ascii (fp) : "./hrtfs/elev35/L35e030a.dat" +[ 25, 67 ] = ascii (fp) : "./hrtfs/elev35/L35e025a.dat" +[ 25, 68 ] = ascii (fp) : "./hrtfs/elev35/L35e020a.dat" +[ 25, 69 ] = ascii (fp) : "./hrtfs/elev35/L35e015a.dat" +[ 25, 70 ] = ascii (fp) : "./hrtfs/elev35/L35e010a.dat" +[ 25, 71 ] = ascii (fp) : "./hrtfs/elev35/L35e005a.dat" + +[ 26, 0 ] = ascii (fp) : "./hrtfs/elev40/L40e000a.dat" +[ 26, 1 ] = ascii (fp) : "./hrtfs/elev40/L40e355a.dat" +[ 26, 2 ] = ascii (fp) : "./hrtfs/elev40/L40e350a.dat" +[ 26, 3 ] = ascii (fp) : "./hrtfs/elev40/L40e345a.dat" +[ 26, 4 ] = ascii (fp) : "./hrtfs/elev40/L40e340a.dat" +[ 26, 5 ] = ascii (fp) : "./hrtfs/elev40/L40e335a.dat" +[ 26, 6 ] = ascii (fp) : "./hrtfs/elev40/L40e330a.dat" +[ 26, 7 ] = ascii (fp) : "./hrtfs/elev40/L40e325a.dat" +[ 26, 8 ] = ascii (fp) : "./hrtfs/elev40/L40e320a.dat" +[ 26, 9 ] = ascii (fp) : "./hrtfs/elev40/L40e315a.dat" +[ 26, 10 ] = ascii (fp) : "./hrtfs/elev40/L40e310a.dat" +[ 26, 11 ] = ascii (fp) : "./hrtfs/elev40/L40e305a.dat" +[ 26, 12 ] = ascii (fp) : "./hrtfs/elev40/L40e300a.dat" +[ 26, 13 ] = ascii (fp) : "./hrtfs/elev40/L40e295a.dat" +[ 26, 14 ] = ascii (fp) : "./hrtfs/elev40/L40e290a.dat" +[ 26, 15 ] = ascii (fp) : "./hrtfs/elev40/L40e285a.dat" +[ 26, 16 ] = ascii (fp) : "./hrtfs/elev40/L40e280a.dat" +[ 26, 17 ] = ascii (fp) : "./hrtfs/elev40/L40e275a.dat" +[ 26, 18 ] = ascii (fp) : "./hrtfs/elev40/L40e270a.dat" +[ 26, 19 ] = ascii (fp) : "./hrtfs/elev40/L40e265a.dat" +[ 26, 20 ] = ascii (fp) : "./hrtfs/elev40/L40e260a.dat" +[ 26, 21 ] = ascii (fp) : "./hrtfs/elev40/L40e255a.dat" +[ 26, 22 ] = ascii (fp) : "./hrtfs/elev40/L40e250a.dat" +[ 26, 23 ] = ascii (fp) : "./hrtfs/elev40/L40e245a.dat" +[ 26, 24 ] = ascii (fp) : "./hrtfs/elev40/L40e240a.dat" +[ 26, 25 ] = ascii (fp) : "./hrtfs/elev40/L40e235a.dat" +[ 26, 26 ] = ascii (fp) : "./hrtfs/elev40/L40e230a.dat" +[ 26, 27 ] = ascii (fp) : "./hrtfs/elev40/L40e225a.dat" +[ 26, 28 ] = ascii (fp) : "./hrtfs/elev40/L40e220a.dat" +[ 26, 29 ] = ascii (fp) : "./hrtfs/elev40/L40e215a.dat" +[ 26, 30 ] = ascii (fp) : "./hrtfs/elev40/L40e210a.dat" +[ 26, 31 ] = ascii (fp) : "./hrtfs/elev40/L40e205a.dat" +[ 26, 32 ] = ascii (fp) : "./hrtfs/elev40/L40e200a.dat" +[ 26, 33 ] = ascii (fp) : "./hrtfs/elev40/L40e195a.dat" +[ 26, 34 ] = ascii (fp) : "./hrtfs/elev40/L40e190a.dat" +[ 26, 35 ] = ascii (fp) : "./hrtfs/elev40/L40e185a.dat" +[ 26, 36 ] = ascii (fp) : "./hrtfs/elev40/L40e180a.dat" +[ 26, 37 ] = ascii (fp) : "./hrtfs/elev40/L40e175a.dat" +[ 26, 38 ] = ascii (fp) : "./hrtfs/elev40/L40e170a.dat" +[ 26, 39 ] = ascii (fp) : "./hrtfs/elev40/L40e165a.dat" +[ 26, 40 ] = ascii (fp) : "./hrtfs/elev40/L40e160a.dat" +[ 26, 41 ] = ascii (fp) : "./hrtfs/elev40/L40e155a.dat" +[ 26, 42 ] = ascii (fp) : "./hrtfs/elev40/L40e150a.dat" +[ 26, 43 ] = ascii (fp) : "./hrtfs/elev40/L40e145a.dat" +[ 26, 44 ] = ascii (fp) : "./hrtfs/elev40/L40e140a.dat" +[ 26, 45 ] = ascii (fp) : "./hrtfs/elev40/L40e135a.dat" +[ 26, 46 ] = ascii (fp) : "./hrtfs/elev40/L40e130a.dat" +[ 26, 47 ] = ascii (fp) : "./hrtfs/elev40/L40e125a.dat" +[ 26, 48 ] = ascii (fp) : "./hrtfs/elev40/L40e120a.dat" +[ 26, 49 ] = ascii (fp) : "./hrtfs/elev40/L40e115a.dat" +[ 26, 50 ] = ascii (fp) : "./hrtfs/elev40/L40e110a.dat" +[ 26, 51 ] = ascii (fp) : "./hrtfs/elev40/L40e105a.dat" +[ 26, 52 ] = ascii (fp) : "./hrtfs/elev40/L40e100a.dat" +[ 26, 53 ] = ascii (fp) : "./hrtfs/elev40/L40e095a.dat" +[ 26, 54 ] = ascii (fp) : "./hrtfs/elev40/L40e090a.dat" +[ 26, 55 ] = ascii (fp) : "./hrtfs/elev40/L40e085a.dat" +[ 26, 56 ] = ascii (fp) : "./hrtfs/elev40/L40e080a.dat" +[ 26, 57 ] = ascii (fp) : "./hrtfs/elev40/L40e075a.dat" +[ 26, 58 ] = ascii (fp) : "./hrtfs/elev40/L40e070a.dat" +[ 26, 59 ] = ascii (fp) : "./hrtfs/elev40/L40e065a.dat" +[ 26, 60 ] = ascii (fp) : "./hrtfs/elev40/L40e060a.dat" +[ 26, 61 ] = ascii (fp) : "./hrtfs/elev40/L40e055a.dat" +[ 26, 62 ] = ascii (fp) : "./hrtfs/elev40/L40e050a.dat" +[ 26, 63 ] = ascii (fp) : "./hrtfs/elev40/L40e045a.dat" +[ 26, 64 ] = ascii (fp) : "./hrtfs/elev40/L40e040a.dat" +[ 26, 65 ] = ascii (fp) : "./hrtfs/elev40/L40e035a.dat" +[ 26, 66 ] = ascii (fp) : "./hrtfs/elev40/L40e030a.dat" +[ 26, 67 ] = ascii (fp) : "./hrtfs/elev40/L40e025a.dat" +[ 26, 68 ] = ascii (fp) : "./hrtfs/elev40/L40e020a.dat" +[ 26, 69 ] = ascii (fp) : "./hrtfs/elev40/L40e015a.dat" +[ 26, 70 ] = ascii (fp) : "./hrtfs/elev40/L40e010a.dat" +[ 26, 71 ] = ascii (fp) : "./hrtfs/elev40/L40e005a.dat" + +[ 27, 0 ] = ascii (fp) : "./hrtfs/elev45/L45e000a.dat" +[ 27, 1 ] = ascii (fp) : "./hrtfs/elev45/L45e355a.dat" +[ 27, 2 ] = ascii (fp) : "./hrtfs/elev45/L45e350a.dat" +[ 27, 3 ] = ascii (fp) : "./hrtfs/elev45/L45e345a.dat" +[ 27, 4 ] = ascii (fp) : "./hrtfs/elev45/L45e340a.dat" +[ 27, 5 ] = ascii (fp) : "./hrtfs/elev45/L45e335a.dat" +[ 27, 6 ] = ascii (fp) : "./hrtfs/elev45/L45e330a.dat" +[ 27, 7 ] = ascii (fp) : "./hrtfs/elev45/L45e325a.dat" +[ 27, 8 ] = ascii (fp) : "./hrtfs/elev45/L45e320a.dat" +[ 27, 9 ] = ascii (fp) : "./hrtfs/elev45/L45e315a.dat" +[ 27, 10 ] = ascii (fp) : "./hrtfs/elev45/L45e310a.dat" +[ 27, 11 ] = ascii (fp) : "./hrtfs/elev45/L45e305a.dat" +[ 27, 12 ] = ascii (fp) : "./hrtfs/elev45/L45e300a.dat" +[ 27, 13 ] = ascii (fp) : "./hrtfs/elev45/L45e295a.dat" +[ 27, 14 ] = ascii (fp) : "./hrtfs/elev45/L45e290a.dat" +[ 27, 15 ] = ascii (fp) : "./hrtfs/elev45/L45e285a.dat" +[ 27, 16 ] = ascii (fp) : "./hrtfs/elev45/L45e280a.dat" +[ 27, 17 ] = ascii (fp) : "./hrtfs/elev45/L45e275a.dat" +[ 27, 18 ] = ascii (fp) : "./hrtfs/elev45/L45e270a.dat" +[ 27, 19 ] = ascii (fp) : "./hrtfs/elev45/L45e265a.dat" +[ 27, 20 ] = ascii (fp) : "./hrtfs/elev45/L45e260a.dat" +[ 27, 21 ] = ascii (fp) : "./hrtfs/elev45/L45e255a.dat" +[ 27, 22 ] = ascii (fp) : "./hrtfs/elev45/L45e250a.dat" +[ 27, 23 ] = ascii (fp) : "./hrtfs/elev45/L45e245a.dat" +[ 27, 24 ] = ascii (fp) : "./hrtfs/elev45/L45e240a.dat" +[ 27, 25 ] = ascii (fp) : "./hrtfs/elev45/L45e235a.dat" +[ 27, 26 ] = ascii (fp) : "./hrtfs/elev45/L45e230a.dat" +[ 27, 27 ] = ascii (fp) : "./hrtfs/elev45/L45e225a.dat" +[ 27, 28 ] = ascii (fp) : "./hrtfs/elev45/L45e220a.dat" +[ 27, 29 ] = ascii (fp) : "./hrtfs/elev45/L45e215a.dat" +[ 27, 30 ] = ascii (fp) : "./hrtfs/elev45/L45e210a.dat" +[ 27, 31 ] = ascii (fp) : "./hrtfs/elev45/L45e205a.dat" +[ 27, 32 ] = ascii (fp) : "./hrtfs/elev45/L45e200a.dat" +[ 27, 33 ] = ascii (fp) : "./hrtfs/elev45/L45e195a.dat" +[ 27, 34 ] = ascii (fp) : "./hrtfs/elev45/L45e190a.dat" +[ 27, 35 ] = ascii (fp) : "./hrtfs/elev45/L45e185a.dat" +[ 27, 36 ] = ascii (fp) : "./hrtfs/elev45/L45e180a.dat" +[ 27, 37 ] = ascii (fp) : "./hrtfs/elev45/L45e175a.dat" +[ 27, 38 ] = ascii (fp) : "./hrtfs/elev45/L45e170a.dat" +[ 27, 39 ] = ascii (fp) : "./hrtfs/elev45/L45e165a.dat" +[ 27, 40 ] = ascii (fp) : "./hrtfs/elev45/L45e160a.dat" +[ 27, 41 ] = ascii (fp) : "./hrtfs/elev45/L45e155a.dat" +[ 27, 42 ] = ascii (fp) : "./hrtfs/elev45/L45e150a.dat" +[ 27, 43 ] = ascii (fp) : "./hrtfs/elev45/L45e145a.dat" +[ 27, 44 ] = ascii (fp) : "./hrtfs/elev45/L45e140a.dat" +[ 27, 45 ] = ascii (fp) : "./hrtfs/elev45/L45e135a.dat" +[ 27, 46 ] = ascii (fp) : "./hrtfs/elev45/L45e130a.dat" +[ 27, 47 ] = ascii (fp) : "./hrtfs/elev45/L45e125a.dat" +[ 27, 48 ] = ascii (fp) : "./hrtfs/elev45/L45e120a.dat" +[ 27, 49 ] = ascii (fp) : "./hrtfs/elev45/L45e115a.dat" +[ 27, 50 ] = ascii (fp) : "./hrtfs/elev45/L45e110a.dat" +[ 27, 51 ] = ascii (fp) : "./hrtfs/elev45/L45e105a.dat" +[ 27, 52 ] = ascii (fp) : "./hrtfs/elev45/L45e100a.dat" +[ 27, 53 ] = ascii (fp) : "./hrtfs/elev45/L45e095a.dat" +[ 27, 54 ] = ascii (fp) : "./hrtfs/elev45/L45e090a.dat" +[ 27, 55 ] = ascii (fp) : "./hrtfs/elev45/L45e085a.dat" +[ 27, 56 ] = ascii (fp) : "./hrtfs/elev45/L45e080a.dat" +[ 27, 57 ] = ascii (fp) : "./hrtfs/elev45/L45e075a.dat" +[ 27, 58 ] = ascii (fp) : "./hrtfs/elev45/L45e070a.dat" +[ 27, 59 ] = ascii (fp) : "./hrtfs/elev45/L45e065a.dat" +[ 27, 60 ] = ascii (fp) : "./hrtfs/elev45/L45e060a.dat" +[ 27, 61 ] = ascii (fp) : "./hrtfs/elev45/L45e055a.dat" +[ 27, 62 ] = ascii (fp) : "./hrtfs/elev45/L45e050a.dat" +[ 27, 63 ] = ascii (fp) : "./hrtfs/elev45/L45e045a.dat" +[ 27, 64 ] = ascii (fp) : "./hrtfs/elev45/L45e040a.dat" +[ 27, 65 ] = ascii (fp) : "./hrtfs/elev45/L45e035a.dat" +[ 27, 66 ] = ascii (fp) : "./hrtfs/elev45/L45e030a.dat" +[ 27, 67 ] = ascii (fp) : "./hrtfs/elev45/L45e025a.dat" +[ 27, 68 ] = ascii (fp) : "./hrtfs/elev45/L45e020a.dat" +[ 27, 69 ] = ascii (fp) : "./hrtfs/elev45/L45e015a.dat" +[ 27, 70 ] = ascii (fp) : "./hrtfs/elev45/L45e010a.dat" +[ 27, 71 ] = ascii (fp) : "./hrtfs/elev45/L45e005a.dat" + +[ 28, 0 ] = ascii (fp) : "./hrtfs/elev50/L50e000a.dat" +[ 28, 1 ] = ascii (fp) : "./hrtfs/elev50/L50e355a.dat" +[ 28, 2 ] = ascii (fp) : "./hrtfs/elev50/L50e350a.dat" +[ 28, 3 ] = ascii (fp) : "./hrtfs/elev50/L50e345a.dat" +[ 28, 4 ] = ascii (fp) : "./hrtfs/elev50/L50e340a.dat" +[ 28, 5 ] = ascii (fp) : "./hrtfs/elev50/L50e335a.dat" +[ 28, 6 ] = ascii (fp) : "./hrtfs/elev50/L50e330a.dat" +[ 28, 7 ] = ascii (fp) : "./hrtfs/elev50/L50e325a.dat" +[ 28, 8 ] = ascii (fp) : "./hrtfs/elev50/L50e320a.dat" +[ 28, 9 ] = ascii (fp) : "./hrtfs/elev50/L50e315a.dat" +[ 28, 10 ] = ascii (fp) : "./hrtfs/elev50/L50e310a.dat" +[ 28, 11 ] = ascii (fp) : "./hrtfs/elev50/L50e305a.dat" +[ 28, 12 ] = ascii (fp) : "./hrtfs/elev50/L50e300a.dat" +[ 28, 13 ] = ascii (fp) : "./hrtfs/elev50/L50e295a.dat" +[ 28, 14 ] = ascii (fp) : "./hrtfs/elev50/L50e290a.dat" +[ 28, 15 ] = ascii (fp) : "./hrtfs/elev50/L50e285a.dat" +[ 28, 16 ] = ascii (fp) : "./hrtfs/elev50/L50e280a.dat" +[ 28, 17 ] = ascii (fp) : "./hrtfs/elev50/L50e275a.dat" +[ 28, 18 ] = ascii (fp) : "./hrtfs/elev50/L50e270a.dat" +[ 28, 19 ] = ascii (fp) : "./hrtfs/elev50/L50e265a.dat" +[ 28, 20 ] = ascii (fp) : "./hrtfs/elev50/L50e260a.dat" +[ 28, 21 ] = ascii (fp) : "./hrtfs/elev50/L50e255a.dat" +[ 28, 22 ] = ascii (fp) : "./hrtfs/elev50/L50e250a.dat" +[ 28, 23 ] = ascii (fp) : "./hrtfs/elev50/L50e245a.dat" +[ 28, 24 ] = ascii (fp) : "./hrtfs/elev50/L50e240a.dat" +[ 28, 25 ] = ascii (fp) : "./hrtfs/elev50/L50e235a.dat" +[ 28, 26 ] = ascii (fp) : "./hrtfs/elev50/L50e230a.dat" +[ 28, 27 ] = ascii (fp) : "./hrtfs/elev50/L50e225a.dat" +[ 28, 28 ] = ascii (fp) : "./hrtfs/elev50/L50e220a.dat" +[ 28, 29 ] = ascii (fp) : "./hrtfs/elev50/L50e215a.dat" +[ 28, 30 ] = ascii (fp) : "./hrtfs/elev50/L50e210a.dat" +[ 28, 31 ] = ascii (fp) : "./hrtfs/elev50/L50e205a.dat" +[ 28, 32 ] = ascii (fp) : "./hrtfs/elev50/L50e200a.dat" +[ 28, 33 ] = ascii (fp) : "./hrtfs/elev50/L50e195a.dat" +[ 28, 34 ] = ascii (fp) : "./hrtfs/elev50/L50e190a.dat" +[ 28, 35 ] = ascii (fp) : "./hrtfs/elev50/L50e185a.dat" +[ 28, 36 ] = ascii (fp) : "./hrtfs/elev50/L50e180a.dat" +[ 28, 37 ] = ascii (fp) : "./hrtfs/elev50/L50e175a.dat" +[ 28, 38 ] = ascii (fp) : "./hrtfs/elev50/L50e170a.dat" +[ 28, 39 ] = ascii (fp) : "./hrtfs/elev50/L50e165a.dat" +[ 28, 40 ] = ascii (fp) : "./hrtfs/elev50/L50e160a.dat" +[ 28, 41 ] = ascii (fp) : "./hrtfs/elev50/L50e155a.dat" +[ 28, 42 ] = ascii (fp) : "./hrtfs/elev50/L50e150a.dat" +[ 28, 43 ] = ascii (fp) : "./hrtfs/elev50/L50e145a.dat" +[ 28, 44 ] = ascii (fp) : "./hrtfs/elev50/L50e140a.dat" +[ 28, 45 ] = ascii (fp) : "./hrtfs/elev50/L50e135a.dat" +[ 28, 46 ] = ascii (fp) : "./hrtfs/elev50/L50e130a.dat" +[ 28, 47 ] = ascii (fp) : "./hrtfs/elev50/L50e125a.dat" +[ 28, 48 ] = ascii (fp) : "./hrtfs/elev50/L50e120a.dat" +[ 28, 49 ] = ascii (fp) : "./hrtfs/elev50/L50e115a.dat" +[ 28, 50 ] = ascii (fp) : "./hrtfs/elev50/L50e110a.dat" +[ 28, 51 ] = ascii (fp) : "./hrtfs/elev50/L50e105a.dat" +[ 28, 52 ] = ascii (fp) : "./hrtfs/elev50/L50e100a.dat" +[ 28, 53 ] = ascii (fp) : "./hrtfs/elev50/L50e095a.dat" +[ 28, 54 ] = ascii (fp) : "./hrtfs/elev50/L50e090a.dat" +[ 28, 55 ] = ascii (fp) : "./hrtfs/elev50/L50e085a.dat" +[ 28, 56 ] = ascii (fp) : "./hrtfs/elev50/L50e080a.dat" +[ 28, 57 ] = ascii (fp) : "./hrtfs/elev50/L50e075a.dat" +[ 28, 58 ] = ascii (fp) : "./hrtfs/elev50/L50e070a.dat" +[ 28, 59 ] = ascii (fp) : "./hrtfs/elev50/L50e065a.dat" +[ 28, 60 ] = ascii (fp) : "./hrtfs/elev50/L50e060a.dat" +[ 28, 61 ] = ascii (fp) : "./hrtfs/elev50/L50e055a.dat" +[ 28, 62 ] = ascii (fp) : "./hrtfs/elev50/L50e050a.dat" +[ 28, 63 ] = ascii (fp) : "./hrtfs/elev50/L50e045a.dat" +[ 28, 64 ] = ascii (fp) : "./hrtfs/elev50/L50e040a.dat" +[ 28, 65 ] = ascii (fp) : "./hrtfs/elev50/L50e035a.dat" +[ 28, 66 ] = ascii (fp) : "./hrtfs/elev50/L50e030a.dat" +[ 28, 67 ] = ascii (fp) : "./hrtfs/elev50/L50e025a.dat" +[ 28, 68 ] = ascii (fp) : "./hrtfs/elev50/L50e020a.dat" +[ 28, 69 ] = ascii (fp) : "./hrtfs/elev50/L50e015a.dat" +[ 28, 70 ] = ascii (fp) : "./hrtfs/elev50/L50e010a.dat" +[ 28, 71 ] = ascii (fp) : "./hrtfs/elev50/L50e005a.dat" + +[ 29, 0 ] = ascii (fp) : "./hrtfs/elev55/L55e000a.dat" +[ 29, 1 ] = ascii (fp) : "./hrtfs/elev55/L55e355a.dat" +[ 29, 2 ] = ascii (fp) : "./hrtfs/elev55/L55e350a.dat" +[ 29, 3 ] = ascii (fp) : "./hrtfs/elev55/L55e345a.dat" +[ 29, 4 ] = ascii (fp) : "./hrtfs/elev55/L55e340a.dat" +[ 29, 5 ] = ascii (fp) : "./hrtfs/elev55/L55e335a.dat" +[ 29, 6 ] = ascii (fp) : "./hrtfs/elev55/L55e330a.dat" +[ 29, 7 ] = ascii (fp) : "./hrtfs/elev55/L55e325a.dat" +[ 29, 8 ] = ascii (fp) : "./hrtfs/elev55/L55e320a.dat" +[ 29, 9 ] = ascii (fp) : "./hrtfs/elev55/L55e315a.dat" +[ 29, 10 ] = ascii (fp) : "./hrtfs/elev55/L55e310a.dat" +[ 29, 11 ] = ascii (fp) : "./hrtfs/elev55/L55e305a.dat" +[ 29, 12 ] = ascii (fp) : "./hrtfs/elev55/L55e300a.dat" +[ 29, 13 ] = ascii (fp) : "./hrtfs/elev55/L55e295a.dat" +[ 29, 14 ] = ascii (fp) : "./hrtfs/elev55/L55e290a.dat" +[ 29, 15 ] = ascii (fp) : "./hrtfs/elev55/L55e285a.dat" +[ 29, 16 ] = ascii (fp) : "./hrtfs/elev55/L55e280a.dat" +[ 29, 17 ] = ascii (fp) : "./hrtfs/elev55/L55e275a.dat" +[ 29, 18 ] = ascii (fp) : "./hrtfs/elev55/L55e270a.dat" +[ 29, 19 ] = ascii (fp) : "./hrtfs/elev55/L55e265a.dat" +[ 29, 20 ] = ascii (fp) : "./hrtfs/elev55/L55e260a.dat" +[ 29, 21 ] = ascii (fp) : "./hrtfs/elev55/L55e255a.dat" +[ 29, 22 ] = ascii (fp) : "./hrtfs/elev55/L55e250a.dat" +[ 29, 23 ] = ascii (fp) : "./hrtfs/elev55/L55e245a.dat" +[ 29, 24 ] = ascii (fp) : "./hrtfs/elev55/L55e240a.dat" +[ 29, 25 ] = ascii (fp) : "./hrtfs/elev55/L55e235a.dat" +[ 29, 26 ] = ascii (fp) : "./hrtfs/elev55/L55e230a.dat" +[ 29, 27 ] = ascii (fp) : "./hrtfs/elev55/L55e225a.dat" +[ 29, 28 ] = ascii (fp) : "./hrtfs/elev55/L55e220a.dat" +[ 29, 29 ] = ascii (fp) : "./hrtfs/elev55/L55e215a.dat" +[ 29, 30 ] = ascii (fp) : "./hrtfs/elev55/L55e210a.dat" +[ 29, 31 ] = ascii (fp) : "./hrtfs/elev55/L55e205a.dat" +[ 29, 32 ] = ascii (fp) : "./hrtfs/elev55/L55e200a.dat" +[ 29, 33 ] = ascii (fp) : "./hrtfs/elev55/L55e195a.dat" +[ 29, 34 ] = ascii (fp) : "./hrtfs/elev55/L55e190a.dat" +[ 29, 35 ] = ascii (fp) : "./hrtfs/elev55/L55e185a.dat" +[ 29, 36 ] = ascii (fp) : "./hrtfs/elev55/L55e180a.dat" +[ 29, 37 ] = ascii (fp) : "./hrtfs/elev55/L55e175a.dat" +[ 29, 38 ] = ascii (fp) : "./hrtfs/elev55/L55e170a.dat" +[ 29, 39 ] = ascii (fp) : "./hrtfs/elev55/L55e165a.dat" +[ 29, 40 ] = ascii (fp) : "./hrtfs/elev55/L55e160a.dat" +[ 29, 41 ] = ascii (fp) : "./hrtfs/elev55/L55e155a.dat" +[ 29, 42 ] = ascii (fp) : "./hrtfs/elev55/L55e150a.dat" +[ 29, 43 ] = ascii (fp) : "./hrtfs/elev55/L55e145a.dat" +[ 29, 44 ] = ascii (fp) : "./hrtfs/elev55/L55e140a.dat" +[ 29, 45 ] = ascii (fp) : "./hrtfs/elev55/L55e135a.dat" +[ 29, 46 ] = ascii (fp) : "./hrtfs/elev55/L55e130a.dat" +[ 29, 47 ] = ascii (fp) : "./hrtfs/elev55/L55e125a.dat" +[ 29, 48 ] = ascii (fp) : "./hrtfs/elev55/L55e120a.dat" +[ 29, 49 ] = ascii (fp) : "./hrtfs/elev55/L55e115a.dat" +[ 29, 50 ] = ascii (fp) : "./hrtfs/elev55/L55e110a.dat" +[ 29, 51 ] = ascii (fp) : "./hrtfs/elev55/L55e105a.dat" +[ 29, 52 ] = ascii (fp) : "./hrtfs/elev55/L55e100a.dat" +[ 29, 53 ] = ascii (fp) : "./hrtfs/elev55/L55e095a.dat" +[ 29, 54 ] = ascii (fp) : "./hrtfs/elev55/L55e090a.dat" +[ 29, 55 ] = ascii (fp) : "./hrtfs/elev55/L55e085a.dat" +[ 29, 56 ] = ascii (fp) : "./hrtfs/elev55/L55e080a.dat" +[ 29, 57 ] = ascii (fp) : "./hrtfs/elev55/L55e075a.dat" +[ 29, 58 ] = ascii (fp) : "./hrtfs/elev55/L55e070a.dat" +[ 29, 59 ] = ascii (fp) : "./hrtfs/elev55/L55e065a.dat" +[ 29, 60 ] = ascii (fp) : "./hrtfs/elev55/L55e060a.dat" +[ 29, 61 ] = ascii (fp) : "./hrtfs/elev55/L55e055a.dat" +[ 29, 62 ] = ascii (fp) : "./hrtfs/elev55/L55e050a.dat" +[ 29, 63 ] = ascii (fp) : "./hrtfs/elev55/L55e045a.dat" +[ 29, 64 ] = ascii (fp) : "./hrtfs/elev55/L55e040a.dat" +[ 29, 65 ] = ascii (fp) : "./hrtfs/elev55/L55e035a.dat" +[ 29, 66 ] = ascii (fp) : "./hrtfs/elev55/L55e030a.dat" +[ 29, 67 ] = ascii (fp) : "./hrtfs/elev55/L55e025a.dat" +[ 29, 68 ] = ascii (fp) : "./hrtfs/elev55/L55e020a.dat" +[ 29, 69 ] = ascii (fp) : "./hrtfs/elev55/L55e015a.dat" +[ 29, 70 ] = ascii (fp) : "./hrtfs/elev55/L55e010a.dat" +[ 29, 71 ] = ascii (fp) : "./hrtfs/elev55/L55e005a.dat" + +[ 30, 0 ] = ascii (fp) : "./hrtfs/elev60/L60e000a.dat" +[ 30, 1 ] = ascii (fp) : "./hrtfs/elev60/L60e355a.dat" +[ 30, 2 ] = ascii (fp) : "./hrtfs/elev60/L60e350a.dat" +[ 30, 3 ] = ascii (fp) : "./hrtfs/elev60/L60e345a.dat" +[ 30, 4 ] = ascii (fp) : "./hrtfs/elev60/L60e340a.dat" +[ 30, 5 ] = ascii (fp) : "./hrtfs/elev60/L60e335a.dat" +[ 30, 6 ] = ascii (fp) : "./hrtfs/elev60/L60e330a.dat" +[ 30, 7 ] = ascii (fp) : "./hrtfs/elev60/L60e325a.dat" +[ 30, 8 ] = ascii (fp) : "./hrtfs/elev60/L60e320a.dat" +[ 30, 9 ] = ascii (fp) : "./hrtfs/elev60/L60e315a.dat" +[ 30, 10 ] = ascii (fp) : "./hrtfs/elev60/L60e310a.dat" +[ 30, 11 ] = ascii (fp) : "./hrtfs/elev60/L60e305a.dat" +[ 30, 12 ] = ascii (fp) : "./hrtfs/elev60/L60e300a.dat" +[ 30, 13 ] = ascii (fp) : "./hrtfs/elev60/L60e295a.dat" +[ 30, 14 ] = ascii (fp) : "./hrtfs/elev60/L60e290a.dat" +[ 30, 15 ] = ascii (fp) : "./hrtfs/elev60/L60e285a.dat" +[ 30, 16 ] = ascii (fp) : "./hrtfs/elev60/L60e280a.dat" +[ 30, 17 ] = ascii (fp) : "./hrtfs/elev60/L60e275a.dat" +[ 30, 18 ] = ascii (fp) : "./hrtfs/elev60/L60e270a.dat" +[ 30, 19 ] = ascii (fp) : "./hrtfs/elev60/L60e265a.dat" +[ 30, 20 ] = ascii (fp) : "./hrtfs/elev60/L60e260a.dat" +[ 30, 21 ] = ascii (fp) : "./hrtfs/elev60/L60e255a.dat" +[ 30, 22 ] = ascii (fp) : "./hrtfs/elev60/L60e250a.dat" +[ 30, 23 ] = ascii (fp) : "./hrtfs/elev60/L60e245a.dat" +[ 30, 24 ] = ascii (fp) : "./hrtfs/elev60/L60e240a.dat" +[ 30, 25 ] = ascii (fp) : "./hrtfs/elev60/L60e235a.dat" +[ 30, 26 ] = ascii (fp) : "./hrtfs/elev60/L60e230a.dat" +[ 30, 27 ] = ascii (fp) : "./hrtfs/elev60/L60e225a.dat" +[ 30, 28 ] = ascii (fp) : "./hrtfs/elev60/L60e220a.dat" +[ 30, 29 ] = ascii (fp) : "./hrtfs/elev60/L60e215a.dat" +[ 30, 30 ] = ascii (fp) : "./hrtfs/elev60/L60e210a.dat" +[ 30, 31 ] = ascii (fp) : "./hrtfs/elev60/L60e205a.dat" +[ 30, 32 ] = ascii (fp) : "./hrtfs/elev60/L60e200a.dat" +[ 30, 33 ] = ascii (fp) : "./hrtfs/elev60/L60e195a.dat" +[ 30, 34 ] = ascii (fp) : "./hrtfs/elev60/L60e190a.dat" +[ 30, 35 ] = ascii (fp) : "./hrtfs/elev60/L60e185a.dat" +[ 30, 36 ] = ascii (fp) : "./hrtfs/elev60/L60e180a.dat" +[ 30, 37 ] = ascii (fp) : "./hrtfs/elev60/L60e175a.dat" +[ 30, 38 ] = ascii (fp) : "./hrtfs/elev60/L60e170a.dat" +[ 30, 39 ] = ascii (fp) : "./hrtfs/elev60/L60e165a.dat" +[ 30, 40 ] = ascii (fp) : "./hrtfs/elev60/L60e160a.dat" +[ 30, 41 ] = ascii (fp) : "./hrtfs/elev60/L60e155a.dat" +[ 30, 42 ] = ascii (fp) : "./hrtfs/elev60/L60e150a.dat" +[ 30, 43 ] = ascii (fp) : "./hrtfs/elev60/L60e145a.dat" +[ 30, 44 ] = ascii (fp) : "./hrtfs/elev60/L60e140a.dat" +[ 30, 45 ] = ascii (fp) : "./hrtfs/elev60/L60e135a.dat" +[ 30, 46 ] = ascii (fp) : "./hrtfs/elev60/L60e130a.dat" +[ 30, 47 ] = ascii (fp) : "./hrtfs/elev60/L60e125a.dat" +[ 30, 48 ] = ascii (fp) : "./hrtfs/elev60/L60e120a.dat" +[ 30, 49 ] = ascii (fp) : "./hrtfs/elev60/L60e115a.dat" +[ 30, 50 ] = ascii (fp) : "./hrtfs/elev60/L60e110a.dat" +[ 30, 51 ] = ascii (fp) : "./hrtfs/elev60/L60e105a.dat" +[ 30, 52 ] = ascii (fp) : "./hrtfs/elev60/L60e100a.dat" +[ 30, 53 ] = ascii (fp) : "./hrtfs/elev60/L60e095a.dat" +[ 30, 54 ] = ascii (fp) : "./hrtfs/elev60/L60e090a.dat" +[ 30, 55 ] = ascii (fp) : "./hrtfs/elev60/L60e085a.dat" +[ 30, 56 ] = ascii (fp) : "./hrtfs/elev60/L60e080a.dat" +[ 30, 57 ] = ascii (fp) : "./hrtfs/elev60/L60e075a.dat" +[ 30, 58 ] = ascii (fp) : "./hrtfs/elev60/L60e070a.dat" +[ 30, 59 ] = ascii (fp) : "./hrtfs/elev60/L60e065a.dat" +[ 30, 60 ] = ascii (fp) : "./hrtfs/elev60/L60e060a.dat" +[ 30, 61 ] = ascii (fp) : "./hrtfs/elev60/L60e055a.dat" +[ 30, 62 ] = ascii (fp) : "./hrtfs/elev60/L60e050a.dat" +[ 30, 63 ] = ascii (fp) : "./hrtfs/elev60/L60e045a.dat" +[ 30, 64 ] = ascii (fp) : "./hrtfs/elev60/L60e040a.dat" +[ 30, 65 ] = ascii (fp) : "./hrtfs/elev60/L60e035a.dat" +[ 30, 66 ] = ascii (fp) : "./hrtfs/elev60/L60e030a.dat" +[ 30, 67 ] = ascii (fp) : "./hrtfs/elev60/L60e025a.dat" +[ 30, 68 ] = ascii (fp) : "./hrtfs/elev60/L60e020a.dat" +[ 30, 69 ] = ascii (fp) : "./hrtfs/elev60/L60e015a.dat" +[ 30, 70 ] = ascii (fp) : "./hrtfs/elev60/L60e010a.dat" +[ 30, 71 ] = ascii (fp) : "./hrtfs/elev60/L60e005a.dat" + +[ 31, 0 ] = ascii (fp) : "./hrtfs/elev65/L65e000a.dat" +[ 31, 1 ] = ascii (fp) : "./hrtfs/elev65/L65e355a.dat" +[ 31, 2 ] = ascii (fp) : "./hrtfs/elev65/L65e350a.dat" +[ 31, 3 ] = ascii (fp) : "./hrtfs/elev65/L65e345a.dat" +[ 31, 4 ] = ascii (fp) : "./hrtfs/elev65/L65e340a.dat" +[ 31, 5 ] = ascii (fp) : "./hrtfs/elev65/L65e335a.dat" +[ 31, 6 ] = ascii (fp) : "./hrtfs/elev65/L65e330a.dat" +[ 31, 7 ] = ascii (fp) : "./hrtfs/elev65/L65e325a.dat" +[ 31, 8 ] = ascii (fp) : "./hrtfs/elev65/L65e320a.dat" +[ 31, 9 ] = ascii (fp) : "./hrtfs/elev65/L65e315a.dat" +[ 31, 10 ] = ascii (fp) : "./hrtfs/elev65/L65e310a.dat" +[ 31, 11 ] = ascii (fp) : "./hrtfs/elev65/L65e305a.dat" +[ 31, 12 ] = ascii (fp) : "./hrtfs/elev65/L65e300a.dat" +[ 31, 13 ] = ascii (fp) : "./hrtfs/elev65/L65e295a.dat" +[ 31, 14 ] = ascii (fp) : "./hrtfs/elev65/L65e290a.dat" +[ 31, 15 ] = ascii (fp) : "./hrtfs/elev65/L65e285a.dat" +[ 31, 16 ] = ascii (fp) : "./hrtfs/elev65/L65e280a.dat" +[ 31, 17 ] = ascii (fp) : "./hrtfs/elev65/L65e275a.dat" +[ 31, 18 ] = ascii (fp) : "./hrtfs/elev65/L65e270a.dat" +[ 31, 19 ] = ascii (fp) : "./hrtfs/elev65/L65e265a.dat" +[ 31, 20 ] = ascii (fp) : "./hrtfs/elev65/L65e260a.dat" +[ 31, 21 ] = ascii (fp) : "./hrtfs/elev65/L65e255a.dat" +[ 31, 22 ] = ascii (fp) : "./hrtfs/elev65/L65e250a.dat" +[ 31, 23 ] = ascii (fp) : "./hrtfs/elev65/L65e245a.dat" +[ 31, 24 ] = ascii (fp) : "./hrtfs/elev65/L65e240a.dat" +[ 31, 25 ] = ascii (fp) : "./hrtfs/elev65/L65e235a.dat" +[ 31, 26 ] = ascii (fp) : "./hrtfs/elev65/L65e230a.dat" +[ 31, 27 ] = ascii (fp) : "./hrtfs/elev65/L65e225a.dat" +[ 31, 28 ] = ascii (fp) : "./hrtfs/elev65/L65e220a.dat" +[ 31, 29 ] = ascii (fp) : "./hrtfs/elev65/L65e215a.dat" +[ 31, 30 ] = ascii (fp) : "./hrtfs/elev65/L65e210a.dat" +[ 31, 31 ] = ascii (fp) : "./hrtfs/elev65/L65e205a.dat" +[ 31, 32 ] = ascii (fp) : "./hrtfs/elev65/L65e200a.dat" +[ 31, 33 ] = ascii (fp) : "./hrtfs/elev65/L65e195a.dat" +[ 31, 34 ] = ascii (fp) : "./hrtfs/elev65/L65e190a.dat" +[ 31, 35 ] = ascii (fp) : "./hrtfs/elev65/L65e185a.dat" +[ 31, 36 ] = ascii (fp) : "./hrtfs/elev65/L65e180a.dat" +[ 31, 37 ] = ascii (fp) : "./hrtfs/elev65/L65e175a.dat" +[ 31, 38 ] = ascii (fp) : "./hrtfs/elev65/L65e170a.dat" +[ 31, 39 ] = ascii (fp) : "./hrtfs/elev65/L65e165a.dat" +[ 31, 40 ] = ascii (fp) : "./hrtfs/elev65/L65e160a.dat" +[ 31, 41 ] = ascii (fp) : "./hrtfs/elev65/L65e155a.dat" +[ 31, 42 ] = ascii (fp) : "./hrtfs/elev65/L65e150a.dat" +[ 31, 43 ] = ascii (fp) : "./hrtfs/elev65/L65e145a.dat" +[ 31, 44 ] = ascii (fp) : "./hrtfs/elev65/L65e140a.dat" +[ 31, 45 ] = ascii (fp) : "./hrtfs/elev65/L65e135a.dat" +[ 31, 46 ] = ascii (fp) : "./hrtfs/elev65/L65e130a.dat" +[ 31, 47 ] = ascii (fp) : "./hrtfs/elev65/L65e125a.dat" +[ 31, 48 ] = ascii (fp) : "./hrtfs/elev65/L65e120a.dat" +[ 31, 49 ] = ascii (fp) : "./hrtfs/elev65/L65e115a.dat" +[ 31, 50 ] = ascii (fp) : "./hrtfs/elev65/L65e110a.dat" +[ 31, 51 ] = ascii (fp) : "./hrtfs/elev65/L65e105a.dat" +[ 31, 52 ] = ascii (fp) : "./hrtfs/elev65/L65e100a.dat" +[ 31, 53 ] = ascii (fp) : "./hrtfs/elev65/L65e095a.dat" +[ 31, 54 ] = ascii (fp) : "./hrtfs/elev65/L65e090a.dat" +[ 31, 55 ] = ascii (fp) : "./hrtfs/elev65/L65e085a.dat" +[ 31, 56 ] = ascii (fp) : "./hrtfs/elev65/L65e080a.dat" +[ 31, 57 ] = ascii (fp) : "./hrtfs/elev65/L65e075a.dat" +[ 31, 58 ] = ascii (fp) : "./hrtfs/elev65/L65e070a.dat" +[ 31, 59 ] = ascii (fp) : "./hrtfs/elev65/L65e065a.dat" +[ 31, 60 ] = ascii (fp) : "./hrtfs/elev65/L65e060a.dat" +[ 31, 61 ] = ascii (fp) : "./hrtfs/elev65/L65e055a.dat" +[ 31, 62 ] = ascii (fp) : "./hrtfs/elev65/L65e050a.dat" +[ 31, 63 ] = ascii (fp) : "./hrtfs/elev65/L65e045a.dat" +[ 31, 64 ] = ascii (fp) : "./hrtfs/elev65/L65e040a.dat" +[ 31, 65 ] = ascii (fp) : "./hrtfs/elev65/L65e035a.dat" +[ 31, 66 ] = ascii (fp) : "./hrtfs/elev65/L65e030a.dat" +[ 31, 67 ] = ascii (fp) : "./hrtfs/elev65/L65e025a.dat" +[ 31, 68 ] = ascii (fp) : "./hrtfs/elev65/L65e020a.dat" +[ 31, 69 ] = ascii (fp) : "./hrtfs/elev65/L65e015a.dat" +[ 31, 70 ] = ascii (fp) : "./hrtfs/elev65/L65e010a.dat" +[ 31, 71 ] = ascii (fp) : "./hrtfs/elev65/L65e005a.dat" + +[ 32, 0 ] = ascii (fp) : "./hrtfs/elev70/L70e000a.dat" +[ 32, 1 ] = ascii (fp) : "./hrtfs/elev70/L70e355a.dat" +[ 32, 2 ] = ascii (fp) : "./hrtfs/elev70/L70e350a.dat" +[ 32, 3 ] = ascii (fp) : "./hrtfs/elev70/L70e345a.dat" +[ 32, 4 ] = ascii (fp) : "./hrtfs/elev70/L70e340a.dat" +[ 32, 5 ] = ascii (fp) : "./hrtfs/elev70/L70e335a.dat" +[ 32, 6 ] = ascii (fp) : "./hrtfs/elev70/L70e330a.dat" +[ 32, 7 ] = ascii (fp) : "./hrtfs/elev70/L70e325a.dat" +[ 32, 8 ] = ascii (fp) : "./hrtfs/elev70/L70e320a.dat" +[ 32, 9 ] = ascii (fp) : "./hrtfs/elev70/L70e315a.dat" +[ 32, 10 ] = ascii (fp) : "./hrtfs/elev70/L70e310a.dat" +[ 32, 11 ] = ascii (fp) : "./hrtfs/elev70/L70e305a.dat" +[ 32, 12 ] = ascii (fp) : "./hrtfs/elev70/L70e300a.dat" +[ 32, 13 ] = ascii (fp) : "./hrtfs/elev70/L70e295a.dat" +[ 32, 14 ] = ascii (fp) : "./hrtfs/elev70/L70e290a.dat" +[ 32, 15 ] = ascii (fp) : "./hrtfs/elev70/L70e285a.dat" +[ 32, 16 ] = ascii (fp) : "./hrtfs/elev70/L70e280a.dat" +[ 32, 17 ] = ascii (fp) : "./hrtfs/elev70/L70e275a.dat" +[ 32, 18 ] = ascii (fp) : "./hrtfs/elev70/L70e270a.dat" +[ 32, 19 ] = ascii (fp) : "./hrtfs/elev70/L70e265a.dat" +[ 32, 20 ] = ascii (fp) : "./hrtfs/elev70/L70e260a.dat" +[ 32, 21 ] = ascii (fp) : "./hrtfs/elev70/L70e255a.dat" +[ 32, 22 ] = ascii (fp) : "./hrtfs/elev70/L70e250a.dat" +[ 32, 23 ] = ascii (fp) : "./hrtfs/elev70/L70e245a.dat" +[ 32, 24 ] = ascii (fp) : "./hrtfs/elev70/L70e240a.dat" +[ 32, 25 ] = ascii (fp) : "./hrtfs/elev70/L70e235a.dat" +[ 32, 26 ] = ascii (fp) : "./hrtfs/elev70/L70e230a.dat" +[ 32, 27 ] = ascii (fp) : "./hrtfs/elev70/L70e225a.dat" +[ 32, 28 ] = ascii (fp) : "./hrtfs/elev70/L70e220a.dat" +[ 32, 29 ] = ascii (fp) : "./hrtfs/elev70/L70e215a.dat" +[ 32, 30 ] = ascii (fp) : "./hrtfs/elev70/L70e210a.dat" +[ 32, 31 ] = ascii (fp) : "./hrtfs/elev70/L70e205a.dat" +[ 32, 32 ] = ascii (fp) : "./hrtfs/elev70/L70e200a.dat" +[ 32, 33 ] = ascii (fp) : "./hrtfs/elev70/L70e195a.dat" +[ 32, 34 ] = ascii (fp) : "./hrtfs/elev70/L70e190a.dat" +[ 32, 35 ] = ascii (fp) : "./hrtfs/elev70/L70e185a.dat" +[ 32, 36 ] = ascii (fp) : "./hrtfs/elev70/L70e180a.dat" +[ 32, 37 ] = ascii (fp) : "./hrtfs/elev70/L70e175a.dat" +[ 32, 38 ] = ascii (fp) : "./hrtfs/elev70/L70e170a.dat" +[ 32, 39 ] = ascii (fp) : "./hrtfs/elev70/L70e165a.dat" +[ 32, 40 ] = ascii (fp) : "./hrtfs/elev70/L70e160a.dat" +[ 32, 41 ] = ascii (fp) : "./hrtfs/elev70/L70e155a.dat" +[ 32, 42 ] = ascii (fp) : "./hrtfs/elev70/L70e150a.dat" +[ 32, 43 ] = ascii (fp) : "./hrtfs/elev70/L70e145a.dat" +[ 32, 44 ] = ascii (fp) : "./hrtfs/elev70/L70e140a.dat" +[ 32, 45 ] = ascii (fp) : "./hrtfs/elev70/L70e135a.dat" +[ 32, 46 ] = ascii (fp) : "./hrtfs/elev70/L70e130a.dat" +[ 32, 47 ] = ascii (fp) : "./hrtfs/elev70/L70e125a.dat" +[ 32, 48 ] = ascii (fp) : "./hrtfs/elev70/L70e120a.dat" +[ 32, 49 ] = ascii (fp) : "./hrtfs/elev70/L70e115a.dat" +[ 32, 50 ] = ascii (fp) : "./hrtfs/elev70/L70e110a.dat" +[ 32, 51 ] = ascii (fp) : "./hrtfs/elev70/L70e105a.dat" +[ 32, 52 ] = ascii (fp) : "./hrtfs/elev70/L70e100a.dat" +[ 32, 53 ] = ascii (fp) : "./hrtfs/elev70/L70e095a.dat" +[ 32, 54 ] = ascii (fp) : "./hrtfs/elev70/L70e090a.dat" +[ 32, 55 ] = ascii (fp) : "./hrtfs/elev70/L70e085a.dat" +[ 32, 56 ] = ascii (fp) : "./hrtfs/elev70/L70e080a.dat" +[ 32, 57 ] = ascii (fp) : "./hrtfs/elev70/L70e075a.dat" +[ 32, 58 ] = ascii (fp) : "./hrtfs/elev70/L70e070a.dat" +[ 32, 59 ] = ascii (fp) : "./hrtfs/elev70/L70e065a.dat" +[ 32, 60 ] = ascii (fp) : "./hrtfs/elev70/L70e060a.dat" +[ 32, 61 ] = ascii (fp) : "./hrtfs/elev70/L70e055a.dat" +[ 32, 62 ] = ascii (fp) : "./hrtfs/elev70/L70e050a.dat" +[ 32, 63 ] = ascii (fp) : "./hrtfs/elev70/L70e045a.dat" +[ 32, 64 ] = ascii (fp) : "./hrtfs/elev70/L70e040a.dat" +[ 32, 65 ] = ascii (fp) : "./hrtfs/elev70/L70e035a.dat" +[ 32, 66 ] = ascii (fp) : "./hrtfs/elev70/L70e030a.dat" +[ 32, 67 ] = ascii (fp) : "./hrtfs/elev70/L70e025a.dat" +[ 32, 68 ] = ascii (fp) : "./hrtfs/elev70/L70e020a.dat" +[ 32, 69 ] = ascii (fp) : "./hrtfs/elev70/L70e015a.dat" +[ 32, 70 ] = ascii (fp) : "./hrtfs/elev70/L70e010a.dat" +[ 32, 71 ] = ascii (fp) : "./hrtfs/elev70/L70e005a.dat" + +[ 33, 0 ] = ascii (fp) : "./hrtfs/elev75/L75e000a.dat" +[ 33, 1 ] = ascii (fp) : "./hrtfs/elev75/L75e355a.dat" +[ 33, 2 ] = ascii (fp) : "./hrtfs/elev75/L75e350a.dat" +[ 33, 3 ] = ascii (fp) : "./hrtfs/elev75/L75e345a.dat" +[ 33, 4 ] = ascii (fp) : "./hrtfs/elev75/L75e340a.dat" +[ 33, 5 ] = ascii (fp) : "./hrtfs/elev75/L75e335a.dat" +[ 33, 6 ] = ascii (fp) : "./hrtfs/elev75/L75e330a.dat" +[ 33, 7 ] = ascii (fp) : "./hrtfs/elev75/L75e325a.dat" +[ 33, 8 ] = ascii (fp) : "./hrtfs/elev75/L75e320a.dat" +[ 33, 9 ] = ascii (fp) : "./hrtfs/elev75/L75e315a.dat" +[ 33, 10 ] = ascii (fp) : "./hrtfs/elev75/L75e310a.dat" +[ 33, 11 ] = ascii (fp) : "./hrtfs/elev75/L75e305a.dat" +[ 33, 12 ] = ascii (fp) : "./hrtfs/elev75/L75e300a.dat" +[ 33, 13 ] = ascii (fp) : "./hrtfs/elev75/L75e295a.dat" +[ 33, 14 ] = ascii (fp) : "./hrtfs/elev75/L75e290a.dat" +[ 33, 15 ] = ascii (fp) : "./hrtfs/elev75/L75e285a.dat" +[ 33, 16 ] = ascii (fp) : "./hrtfs/elev75/L75e280a.dat" +[ 33, 17 ] = ascii (fp) : "./hrtfs/elev75/L75e275a.dat" +[ 33, 18 ] = ascii (fp) : "./hrtfs/elev75/L75e270a.dat" +[ 33, 19 ] = ascii (fp) : "./hrtfs/elev75/L75e265a.dat" +[ 33, 20 ] = ascii (fp) : "./hrtfs/elev75/L75e260a.dat" +[ 33, 21 ] = ascii (fp) : "./hrtfs/elev75/L75e255a.dat" +[ 33, 22 ] = ascii (fp) : "./hrtfs/elev75/L75e250a.dat" +[ 33, 23 ] = ascii (fp) : "./hrtfs/elev75/L75e245a.dat" +[ 33, 24 ] = ascii (fp) : "./hrtfs/elev75/L75e240a.dat" +[ 33, 25 ] = ascii (fp) : "./hrtfs/elev75/L75e235a.dat" +[ 33, 26 ] = ascii (fp) : "./hrtfs/elev75/L75e230a.dat" +[ 33, 27 ] = ascii (fp) : "./hrtfs/elev75/L75e225a.dat" +[ 33, 28 ] = ascii (fp) : "./hrtfs/elev75/L75e220a.dat" +[ 33, 29 ] = ascii (fp) : "./hrtfs/elev75/L75e215a.dat" +[ 33, 30 ] = ascii (fp) : "./hrtfs/elev75/L75e210a.dat" +[ 33, 31 ] = ascii (fp) : "./hrtfs/elev75/L75e205a.dat" +[ 33, 32 ] = ascii (fp) : "./hrtfs/elev75/L75e200a.dat" +[ 33, 33 ] = ascii (fp) : "./hrtfs/elev75/L75e195a.dat" +[ 33, 34 ] = ascii (fp) : "./hrtfs/elev75/L75e190a.dat" +[ 33, 35 ] = ascii (fp) : "./hrtfs/elev75/L75e185a.dat" +[ 33, 36 ] = ascii (fp) : "./hrtfs/elev75/L75e180a.dat" +[ 33, 37 ] = ascii (fp) : "./hrtfs/elev75/L75e175a.dat" +[ 33, 38 ] = ascii (fp) : "./hrtfs/elev75/L75e170a.dat" +[ 33, 39 ] = ascii (fp) : "./hrtfs/elev75/L75e165a.dat" +[ 33, 40 ] = ascii (fp) : "./hrtfs/elev75/L75e160a.dat" +[ 33, 41 ] = ascii (fp) : "./hrtfs/elev75/L75e155a.dat" +[ 33, 42 ] = ascii (fp) : "./hrtfs/elev75/L75e150a.dat" +[ 33, 43 ] = ascii (fp) : "./hrtfs/elev75/L75e145a.dat" +[ 33, 44 ] = ascii (fp) : "./hrtfs/elev75/L75e140a.dat" +[ 33, 45 ] = ascii (fp) : "./hrtfs/elev75/L75e135a.dat" +[ 33, 46 ] = ascii (fp) : "./hrtfs/elev75/L75e130a.dat" +[ 33, 47 ] = ascii (fp) : "./hrtfs/elev75/L75e125a.dat" +[ 33, 48 ] = ascii (fp) : "./hrtfs/elev75/L75e120a.dat" +[ 33, 49 ] = ascii (fp) : "./hrtfs/elev75/L75e115a.dat" +[ 33, 50 ] = ascii (fp) : "./hrtfs/elev75/L75e110a.dat" +[ 33, 51 ] = ascii (fp) : "./hrtfs/elev75/L75e105a.dat" +[ 33, 52 ] = ascii (fp) : "./hrtfs/elev75/L75e100a.dat" +[ 33, 53 ] = ascii (fp) : "./hrtfs/elev75/L75e095a.dat" +[ 33, 54 ] = ascii (fp) : "./hrtfs/elev75/L75e090a.dat" +[ 33, 55 ] = ascii (fp) : "./hrtfs/elev75/L75e085a.dat" +[ 33, 56 ] = ascii (fp) : "./hrtfs/elev75/L75e080a.dat" +[ 33, 57 ] = ascii (fp) : "./hrtfs/elev75/L75e075a.dat" +[ 33, 58 ] = ascii (fp) : "./hrtfs/elev75/L75e070a.dat" +[ 33, 59 ] = ascii (fp) : "./hrtfs/elev75/L75e065a.dat" +[ 33, 60 ] = ascii (fp) : "./hrtfs/elev75/L75e060a.dat" +[ 33, 61 ] = ascii (fp) : "./hrtfs/elev75/L75e055a.dat" +[ 33, 62 ] = ascii (fp) : "./hrtfs/elev75/L75e050a.dat" +[ 33, 63 ] = ascii (fp) : "./hrtfs/elev75/L75e045a.dat" +[ 33, 64 ] = ascii (fp) : "./hrtfs/elev75/L75e040a.dat" +[ 33, 65 ] = ascii (fp) : "./hrtfs/elev75/L75e035a.dat" +[ 33, 66 ] = ascii (fp) : "./hrtfs/elev75/L75e030a.dat" +[ 33, 67 ] = ascii (fp) : "./hrtfs/elev75/L75e025a.dat" +[ 33, 68 ] = ascii (fp) : "./hrtfs/elev75/L75e020a.dat" +[ 33, 69 ] = ascii (fp) : "./hrtfs/elev75/L75e015a.dat" +[ 33, 70 ] = ascii (fp) : "./hrtfs/elev75/L75e010a.dat" +[ 33, 71 ] = ascii (fp) : "./hrtfs/elev75/L75e005a.dat" + +[ 34, 0 ] = ascii (fp) : "./hrtfs/elev80/L80e000a.dat" +[ 34, 1 ] = ascii (fp) : "./hrtfs/elev80/L80e355a.dat" +[ 34, 2 ] = ascii (fp) : "./hrtfs/elev80/L80e350a.dat" +[ 34, 3 ] = ascii (fp) : "./hrtfs/elev80/L80e345a.dat" +[ 34, 4 ] = ascii (fp) : "./hrtfs/elev80/L80e340a.dat" +[ 34, 5 ] = ascii (fp) : "./hrtfs/elev80/L80e335a.dat" +[ 34, 6 ] = ascii (fp) : "./hrtfs/elev80/L80e330a.dat" +[ 34, 7 ] = ascii (fp) : "./hrtfs/elev80/L80e325a.dat" +[ 34, 8 ] = ascii (fp) : "./hrtfs/elev80/L80e320a.dat" +[ 34, 9 ] = ascii (fp) : "./hrtfs/elev80/L80e315a.dat" +[ 34, 10 ] = ascii (fp) : "./hrtfs/elev80/L80e310a.dat" +[ 34, 11 ] = ascii (fp) : "./hrtfs/elev80/L80e305a.dat" +[ 34, 12 ] = ascii (fp) : "./hrtfs/elev80/L80e300a.dat" +[ 34, 13 ] = ascii (fp) : "./hrtfs/elev80/L80e295a.dat" +[ 34, 14 ] = ascii (fp) : "./hrtfs/elev80/L80e290a.dat" +[ 34, 15 ] = ascii (fp) : "./hrtfs/elev80/L80e285a.dat" +[ 34, 16 ] = ascii (fp) : "./hrtfs/elev80/L80e280a.dat" +[ 34, 17 ] = ascii (fp) : "./hrtfs/elev80/L80e275a.dat" +[ 34, 18 ] = ascii (fp) : "./hrtfs/elev80/L80e270a.dat" +[ 34, 19 ] = ascii (fp) : "./hrtfs/elev80/L80e265a.dat" +[ 34, 20 ] = ascii (fp) : "./hrtfs/elev80/L80e260a.dat" +[ 34, 21 ] = ascii (fp) : "./hrtfs/elev80/L80e255a.dat" +[ 34, 22 ] = ascii (fp) : "./hrtfs/elev80/L80e250a.dat" +[ 34, 23 ] = ascii (fp) : "./hrtfs/elev80/L80e245a.dat" +[ 34, 24 ] = ascii (fp) : "./hrtfs/elev80/L80e240a.dat" +[ 34, 25 ] = ascii (fp) : "./hrtfs/elev80/L80e235a.dat" +[ 34, 26 ] = ascii (fp) : "./hrtfs/elev80/L80e230a.dat" +[ 34, 27 ] = ascii (fp) : "./hrtfs/elev80/L80e225a.dat" +[ 34, 28 ] = ascii (fp) : "./hrtfs/elev80/L80e220a.dat" +[ 34, 29 ] = ascii (fp) : "./hrtfs/elev80/L80e215a.dat" +[ 34, 30 ] = ascii (fp) : "./hrtfs/elev80/L80e210a.dat" +[ 34, 31 ] = ascii (fp) : "./hrtfs/elev80/L80e205a.dat" +[ 34, 32 ] = ascii (fp) : "./hrtfs/elev80/L80e200a.dat" +[ 34, 33 ] = ascii (fp) : "./hrtfs/elev80/L80e195a.dat" +[ 34, 34 ] = ascii (fp) : "./hrtfs/elev80/L80e190a.dat" +[ 34, 35 ] = ascii (fp) : "./hrtfs/elev80/L80e185a.dat" +[ 34, 36 ] = ascii (fp) : "./hrtfs/elev80/L80e180a.dat" +[ 34, 37 ] = ascii (fp) : "./hrtfs/elev80/L80e175a.dat" +[ 34, 38 ] = ascii (fp) : "./hrtfs/elev80/L80e170a.dat" +[ 34, 39 ] = ascii (fp) : "./hrtfs/elev80/L80e165a.dat" +[ 34, 40 ] = ascii (fp) : "./hrtfs/elev80/L80e160a.dat" +[ 34, 41 ] = ascii (fp) : "./hrtfs/elev80/L80e155a.dat" +[ 34, 42 ] = ascii (fp) : "./hrtfs/elev80/L80e150a.dat" +[ 34, 43 ] = ascii (fp) : "./hrtfs/elev80/L80e145a.dat" +[ 34, 44 ] = ascii (fp) : "./hrtfs/elev80/L80e140a.dat" +[ 34, 45 ] = ascii (fp) : "./hrtfs/elev80/L80e135a.dat" +[ 34, 46 ] = ascii (fp) : "./hrtfs/elev80/L80e130a.dat" +[ 34, 47 ] = ascii (fp) : "./hrtfs/elev80/L80e125a.dat" +[ 34, 48 ] = ascii (fp) : "./hrtfs/elev80/L80e120a.dat" +[ 34, 49 ] = ascii (fp) : "./hrtfs/elev80/L80e115a.dat" +[ 34, 50 ] = ascii (fp) : "./hrtfs/elev80/L80e110a.dat" +[ 34, 51 ] = ascii (fp) : "./hrtfs/elev80/L80e105a.dat" +[ 34, 52 ] = ascii (fp) : "./hrtfs/elev80/L80e100a.dat" +[ 34, 53 ] = ascii (fp) : "./hrtfs/elev80/L80e095a.dat" +[ 34, 54 ] = ascii (fp) : "./hrtfs/elev80/L80e090a.dat" +[ 34, 55 ] = ascii (fp) : "./hrtfs/elev80/L80e085a.dat" +[ 34, 56 ] = ascii (fp) : "./hrtfs/elev80/L80e080a.dat" +[ 34, 57 ] = ascii (fp) : "./hrtfs/elev80/L80e075a.dat" +[ 34, 58 ] = ascii (fp) : "./hrtfs/elev80/L80e070a.dat" +[ 34, 59 ] = ascii (fp) : "./hrtfs/elev80/L80e065a.dat" +[ 34, 60 ] = ascii (fp) : "./hrtfs/elev80/L80e060a.dat" +[ 34, 61 ] = ascii (fp) : "./hrtfs/elev80/L80e055a.dat" +[ 34, 62 ] = ascii (fp) : "./hrtfs/elev80/L80e050a.dat" +[ 34, 63 ] = ascii (fp) : "./hrtfs/elev80/L80e045a.dat" +[ 34, 64 ] = ascii (fp) : "./hrtfs/elev80/L80e040a.dat" +[ 34, 65 ] = ascii (fp) : "./hrtfs/elev80/L80e035a.dat" +[ 34, 66 ] = ascii (fp) : "./hrtfs/elev80/L80e030a.dat" +[ 34, 67 ] = ascii (fp) : "./hrtfs/elev80/L80e025a.dat" +[ 34, 68 ] = ascii (fp) : "./hrtfs/elev80/L80e020a.dat" +[ 34, 69 ] = ascii (fp) : "./hrtfs/elev80/L80e015a.dat" +[ 34, 70 ] = ascii (fp) : "./hrtfs/elev80/L80e010a.dat" +[ 34, 71 ] = ascii (fp) : "./hrtfs/elev80/L80e005a.dat" + +[ 35, 0 ] = ascii (fp) : "./hrtfs/elev85/L85e000a.dat" +[ 35, 1 ] = ascii (fp) : "./hrtfs/elev85/L85e355a.dat" +[ 35, 2 ] = ascii (fp) : "./hrtfs/elev85/L85e350a.dat" +[ 35, 3 ] = ascii (fp) : "./hrtfs/elev85/L85e345a.dat" +[ 35, 4 ] = ascii (fp) : "./hrtfs/elev85/L85e340a.dat" +[ 35, 5 ] = ascii (fp) : "./hrtfs/elev85/L85e335a.dat" +[ 35, 6 ] = ascii (fp) : "./hrtfs/elev85/L85e330a.dat" +[ 35, 7 ] = ascii (fp) : "./hrtfs/elev85/L85e325a.dat" +[ 35, 8 ] = ascii (fp) : "./hrtfs/elev85/L85e320a.dat" +[ 35, 9 ] = ascii (fp) : "./hrtfs/elev85/L85e315a.dat" +[ 35, 10 ] = ascii (fp) : "./hrtfs/elev85/L85e310a.dat" +[ 35, 11 ] = ascii (fp) : "./hrtfs/elev85/L85e305a.dat" +[ 35, 12 ] = ascii (fp) : "./hrtfs/elev85/L85e300a.dat" +[ 35, 13 ] = ascii (fp) : "./hrtfs/elev85/L85e295a.dat" +[ 35, 14 ] = ascii (fp) : "./hrtfs/elev85/L85e290a.dat" +[ 35, 15 ] = ascii (fp) : "./hrtfs/elev85/L85e285a.dat" +[ 35, 16 ] = ascii (fp) : "./hrtfs/elev85/L85e280a.dat" +[ 35, 17 ] = ascii (fp) : "./hrtfs/elev85/L85e275a.dat" +[ 35, 18 ] = ascii (fp) : "./hrtfs/elev85/L85e270a.dat" +[ 35, 19 ] = ascii (fp) : "./hrtfs/elev85/L85e265a.dat" +[ 35, 20 ] = ascii (fp) : "./hrtfs/elev85/L85e260a.dat" +[ 35, 21 ] = ascii (fp) : "./hrtfs/elev85/L85e255a.dat" +[ 35, 22 ] = ascii (fp) : "./hrtfs/elev85/L85e250a.dat" +[ 35, 23 ] = ascii (fp) : "./hrtfs/elev85/L85e245a.dat" +[ 35, 24 ] = ascii (fp) : "./hrtfs/elev85/L85e240a.dat" +[ 35, 25 ] = ascii (fp) : "./hrtfs/elev85/L85e235a.dat" +[ 35, 26 ] = ascii (fp) : "./hrtfs/elev85/L85e230a.dat" +[ 35, 27 ] = ascii (fp) : "./hrtfs/elev85/L85e225a.dat" +[ 35, 28 ] = ascii (fp) : "./hrtfs/elev85/L85e220a.dat" +[ 35, 29 ] = ascii (fp) : "./hrtfs/elev85/L85e215a.dat" +[ 35, 30 ] = ascii (fp) : "./hrtfs/elev85/L85e210a.dat" +[ 35, 31 ] = ascii (fp) : "./hrtfs/elev85/L85e205a.dat" +[ 35, 32 ] = ascii (fp) : "./hrtfs/elev85/L85e200a.dat" +[ 35, 33 ] = ascii (fp) : "./hrtfs/elev85/L85e195a.dat" +[ 35, 34 ] = ascii (fp) : "./hrtfs/elev85/L85e190a.dat" +[ 35, 35 ] = ascii (fp) : "./hrtfs/elev85/L85e185a.dat" +[ 35, 36 ] = ascii (fp) : "./hrtfs/elev85/L85e180a.dat" +[ 35, 37 ] = ascii (fp) : "./hrtfs/elev85/L85e175a.dat" +[ 35, 38 ] = ascii (fp) : "./hrtfs/elev85/L85e170a.dat" +[ 35, 39 ] = ascii (fp) : "./hrtfs/elev85/L85e165a.dat" +[ 35, 40 ] = ascii (fp) : "./hrtfs/elev85/L85e160a.dat" +[ 35, 41 ] = ascii (fp) : "./hrtfs/elev85/L85e155a.dat" +[ 35, 42 ] = ascii (fp) : "./hrtfs/elev85/L85e150a.dat" +[ 35, 43 ] = ascii (fp) : "./hrtfs/elev85/L85e145a.dat" +[ 35, 44 ] = ascii (fp) : "./hrtfs/elev85/L85e140a.dat" +[ 35, 45 ] = ascii (fp) : "./hrtfs/elev85/L85e135a.dat" +[ 35, 46 ] = ascii (fp) : "./hrtfs/elev85/L85e130a.dat" +[ 35, 47 ] = ascii (fp) : "./hrtfs/elev85/L85e125a.dat" +[ 35, 48 ] = ascii (fp) : "./hrtfs/elev85/L85e120a.dat" +[ 35, 49 ] = ascii (fp) : "./hrtfs/elev85/L85e115a.dat" +[ 35, 50 ] = ascii (fp) : "./hrtfs/elev85/L85e110a.dat" +[ 35, 51 ] = ascii (fp) : "./hrtfs/elev85/L85e105a.dat" +[ 35, 52 ] = ascii (fp) : "./hrtfs/elev85/L85e100a.dat" +[ 35, 53 ] = ascii (fp) : "./hrtfs/elev85/L85e095a.dat" +[ 35, 54 ] = ascii (fp) : "./hrtfs/elev85/L85e090a.dat" +[ 35, 55 ] = ascii (fp) : "./hrtfs/elev85/L85e085a.dat" +[ 35, 56 ] = ascii (fp) : "./hrtfs/elev85/L85e080a.dat" +[ 35, 57 ] = ascii (fp) : "./hrtfs/elev85/L85e075a.dat" +[ 35, 58 ] = ascii (fp) : "./hrtfs/elev85/L85e070a.dat" +[ 35, 59 ] = ascii (fp) : "./hrtfs/elev85/L85e065a.dat" +[ 35, 60 ] = ascii (fp) : "./hrtfs/elev85/L85e060a.dat" +[ 35, 61 ] = ascii (fp) : "./hrtfs/elev85/L85e055a.dat" +[ 35, 62 ] = ascii (fp) : "./hrtfs/elev85/L85e050a.dat" +[ 35, 63 ] = ascii (fp) : "./hrtfs/elev85/L85e045a.dat" +[ 35, 64 ] = ascii (fp) : "./hrtfs/elev85/L85e040a.dat" +[ 35, 65 ] = ascii (fp) : "./hrtfs/elev85/L85e035a.dat" +[ 35, 66 ] = ascii (fp) : "./hrtfs/elev85/L85e030a.dat" +[ 35, 67 ] = ascii (fp) : "./hrtfs/elev85/L85e025a.dat" +[ 35, 68 ] = ascii (fp) : "./hrtfs/elev85/L85e020a.dat" +[ 35, 69 ] = ascii (fp) : "./hrtfs/elev85/L85e015a.dat" +[ 35, 70 ] = ascii (fp) : "./hrtfs/elev85/L85e010a.dat" +[ 35, 71 ] = ascii (fp) : "./hrtfs/elev85/L85e005a.dat" + +[ 36, 0 ] = ascii (fp) : "./hrtfs/elev90/L90e000a.dat" + + diff --git a/jni/openal-soft-android/utils/IRC_1005.def b/jni/openal-soft-android/utils/IRC_1005.def new file mode 100644 index 00000000..f5a16934 --- /dev/null +++ b/jni/openal-soft-android/utils/IRC_1005.def @@ -0,0 +1,421 @@ +# This is a makehrtf HRIR definition file. It is used to define the layout +# and source data to be processed into an OpenAL Soft compatible HRTF. +# +# This definition is used to transform an average of the left and right ear +# HRIRs from any raw data set from the IRCAM/AKG Listen HRTF database. +# +# The data sets are available free of charge from: +# +# http://recherche.ircam.fr/equipes/salles/listen/index.html +# +# Contact for the Listen HRTF Database: +# +# Olivier Warusfel , +# Room Acoustics Team, IRCAM +# 1, place Igor Stravinsky +# 75004 PARIS, France + +rate = 44100 + +# The raw sets have up to 8192 samples, but 2048 seems large enough. +points = 2048 + +# The IRCAM sets are not as dense as the MIT set. +azimuths = 1, 6, 12, 24, 24, 24, 24, 24, 24, 24, 12, 6, 1 + +# No head radius was provided. Just use the average radius of 9 cm. +radius = 0.09 + +# The distance between the source and the listener (in meters). +distance = 1.95 + +# The IRCAM source azimuth is counter-clockwise, so it needs to be flipped. +# Left and right ear HRIRs (from the respective WAVE channels) are averaged. + +# Replace all occurrences of IRC_#### for the desired subject (1005 was used +# in this demonstration). + +[ 3, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav" +[ 3, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav" +[ 3, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav" +[ 3, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav" +[ 3, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav" +[ 3, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav" +[ 3, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav" +[ 3, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav" +[ 3, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav" +[ 3, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav" +[ 3, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav" +[ 3, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav" +[ 3, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav" +[ 3, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav" +[ 3, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav" +[ 3, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav" +[ 3, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav" +[ 3, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav" +[ 3, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav" +[ 3, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav" +[ 3, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav" +[ 3, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav" +[ 3, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav" +[ 3, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav" + +[ 4, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav" +[ 4, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav" +[ 4, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav" +[ 4, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav" +[ 4, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav" +[ 4, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav" +[ 4, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav" +[ 4, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav" +[ 4, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav" +[ 4, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav" +[ 4, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav" +[ 4, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav" +[ 4, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav" +[ 4, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav" +[ 4, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav" +[ 4, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav" +[ 4, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav" +[ 4, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav" +[ 4, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav" +[ 4, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav" +[ 4, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav" +[ 4, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav" +[ 4, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav" +[ 4, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav" + +[ 5, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav" +[ 5, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav" +[ 5, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav" +[ 5, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav" +[ 5, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav" +[ 5, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav" +[ 5, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav" +[ 5, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav" +[ 5, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav" +[ 5, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav" +[ 5, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav" +[ 5, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav" +[ 5, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav" +[ 5, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav" +[ 5, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav" +[ 5, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav" +[ 5, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav" +[ 5, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav" +[ 5, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav" +[ 5, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav" +[ 5, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav" +[ 5, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav" +[ 5, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav" +[ 5, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav" + +[ 6, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav" +[ 6, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav" +[ 6, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav" +[ 6, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav" +[ 6, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav" +[ 6, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav" +[ 6, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav" +[ 6, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav" +[ 6, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav" +[ 6, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav" +[ 6, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav" +[ 6, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav" +[ 6, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav" +[ 6, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav" +[ 6, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav" +[ 6, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav" +[ 6, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav" +[ 6, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav" +[ 6, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav" +[ 6, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav" +[ 6, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav" +[ 6, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav" +[ 6, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav" +[ 6, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav" + +[ 7, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav" +[ 7, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav" +[ 7, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav" +[ 7, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav" +[ 7, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav" +[ 7, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav" +[ 7, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav" +[ 7, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav" +[ 7, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav" +[ 7, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav" +[ 7, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav" +[ 7, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav" +[ 7, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav" +[ 7, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav" +[ 7, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav" +[ 7, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav" +[ 7, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav" +[ 7, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav" +[ 7, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav" +[ 7, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav" +[ 7, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav" +[ 7, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav" +[ 7, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav" +[ 7, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav" + +[ 8, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav" +[ 8, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav" +[ 8, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav" +[ 8, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav" +[ 8, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav" +[ 8, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav" +[ 8, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav" +[ 8, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav" +[ 8, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav" +[ 8, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav" +[ 8, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav" +[ 8, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav" +[ 8, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav" +[ 8, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav" +[ 8, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav" +[ 8, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav" +[ 8, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav" +[ 8, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav" +[ 8, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav" +[ 8, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav" +[ 8, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav" +[ 8, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav" +[ 8, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav" +[ 8, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav" + +[ 9, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav" +[ 9, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav" +[ 9, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav" +[ 9, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav" +[ 9, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav" +[ 9, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav" +[ 9, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav" +[ 9, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav" +[ 9, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav" +[ 9, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav" +[ 9, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav" +[ 9, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav" +[ 9, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav" +[ 9, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav" +[ 9, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav" +[ 9, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav" +[ 9, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav" +[ 9, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav" +[ 9, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav" +[ 9, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav" +[ 9, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav" +[ 9, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav" +[ 9, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav" +[ 9, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav" + +[ 10, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav" +[ 10, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav" +[ 10, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav" +[ 10, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav" +[ 10, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav" +[ 10, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav" +[ 10, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav" +[ 10, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav" +[ 10, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav" +[ 10, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav" +[ 10, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav" +[ 10, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav" + +[ 11, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav" +[ 11, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav" +[ 11, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav" +[ 11, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav" +[ 11, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav" +[ 11, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav" + +[ 12, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav" + + wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav" + diff --git a/jni/openal-soft-android/utils/MIT_KEMAR.def b/jni/openal-soft-android/utils/MIT_KEMAR.def new file mode 100644 index 00000000..1067e0b4 --- /dev/null +++ b/jni/openal-soft-android/utils/MIT_KEMAR.def @@ -0,0 +1,823 @@ +# This is a makehrtf HRIR definition file. It is used to define the layout +# and source data to be processed into an OpenAL Soft compatible HRTF. +# +# This definition is used to transform the left ear HRIRs from the full set +# of KEMAR HRIRs provided by Bill Gardner and Keith +# Martin of MIT Media Laboratory. +# +# The data (full.zip) is available from: +# +# http://sound.media.mit.edu/resources/KEMAR.html +# +# It is copyrighted 1994 by MIT Media Laboratory, and provided free of charge +# with no restrictions on use so long as the authors (above) are cited. +# +# This definition is used to generate the internal HRTF table used by OpenAL +# Soft. + +# The following are the data set metrics. They must always be specified at +# start of a definition file, but their order is not important. + +# Sampling rate of the HRIR data (in hertz). +rate = 44100 + +# The number of points to use from the HRIR data. This should be a +# sufficiently large value (to encompass the entire impulse response). It +# cannot be smaller than the truncation size (default is 32) specified on the +# command line. +points = 512 + +# A list of the number of azimuths measured for each elevation. There must +# be at least 5 elevations covering the 180 degrees for the data set to be +# viable. +azimuths = 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1 + +# The radius of the listener's head (measured ear-to-ear in meters). The +# makehrtf utility uses this value to rescale measured propagation delays +# when a custom head radius is specified on the command line. It is also +# used as the default radius when the spherical model is used to calculate an +# approximate set of delays. This should match the data set as close as +# possible for accurate rescaling when using the measured delays (the +# default). At the moment, radius rescaling does not adjust HRIR coupling. +radius = 0.09 + +# The distance between the source and the listener (in meters). This does +# have to match the data set, but it's effect is minimal at the moment due to +# the coupled nature of OpenAL Soft's HRTF model. +distance = 1.4 + +# Following the metrics is the list of source HRIRs for each elevation and +# azimuth pair. They don't have to be specified in order, but the final +# composition must not be sparse. They can however begin above a number of +# elevations (as typical for HRIR measurements). +# +# The elevation and azimuth indices are used to determine the resulting polar +# coordinates following OpenAL Soft's convention (-90 degree elevation +# increasing counter-clockwise from the bottom; 0 degree azimuth increasing +# clockwise from the front). +# +# More than one HRIR can be used per source, in which case the average +# magnitude response of all references for that source is used. +# +# Source specification is of the form (~BNF): +# +# source = '[' ev_index ',' az_index ']' '=' source_ref [ '+' source_ref ]* +# +# ev_index = unsigned_integer +# az_index = unsigned_integer +# source_ref = ref_spec ':' filename +# +# ref_spec = ( wave_fmt '(' wave_parms ')' [ '@' start_sample ] ) | +# ( bin_fmt '(' bini_parms ')' [ '@' start_bytes ] ) | +# ( bin_fmt '(' binf_parms ')' [ '@' start_bytes ] ) | +# ( ascii_fmt '(' asci_parms ')' [ '@' start_elements ] ) | +# ( ascii_fmt '(' ascf_parms ')' [ '@' start_elements ] ) +# filename = double_quoted_string +# +# wave_fmt = 'wave' +# wave_parms = channel +# bin_fmt = 'bin_le' | 'bin_be' +# bini_parms = 'int' ',' byte_size [ ',' bin_sig_bits ] [ ';' skip_bytes ] +# binf_parms = 'fp' ',' byte_size [ ';' skip_bytes ] +# ascii_fmt = 'ascii' +# asci_parms = 'int' ',' sig_bits [ ';' skip_elements ] +# ascf_parms = 'fp' [ ';' skip_elements ] +# start_sample = unsigned_integer +# start_bytes = unsigned_integer +# start_elements = unsigned_integer +# +# channel = unsigned_integer +# byte_size = unsigned_integer +# bin_sig_bits = signed_integer +# skip_bytes = unsigned_integer +# sig_bits = unsigned_integer +# skip_elements = unsigned_integer +# +# For bin_sig_bits, positive values mean the significant bits start at the +# MSB (padding toward the LSB) while negative values mean they start at the +# LSB. + +[ 5, 0 ] = wave (0) : "./MITfull/elev-40/L-40e000a.wav" +[ 5, 1 ] = wave (0) : "./MITfull/elev-40/L-40e006a.wav" +[ 5, 2 ] = wave (0) : "./MITfull/elev-40/L-40e013a.wav" +[ 5, 3 ] = wave (0) : "./MITfull/elev-40/L-40e019a.wav" +[ 5, 4 ] = wave (0) : "./MITfull/elev-40/L-40e026a.wav" +[ 5, 5 ] = wave (0) : "./MITfull/elev-40/L-40e032a.wav" +[ 5, 6 ] = wave (0) : "./MITfull/elev-40/L-40e039a.wav" +[ 5, 7 ] = wave (0) : "./MITfull/elev-40/L-40e045a.wav" +[ 5, 8 ] = wave (0) : "./MITfull/elev-40/L-40e051a.wav" +[ 5, 9 ] = wave (0) : "./MITfull/elev-40/L-40e058a.wav" +[ 5, 10 ] = wave (0) : "./MITfull/elev-40/L-40e064a.wav" +[ 5, 11 ] = wave (0) : "./MITfull/elev-40/L-40e071a.wav" +[ 5, 12 ] = wave (0) : "./MITfull/elev-40/L-40e077a.wav" +[ 5, 13 ] = wave (0) : "./MITfull/elev-40/L-40e084a.wav" +[ 5, 14 ] = wave (0) : "./MITfull/elev-40/L-40e090a.wav" +[ 5, 15 ] = wave (0) : "./MITfull/elev-40/L-40e096a.wav" +[ 5, 16 ] = wave (0) : "./MITfull/elev-40/L-40e103a.wav" +[ 5, 17 ] = wave (0) : "./MITfull/elev-40/L-40e109a.wav" +[ 5, 18 ] = wave (0) : "./MITfull/elev-40/L-40e116a.wav" +[ 5, 19 ] = wave (0) : "./MITfull/elev-40/L-40e122a.wav" +[ 5, 20 ] = wave (0) : "./MITfull/elev-40/L-40e129a.wav" +[ 5, 21 ] = wave (0) : "./MITfull/elev-40/L-40e135a.wav" +[ 5, 22 ] = wave (0) : "./MITfull/elev-40/L-40e141a.wav" +[ 5, 23 ] = wave (0) : "./MITfull/elev-40/L-40e148a.wav" +[ 5, 24 ] = wave (0) : "./MITfull/elev-40/L-40e154a.wav" +[ 5, 25 ] = wave (0) : "./MITfull/elev-40/L-40e161a.wav" +[ 5, 26 ] = wave (0) : "./MITfull/elev-40/L-40e167a.wav" +[ 5, 27 ] = wave (0) : "./MITfull/elev-40/L-40e174a.wav" +[ 5, 28 ] = wave (0) : "./MITfull/elev-40/L-40e180a.wav" +[ 5, 29 ] = wave (0) : "./MITfull/elev-40/L-40e186a.wav" +[ 5, 30 ] = wave (0) : "./MITfull/elev-40/L-40e193a.wav" +[ 5, 31 ] = wave (0) : "./MITfull/elev-40/L-40e199a.wav" +[ 5, 32 ] = wave (0) : "./MITfull/elev-40/L-40e206a.wav" +[ 5, 33 ] = wave (0) : "./MITfull/elev-40/L-40e212a.wav" +[ 5, 34 ] = wave (0) : "./MITfull/elev-40/L-40e219a.wav" +[ 5, 35 ] = wave (0) : "./MITfull/elev-40/L-40e225a.wav" +[ 5, 36 ] = wave (0) : "./MITfull/elev-40/L-40e231a.wav" +[ 5, 37 ] = wave (0) : "./MITfull/elev-40/L-40e238a.wav" +[ 5, 38 ] = wave (0) : "./MITfull/elev-40/L-40e244a.wav" +[ 5, 39 ] = wave (0) : "./MITfull/elev-40/L-40e251a.wav" +[ 5, 40 ] = wave (0) : "./MITfull/elev-40/L-40e257a.wav" +[ 5, 41 ] = wave (0) : "./MITfull/elev-40/L-40e264a.wav" +[ 5, 42 ] = wave (0) : "./MITfull/elev-40/L-40e270a.wav" +[ 5, 43 ] = wave (0) : "./MITfull/elev-40/L-40e276a.wav" +[ 5, 44 ] = wave (0) : "./MITfull/elev-40/L-40e283a.wav" +[ 5, 45 ] = wave (0) : "./MITfull/elev-40/L-40e289a.wav" +[ 5, 46 ] = wave (0) : "./MITfull/elev-40/L-40e296a.wav" +[ 5, 47 ] = wave (0) : "./MITfull/elev-40/L-40e302a.wav" +[ 5, 48 ] = wave (0) : "./MITfull/elev-40/L-40e309a.wav" +[ 5, 49 ] = wave (0) : "./MITfull/elev-40/L-40e315a.wav" +[ 5, 50 ] = wave (0) : "./MITfull/elev-40/L-40e321a.wav" +[ 5, 51 ] = wave (0) : "./MITfull/elev-40/L-40e328a.wav" +[ 5, 52 ] = wave (0) : "./MITfull/elev-40/L-40e334a.wav" +[ 5, 53 ] = wave (0) : "./MITfull/elev-40/L-40e341a.wav" +[ 5, 54 ] = wave (0) : "./MITfull/elev-40/L-40e347a.wav" +[ 5, 55 ] = wave (0) : "./MITfull/elev-40/L-40e354a.wav" + +[ 6, 0 ] = wave (0) : "./MITfull/elev-30/L-30e000a.wav" +[ 6, 1 ] = wave (0) : "./MITfull/elev-30/L-30e006a.wav" +[ 6, 2 ] = wave (0) : "./MITfull/elev-30/L-30e012a.wav" +[ 6, 3 ] = wave (0) : "./MITfull/elev-30/L-30e018a.wav" +[ 6, 4 ] = wave (0) : "./MITfull/elev-30/L-30e024a.wav" +[ 6, 5 ] = wave (0) : "./MITfull/elev-30/L-30e030a.wav" +[ 6, 6 ] = wave (0) : "./MITfull/elev-30/L-30e036a.wav" +[ 6, 7 ] = wave (0) : "./MITfull/elev-30/L-30e042a.wav" +[ 6, 8 ] = wave (0) : "./MITfull/elev-30/L-30e048a.wav" +[ 6, 9 ] = wave (0) : "./MITfull/elev-30/L-30e054a.wav" +[ 6, 10 ] = wave (0) : "./MITfull/elev-30/L-30e060a.wav" +[ 6, 11 ] = wave (0) : "./MITfull/elev-30/L-30e066a.wav" +[ 6, 12 ] = wave (0) : "./MITfull/elev-30/L-30e072a.wav" +[ 6, 13 ] = wave (0) : "./MITfull/elev-30/L-30e078a.wav" +[ 6, 14 ] = wave (0) : "./MITfull/elev-30/L-30e084a.wav" +[ 6, 15 ] = wave (0) : "./MITfull/elev-30/L-30e090a.wav" +[ 6, 16 ] = wave (0) : "./MITfull/elev-30/L-30e096a.wav" +[ 6, 17 ] = wave (0) : "./MITfull/elev-30/L-30e102a.wav" +[ 6, 18 ] = wave (0) : "./MITfull/elev-30/L-30e108a.wav" +[ 6, 19 ] = wave (0) : "./MITfull/elev-30/L-30e114a.wav" +[ 6, 20 ] = wave (0) : "./MITfull/elev-30/L-30e120a.wav" +[ 6, 21 ] = wave (0) : "./MITfull/elev-30/L-30e126a.wav" +[ 6, 22 ] = wave (0) : "./MITfull/elev-30/L-30e132a.wav" +[ 6, 23 ] = wave (0) : "./MITfull/elev-30/L-30e138a.wav" +[ 6, 24 ] = wave (0) : "./MITfull/elev-30/L-30e144a.wav" +[ 6, 25 ] = wave (0) : "./MITfull/elev-30/L-30e150a.wav" +[ 6, 26 ] = wave (0) : "./MITfull/elev-30/L-30e156a.wav" +[ 6, 27 ] = wave (0) : "./MITfull/elev-30/L-30e162a.wav" +[ 6, 28 ] = wave (0) : "./MITfull/elev-30/L-30e168a.wav" +[ 6, 29 ] = wave (0) : "./MITfull/elev-30/L-30e174a.wav" +[ 6, 30 ] = wave (0) : "./MITfull/elev-30/L-30e180a.wav" +[ 6, 31 ] = wave (0) : "./MITfull/elev-30/L-30e186a.wav" +[ 6, 32 ] = wave (0) : "./MITfull/elev-30/L-30e192a.wav" +[ 6, 33 ] = wave (0) : "./MITfull/elev-30/L-30e198a.wav" +[ 6, 34 ] = wave (0) : "./MITfull/elev-30/L-30e204a.wav" +[ 6, 35 ] = wave (0) : "./MITfull/elev-30/L-30e210a.wav" +[ 6, 36 ] = wave (0) : "./MITfull/elev-30/L-30e216a.wav" +[ 6, 37 ] = wave (0) : "./MITfull/elev-30/L-30e222a.wav" +[ 6, 38 ] = wave (0) : "./MITfull/elev-30/L-30e228a.wav" +[ 6, 39 ] = wave (0) : "./MITfull/elev-30/L-30e234a.wav" +[ 6, 40 ] = wave (0) : "./MITfull/elev-30/L-30e240a.wav" +[ 6, 41 ] = wave (0) : "./MITfull/elev-30/L-30e246a.wav" +[ 6, 42 ] = wave (0) : "./MITfull/elev-30/L-30e252a.wav" +[ 6, 43 ] = wave (0) : "./MITfull/elev-30/L-30e258a.wav" +[ 6, 44 ] = wave (0) : "./MITfull/elev-30/L-30e264a.wav" +[ 6, 45 ] = wave (0) : "./MITfull/elev-30/L-30e270a.wav" +[ 6, 46 ] = wave (0) : "./MITfull/elev-30/L-30e276a.wav" +[ 6, 47 ] = wave (0) : "./MITfull/elev-30/L-30e282a.wav" +[ 6, 48 ] = wave (0) : "./MITfull/elev-30/L-30e288a.wav" +[ 6, 49 ] = wave (0) : "./MITfull/elev-30/L-30e294a.wav" +[ 6, 50 ] = wave (0) : "./MITfull/elev-30/L-30e300a.wav" +[ 6, 51 ] = wave (0) : "./MITfull/elev-30/L-30e306a.wav" +[ 6, 52 ] = wave (0) : "./MITfull/elev-30/L-30e312a.wav" +[ 6, 53 ] = wave (0) : "./MITfull/elev-30/L-30e318a.wav" +[ 6, 54 ] = wave (0) : "./MITfull/elev-30/L-30e324a.wav" +[ 6, 55 ] = wave (0) : "./MITfull/elev-30/L-30e330a.wav" +[ 6, 56 ] = wave (0) : "./MITfull/elev-30/L-30e336a.wav" +[ 6, 57 ] = wave (0) : "./MITfull/elev-30/L-30e342a.wav" +[ 6, 58 ] = wave (0) : "./MITfull/elev-30/L-30e348a.wav" +[ 6, 59 ] = wave (0) : "./MITfull/elev-30/L-30e354a.wav" + +[ 7, 0 ] = wave (0) : "./MITfull/elev-20/L-20e000a.wav" +[ 7, 1 ] = wave (0) : "./MITfull/elev-20/L-20e005a.wav" +[ 7, 2 ] = wave (0) : "./MITfull/elev-20/L-20e010a.wav" +[ 7, 3 ] = wave (0) : "./MITfull/elev-20/L-20e015a.wav" +[ 7, 4 ] = wave (0) : "./MITfull/elev-20/L-20e020a.wav" +[ 7, 5 ] = wave (0) : "./MITfull/elev-20/L-20e025a.wav" +[ 7, 6 ] = wave (0) : "./MITfull/elev-20/L-20e030a.wav" +[ 7, 7 ] = wave (0) : "./MITfull/elev-20/L-20e035a.wav" +[ 7, 8 ] = wave (0) : "./MITfull/elev-20/L-20e040a.wav" +[ 7, 9 ] = wave (0) : "./MITfull/elev-20/L-20e045a.wav" +[ 7, 10 ] = wave (0) : "./MITfull/elev-20/L-20e050a.wav" +[ 7, 11 ] = wave (0) : "./MITfull/elev-20/L-20e055a.wav" +[ 7, 12 ] = wave (0) : "./MITfull/elev-20/L-20e060a.wav" +[ 7, 13 ] = wave (0) : "./MITfull/elev-20/L-20e065a.wav" +[ 7, 14 ] = wave (0) : "./MITfull/elev-20/L-20e070a.wav" +[ 7, 15 ] = wave (0) : "./MITfull/elev-20/L-20e075a.wav" +[ 7, 16 ] = wave (0) : "./MITfull/elev-20/L-20e080a.wav" +[ 7, 17 ] = wave (0) : "./MITfull/elev-20/L-20e085a.wav" +[ 7, 18 ] = wave (0) : "./MITfull/elev-20/L-20e090a.wav" +[ 7, 19 ] = wave (0) : "./MITfull/elev-20/L-20e095a.wav" +[ 7, 20 ] = wave (0) : "./MITfull/elev-20/L-20e100a.wav" +[ 7, 21 ] = wave (0) : "./MITfull/elev-20/L-20e105a.wav" +[ 7, 22 ] = wave (0) : "./MITfull/elev-20/L-20e110a.wav" +[ 7, 23 ] = wave (0) : "./MITfull/elev-20/L-20e115a.wav" +[ 7, 24 ] = wave (0) : "./MITfull/elev-20/L-20e120a.wav" +[ 7, 25 ] = wave (0) : "./MITfull/elev-20/L-20e125a.wav" +[ 7, 26 ] = wave (0) : "./MITfull/elev-20/L-20e130a.wav" +[ 7, 27 ] = wave (0) : "./MITfull/elev-20/L-20e135a.wav" +[ 7, 28 ] = wave (0) : "./MITfull/elev-20/L-20e140a.wav" +[ 7, 29 ] = wave (0) : "./MITfull/elev-20/L-20e145a.wav" +[ 7, 30 ] = wave (0) : "./MITfull/elev-20/L-20e150a.wav" +[ 7, 31 ] = wave (0) : "./MITfull/elev-20/L-20e155a.wav" +[ 7, 32 ] = wave (0) : "./MITfull/elev-20/L-20e160a.wav" +[ 7, 33 ] = wave (0) : "./MITfull/elev-20/L-20e165a.wav" +[ 7, 34 ] = wave (0) : "./MITfull/elev-20/L-20e170a.wav" +[ 7, 35 ] = wave (0) : "./MITfull/elev-20/L-20e175a.wav" +[ 7, 36 ] = wave (0) : "./MITfull/elev-20/L-20e180a.wav" +[ 7, 37 ] = wave (0) : "./MITfull/elev-20/L-20e185a.wav" +[ 7, 38 ] = wave (0) : "./MITfull/elev-20/L-20e190a.wav" +[ 7, 39 ] = wave (0) : "./MITfull/elev-20/L-20e195a.wav" +[ 7, 40 ] = wave (0) : "./MITfull/elev-20/L-20e200a.wav" +[ 7, 41 ] = wave (0) : "./MITfull/elev-20/L-20e205a.wav" +[ 7, 42 ] = wave (0) : "./MITfull/elev-20/L-20e210a.wav" +[ 7, 43 ] = wave (0) : "./MITfull/elev-20/L-20e215a.wav" +[ 7, 44 ] = wave (0) : "./MITfull/elev-20/L-20e220a.wav" +[ 7, 45 ] = wave (0) : "./MITfull/elev-20/L-20e225a.wav" +[ 7, 46 ] = wave (0) : "./MITfull/elev-20/L-20e230a.wav" +[ 7, 47 ] = wave (0) : "./MITfull/elev-20/L-20e235a.wav" +[ 7, 48 ] = wave (0) : "./MITfull/elev-20/L-20e240a.wav" +[ 7, 49 ] = wave (0) : "./MITfull/elev-20/L-20e245a.wav" +[ 7, 50 ] = wave (0) : "./MITfull/elev-20/L-20e250a.wav" +[ 7, 51 ] = wave (0) : "./MITfull/elev-20/L-20e255a.wav" +[ 7, 52 ] = wave (0) : "./MITfull/elev-20/L-20e260a.wav" +[ 7, 53 ] = wave (0) : "./MITfull/elev-20/L-20e265a.wav" +[ 7, 54 ] = wave (0) : "./MITfull/elev-20/L-20e270a.wav" +[ 7, 55 ] = wave (0) : "./MITfull/elev-20/L-20e275a.wav" +[ 7, 56 ] = wave (0) : "./MITfull/elev-20/L-20e280a.wav" +[ 7, 57 ] = wave (0) : "./MITfull/elev-20/L-20e285a.wav" +[ 7, 58 ] = wave (0) : "./MITfull/elev-20/L-20e290a.wav" +[ 7, 59 ] = wave (0) : "./MITfull/elev-20/L-20e295a.wav" +[ 7, 60 ] = wave (0) : "./MITfull/elev-20/L-20e300a.wav" +[ 7, 61 ] = wave (0) : "./MITfull/elev-20/L-20e305a.wav" +[ 7, 62 ] = wave (0) : "./MITfull/elev-20/L-20e310a.wav" +[ 7, 63 ] = wave (0) : "./MITfull/elev-20/L-20e315a.wav" +[ 7, 64 ] = wave (0) : "./MITfull/elev-20/L-20e320a.wav" +[ 7, 65 ] = wave (0) : "./MITfull/elev-20/L-20e325a.wav" +[ 7, 66 ] = wave (0) : "./MITfull/elev-20/L-20e330a.wav" +[ 7, 67 ] = wave (0) : "./MITfull/elev-20/L-20e335a.wav" +[ 7, 68 ] = wave (0) : "./MITfull/elev-20/L-20e340a.wav" +[ 7, 69 ] = wave (0) : "./MITfull/elev-20/L-20e345a.wav" +[ 7, 70 ] = wave (0) : "./MITfull/elev-20/L-20e350a.wav" +[ 7, 71 ] = wave (0) : "./MITfull/elev-20/L-20e355a.wav" + +[ 8, 0 ] = wave (0) : "./MITfull/elev-10/L-10e000a.wav" +[ 8, 1 ] = wave (0) : "./MITfull/elev-10/L-10e005a.wav" +[ 8, 2 ] = wave (0) : "./MITfull/elev-10/L-10e010a.wav" +[ 8, 3 ] = wave (0) : "./MITfull/elev-10/L-10e015a.wav" +[ 8, 4 ] = wave (0) : "./MITfull/elev-10/L-10e020a.wav" +[ 8, 5 ] = wave (0) : "./MITfull/elev-10/L-10e025a.wav" +[ 8, 6 ] = wave (0) : "./MITfull/elev-10/L-10e030a.wav" +[ 8, 7 ] = wave (0) : "./MITfull/elev-10/L-10e035a.wav" +[ 8, 8 ] = wave (0) : "./MITfull/elev-10/L-10e040a.wav" +[ 8, 9 ] = wave (0) : "./MITfull/elev-10/L-10e045a.wav" +[ 8, 10 ] = wave (0) : "./MITfull/elev-10/L-10e050a.wav" +[ 8, 11 ] = wave (0) : "./MITfull/elev-10/L-10e055a.wav" +[ 8, 12 ] = wave (0) : "./MITfull/elev-10/L-10e060a.wav" +[ 8, 13 ] = wave (0) : "./MITfull/elev-10/L-10e065a.wav" +[ 8, 14 ] = wave (0) : "./MITfull/elev-10/L-10e070a.wav" +[ 8, 15 ] = wave (0) : "./MITfull/elev-10/L-10e075a.wav" +[ 8, 16 ] = wave (0) : "./MITfull/elev-10/L-10e080a.wav" +[ 8, 17 ] = wave (0) : "./MITfull/elev-10/L-10e085a.wav" +[ 8, 18 ] = wave (0) : "./MITfull/elev-10/L-10e090a.wav" +[ 8, 19 ] = wave (0) : "./MITfull/elev-10/L-10e095a.wav" +[ 8, 20 ] = wave (0) : "./MITfull/elev-10/L-10e100a.wav" +[ 8, 21 ] = wave (0) : "./MITfull/elev-10/L-10e105a.wav" +[ 8, 22 ] = wave (0) : "./MITfull/elev-10/L-10e110a.wav" +[ 8, 23 ] = wave (0) : "./MITfull/elev-10/L-10e115a.wav" +[ 8, 24 ] = wave (0) : "./MITfull/elev-10/L-10e120a.wav" +[ 8, 25 ] = wave (0) : "./MITfull/elev-10/L-10e125a.wav" +[ 8, 26 ] = wave (0) : "./MITfull/elev-10/L-10e130a.wav" +[ 8, 27 ] = wave (0) : "./MITfull/elev-10/L-10e135a.wav" +[ 8, 28 ] = wave (0) : "./MITfull/elev-10/L-10e140a.wav" +[ 8, 29 ] = wave (0) : "./MITfull/elev-10/L-10e145a.wav" +[ 8, 30 ] = wave (0) : "./MITfull/elev-10/L-10e150a.wav" +[ 8, 31 ] = wave (0) : "./MITfull/elev-10/L-10e155a.wav" +[ 8, 32 ] = wave (0) : "./MITfull/elev-10/L-10e160a.wav" +[ 8, 33 ] = wave (0) : "./MITfull/elev-10/L-10e165a.wav" +[ 8, 34 ] = wave (0) : "./MITfull/elev-10/L-10e170a.wav" +[ 8, 35 ] = wave (0) : "./MITfull/elev-10/L-10e175a.wav" +[ 8, 36 ] = wave (0) : "./MITfull/elev-10/L-10e180a.wav" +[ 8, 37 ] = wave (0) : "./MITfull/elev-10/L-10e185a.wav" +[ 8, 38 ] = wave (0) : "./MITfull/elev-10/L-10e190a.wav" +[ 8, 39 ] = wave (0) : "./MITfull/elev-10/L-10e195a.wav" +[ 8, 40 ] = wave (0) : "./MITfull/elev-10/L-10e200a.wav" +[ 8, 41 ] = wave (0) : "./MITfull/elev-10/L-10e205a.wav" +[ 8, 42 ] = wave (0) : "./MITfull/elev-10/L-10e210a.wav" +[ 8, 43 ] = wave (0) : "./MITfull/elev-10/L-10e215a.wav" +[ 8, 44 ] = wave (0) : "./MITfull/elev-10/L-10e220a.wav" +[ 8, 45 ] = wave (0) : "./MITfull/elev-10/L-10e225a.wav" +[ 8, 46 ] = wave (0) : "./MITfull/elev-10/L-10e230a.wav" +[ 8, 47 ] = wave (0) : "./MITfull/elev-10/L-10e235a.wav" +[ 8, 48 ] = wave (0) : "./MITfull/elev-10/L-10e240a.wav" +[ 8, 49 ] = wave (0) : "./MITfull/elev-10/L-10e245a.wav" +[ 8, 50 ] = wave (0) : "./MITfull/elev-10/L-10e250a.wav" +[ 8, 51 ] = wave (0) : "./MITfull/elev-10/L-10e255a.wav" +[ 8, 52 ] = wave (0) : "./MITfull/elev-10/L-10e260a.wav" +[ 8, 53 ] = wave (0) : "./MITfull/elev-10/L-10e265a.wav" +[ 8, 54 ] = wave (0) : "./MITfull/elev-10/L-10e270a.wav" +[ 8, 55 ] = wave (0) : "./MITfull/elev-10/L-10e275a.wav" +[ 8, 56 ] = wave (0) : "./MITfull/elev-10/L-10e280a.wav" +[ 8, 57 ] = wave (0) : "./MITfull/elev-10/L-10e285a.wav" +[ 8, 58 ] = wave (0) : "./MITfull/elev-10/L-10e290a.wav" +[ 8, 59 ] = wave (0) : "./MITfull/elev-10/L-10e295a.wav" +[ 8, 60 ] = wave (0) : "./MITfull/elev-10/L-10e300a.wav" +[ 8, 61 ] = wave (0) : "./MITfull/elev-10/L-10e305a.wav" +[ 8, 62 ] = wave (0) : "./MITfull/elev-10/L-10e310a.wav" +[ 8, 63 ] = wave (0) : "./MITfull/elev-10/L-10e315a.wav" +[ 8, 64 ] = wave (0) : "./MITfull/elev-10/L-10e320a.wav" +[ 8, 65 ] = wave (0) : "./MITfull/elev-10/L-10e325a.wav" +[ 8, 66 ] = wave (0) : "./MITfull/elev-10/L-10e330a.wav" +[ 8, 67 ] = wave (0) : "./MITfull/elev-10/L-10e335a.wav" +[ 8, 68 ] = wave (0) : "./MITfull/elev-10/L-10e340a.wav" +[ 8, 69 ] = wave (0) : "./MITfull/elev-10/L-10e345a.wav" +[ 8, 70 ] = wave (0) : "./MITfull/elev-10/L-10e350a.wav" +[ 8, 71 ] = wave (0) : "./MITfull/elev-10/L-10e355a.wav" + +[ 9, 0 ] = wave (0) : "./MITfull/elev0/L0e000a.wav" +[ 9, 1 ] = wave (0) : "./MITfull/elev0/L0e005a.wav" +[ 9, 2 ] = wave (0) : "./MITfull/elev0/L0e010a.wav" +[ 9, 3 ] = wave (0) : "./MITfull/elev0/L0e015a.wav" +[ 9, 4 ] = wave (0) : "./MITfull/elev0/L0e020a.wav" +[ 9, 5 ] = wave (0) : "./MITfull/elev0/L0e025a.wav" +[ 9, 6 ] = wave (0) : "./MITfull/elev0/L0e030a.wav" +[ 9, 7 ] = wave (0) : "./MITfull/elev0/L0e035a.wav" +[ 9, 8 ] = wave (0) : "./MITfull/elev0/L0e040a.wav" +[ 9, 9 ] = wave (0) : "./MITfull/elev0/L0e045a.wav" +[ 9, 10 ] = wave (0) : "./MITfull/elev0/L0e050a.wav" +[ 9, 11 ] = wave (0) : "./MITfull/elev0/L0e055a.wav" +[ 9, 12 ] = wave (0) : "./MITfull/elev0/L0e060a.wav" +[ 9, 13 ] = wave (0) : "./MITfull/elev0/L0e065a.wav" +[ 9, 14 ] = wave (0) : "./MITfull/elev0/L0e070a.wav" +[ 9, 15 ] = wave (0) : "./MITfull/elev0/L0e075a.wav" +[ 9, 16 ] = wave (0) : "./MITfull/elev0/L0e080a.wav" +[ 9, 17 ] = wave (0) : "./MITfull/elev0/L0e085a.wav" +[ 9, 18 ] = wave (0) : "./MITfull/elev0/L0e090a.wav" +[ 9, 19 ] = wave (0) : "./MITfull/elev0/L0e095a.wav" +[ 9, 20 ] = wave (0) : "./MITfull/elev0/L0e100a.wav" +[ 9, 21 ] = wave (0) : "./MITfull/elev0/L0e105a.wav" +[ 9, 22 ] = wave (0) : "./MITfull/elev0/L0e110a.wav" +[ 9, 23 ] = wave (0) : "./MITfull/elev0/L0e115a.wav" +[ 9, 24 ] = wave (0) : "./MITfull/elev0/L0e120a.wav" +[ 9, 25 ] = wave (0) : "./MITfull/elev0/L0e125a.wav" +[ 9, 26 ] = wave (0) : "./MITfull/elev0/L0e130a.wav" +[ 9, 27 ] = wave (0) : "./MITfull/elev0/L0e135a.wav" +[ 9, 28 ] = wave (0) : "./MITfull/elev0/L0e140a.wav" +[ 9, 29 ] = wave (0) : "./MITfull/elev0/L0e145a.wav" +[ 9, 30 ] = wave (0) : "./MITfull/elev0/L0e150a.wav" +[ 9, 31 ] = wave (0) : "./MITfull/elev0/L0e155a.wav" +[ 9, 32 ] = wave (0) : "./MITfull/elev0/L0e160a.wav" +[ 9, 33 ] = wave (0) : "./MITfull/elev0/L0e165a.wav" +[ 9, 34 ] = wave (0) : "./MITfull/elev0/L0e170a.wav" +[ 9, 35 ] = wave (0) : "./MITfull/elev0/L0e175a.wav" +[ 9, 36 ] = wave (0) : "./MITfull/elev0/L0e180a.wav" +[ 9, 37 ] = wave (0) : "./MITfull/elev0/L0e185a.wav" +[ 9, 38 ] = wave (0) : "./MITfull/elev0/L0e190a.wav" +[ 9, 39 ] = wave (0) : "./MITfull/elev0/L0e195a.wav" +[ 9, 40 ] = wave (0) : "./MITfull/elev0/L0e200a.wav" +[ 9, 41 ] = wave (0) : "./MITfull/elev0/L0e205a.wav" +[ 9, 42 ] = wave (0) : "./MITfull/elev0/L0e210a.wav" +[ 9, 43 ] = wave (0) : "./MITfull/elev0/L0e215a.wav" +[ 9, 44 ] = wave (0) : "./MITfull/elev0/L0e220a.wav" +[ 9, 45 ] = wave (0) : "./MITfull/elev0/L0e225a.wav" +[ 9, 46 ] = wave (0) : "./MITfull/elev0/L0e230a.wav" +[ 9, 47 ] = wave (0) : "./MITfull/elev0/L0e235a.wav" +[ 9, 48 ] = wave (0) : "./MITfull/elev0/L0e240a.wav" +[ 9, 49 ] = wave (0) : "./MITfull/elev0/L0e245a.wav" +[ 9, 50 ] = wave (0) : "./MITfull/elev0/L0e250a.wav" +[ 9, 51 ] = wave (0) : "./MITfull/elev0/L0e255a.wav" +[ 9, 52 ] = wave (0) : "./MITfull/elev0/L0e260a.wav" +[ 9, 53 ] = wave (0) : "./MITfull/elev0/L0e265a.wav" +[ 9, 54 ] = wave (0) : "./MITfull/elev0/L0e270a.wav" +[ 9, 55 ] = wave (0) : "./MITfull/elev0/L0e275a.wav" +[ 9, 56 ] = wave (0) : "./MITfull/elev0/L0e280a.wav" +[ 9, 57 ] = wave (0) : "./MITfull/elev0/L0e285a.wav" +[ 9, 58 ] = wave (0) : "./MITfull/elev0/L0e290a.wav" +[ 9, 59 ] = wave (0) : "./MITfull/elev0/L0e295a.wav" +[ 9, 60 ] = wave (0) : "./MITfull/elev0/L0e300a.wav" +[ 9, 61 ] = wave (0) : "./MITfull/elev0/L0e305a.wav" +[ 9, 62 ] = wave (0) : "./MITfull/elev0/L0e310a.wav" +[ 9, 63 ] = wave (0) : "./MITfull/elev0/L0e315a.wav" +[ 9, 64 ] = wave (0) : "./MITfull/elev0/L0e320a.wav" +[ 9, 65 ] = wave (0) : "./MITfull/elev0/L0e325a.wav" +[ 9, 66 ] = wave (0) : "./MITfull/elev0/L0e330a.wav" +[ 9, 67 ] = wave (0) : "./MITfull/elev0/L0e335a.wav" +[ 9, 68 ] = wave (0) : "./MITfull/elev0/L0e340a.wav" +[ 9, 69 ] = wave (0) : "./MITfull/elev0/L0e345a.wav" +[ 9, 70 ] = wave (0) : "./MITfull/elev0/L0e350a.wav" +[ 9, 71 ] = wave (0) : "./MITfull/elev0/L0e355a.wav" + +[ 10, 0 ] = wave (0) : "./MITfull/elev10/L10e000a.wav" +[ 10, 1 ] = wave (0) : "./MITfull/elev10/L10e005a.wav" +[ 10, 2 ] = wave (0) : "./MITfull/elev10/L10e010a.wav" +[ 10, 3 ] = wave (0) : "./MITfull/elev10/L10e015a.wav" +[ 10, 4 ] = wave (0) : "./MITfull/elev10/L10e020a.wav" +[ 10, 5 ] = wave (0) : "./MITfull/elev10/L10e025a.wav" +[ 10, 6 ] = wave (0) : "./MITfull/elev10/L10e030a.wav" +[ 10, 7 ] = wave (0) : "./MITfull/elev10/L10e035a.wav" +[ 10, 8 ] = wave (0) : "./MITfull/elev10/L10e040a.wav" +[ 10, 9 ] = wave (0) : "./MITfull/elev10/L10e045a.wav" +[ 10, 10 ] = wave (0) : "./MITfull/elev10/L10e050a.wav" +[ 10, 11 ] = wave (0) : "./MITfull/elev10/L10e055a.wav" +[ 10, 12 ] = wave (0) : "./MITfull/elev10/L10e060a.wav" +[ 10, 13 ] = wave (0) : "./MITfull/elev10/L10e065a.wav" +[ 10, 14 ] = wave (0) : "./MITfull/elev10/L10e070a.wav" +[ 10, 15 ] = wave (0) : "./MITfull/elev10/L10e075a.wav" +[ 10, 16 ] = wave (0) : "./MITfull/elev10/L10e080a.wav" +[ 10, 17 ] = wave (0) : "./MITfull/elev10/L10e085a.wav" +[ 10, 18 ] = wave (0) : "./MITfull/elev10/L10e090a.wav" +[ 10, 19 ] = wave (0) : "./MITfull/elev10/L10e095a.wav" +[ 10, 20 ] = wave (0) : "./MITfull/elev10/L10e100a.wav" +[ 10, 21 ] = wave (0) : "./MITfull/elev10/L10e105a.wav" +[ 10, 22 ] = wave (0) : "./MITfull/elev10/L10e110a.wav" +[ 10, 23 ] = wave (0) : "./MITfull/elev10/L10e115a.wav" +[ 10, 24 ] = wave (0) : "./MITfull/elev10/L10e120a.wav" +[ 10, 25 ] = wave (0) : "./MITfull/elev10/L10e125a.wav" +[ 10, 26 ] = wave (0) : "./MITfull/elev10/L10e130a.wav" +[ 10, 27 ] = wave (0) : "./MITfull/elev10/L10e135a.wav" +[ 10, 28 ] = wave (0) : "./MITfull/elev10/L10e140a.wav" +[ 10, 29 ] = wave (0) : "./MITfull/elev10/L10e145a.wav" +[ 10, 30 ] = wave (0) : "./MITfull/elev10/L10e150a.wav" +[ 10, 31 ] = wave (0) : "./MITfull/elev10/L10e155a.wav" +[ 10, 32 ] = wave (0) : "./MITfull/elev10/L10e160a.wav" +[ 10, 33 ] = wave (0) : "./MITfull/elev10/L10e165a.wav" +[ 10, 34 ] = wave (0) : "./MITfull/elev10/L10e170a.wav" +[ 10, 35 ] = wave (0) : "./MITfull/elev10/L10e175a.wav" +[ 10, 36 ] = wave (0) : "./MITfull/elev10/L10e180a.wav" +[ 10, 37 ] = wave (0) : "./MITfull/elev10/L10e185a.wav" +[ 10, 38 ] = wave (0) : "./MITfull/elev10/L10e190a.wav" +[ 10, 39 ] = wave (0) : "./MITfull/elev10/L10e195a.wav" +[ 10, 40 ] = wave (0) : "./MITfull/elev10/L10e200a.wav" +[ 10, 41 ] = wave (0) : "./MITfull/elev10/L10e205a.wav" +[ 10, 42 ] = wave (0) : "./MITfull/elev10/L10e210a.wav" +[ 10, 43 ] = wave (0) : "./MITfull/elev10/L10e215a.wav" +[ 10, 44 ] = wave (0) : "./MITfull/elev10/L10e220a.wav" +[ 10, 45 ] = wave (0) : "./MITfull/elev10/L10e225a.wav" +[ 10, 46 ] = wave (0) : "./MITfull/elev10/L10e230a.wav" +[ 10, 47 ] = wave (0) : "./MITfull/elev10/L10e235a.wav" +[ 10, 48 ] = wave (0) : "./MITfull/elev10/L10e240a.wav" +[ 10, 49 ] = wave (0) : "./MITfull/elev10/L10e245a.wav" +[ 10, 50 ] = wave (0) : "./MITfull/elev10/L10e250a.wav" +[ 10, 51 ] = wave (0) : "./MITfull/elev10/L10e255a.wav" +[ 10, 52 ] = wave (0) : "./MITfull/elev10/L10e260a.wav" +[ 10, 53 ] = wave (0) : "./MITfull/elev10/L10e265a.wav" +[ 10, 54 ] = wave (0) : "./MITfull/elev10/L10e270a.wav" +[ 10, 55 ] = wave (0) : "./MITfull/elev10/L10e275a.wav" +[ 10, 56 ] = wave (0) : "./MITfull/elev10/L10e280a.wav" +[ 10, 57 ] = wave (0) : "./MITfull/elev10/L10e285a.wav" +[ 10, 58 ] = wave (0) : "./MITfull/elev10/L10e290a.wav" +[ 10, 59 ] = wave (0) : "./MITfull/elev10/L10e295a.wav" +[ 10, 60 ] = wave (0) : "./MITfull/elev10/L10e300a.wav" +[ 10, 61 ] = wave (0) : "./MITfull/elev10/L10e305a.wav" +[ 10, 62 ] = wave (0) : "./MITfull/elev10/L10e310a.wav" +[ 10, 63 ] = wave (0) : "./MITfull/elev10/L10e315a.wav" +[ 10, 64 ] = wave (0) : "./MITfull/elev10/L10e320a.wav" +[ 10, 65 ] = wave (0) : "./MITfull/elev10/L10e325a.wav" +[ 10, 66 ] = wave (0) : "./MITfull/elev10/L10e330a.wav" +[ 10, 67 ] = wave (0) : "./MITfull/elev10/L10e335a.wav" +[ 10, 68 ] = wave (0) : "./MITfull/elev10/L10e340a.wav" +[ 10, 69 ] = wave (0) : "./MITfull/elev10/L10e345a.wav" +[ 10, 70 ] = wave (0) : "./MITfull/elev10/L10e350a.wav" +[ 10, 71 ] = wave (0) : "./MITfull/elev10/L10e355a.wav" + +[ 11, 0 ] = wave (0) : "./MITfull/elev20/L20e000a.wav" +[ 11, 1 ] = wave (0) : "./MITfull/elev20/L20e005a.wav" +[ 11, 2 ] = wave (0) : "./MITfull/elev20/L20e010a.wav" +[ 11, 3 ] = wave (0) : "./MITfull/elev20/L20e015a.wav" +[ 11, 4 ] = wave (0) : "./MITfull/elev20/L20e020a.wav" +[ 11, 5 ] = wave (0) : "./MITfull/elev20/L20e025a.wav" +[ 11, 6 ] = wave (0) : "./MITfull/elev20/L20e030a.wav" +[ 11, 7 ] = wave (0) : "./MITfull/elev20/L20e035a.wav" +[ 11, 8 ] = wave (0) : "./MITfull/elev20/L20e040a.wav" +[ 11, 9 ] = wave (0) : "./MITfull/elev20/L20e045a.wav" +[ 11, 10 ] = wave (0) : "./MITfull/elev20/L20e050a.wav" +[ 11, 11 ] = wave (0) : "./MITfull/elev20/L20e055a.wav" +[ 11, 12 ] = wave (0) : "./MITfull/elev20/L20e060a.wav" +[ 11, 13 ] = wave (0) : "./MITfull/elev20/L20e065a.wav" +[ 11, 14 ] = wave (0) : "./MITfull/elev20/L20e070a.wav" +[ 11, 15 ] = wave (0) : "./MITfull/elev20/L20e075a.wav" +[ 11, 16 ] = wave (0) : "./MITfull/elev20/L20e080a.wav" +[ 11, 17 ] = wave (0) : "./MITfull/elev20/L20e085a.wav" +[ 11, 18 ] = wave (0) : "./MITfull/elev20/L20e090a.wav" +[ 11, 19 ] = wave (0) : "./MITfull/elev20/L20e095a.wav" +[ 11, 20 ] = wave (0) : "./MITfull/elev20/L20e100a.wav" +[ 11, 21 ] = wave (0) : "./MITfull/elev20/L20e105a.wav" +[ 11, 22 ] = wave (0) : "./MITfull/elev20/L20e110a.wav" +[ 11, 23 ] = wave (0) : "./MITfull/elev20/L20e115a.wav" +[ 11, 24 ] = wave (0) : "./MITfull/elev20/L20e120a.wav" +[ 11, 25 ] = wave (0) : "./MITfull/elev20/L20e125a.wav" +[ 11, 26 ] = wave (0) : "./MITfull/elev20/L20e130a.wav" +[ 11, 27 ] = wave (0) : "./MITfull/elev20/L20e135a.wav" +[ 11, 28 ] = wave (0) : "./MITfull/elev20/L20e140a.wav" +[ 11, 29 ] = wave (0) : "./MITfull/elev20/L20e145a.wav" +[ 11, 30 ] = wave (0) : "./MITfull/elev20/L20e150a.wav" +[ 11, 31 ] = wave (0) : "./MITfull/elev20/L20e155a.wav" +[ 11, 32 ] = wave (0) : "./MITfull/elev20/L20e160a.wav" +[ 11, 33 ] = wave (0) : "./MITfull/elev20/L20e165a.wav" +[ 11, 34 ] = wave (0) : "./MITfull/elev20/L20e170a.wav" +[ 11, 35 ] = wave (0) : "./MITfull/elev20/L20e175a.wav" +[ 11, 36 ] = wave (0) : "./MITfull/elev20/L20e180a.wav" +[ 11, 37 ] = wave (0) : "./MITfull/elev20/L20e185a.wav" +[ 11, 38 ] = wave (0) : "./MITfull/elev20/L20e190a.wav" +[ 11, 39 ] = wave (0) : "./MITfull/elev20/L20e195a.wav" +[ 11, 40 ] = wave (0) : "./MITfull/elev20/L20e200a.wav" +[ 11, 41 ] = wave (0) : "./MITfull/elev20/L20e205a.wav" +[ 11, 42 ] = wave (0) : "./MITfull/elev20/L20e210a.wav" +[ 11, 43 ] = wave (0) : "./MITfull/elev20/L20e215a.wav" +[ 11, 44 ] = wave (0) : "./MITfull/elev20/L20e220a.wav" +[ 11, 45 ] = wave (0) : "./MITfull/elev20/L20e225a.wav" +[ 11, 46 ] = wave (0) : "./MITfull/elev20/L20e230a.wav" +[ 11, 47 ] = wave (0) : "./MITfull/elev20/L20e235a.wav" +[ 11, 48 ] = wave (0) : "./MITfull/elev20/L20e240a.wav" +[ 11, 49 ] = wave (0) : "./MITfull/elev20/L20e245a.wav" +[ 11, 50 ] = wave (0) : "./MITfull/elev20/L20e250a.wav" +[ 11, 51 ] = wave (0) : "./MITfull/elev20/L20e255a.wav" +[ 11, 52 ] = wave (0) : "./MITfull/elev20/L20e260a.wav" +[ 11, 53 ] = wave (0) : "./MITfull/elev20/L20e265a.wav" +[ 11, 54 ] = wave (0) : "./MITfull/elev20/L20e270a.wav" +[ 11, 55 ] = wave (0) : "./MITfull/elev20/L20e275a.wav" +[ 11, 56 ] = wave (0) : "./MITfull/elev20/L20e280a.wav" +[ 11, 57 ] = wave (0) : "./MITfull/elev20/L20e285a.wav" +[ 11, 58 ] = wave (0) : "./MITfull/elev20/L20e290a.wav" +[ 11, 59 ] = wave (0) : "./MITfull/elev20/L20e295a.wav" +[ 11, 60 ] = wave (0) : "./MITfull/elev20/L20e300a.wav" +[ 11, 61 ] = wave (0) : "./MITfull/elev20/L20e305a.wav" +[ 11, 62 ] = wave (0) : "./MITfull/elev20/L20e310a.wav" +[ 11, 63 ] = wave (0) : "./MITfull/elev20/L20e315a.wav" +[ 11, 64 ] = wave (0) : "./MITfull/elev20/L20e320a.wav" +[ 11, 65 ] = wave (0) : "./MITfull/elev20/L20e325a.wav" +[ 11, 66 ] = wave (0) : "./MITfull/elev20/L20e330a.wav" +[ 11, 67 ] = wave (0) : "./MITfull/elev20/L20e335a.wav" +[ 11, 68 ] = wave (0) : "./MITfull/elev20/L20e340a.wav" +[ 11, 69 ] = wave (0) : "./MITfull/elev20/L20e345a.wav" +[ 11, 70 ] = wave (0) : "./MITfull/elev20/L20e350a.wav" +[ 11, 71 ] = wave (0) : "./MITfull/elev20/L20e355a.wav" + +[ 12, 0 ] = wave (0) : "./MITfull/elev30/L30e000a.wav" +[ 12, 1 ] = wave (0) : "./MITfull/elev30/L30e006a.wav" +[ 12, 2 ] = wave (0) : "./MITfull/elev30/L30e012a.wav" +[ 12, 3 ] = wave (0) : "./MITfull/elev30/L30e018a.wav" +[ 12, 4 ] = wave (0) : "./MITfull/elev30/L30e024a.wav" +[ 12, 5 ] = wave (0) : "./MITfull/elev30/L30e030a.wav" +[ 12, 6 ] = wave (0) : "./MITfull/elev30/L30e036a.wav" +[ 12, 7 ] = wave (0) : "./MITfull/elev30/L30e042a.wav" +[ 12, 8 ] = wave (0) : "./MITfull/elev30/L30e048a.wav" +[ 12, 9 ] = wave (0) : "./MITfull/elev30/L30e054a.wav" +[ 12, 10 ] = wave (0) : "./MITfull/elev30/L30e060a.wav" +[ 12, 11 ] = wave (0) : "./MITfull/elev30/L30e066a.wav" +[ 12, 12 ] = wave (0) : "./MITfull/elev30/L30e072a.wav" +[ 12, 13 ] = wave (0) : "./MITfull/elev30/L30e078a.wav" +[ 12, 14 ] = wave (0) : "./MITfull/elev30/L30e084a.wav" +[ 12, 15 ] = wave (0) : "./MITfull/elev30/L30e090a.wav" +[ 12, 16 ] = wave (0) : "./MITfull/elev30/L30e096a.wav" +[ 12, 17 ] = wave (0) : "./MITfull/elev30/L30e102a.wav" +[ 12, 18 ] = wave (0) : "./MITfull/elev30/L30e108a.wav" +[ 12, 19 ] = wave (0) : "./MITfull/elev30/L30e114a.wav" +[ 12, 20 ] = wave (0) : "./MITfull/elev30/L30e120a.wav" +[ 12, 21 ] = wave (0) : "./MITfull/elev30/L30e126a.wav" +[ 12, 22 ] = wave (0) : "./MITfull/elev30/L30e132a.wav" +[ 12, 23 ] = wave (0) : "./MITfull/elev30/L30e138a.wav" +[ 12, 24 ] = wave (0) : "./MITfull/elev30/L30e144a.wav" +[ 12, 25 ] = wave (0) : "./MITfull/elev30/L30e150a.wav" +[ 12, 26 ] = wave (0) : "./MITfull/elev30/L30e156a.wav" +[ 12, 27 ] = wave (0) : "./MITfull/elev30/L30e162a.wav" +[ 12, 28 ] = wave (0) : "./MITfull/elev30/L30e168a.wav" +[ 12, 29 ] = wave (0) : "./MITfull/elev30/L30e174a.wav" +[ 12, 30 ] = wave (0) : "./MITfull/elev30/L30e180a.wav" +[ 12, 31 ] = wave (0) : "./MITfull/elev30/L30e186a.wav" +[ 12, 32 ] = wave (0) : "./MITfull/elev30/L30e192a.wav" +[ 12, 33 ] = wave (0) : "./MITfull/elev30/L30e198a.wav" +[ 12, 34 ] = wave (0) : "./MITfull/elev30/L30e204a.wav" +[ 12, 35 ] = wave (0) : "./MITfull/elev30/L30e210a.wav" +[ 12, 36 ] = wave (0) : "./MITfull/elev30/L30e216a.wav" +[ 12, 37 ] = wave (0) : "./MITfull/elev30/L30e222a.wav" +[ 12, 38 ] = wave (0) : "./MITfull/elev30/L30e228a.wav" +[ 12, 39 ] = wave (0) : "./MITfull/elev30/L30e234a.wav" +[ 12, 40 ] = wave (0) : "./MITfull/elev30/L30e240a.wav" +[ 12, 41 ] = wave (0) : "./MITfull/elev30/L30e246a.wav" +[ 12, 42 ] = wave (0) : "./MITfull/elev30/L30e252a.wav" +[ 12, 43 ] = wave (0) : "./MITfull/elev30/L30e258a.wav" +[ 12, 44 ] = wave (0) : "./MITfull/elev30/L30e264a.wav" +[ 12, 45 ] = wave (0) : "./MITfull/elev30/L30e270a.wav" +[ 12, 46 ] = wave (0) : "./MITfull/elev30/L30e276a.wav" +[ 12, 47 ] = wave (0) : "./MITfull/elev30/L30e282a.wav" +[ 12, 48 ] = wave (0) : "./MITfull/elev30/L30e288a.wav" +[ 12, 49 ] = wave (0) : "./MITfull/elev30/L30e294a.wav" +[ 12, 50 ] = wave (0) : "./MITfull/elev30/L30e300a.wav" +[ 12, 51 ] = wave (0) : "./MITfull/elev30/L30e306a.wav" +[ 12, 52 ] = wave (0) : "./MITfull/elev30/L30e312a.wav" +[ 12, 53 ] = wave (0) : "./MITfull/elev30/L30e318a.wav" +[ 12, 54 ] = wave (0) : "./MITfull/elev30/L30e324a.wav" +[ 12, 55 ] = wave (0) : "./MITfull/elev30/L30e330a.wav" +[ 12, 56 ] = wave (0) : "./MITfull/elev30/L30e336a.wav" +[ 12, 57 ] = wave (0) : "./MITfull/elev30/L30e342a.wav" +[ 12, 58 ] = wave (0) : "./MITfull/elev30/L30e348a.wav" +[ 12, 59 ] = wave (0) : "./MITfull/elev30/L30e354a.wav" + +[ 13, 0 ] = wave (0) : "./MITfull/elev40/L40e000a.wav" +[ 13, 1 ] = wave (0) : "./MITfull/elev40/L40e006a.wav" +[ 13, 2 ] = wave (0) : "./MITfull/elev40/L40e013a.wav" +[ 13, 3 ] = wave (0) : "./MITfull/elev40/L40e019a.wav" +[ 13, 4 ] = wave (0) : "./MITfull/elev40/L40e026a.wav" +[ 13, 5 ] = wave (0) : "./MITfull/elev40/L40e032a.wav" +[ 13, 6 ] = wave (0) : "./MITfull/elev40/L40e039a.wav" +[ 13, 7 ] = wave (0) : "./MITfull/elev40/L40e045a.wav" +[ 13, 8 ] = wave (0) : "./MITfull/elev40/L40e051a.wav" +[ 13, 9 ] = wave (0) : "./MITfull/elev40/L40e058a.wav" +[ 13, 10 ] = wave (0) : "./MITfull/elev40/L40e064a.wav" +[ 13, 11 ] = wave (0) : "./MITfull/elev40/L40e071a.wav" +[ 13, 12 ] = wave (0) : "./MITfull/elev40/L40e077a.wav" +[ 13, 13 ] = wave (0) : "./MITfull/elev40/L40e084a.wav" +[ 13, 14 ] = wave (0) : "./MITfull/elev40/L40e090a.wav" +[ 13, 15 ] = wave (0) : "./MITfull/elev40/L40e096a.wav" +[ 13, 16 ] = wave (0) : "./MITfull/elev40/L40e103a.wav" +[ 13, 17 ] = wave (0) : "./MITfull/elev40/L40e109a.wav" +[ 13, 18 ] = wave (0) : "./MITfull/elev40/L40e116a.wav" +[ 13, 19 ] = wave (0) : "./MITfull/elev40/L40e122a.wav" +[ 13, 20 ] = wave (0) : "./MITfull/elev40/L40e129a.wav" +[ 13, 21 ] = wave (0) : "./MITfull/elev40/L40e135a.wav" +[ 13, 22 ] = wave (0) : "./MITfull/elev40/L40e141a.wav" +[ 13, 23 ] = wave (0) : "./MITfull/elev40/L40e148a.wav" +[ 13, 24 ] = wave (0) : "./MITfull/elev40/L40e154a.wav" +[ 13, 25 ] = wave (0) : "./MITfull/elev40/L40e161a.wav" +[ 13, 26 ] = wave (0) : "./MITfull/elev40/L40e167a.wav" +[ 13, 27 ] = wave (0) : "./MITfull/elev40/L40e174a.wav" +[ 13, 28 ] = wave (0) : "./MITfull/elev40/L40e180a.wav" +[ 13, 29 ] = wave (0) : "./MITfull/elev40/L40e186a.wav" +[ 13, 30 ] = wave (0) : "./MITfull/elev40/L40e193a.wav" +[ 13, 31 ] = wave (0) : "./MITfull/elev40/L40e199a.wav" +[ 13, 32 ] = wave (0) : "./MITfull/elev40/L40e206a.wav" +[ 13, 33 ] = wave (0) : "./MITfull/elev40/L40e212a.wav" +[ 13, 34 ] = wave (0) : "./MITfull/elev40/L40e219a.wav" +[ 13, 35 ] = wave (0) : "./MITfull/elev40/L40e225a.wav" +[ 13, 36 ] = wave (0) : "./MITfull/elev40/L40e231a.wav" +[ 13, 37 ] = wave (0) : "./MITfull/elev40/L40e238a.wav" +[ 13, 38 ] = wave (0) : "./MITfull/elev40/L40e244a.wav" +[ 13, 39 ] = wave (0) : "./MITfull/elev40/L40e251a.wav" +[ 13, 40 ] = wave (0) : "./MITfull/elev40/L40e257a.wav" +[ 13, 41 ] = wave (0) : "./MITfull/elev40/L40e264a.wav" +[ 13, 42 ] = wave (0) : "./MITfull/elev40/L40e270a.wav" +[ 13, 43 ] = wave (0) : "./MITfull/elev40/L40e276a.wav" +[ 13, 44 ] = wave (0) : "./MITfull/elev40/L40e283a.wav" +[ 13, 45 ] = wave (0) : "./MITfull/elev40/L40e289a.wav" +[ 13, 46 ] = wave (0) : "./MITfull/elev40/L40e296a.wav" +[ 13, 47 ] = wave (0) : "./MITfull/elev40/L40e302a.wav" +[ 13, 48 ] = wave (0) : "./MITfull/elev40/L40e309a.wav" +[ 13, 49 ] = wave (0) : "./MITfull/elev40/L40e315a.wav" +[ 13, 50 ] = wave (0) : "./MITfull/elev40/L40e321a.wav" +[ 13, 51 ] = wave (0) : "./MITfull/elev40/L40e328a.wav" +[ 13, 52 ] = wave (0) : "./MITfull/elev40/L40e334a.wav" +[ 13, 53 ] = wave (0) : "./MITfull/elev40/L40e341a.wav" +[ 13, 54 ] = wave (0) : "./MITfull/elev40/L40e347a.wav" +[ 13, 55 ] = wave (0) : "./MITfull/elev40/L40e354a.wav" + +[ 14, 0 ] = wave (0) : "./MITfull/elev50/L50e000a.wav" +[ 14, 1 ] = wave (0) : "./MITfull/elev50/L50e008a.wav" +[ 14, 2 ] = wave (0) : "./MITfull/elev50/L50e016a.wav" +[ 14, 3 ] = wave (0) : "./MITfull/elev50/L50e024a.wav" +[ 14, 4 ] = wave (0) : "./MITfull/elev50/L50e032a.wav" +[ 14, 5 ] = wave (0) : "./MITfull/elev50/L50e040a.wav" +[ 14, 6 ] = wave (0) : "./MITfull/elev50/L50e048a.wav" +[ 14, 7 ] = wave (0) : "./MITfull/elev50/L50e056a.wav" +[ 14, 8 ] = wave (0) : "./MITfull/elev50/L50e064a.wav" +[ 14, 9 ] = wave (0) : "./MITfull/elev50/L50e072a.wav" +[ 14, 10 ] = wave (0) : "./MITfull/elev50/L50e080a.wav" +[ 14, 11 ] = wave (0) : "./MITfull/elev50/L50e088a.wav" +[ 14, 12 ] = wave (0) : "./MITfull/elev50/L50e096a.wav" +[ 14, 13 ] = wave (0) : "./MITfull/elev50/L50e104a.wav" +[ 14, 14 ] = wave (0) : "./MITfull/elev50/L50e112a.wav" +[ 14, 15 ] = wave (0) : "./MITfull/elev50/L50e120a.wav" +[ 14, 16 ] = wave (0) : "./MITfull/elev50/L50e128a.wav" +[ 14, 17 ] = wave (0) : "./MITfull/elev50/L50e136a.wav" +[ 14, 18 ] = wave (0) : "./MITfull/elev50/L50e144a.wav" +[ 14, 19 ] = wave (0) : "./MITfull/elev50/L50e152a.wav" +[ 14, 20 ] = wave (0) : "./MITfull/elev50/L50e160a.wav" +[ 14, 21 ] = wave (0) : "./MITfull/elev50/L50e168a.wav" +[ 14, 22 ] = wave (0) : "./MITfull/elev50/L50e176a.wav" +[ 14, 23 ] = wave (0) : "./MITfull/elev50/L50e184a.wav" +[ 14, 24 ] = wave (0) : "./MITfull/elev50/L50e192a.wav" +[ 14, 25 ] = wave (0) : "./MITfull/elev50/L50e200a.wav" +[ 14, 26 ] = wave (0) : "./MITfull/elev50/L50e208a.wav" +[ 14, 27 ] = wave (0) : "./MITfull/elev50/L50e216a.wav" +[ 14, 28 ] = wave (0) : "./MITfull/elev50/L50e224a.wav" +[ 14, 29 ] = wave (0) : "./MITfull/elev50/L50e232a.wav" +[ 14, 30 ] = wave (0) : "./MITfull/elev50/L50e240a.wav" +[ 14, 31 ] = wave (0) : "./MITfull/elev50/L50e248a.wav" +[ 14, 32 ] = wave (0) : "./MITfull/elev50/L50e256a.wav" +[ 14, 33 ] = wave (0) : "./MITfull/elev50/L50e264a.wav" +[ 14, 34 ] = wave (0) : "./MITfull/elev50/L50e272a.wav" +[ 14, 35 ] = wave (0) : "./MITfull/elev50/L50e280a.wav" +[ 14, 36 ] = wave (0) : "./MITfull/elev50/L50e288a.wav" +[ 14, 37 ] = wave (0) : "./MITfull/elev50/L50e296a.wav" +[ 14, 38 ] = wave (0) : "./MITfull/elev50/L50e304a.wav" +[ 14, 39 ] = wave (0) : "./MITfull/elev50/L50e312a.wav" +[ 14, 40 ] = wave (0) : "./MITfull/elev50/L50e320a.wav" +[ 14, 41 ] = wave (0) : "./MITfull/elev50/L50e328a.wav" +[ 14, 42 ] = wave (0) : "./MITfull/elev50/L50e336a.wav" +[ 14, 43 ] = wave (0) : "./MITfull/elev50/L50e344a.wav" +[ 14, 44 ] = wave (0) : "./MITfull/elev50/L50e352a.wav" + +[ 15, 0 ] = wave (0) : "./MITfull/elev60/L60e000a.wav" +[ 15, 1 ] = wave (0) : "./MITfull/elev60/L60e010a.wav" +[ 15, 2 ] = wave (0) : "./MITfull/elev60/L60e020a.wav" +[ 15, 3 ] = wave (0) : "./MITfull/elev60/L60e030a.wav" +[ 15, 4 ] = wave (0) : "./MITfull/elev60/L60e040a.wav" +[ 15, 5 ] = wave (0) : "./MITfull/elev60/L60e050a.wav" +[ 15, 6 ] = wave (0) : "./MITfull/elev60/L60e060a.wav" +[ 15, 7 ] = wave (0) : "./MITfull/elev60/L60e070a.wav" +[ 15, 8 ] = wave (0) : "./MITfull/elev60/L60e080a.wav" +[ 15, 9 ] = wave (0) : "./MITfull/elev60/L60e090a.wav" +[ 15, 10 ] = wave (0) : "./MITfull/elev60/L60e100a.wav" +[ 15, 11 ] = wave (0) : "./MITfull/elev60/L60e110a.wav" +[ 15, 12 ] = wave (0) : "./MITfull/elev60/L60e120a.wav" +[ 15, 13 ] = wave (0) : "./MITfull/elev60/L60e130a.wav" +[ 15, 14 ] = wave (0) : "./MITfull/elev60/L60e140a.wav" +[ 15, 15 ] = wave (0) : "./MITfull/elev60/L60e150a.wav" +[ 15, 16 ] = wave (0) : "./MITfull/elev60/L60e160a.wav" +[ 15, 17 ] = wave (0) : "./MITfull/elev60/L60e170a.wav" +[ 15, 18 ] = wave (0) : "./MITfull/elev60/L60e180a.wav" +[ 15, 19 ] = wave (0) : "./MITfull/elev60/L60e190a.wav" +[ 15, 20 ] = wave (0) : "./MITfull/elev60/L60e200a.wav" +[ 15, 21 ] = wave (0) : "./MITfull/elev60/L60e210a.wav" +[ 15, 22 ] = wave (0) : "./MITfull/elev60/L60e220a.wav" +[ 15, 23 ] = wave (0) : "./MITfull/elev60/L60e230a.wav" +[ 15, 24 ] = wave (0) : "./MITfull/elev60/L60e240a.wav" +[ 15, 25 ] = wave (0) : "./MITfull/elev60/L60e250a.wav" +[ 15, 26 ] = wave (0) : "./MITfull/elev60/L60e260a.wav" +[ 15, 27 ] = wave (0) : "./MITfull/elev60/L60e270a.wav" +[ 15, 28 ] = wave (0) : "./MITfull/elev60/L60e280a.wav" +[ 15, 29 ] = wave (0) : "./MITfull/elev60/L60e290a.wav" +[ 15, 30 ] = wave (0) : "./MITfull/elev60/L60e300a.wav" +[ 15, 31 ] = wave (0) : "./MITfull/elev60/L60e310a.wav" +[ 15, 32 ] = wave (0) : "./MITfull/elev60/L60e320a.wav" +[ 15, 33 ] = wave (0) : "./MITfull/elev60/L60e330a.wav" +[ 15, 34 ] = wave (0) : "./MITfull/elev60/L60e340a.wav" +[ 15, 35 ] = wave (0) : "./MITfull/elev60/L60e350a.wav" + +[ 16, 0 ] = wave (0) : "./MITfull/elev70/L70e000a.wav" +[ 16, 1 ] = wave (0) : "./MITfull/elev70/L70e015a.wav" +[ 16, 2 ] = wave (0) : "./MITfull/elev70/L70e030a.wav" +[ 16, 3 ] = wave (0) : "./MITfull/elev70/L70e045a.wav" +[ 16, 4 ] = wave (0) : "./MITfull/elev70/L70e060a.wav" +[ 16, 5 ] = wave (0) : "./MITfull/elev70/L70e075a.wav" +[ 16, 6 ] = wave (0) : "./MITfull/elev70/L70e090a.wav" +[ 16, 7 ] = wave (0) : "./MITfull/elev70/L70e105a.wav" +[ 16, 8 ] = wave (0) : "./MITfull/elev70/L70e120a.wav" +[ 16, 9 ] = wave (0) : "./MITfull/elev70/L70e135a.wav" +[ 16, 10 ] = wave (0) : "./MITfull/elev70/L70e150a.wav" +[ 16, 11 ] = wave (0) : "./MITfull/elev70/L70e165a.wav" +[ 16, 12 ] = wave (0) : "./MITfull/elev70/L70e180a.wav" +[ 16, 13 ] = wave (0) : "./MITfull/elev70/L70e195a.wav" +[ 16, 14 ] = wave (0) : "./MITfull/elev70/L70e210a.wav" +[ 16, 15 ] = wave (0) : "./MITfull/elev70/L70e225a.wav" +[ 16, 16 ] = wave (0) : "./MITfull/elev70/L70e240a.wav" +[ 16, 17 ] = wave (0) : "./MITfull/elev70/L70e255a.wav" +[ 16, 18 ] = wave (0) : "./MITfull/elev70/L70e270a.wav" +[ 16, 19 ] = wave (0) : "./MITfull/elev70/L70e285a.wav" +[ 16, 20 ] = wave (0) : "./MITfull/elev70/L70e300a.wav" +[ 16, 21 ] = wave (0) : "./MITfull/elev70/L70e315a.wav" +[ 16, 22 ] = wave (0) : "./MITfull/elev70/L70e330a.wav" +[ 16, 23 ] = wave (0) : "./MITfull/elev70/L70e345a.wav" + +[ 17, 0 ] = wave (0) : "./MITfull/elev80/L80e000a.wav" +[ 17, 1 ] = wave (0) : "./MITfull/elev80/L80e030a.wav" +[ 17, 2 ] = wave (0) : "./MITfull/elev80/L80e060a.wav" +[ 17, 3 ] = wave (0) : "./MITfull/elev80/L80e090a.wav" +[ 17, 4 ] = wave (0) : "./MITfull/elev80/L80e120a.wav" +[ 17, 5 ] = wave (0) : "./MITfull/elev80/L80e150a.wav" +[ 17, 6 ] = wave (0) : "./MITfull/elev80/L80e180a.wav" +[ 17, 7 ] = wave (0) : "./MITfull/elev80/L80e210a.wav" +[ 17, 8 ] = wave (0) : "./MITfull/elev80/L80e240a.wav" +[ 17, 9 ] = wave (0) : "./MITfull/elev80/L80e270a.wav" +[ 17, 10 ] = wave (0) : "./MITfull/elev80/L80e300a.wav" +[ 17, 11 ] = wave (0) : "./MITfull/elev80/L80e330a.wav" + +[ 18, 0 ] = wave (0) : "./MITfull/elev90/L90e000a.wav" + diff --git a/jni/openal-soft-android/utils/alsoft-config/CMakeLists.txt b/jni/openal-soft-android/utils/alsoft-config/CMakeLists.txt new file mode 100644 index 00000000..a6707a3d --- /dev/null +++ b/jni/openal-soft-android/utils/alsoft-config/CMakeLists.txt @@ -0,0 +1,29 @@ +project(alsoft-config) + +include_directories("${alsoft-config_BINARY_DIR}") + +# Need Qt 4.8.0 or newer for the iconset theme attribute to work +find_package(Qt4 4.8.0 COMPONENTS QtCore QtGui) +if(QT4_FOUND) + include(${QT_USE_FILE}) + + set(alsoft-config_SRCS main.cpp + mainwindow.cpp + ) + + set(alsoft-config_UIS mainwindow.ui) + QT4_WRAP_UI(UIS ${alsoft-config_UIS}) + + set(alsoft-config_MOCS mainwindow.h) + QT4_WRAP_CPP(MOCS ${alsoft-config_MOCS}) + + add_executable(alsoft-config ${alsoft-config_SRCS} ${UIS} ${RSCS} ${TRS} ${MOCS}) + target_link_libraries(alsoft-config ${QT_LIBRARIES}) + set_target_properties(alsoft-config PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OpenAL_BINARY_DIR}) + + install(TARGETS alsoft-config + RUNTIME DESTINATION bin + LIBRARY DESTINATION "lib${LIB_SUFFIX}" + ARCHIVE DESTINATION "lib${LIB_SUFFIX}" + ) +endif() diff --git a/jni/openal-soft-android/utils/alsoft-config/main.cpp b/jni/openal-soft-android/utils/alsoft-config/main.cpp new file mode 100644 index 00000000..b48f94ec --- /dev/null +++ b/jni/openal-soft-android/utils/alsoft-config/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/jni/openal-soft-android/utils/alsoft-config/mainwindow.cpp b/jni/openal-soft-android/utils/alsoft-config/mainwindow.cpp new file mode 100644 index 00000000..0047233f --- /dev/null +++ b/jni/openal-soft-android/utils/alsoft-config/mainwindow.cpp @@ -0,0 +1,586 @@ +#include +#include +#include +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" + +namespace { +static const struct { + char backend_name[16]; + char menu_string[32]; +} backendMenuList[] = { +#ifdef Q_OS_WIN32 + { "mmdevapi", "Add MMDevAPI" }, + { "dsound", "Add DirectSound" }, + { "winmm", "Add Windows Multimedia" }, +#endif +#ifdef Q_OS_MAC + { "core", "Add CoreAudio" }, +#endif + { "pulse", "Add PulseAudio" }, +#ifdef Q_OS_UNIX + { "alsa", "Add ALSA" }, + { "oss", "Add OSS" }, + { "solaris", "Add Solaris" }, + { "sndio", "Add SndIO" }, + { "qsa", "Add QSA" }, +#endif + { "port", "Add PortAudio" }, + { "opensl", "Add OpenSL" }, + { "null", "Add Null Output" }, + { "wave", "Add Wave Writer" }, + { "", "" } +}; + +static QString getDefaultConfigName() +{ +#ifdef Q_OS_WIN32 + static const char fname[] = "alsoft.ini"; + QByteArray base = qgetenv("AppData"); +#else + static const char fname[] = "alsoft.conf"; + QByteArray base = qgetenv("XDG_CONFIG_HOME"); + if(base.isEmpty()) + { + base = qgetenv("HOME"); + if(base.isEmpty() == false) + base += "/.config"; + } +#endif + if(base.isEmpty() == false) + return base +'/'+ fname; + return fname; +} +} + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow), + mPeriodSizeValidator(NULL), + mPeriodCountValidator(NULL), + mSourceCountValidator(NULL), + mEffectSlotValidator(NULL), + mSourceSendValidator(NULL), + mSampleRateValidator(NULL), + mReverbBoostValidator(NULL) +{ + ui->setupUi(this); + + mPeriodSizeValidator = new QIntValidator(64, 8192, this); + ui->periodSizeEdit->setValidator(mPeriodSizeValidator); + mPeriodCountValidator = new QIntValidator(2, 16, this); + ui->periodCountEdit->setValidator(mPeriodCountValidator); + + mSourceCountValidator = new QIntValidator(0, 256, this); + ui->srcCountLineEdit->setValidator(mSourceCountValidator); + mEffectSlotValidator = new QIntValidator(0, 16, this); + ui->effectSlotLineEdit->setValidator(mEffectSlotValidator); + mSourceSendValidator = new QIntValidator(0, 4, this); + ui->srcSendLineEdit->setValidator(mSourceSendValidator); + mSampleRateValidator = new QIntValidator(8000, 192000, this); + ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator); + + mReverbBoostValidator = new QDoubleValidator(-12.0, +12.0, 1, this); + ui->reverbBoostEdit->setValidator(mReverbBoostValidator); + + connect(ui->actionLoad, SIGNAL(triggered()), this, SLOT(loadConfigFromFile())); + connect(ui->actionSave_As, SIGNAL(triggered()), this, SLOT(saveConfigAsFile())); + + connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(saveCurrentConfig())); + + connect(ui->periodSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodSizeEdit(int))); + connect(ui->periodSizeEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodSizeSlider())); + connect(ui->periodCountSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodCountEdit(int))); + connect(ui->periodCountEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodCountSlider())); + + connect(ui->hrtfAddButton, SIGNAL(clicked()), this, SLOT(addHrtfFile())); + connect(ui->hrtfRemoveButton, SIGNAL(clicked()), this, SLOT(removeHrtfFile())); + connect(ui->hrtfFileList, SIGNAL(itemSelectionChanged()), this, SLOT(updateHrtfRemoveButton())); + + ui->enabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->enabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showEnabledBackendMenu(QPoint))); + + ui->disabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->disabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDisabledBackendMenu(QPoint))); + + connect(ui->reverbBoostSlider, SIGNAL(valueChanged(int)), this, SLOT(updateReverbBoostEdit(int))); + connect(ui->reverbBoostEdit, SIGNAL(textEdited(QString)), this, SLOT(updateReverbBoostSlider(QString))); + + loadConfig(getDefaultConfigName()); +} + +MainWindow::~MainWindow() +{ + delete ui; + delete mPeriodSizeValidator; + delete mPeriodCountValidator; + delete mSourceCountValidator; + delete mEffectSlotValidator; + delete mSourceSendValidator; + delete mSampleRateValidator; + delete mReverbBoostValidator; +} + +void MainWindow::loadConfigFromFile() +{ + QString fname = QFileDialog::getOpenFileName(this, tr("Select Files")); + if(fname.isEmpty() == false) + loadConfig(fname); +} + +void MainWindow::loadConfig(const QString &fname) +{ + QSettings settings(fname, QSettings::IniFormat); + + QString sampletype = settings.value("sample-type").toString(); + ui->sampleFormatCombo->setCurrentIndex(0); + if(sampletype.isEmpty() == false) + { + for(int i = 1;i < ui->sampleFormatCombo->count();i++) + { + QString item = ui->sampleFormatCombo->itemText(i); + if(item.startsWith(sampletype)) + { + ui->sampleFormatCombo->setCurrentIndex(i); + break; + } + } + } + + QString channelconfig = settings.value("channels").toString(); + ui->channelConfigCombo->setCurrentIndex(0); + if(channelconfig.isEmpty() == false) + { + for(int i = 1;i < ui->channelConfigCombo->count();i++) + { + QString item = ui->channelConfigCombo->itemText(i); + if(item.startsWith(channelconfig)) + { + ui->channelConfigCombo->setCurrentIndex(i); + break; + } + } + } + + QString srate = settings.value("frequency").toString(); + if(srate.isEmpty()) + ui->sampleRateCombo->setCurrentIndex(0); + else + { + ui->sampleRateCombo->lineEdit()->clear(); + ui->sampleRateCombo->lineEdit()->insert(srate); + } + + ui->srcCountLineEdit->clear(); + ui->srcCountLineEdit->insert(settings.value("sources").toString()); + ui->effectSlotLineEdit->clear(); + ui->effectSlotLineEdit->insert(settings.value("slots").toString()); + ui->srcSendLineEdit->clear(); + ui->srcSendLineEdit->insert(settings.value("sends").toString()); + + QString resampler = settings.value("resampler").toString().trimmed(); + if(resampler.isEmpty()) + ui->resamplerComboBox->setCurrentIndex(0); + else + { + for(int i = 1;i < ui->resamplerComboBox->count();i++) + { + QString item = ui->resamplerComboBox->itemText(i); + int end = item.indexOf(' '); + if(end < 0) end = item.size(); + if(resampler.size() == end && resampler.compare(item.leftRef(end), Qt::CaseInsensitive) == 0) + { + ui->resamplerComboBox->setCurrentIndex(i); + break; + } + } + } + + int periodsize = settings.value("period_size").toInt(); + ui->periodSizeEdit->clear(); + if(periodsize >= 64) + { + ui->periodSizeEdit->insert(QString::number(periodsize)); + updatePeriodSizeSlider(); + } + + int periodcount = settings.value("periods").toInt(); + ui->periodCountEdit->clear(); + if(periodcount >= 2) + { + ui->periodCountEdit->insert(QString::number(periodcount)); + updatePeriodCountSlider(); + } + + QStringList disabledCpuExts = settings.value("disable-cpu-exts").toStringList(); + if(disabledCpuExts.size() == 1) + disabledCpuExts = disabledCpuExts[0].split(QChar(',')); + std::transform(disabledCpuExts.begin(), disabledCpuExts.end(), + disabledCpuExts.begin(), std::mem_fun_ref(&QString::trimmed)); + ui->disableSSECheckBox->setChecked(disabledCpuExts.contains("sse", Qt::CaseInsensitive)); + ui->disableSSE2CheckBox->setChecked(disabledCpuExts.contains("sse2", Qt::CaseInsensitive)); + ui->disableNeonCheckBox->setChecked(disabledCpuExts.contains("neon", Qt::CaseInsensitive)); + + if(settings.value("hrtf").toString() == QString()) + ui->hrtfEnableButton->setChecked(true); + else + { + if(settings.value("hrtf", true).toBool()) + ui->hrtfForceButton->setChecked(true); + else + ui->hrtfDisableButton->setChecked(true); + } + + QStringList hrtf_tables = settings.value("hrtf_tables").toStringList(); + if(hrtf_tables.size() == 1) + hrtf_tables = hrtf_tables[0].split(QChar(',')); + std::transform(hrtf_tables.begin(), hrtf_tables.end(), + hrtf_tables.begin(), std::mem_fun_ref(&QString::trimmed)); + ui->hrtfFileList->clear(); + ui->hrtfFileList->addItems(hrtf_tables); + updateHrtfRemoveButton(); + + ui->enabledBackendList->clear(); + ui->disabledBackendList->clear(); + QStringList drivers = settings.value("drivers").toStringList(); + if(drivers.size() == 0) + ui->backendCheckBox->setChecked(true); + else + { + if(drivers.size() == 1) + drivers = drivers[0].split(QChar(',')); + std::transform(drivers.begin(), drivers.end(), + drivers.begin(), std::mem_fun_ref(&QString::trimmed)); + + bool lastWasEmpty = false; + foreach(const QString &backend, drivers) + { + lastWasEmpty = backend.isEmpty(); + if(!backend.startsWith(QChar('-')) && !lastWasEmpty) + ui->enabledBackendList->addItem(backend); + else if(backend.size() > 1) + ui->disabledBackendList->addItem(backend.right(backend.size()-1)); + } + ui->backendCheckBox->setChecked(lastWasEmpty); + } + + QString defaultreverb = settings.value("default-reverb").toString().toLower(); + ui->defaultReverbComboBox->setCurrentIndex(0); + if(defaultreverb.isEmpty() == false) + { + for(int i = 0;i < ui->defaultReverbComboBox->count();i++) + { + if(defaultreverb.compare(ui->defaultReverbComboBox->itemText(i).toLower()) == 0) + { + ui->defaultReverbComboBox->setCurrentIndex(i); + break; + } + } + } + + ui->emulateEaxCheckBox->setChecked(settings.value("reverb/emulate-eax", false).toBool()); + ui->reverbBoostEdit->clear(); + ui->reverbBoostEdit->insert(settings.value("reverb/boost").toString()); + + QStringList excludefx = settings.value("excludefx").toStringList(); + if(excludefx.size() == 1) + excludefx = excludefx[0].split(QChar(',')); + std::transform(excludefx.begin(), excludefx.end(), + excludefx.begin(), std::mem_fun_ref(&QString::trimmed)); + ui->disableEaxReverbCheck->setChecked(excludefx.contains("eaxreverb", Qt::CaseInsensitive)); + ui->disableStdReverbCheck->setChecked(excludefx.contains("reverb", Qt::CaseInsensitive)); + ui->disableChorusCheck->setChecked(excludefx.contains("chorus", Qt::CaseInsensitive)); + ui->disableDistortionCheck->setChecked(excludefx.contains("distortion", Qt::CaseInsensitive)); + ui->disableEchoCheck->setChecked(excludefx.contains("echo", Qt::CaseInsensitive)); + ui->disableEqualizerCheck->setChecked(excludefx.contains("equalizer", Qt::CaseInsensitive)); + ui->disableFlangerCheck->setChecked(excludefx.contains("flanger", Qt::CaseInsensitive)); + ui->disableModulatorCheck->setChecked(excludefx.contains("modulator", Qt::CaseInsensitive)); + ui->disableDedicatedCheck->setChecked(excludefx.contains("dedicated", Qt::CaseInsensitive)); +} + +void MainWindow::saveCurrentConfig() +{ + saveConfig(getDefaultConfigName()); + QMessageBox::information(this, tr("Information"), + tr("Applications using OpenAL need to be restarted for changes to take effect.")); +} + +void MainWindow::saveConfigAsFile() +{ + QString fname = QFileDialog::getOpenFileName(this, tr("Select Files")); + if(fname.isEmpty() == false) + saveConfig(fname); +} + +void MainWindow::saveConfig(const QString &fname) const +{ + QSettings settings(fname, QSettings::IniFormat); + + /* HACK: Compound any stringlist values into a comma-separated string. */ + QStringList allkeys = settings.allKeys(); + foreach(const QString &key, allkeys) + { + QStringList vals = settings.value(key).toStringList(); + if(vals.size() > 1) + settings.setValue(key, vals.join(QChar(','))); + } + + QString str = ui->sampleFormatCombo->currentText(); + str.truncate(str.indexOf('-')); + settings.setValue("sample-type", str.trimmed()); + + str = ui->channelConfigCombo->currentText(); + str.truncate(str.indexOf('-')); + settings.setValue("channels", str.trimmed()); + + uint rate = ui->sampleRateCombo->currentText().toUInt(); + if(rate == 0) + settings.setValue("frequency", QString()); + else + settings.setValue("frequency", rate); + + settings.setValue("period_size", ui->periodSizeEdit->text()); + settings.setValue("periods", ui->periodCountEdit->text()); + + settings.setValue("sources", ui->srcCountLineEdit->text()); + settings.setValue("slots", ui->effectSlotLineEdit->text()); + + if(ui->resamplerComboBox->currentIndex() == 0) + settings.setValue("resampler", QString()); + else + { + str = ui->resamplerComboBox->currentText(); + settings.setValue("resampler", str.split(' ').first().toLower()); + } + + QStringList strlist; + if(ui->disableSSECheckBox->isChecked()) + strlist.append("sse"); + if(ui->disableSSE2CheckBox->isChecked()) + strlist.append("sse2"); + if(ui->disableNeonCheckBox->isChecked()) + strlist.append("neon"); + settings.setValue("disable-cpu-exts", strlist.join(QChar(','))); + + if(ui->hrtfForceButton->isChecked()) + settings.setValue("hrtf", "true"); + else if(ui->hrtfDisableButton->isChecked()) + settings.setValue("hrtf", "false"); + else + settings.setValue("hrtf", QString()); + + strlist.clear(); + QList items = ui->hrtfFileList->findItems("*", Qt::MatchWildcard); + foreach(const QListWidgetItem *item, items) + strlist.append(item->text()); + settings.setValue("hrtf_tables", strlist.join(QChar(','))); + + strlist.clear(); + items = ui->enabledBackendList->findItems("*", Qt::MatchWildcard); + foreach(const QListWidgetItem *item, items) + strlist.append(item->text()); + items = ui->disabledBackendList->findItems("*", Qt::MatchWildcard); + foreach(const QListWidgetItem *item, items) + strlist.append(QChar('-')+item->text()); + if(strlist.size() == 0 && !ui->backendCheckBox->isChecked()) + strlist.append("-all"); + else if(ui->backendCheckBox->isChecked()) + strlist.append(QString()); + settings.setValue("drivers", strlist.join(QChar(','))); + + // TODO: Remove check when we can properly match global values. + if(ui->defaultReverbComboBox->currentIndex() == 0) + settings.setValue("default-reverb", QString()); + else + { + str = ui->defaultReverbComboBox->currentText().toLower(); + settings.setValue("default-reverb", str); + } + + if(ui->emulateEaxCheckBox->isChecked()) + settings.setValue("reverb/emulate-eax", "true"); + else + settings.setValue("reverb/emulate-eax", QString()/*"false"*/); + + // TODO: Remove check when we can properly match global values. + if(ui->reverbBoostSlider->sliderPosition() == 0) + settings.setValue("reverb/boost", QString()); + else + settings.setValue("reverb/boost", ui->reverbBoostEdit->text()); + + strlist.clear(); + if(ui->disableEaxReverbCheck->isChecked()) + strlist.append("eaxreverb"); + if(ui->disableStdReverbCheck->isChecked()) + strlist.append("reverb"); + if(ui->disableChorusCheck->isChecked()) + strlist.append("chorus"); + if(ui->disableDistortionCheck->isChecked()) + strlist.append("distortion"); + if(ui->disableEchoCheck->isChecked()) + strlist.append("echo"); + if(ui->disableEqualizerCheck->isChecked()) + strlist.append("equalizer"); + if(ui->disableFlangerCheck->isChecked()) + strlist.append("flanger"); + if(ui->disableModulatorCheck->isChecked()) + strlist.append("modulator"); + if(ui->disableDedicatedCheck->isChecked()) + strlist.append("dedicated"); + settings.setValue("excludefx", strlist.join(QChar(','))); + + /* Remove empty keys + * FIXME: Should only remove keys whose value matches the globally-specified value. + */ + allkeys = settings.allKeys(); + foreach(const QString &key, allkeys) + { + str = settings.value(key).toString(); + if(str == QString()) + settings.remove(key); + } +} + + +void MainWindow::updatePeriodSizeEdit(int size) +{ + ui->periodSizeEdit->clear(); + if(size >= 64) + { + size = (size+32)&~0x3f; + ui->periodSizeEdit->insert(QString::number(size)); + } +} + +void MainWindow::updatePeriodSizeSlider() +{ + int pos = ui->periodSizeEdit->text().toInt(); + if(pos >= 64) + { + if(pos > 8192) + pos = 8192; + ui->periodSizeSlider->setSliderPosition(pos); + } +} + +void MainWindow::updatePeriodCountEdit(int count) +{ + ui->periodCountEdit->clear(); + if(count >= 2) + ui->periodCountEdit->insert(QString::number(count)); +} + +void MainWindow::updatePeriodCountSlider() +{ + int pos = ui->periodCountEdit->text().toInt(); + if(pos < 2) + pos = 0; + else if(pos > 16) + pos = 16; + ui->periodCountSlider->setSliderPosition(pos); +} + + +void MainWindow::addHrtfFile() +{ + QStringList fnames = QFileDialog::getOpenFileNames(this, tr("Select Files"), QString(), + "HRTF Datasets(*.mhr);;All Files(*.*)"); + if(fnames.isEmpty() == false) + ui->hrtfFileList->addItems(fnames); +} + +void MainWindow::removeHrtfFile() +{ + QList selected = ui->hrtfFileList->selectedItems(); + foreach(QListWidgetItem *item, selected) + delete item; +} + +void MainWindow::updateHrtfRemoveButton() +{ + ui->hrtfRemoveButton->setEnabled(ui->hrtfFileList->selectedItems().size() != 0); +} + +void MainWindow::showEnabledBackendMenu(QPoint pt) +{ + QMap actionMap; + + pt = ui->enabledBackendList->mapToGlobal(pt); + + QMenu ctxmenu; + QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove"); + if(ui->enabledBackendList->selectedItems().size() == 0) + removeAction->setEnabled(false); + ctxmenu.addSeparator(); + for(size_t i = 0;backendMenuList[i].backend_name[0];i++) + { + QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string); + actionMap[action] = backendMenuList[i].backend_name; + if(ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 || + ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0) + action->setEnabled(false); + } + + QAction *gotAction = ctxmenu.exec(pt); + if(gotAction == removeAction) + { + QList selected = ui->enabledBackendList->selectedItems(); + foreach(QListWidgetItem *item, selected) + delete item; + } + else if(gotAction != NULL) + { + QMap::const_iterator iter = actionMap.find(gotAction); + if(iter != actionMap.end()) + ui->enabledBackendList->addItem(iter.value()); + } +} + +void MainWindow::showDisabledBackendMenu(QPoint pt) +{ + QMap actionMap; + + pt = ui->disabledBackendList->mapToGlobal(pt); + + QMenu ctxmenu; + QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove"); + if(ui->disabledBackendList->selectedItems().size() == 0) + removeAction->setEnabled(false); + ctxmenu.addSeparator(); + for(size_t i = 0;backendMenuList[i].backend_name[0];i++) + { + QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string); + actionMap[action] = backendMenuList[i].backend_name; + if(ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 || + ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0) + action->setEnabled(false); + } + + QAction *gotAction = ctxmenu.exec(pt); + if(gotAction == removeAction) + { + QList selected = ui->disabledBackendList->selectedItems(); + foreach(QListWidgetItem *item, selected) + delete item; + } + else if(gotAction != NULL) + { + QMap::const_iterator iter = actionMap.find(gotAction); + if(iter != actionMap.end()) + ui->disabledBackendList->addItem(iter.value()); + } +} + +void MainWindow::updateReverbBoostEdit(int value) +{ + ui->reverbBoostEdit->clear(); + if(value != 0) + ui->reverbBoostEdit->insert(QString::number(value/10.0, 'f', 1)); +} + +void MainWindow::updateReverbBoostSlider(QString value) +{ + int pos = int(value.toFloat()*10.0f); + ui->reverbBoostSlider->setSliderPosition(pos); +} diff --git a/jni/openal-soft-android/utils/alsoft-config/mainwindow.h b/jni/openal-soft-android/utils/alsoft-config/mainwindow.h new file mode 100644 index 00000000..0421aabb --- /dev/null +++ b/jni/openal-soft-android/utils/alsoft-config/mainwindow.h @@ -0,0 +1,56 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void saveCurrentConfig(); + + void saveConfigAsFile(); + void loadConfigFromFile(); + + void updatePeriodSizeEdit(int size); + void updatePeriodSizeSlider(); + void updatePeriodCountEdit(int size); + void updatePeriodCountSlider(); + + void addHrtfFile(); + void removeHrtfFile(); + + void updateHrtfRemoveButton(); + + void showEnabledBackendMenu(QPoint pt); + void showDisabledBackendMenu(QPoint pt); + + void updateReverbBoostEdit(int size); + void updateReverbBoostSlider(QString value); + +private: + Ui::MainWindow *ui; + + QValidator *mPeriodSizeValidator; + QValidator *mPeriodCountValidator; + QValidator *mSourceCountValidator; + QValidator *mEffectSlotValidator; + QValidator *mSourceSendValidator; + QValidator *mSampleRateValidator; + QValidator *mReverbBoostValidator; + + void loadConfig(const QString &fname); + void saveConfig(const QString &fname) const; +}; + +#endif // MAINWINDOW_H diff --git a/jni/openal-soft-android/utils/alsoft-config/mainwindow.ui b/jni/openal-soft-android/utils/alsoft-config/mainwindow.ui new file mode 100644 index 00000000..4c7d0c69 --- /dev/null +++ b/jni/openal-soft-android/utils/alsoft-config/mainwindow.ui @@ -0,0 +1,1397 @@ + + + MainWindow + + + + 0 + 0 + 564 + 454 + + + + OpenAL Soft Configuration + + + + + + + + + + + 470 + 405 + 81 + 25 + + + + Apply + + + + + + + + + + + 10 + 0 + 541 + 401 + + + + 0 + + + + Playback + + + + + 120 + 20 + 206 + 23 + + + + The output sample type. Currently, all mixing is done with 32-bit +float and converted to the output sample type as needed. + + + QComboBox::AdjustToContents + + + + - Autodetect - + + + + + int8 - signed 8-bit int + + + + + uint8 - unsigned 8-bit int + + + + + int16 - signed 16-bit int + + + + + uint16 - unsigned 16-bit int + + + + + int32 - signed 32-bit int + + + + + uint32 - unsigned 32-bit int + + + + + float32 - 32-bit float + + + + + + + 10 + 20 + 101 + 21 + + + + Sample Format: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 50 + 101 + 21 + + + + Channels: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 120 + 50 + 247 + 23 + + + + The output channel configuration. Note that not all backends +can properly detect the channel configuration and may default +to stereo output. + + + QComboBox::AdjustToContents + + + + - Autodetect - + + + + + mono - 1-channel Mono + + + + + stereo - 2-channel Stereo + + + + + quad - 4-channel Quadraphonic + + + + + surround51 - 5.1 Surround Sound + + + + + surround61 - 6.1 Surround Sound + + + + + surround71 - 7.1 Surround Sound + + + + + + + 120 + 80 + 123 + 22 + + + + The playback/mixing sample rate. + + + true + + + QComboBox::NoInsert + + + QComboBox::AdjustToContents + + + + - Autodetect - + + + + + 96000 + + + + + 48000 + + + + + 44100 + + + + + 32000 + + + + + 22050 + + + + + 16000 + + + + + 11025 + + + + + 8000 + + + + + + + 10 + 80 + 101 + 21 + + + + Sample Rate: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 200 + 511 + 161 + + + + HRTF (Stereo only) + + + + + 20 + 30 + 71 + 21 + + + + Allows applications to request HRTF mixing. + + + Enable + + + true + + + + + + 20 + 50 + 71 + 21 + + + + Does not allow HRTF mixing, even when requested. + + + Disable + + + + + + 20 + 70 + 71 + 21 + + + + Attempts to force HRTF mixing, even if applications request not +to do it. This may override the channel configuration and +sample rate. + + + Force + + + + + + 110 + 30 + 361 + 121 + + + + A list of files containing HRTF data sets. The listed data sets +are used in place of or in addiiton to the the built-in set. The +filenames may contain these markers, which will be replaced +as needed: +%r - Device sampling rate +%% - Percent sign (%) + + + false + + + QAbstractItemView::InternalMove + + + true + + + QAbstractItemView::ExtendedSelection + + + Qt::ElideNone + + + + + + 475 + 30 + 25 + 25 + + + + + + + + + + + + false + + + + + + 475 + 60 + 25 + 25 + + + + + + + + + + + + + + + + 10 + 110 + 511 + 91 + + + + Buffer Metrics + + + + + 260 + 20 + 241 + 51 + + + + The number of update periods. Higher values create a larger +mix ahead, which helps protect against skips when the CPU is +under load, but increases the delay between a sound getting +mixed and being heard. + + + + + 20 + 0 + 201 + 21 + + + + Period Count + + + Qt::AlignCenter + + + + + + 70 + 20 + 160 + 23 + + + + 1 + + + 16 + + + 1 + + + 2 + + + 1 + + + true + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1 + + + + + + 20 + 20 + 51 + 22 + + + + 4 + + + + + + + 10 + 20 + 241 + 51 + + + + The update period size, in sample frames. This is the number of +frames needed for each mixing update. + + + + + 60 + 20 + 160 + 23 + + + + 0 + + + 8192 + + + 64 + + + 1024 + + + 0 + + + true + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 512 + + + + + + 10 + 0 + 201 + 21 + + + + Period Samples + + + Qt::AlignCenter + + + + + + 10 + 20 + 51 + 22 + + + + 1024 + + + + + + + + Resources + + + + + 190 + 20 + 51 + 22 + + + + The maximum number of allocatable sources. Lower values may +help for systems with apps that try to play more sounds than +the CPU can handle. + + + + + + 3 + + + true + + + 256 + + + + + + 10 + 20 + 171 + 21 + + + + Number of Sound Sources: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 10 + 50 + 171 + 21 + + + + Number of Effect Slots: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 190 + 50 + 51 + 22 + + + + The maximum number of Auxiliary Effect Slots an app can +create. A slot can use a non-negligible amount of CPU time if +an effect is set on it even if no sources are feeding it, so this +may help when apps use more than the system can handle. + + + + + + 1 + + + true + + + 4 + + + + + + 10 + 80 + 171 + 21 + + + + Number of Source Sends: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 190 + 80 + 51 + 22 + + + + The number of auxiliary sends per source. When not specified, +it allows the app to request how many it wants. The maximum +value currently possible is 4. + + + 1 + + + Auto + + + + + + 30 + 120 + 71 + 21 + + + + Resampler: + + + + + + 110 + 120 + 203 + 23 + + + + The resampling method used when mixing sources. + + + QComboBox::AdjustToContents + + + + - Default - + + + + + Point (low quality, fast) + + + + + Linear (basic quality, fast) + + + + + Cubic Spline (good quality) + + + + + + + 10 + 150 + 511 + 61 + + + + Disables use of specific CPU extensions. Certain methods may +utilize CPU extensions when detected, and this is useful for +preventing those extensions from being used. + + + CPU Extensions + + + + + 10 + 20 + 101 + 31 + + + + Disable SSE + + + + + + 200 + 20 + 111 + 31 + + + + Disable SSE2 + + + + + + 380 + 20 + 111 + 31 + + + + Disable Neon + + + + + + + Backends + + + + + 170 + 200 + 161 + 21 + + + + When checked, allows all other available backends not listed in the priority or disabled lists. + + + Allow Other Backends + + + true + + + + + + 40 + 40 + 191 + 151 + + + + The backend driver list order. Unknown backends and +duplicated names are ignored. + + + QAbstractItemView::InternalMove + + + + + + 40 + 20 + 191 + 20 + + + + Priority Backends: + + + + + + 270 + 40 + 191 + 151 + + + + Disabled backend driver list. + + + + + + 270 + 20 + 191 + 20 + + + + Disabled Backends: + + + + + + Effects + + + + + 10 + 60 + 161 + 21 + + + + Uses a simpler reverb method to emulate the EAX reverb +effect. This may slightly improve performance at the cost of +some quality. + + + Qt::RightToLeft + + + Emulate EAX Reverb: + + + + + + 10 + 100 + 511 + 61 + + + + Global amplification for reverb output, expressed in decibels. ++6 will be a scale of (approximately) 2x, +12 will be a scale of +4x, etc. Similarly, -6 will be about half, and -12 about 1/4th. A +value of 0 means no change. + + + Reverb Boost + + + + + 10 + 30 + 391 + 23 + + + + + + + -120 + + + 120 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + + + 410 + 30 + 51 + 22 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0.0 + + + + + + 460 + 30 + 31 + 21 + + + + dB + + + + + + + 9 + 170 + 511 + 181 + + + + Disables effects, preventing apps from recognizing them. This +can help for apps that try to use effects which are too CPU +intensive for the system to handle. + + + Disabled Effects + + + + + 70 + 30 + 131 + 21 + + + + EAX Reverb + + + + + + 70 + 60 + 131 + 21 + + + + Standard Reverb + + + + + + 70 + 90 + 131 + 21 + + + + Chorus + + + + + + 70 + 120 + 131 + 21 + + + + Distortion + + + + + + 70 + 150 + 131 + 21 + + + + Echo + + + + + + 320 + 30 + 131 + 21 + + + + Equalizer + + + + + + 320 + 60 + 131 + 21 + + + + Flanger + + + + + + 320 + 90 + 131 + 21 + + + + Ring Modulator + + + + + + 320 + 120 + 131 + 21 + + + + Disables both the Dedicated Dialog and Dedicated LFE effects +added by the ALC_EXT_DEDICATED extension. + + + Dedicated ... + + + + + + + 10 + 20 + 141 + 21 + + + + Default Reverb Effect: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 160 + 20 + 142 + 23 + + + + QComboBox::AdjustToContents + + + + None + + + + + Generic + + + + + PaddedCell + + + + + Room + + + + + Bathroom + + + + + Livingroom + + + + + Stoneroom + + + + + Auditorium + + + + + ConcertHall + + + + + Cave + + + + + Arena + + + + + Hangar + + + + + CarpetedHallway + + + + + Hallway + + + + + StoneCorridor + + + + + Alley + + + + + Forest + + + + + City + + + + + Mountains + + + + + Quarry + + + + + Plain + + + + + ParkingLot + + + + + SewerPipe + + + + + Underwater + + + + + Drugged + + + + + Dizzy + + + + + Psychotic + + + + + + + + + + 0 + 0 + 564 + 20 + + + + + &File + + + + + + + + + + + + + + + + &Quit + + + + + + + + + + Save &As... + + + Save Configuration As + + + + + + + + + + &Load... + + + Load Configuration File + + + + + + + + actionQuit + activated() + MainWindow + close() + + + -1 + -1 + + + 267 + 181 + + + + + + ShowHRTFContextMenu(QPoint) + + diff --git a/jni/openal-soft-android/utils/makehrtf.c b/jni/openal-soft-android/utils/makehrtf.c new file mode 100644 index 00000000..f9da9429 --- /dev/null +++ b/jni/openal-soft-android/utils/makehrtf.c @@ -0,0 +1,2752 @@ +/* + * HRTF utility for producing and demonstrating the process of creating an + * OpenAL Soft compatible HRIR data set. + * + * Copyright (C) 2011-2014 Christopher Fitzgerald + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * -------------------------------------------------------------------------- + * + * A big thanks goes out to all those whose work done in the field of + * binaural sound synthesis using measured HRTFs makes this utility and the + * OpenAL Soft implementation possible. + * + * The algorithm for diffuse-field equalization was adapted from the work + * done by Rio Emmanuel and Larcher Veronique of IRCAM and Bill Gardner of + * MIT Media Laboratory. It operates as follows: + * + * 1. Take the FFT of each HRIR and only keep the magnitude responses. + * 2. Calculate the diffuse-field power-average of all HRIRs weighted by + * their contribution to the total surface area covered by their + * measurement. + * 3. Take the diffuse-field average and limit its magnitude range. + * 4. Equalize the responses by using the inverse of the diffuse-field + * average. + * 5. Reconstruct the minimum-phase responses. + * 5. Zero the DC component. + * 6. IFFT the result and truncate to the desired-length minimum-phase FIR. + * + * The spherical head algorithm for calculating propagation delay was adapted + * from the paper: + * + * Modeling Interaural Time Difference Assuming a Spherical Head + * Joel David Miller + * Music 150, Musical Acoustics, Stanford University + * December 2, 2001 + * + * The formulae for calculating the Kaiser window metrics are from the + * the textbook: + * + * Discrete-Time Signal Processing + * Alan V. Oppenheim and Ronald W. Schafer + * Prentice-Hall Signal Processing Series + * 1999 + */ + +// Needed for 64-bit unsigned integer. +#include "config.h" + +#include +#include +#include +#include +#include +#include + +// Rely (if naively) on OpenAL's header for the types used for serialization. +#include "AL/al.h" + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +#ifndef HUGE_VAL +#define HUGE_VAL (1.0 / 0.0) +#endif + +// The epsilon used to maintain signal stability. +#define EPSILON (1e-15) + +// Constants for accessing the token reader's ring buffer. +#define TR_RING_BITS (16) +#define TR_RING_SIZE (1 << TR_RING_BITS) +#define TR_RING_MASK (TR_RING_SIZE - 1) + +// The token reader's load interval in bytes. +#define TR_LOAD_SIZE (TR_RING_SIZE >> 2) + +// The maximum identifier length used when processing the data set +// definition. +#define MAX_IDENT_LEN (16) + +// The maximum path length used when processing filenames. +#define MAX_PATH_LEN (256) + +// The limits for the sample 'rate' metric in the data set definition and for +// resampling. +#define MIN_RATE (32000) +#define MAX_RATE (96000) + +// The limits for the HRIR 'points' metric in the data set definition. +#define MIN_POINTS (16) +#define MAX_POINTS (8192) + +// The limits to the number of 'azimuths' listed in the data set definition. +#define MIN_EV_COUNT (5) +#define MAX_EV_COUNT (128) + +// The limits for each of the 'azimuths' listed in the data set definition. +#define MIN_AZ_COUNT (1) +#define MAX_AZ_COUNT (128) + +// The limits for the listener's head 'radius' in the data set definition. +#define MIN_RADIUS (0.05) +#define MAX_RADIUS (0.15) + +// The limits for the 'distance' from source to listener in the definition +// file. +#define MIN_DISTANCE (0.5) +#define MAX_DISTANCE (2.5) + +// The maximum number of channels that can be addressed for a WAVE file +// source listed in the data set definition. +#define MAX_WAVE_CHANNELS (65535) + +// The limits to the byte size for a binary source listed in the definition +// file. +#define MIN_BIN_SIZE (2) +#define MAX_BIN_SIZE (4) + +// The minimum number of significant bits for binary sources listed in the +// data set definition. The maximum is calculated from the byte size. +#define MIN_BIN_BITS (16) + +// The limits to the number of significant bits for an ASCII source listed in +// the data set definition. +#define MIN_ASCII_BITS (16) +#define MAX_ASCII_BITS (32) + +// The limits to the FFT window size override on the command line. +#define MIN_FFTSIZE (512) +#define MAX_FFTSIZE (16384) + +// The limits to the equalization range limit on the command line. +#define MIN_LIMIT (2.0) +#define MAX_LIMIT (120.0) + +// The limits to the truncation window size on the command line. +#define MIN_TRUNCSIZE (8) +#define MAX_TRUNCSIZE (128) + +// The limits to the custom head radius on the command line. +#define MIN_CUSTOM_RADIUS (0.05) +#define MAX_CUSTOM_RADIUS (0.15) + +// The truncation window size must be a multiple of the below value to allow +// for vectorized convolution. +#define MOD_TRUNCSIZE (8) + +// The defaults for the command line options. +#define DEFAULT_EQUALIZE (1) +#define DEFAULT_SURFACE (1) +#define DEFAULT_LIMIT (24.0) +#define DEFAULT_TRUNCSIZE (32) +#define DEFAULT_HEAD_MODEL (HM_DATASET) +#define DEFAULT_CUSTOM_RADIUS (0.0) + +// The four-character-codes for RIFF/RIFX WAVE file chunks. +#define FOURCC_RIFF (0x46464952) // 'RIFF' +#define FOURCC_RIFX (0x58464952) // 'RIFX' +#define FOURCC_WAVE (0x45564157) // 'WAVE' +#define FOURCC_FMT (0x20746D66) // 'fmt ' +#define FOURCC_DATA (0x61746164) // 'data' +#define FOURCC_LIST (0x5453494C) // 'LIST' +#define FOURCC_WAVL (0x6C766177) // 'wavl' +#define FOURCC_SLNT (0x746E6C73) // 'slnt' + +// The supported wave formats. +#define WAVE_FORMAT_PCM (0x0001) +#define WAVE_FORMAT_IEEE_FLOAT (0x0003) +#define WAVE_FORMAT_EXTENSIBLE (0xFFFE) + +// The maximum propagation delay value supported by OpenAL Soft. +#define MAX_HRTD (63.0) + +// The OpenAL Soft HRTF format marker. It stands for minimum-phase head +// response protocol 01. +#define MHR_FORMAT ("MinPHR01") + +// Byte order for the serialization routines. +enum ByteOrderT { + BO_NONE = 0, + BO_LITTLE , + BO_BIG +}; + +// Source format for the references listed in the data set definition. +enum SourceFormatT { + SF_NONE = 0, + SF_WAVE , // RIFF/RIFX WAVE file. + SF_BIN_LE , // Little-endian binary file. + SF_BIN_BE , // Big-endian binary file. + SF_ASCII // ASCII text file. +}; + +// Element types for the references listed in the data set definition. +enum ElementTypeT { + ET_NONE = 0, + ET_INT , // Integer elements. + ET_FP // Floating-point elements. +}; + +// Head model used for calculating the impulse delays. +enum HeadModelT { + HM_NONE = 0, + HM_DATASET , // Measure the onset from the dataset. + HM_SPHERE // Calculate the onset using a spherical head model. +}; + +// Desired output format from the command line. +enum OutputFormatT { + OF_NONE = 0, + OF_MHR , // OpenAL Soft MHR data set file. + OF_TABLE // OpenAL Soft built-in table file (used when compiling). +}; + +// Unsigned integer type. +typedef unsigned int uint; + +// Serialization types. The trailing digit indicates the number of bytes. +typedef ALubyte uint1; + +typedef ALint int4; +typedef ALuint uint4; + +#if defined (HAVE_STDINT_H) +#include + +typedef uint64_t uint8; +#elif defined (HAVE___INT64) +typedef unsigned __int64 uint8; +#elif (SIZEOF_LONG == 8) +typedef unsigned long uint8; +#elif (SIZEOF_LONG_LONG == 8) +typedef unsigned long long uint8; +#endif + +typedef enum ByteOrderT ByteOrderT; +typedef enum SourceFormatT SourceFormatT; +typedef enum ElementTypeT ElementTypeT; +typedef enum HeadModelT HeadModelT; +typedef enum OutputFormatT OutputFormatT; + +typedef struct TokenReaderT TokenReaderT; +typedef struct SourceRefT SourceRefT; +typedef struct HrirDataT HrirDataT; +typedef struct ResamplerT ResamplerT; + +// Token reader state for parsing the data set definition. +struct TokenReaderT { + FILE * mFile; + const char * mName; + uint mLine, + mColumn; + char mRing [TR_RING_SIZE]; + size_t mIn, + mOut; +}; + +// Source reference state used when loading sources. +struct SourceRefT { + SourceFormatT mFormat; + ElementTypeT mType; + uint mSize; + int mBits; + uint mChannel, + mSkip, + mOffset; + char mPath [MAX_PATH_LEN + 1]; +}; + +// The HRIR metrics and data set used when loading, processing, and storing +// the resulting HRTF. +struct HrirDataT { + uint mIrRate, + mIrCount, + mIrSize, + mIrPoints, + mFftSize, + mEvCount, + mEvStart, + mAzCount [MAX_EV_COUNT], + mEvOffset [MAX_EV_COUNT]; + double mRadius, + mDistance, + * mHrirs, + * mHrtds, + mMaxHrtd; +}; + +// The resampler metrics and FIR filter. +struct ResamplerT { + uint mP, + mQ, + mM, + mL; + double * mF; +}; + +/* Token reader routines for parsing text files. Whitespace is not + * significant. It can process tokens as identifiers, numbers (integer and + * floating-point), strings, and operators. Strings must be encapsulated by + * double-quotes and cannot span multiple lines. + */ + +// Setup the reader on the given file. The filename can be NULL if no error +// output is desired. +static void TrSetup (FILE * fp, const char * filename, TokenReaderT * tr) { + const char * name = NULL; + char ch; + + tr -> mFile = fp; + name = filename; + // If a filename was given, store a pointer to the base name. + if (filename != NULL) { + while ((ch = (* filename)) != '\0') { + if ((ch == '/') || (ch == '\\')) + name = filename + 1; + filename ++; + } + } + tr -> mName = name; + tr -> mLine = 1; + tr -> mColumn = 1; + tr -> mIn = 0; + tr -> mOut = 0; +} + +// Prime the reader's ring buffer, and return a result indicating that there +// is text to process. +static int TrLoad (TokenReaderT * tr) { + size_t toLoad, in, count; + + toLoad = TR_RING_SIZE - (tr -> mIn - tr -> mOut); + if ((toLoad >= TR_LOAD_SIZE) && (! feof (tr -> mFile))) { + // Load TR_LOAD_SIZE (or less if at the end of the file) per read. + toLoad = TR_LOAD_SIZE; + in = tr -> mIn & TR_RING_MASK; + count = TR_RING_SIZE - in; + if (count < toLoad) { + tr -> mIn += fread (& tr -> mRing [in], 1, count, tr -> mFile); + tr -> mIn += fread (& tr -> mRing [0], 1, toLoad - count, tr -> mFile); + } else { + tr -> mIn += fread (& tr -> mRing [in], 1, toLoad, tr -> mFile); + } + if (tr -> mOut >= TR_RING_SIZE) { + tr -> mOut -= TR_RING_SIZE; + tr -> mIn -= TR_RING_SIZE; + } + } + if (tr -> mIn > tr -> mOut) + return (1); + return (0); +} + +// Error display routine. Only displays when the base name is not NULL. +static void TrErrorVA (const TokenReaderT * tr, uint line, uint column, const char * format, va_list argPtr) { + if (tr -> mName != NULL) { + fprintf (stderr, "Error (%s:%u:%u): ", tr -> mName, line, column); + vfprintf (stderr, format, argPtr); + } +} + +// Used to display an error at a saved line/column. +static void TrErrorAt (const TokenReaderT * tr, uint line, uint column, const char * format, ...) { + va_list argPtr; + + va_start (argPtr, format); + TrErrorVA (tr, line, column, format, argPtr); + va_end (argPtr); +} + +// Used to display an error at the current line/column. +static void TrError (const TokenReaderT * tr, const char * format, ...) { + va_list argPtr; + + va_start (argPtr, format); + TrErrorVA (tr, tr -> mLine, tr -> mColumn, format, argPtr); + va_end (argPtr); +} + +// Skips to the next line. +static void TrSkipLine (TokenReaderT * tr) { + char ch; + + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + tr -> mOut ++; + if (ch == '\n') { + tr -> mLine ++; + tr -> mColumn = 1; + break; + } + tr -> mColumn ++; + } +} + +// Skips to the next token. +static int TrSkipWhitespace (TokenReaderT * tr) { + char ch; + + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (isspace (ch)) { + tr -> mOut ++; + if (ch == '\n') { + tr -> mLine ++; + tr -> mColumn = 1; + } else { + tr -> mColumn ++; + } + } else if (ch == '#') { + TrSkipLine (tr); + } else { + return (1); + } + } + return (0); +} + +// Get the line and/or column of the next token (or the end of input). +static void TrIndication (TokenReaderT * tr, uint * line, uint * column) { + TrSkipWhitespace (tr); + if (line != NULL) + (* line) = tr -> mLine; + if (column != NULL) + (* column) = tr -> mColumn; +} + +// Checks to see if a token is the given operator. It does not display any +// errors and will not proceed to the next token. +static int TrIsOperator (TokenReaderT * tr, const char * op) { + size_t out, len; + char ch; + + if (! TrSkipWhitespace (tr)) + return (0); + out = tr -> mOut; + len = 0; + while ((op [len] != '\0') && (out < tr -> mIn)) { + ch = tr -> mRing [out & TR_RING_MASK]; + if (ch != op [len]) + break; + len ++; + out ++; + } + if (op [len] == '\0') + return (1); + return (0); +} + +/* The TrRead*() routines obtain the value of a matching token type. They + * display type, form, and boundary errors and will proceed to the next + * token. + */ + +// Reads and validates an identifier token. +static int TrReadIdent (TokenReaderT * tr, const uint maxLen, char * ident) { + uint col, len; + char ch; + + col = tr -> mColumn; + if (TrSkipWhitespace (tr)) { + col = tr -> mColumn; + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if ((ch == '_') || isalpha (ch)) { + len = 0; + do { + if (len < maxLen) + ident [len] = ch; + len ++; + tr -> mOut ++; + if (! TrLoad (tr)) + break; + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + } while ((ch == '_') || isdigit (ch) || isalpha (ch)); + tr -> mColumn += len; + if (len > maxLen) { + TrErrorAt (tr, tr -> mLine, col, "Identifier is too long.\n"); + return (0); + } + ident [len] = '\0'; + return (1); + } + } + TrErrorAt (tr, tr -> mLine, col, "Expected an identifier.\n"); + return (0); +} + +// Reads and validates (including bounds) an integer token. +static int TrReadInt (TokenReaderT * tr, const int loBound, const int hiBound, int * value) { + uint col, digis, len; + char ch, temp [64 + 1]; + + col = tr -> mColumn; + if (TrSkipWhitespace (tr)) { + col = tr -> mColumn; + len = 0; + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if ((ch == '+') || (ch == '-')) { + temp [len] = ch; + len ++; + tr -> mOut ++; + } + digis = 0; + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (! isdigit (ch)) + break; + if (len < 64) + temp [len] = ch; + len ++; + digis ++; + tr -> mOut ++; + } + tr -> mColumn += len; + if ((digis > 0) && (ch != '.') && (! isalpha (ch))) { + if (len > 64) { + TrErrorAt (tr, tr -> mLine, col, "Integer is too long."); + return (0); + } + temp [len] = '\0'; + (* value) = strtol (temp, NULL, 10); + if (((* value) < loBound) || ((* value) > hiBound)) { + TrErrorAt (tr, tr -> mLine, col, "Expected a value from %d to %d.\n", loBound, hiBound); + return (0); + } + return (1); + } + } + TrErrorAt (tr, tr -> mLine, col, "Expected an integer.\n"); + return (0); +} + +// Reads and validates (including bounds) a float token. +static int TrReadFloat (TokenReaderT * tr, const double loBound, const double hiBound, double * value) { + uint col, digis, len; + char ch, temp [64 + 1]; + + col = tr -> mColumn; + if (TrSkipWhitespace (tr)) { + col = tr -> mColumn; + len = 0; + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if ((ch == '+') || (ch == '-')) { + temp [len] = ch; + len ++; + tr -> mOut ++; + } + digis = 0; + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (! isdigit (ch)) + break; + if (len < 64) + temp [len] = ch; + len ++; + digis ++; + tr -> mOut ++; + } + if (ch == '.') { + if (len < 64) + temp [len] = ch; + len ++; + tr -> mOut ++; + } + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (! isdigit (ch)) + break; + if (len < 64) + temp [len] = ch; + len ++; + digis ++; + tr -> mOut ++; + } + if (digis > 0) { + if ((ch == 'E') || (ch == 'e')) { + if (len < 64) + temp [len] = ch; + len ++; + digis = 0; + tr -> mOut ++; + if ((ch == '+') || (ch == '-')) { + if (len < 64) + temp [len] = ch; + len ++; + tr -> mOut ++; + } + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (! isdigit (ch)) + break; + if (len < 64) + temp [len] = ch; + len ++; + digis ++; + tr -> mOut ++; + } + } + tr -> mColumn += len; + if ((digis > 0) && (ch != '.') && (! isalpha (ch))) { + if (len > 64) { + TrErrorAt (tr, tr -> mLine, col, "Float is too long."); + return (0); + } + temp [len] = '\0'; + (* value) = strtod (temp, NULL); + if (((* value) < loBound) || ((* value) > hiBound)) { + TrErrorAt (tr, tr -> mLine, col, "Expected a value from %f to %f.\n", loBound, hiBound); + return (0); + } + return (1); + } + } else { + tr -> mColumn += len; + } + } + TrErrorAt (tr, tr -> mLine, col, "Expected a float.\n"); + return (0); +} + +// Reads and validates a string token. +static int TrReadString (TokenReaderT * tr, const uint maxLen, char * text) { + uint col, len; + char ch; + + col = tr -> mColumn; + if (TrSkipWhitespace (tr)) { + col = tr -> mColumn; + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (ch == '\"') { + tr -> mOut ++; + len = 0; + while (TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + tr -> mOut ++; + if (ch == '\"') + break; + if (ch == '\n') { + TrErrorAt (tr, tr -> mLine, col, "Unterminated string at end of line.\n"); + return (0); + } + if (len < maxLen) + text [len] = ch; + len ++; + } + if (ch != '\"') { + tr -> mColumn += 1 + len; + TrErrorAt (tr, tr -> mLine, col, "Unterminated string at end of input.\n"); + return (0); + } + tr -> mColumn += 2 + len; + if (len > maxLen) { + TrErrorAt (tr, tr -> mLine, col, "String is too long.\n"); + return (0); + } + text [len] = '\0'; + return (1); + } + } + TrErrorAt (tr, tr -> mLine, col, "Expected a string.\n"); + return (0); +} + +// Reads and validates the given operator. +static int TrReadOperator (TokenReaderT * tr, const char * op) { + uint col, len; + char ch; + + col = tr -> mColumn; + if (TrSkipWhitespace (tr)) { + col = tr -> mColumn; + len = 0; + while ((op [len] != '\0') && TrLoad (tr)) { + ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; + if (ch != op [len]) + break; + len ++; + tr -> mOut ++; + } + tr -> mColumn += len; + if (op [len] == '\0') + return (1); + } + TrErrorAt (tr, tr -> mLine, col, "Expected '%s' operator.\n", op); + return (0); +} + +/* Performs a string substitution. Any case-insensitive occurrences of the + * pattern string are replaced with the replacement string. The result is + * truncated if necessary. + */ +static int StrSubst (const char * in, const char * pat, const char * rep, const size_t maxLen, char * out) { + size_t inLen, patLen, repLen; + size_t si, di; + int truncated; + + inLen = strlen (in); + patLen = strlen (pat); + repLen = strlen (rep); + si = 0; + di = 0; + truncated = 0; + while ((si < inLen) && (di < maxLen)) { + if (patLen <= (inLen - si)) { + if (strncasecmp (& in [si], pat, patLen) == 0) { + if (repLen > (maxLen - di)) { + repLen = maxLen - di; + truncated = 1; + } + strncpy (& out [di], rep, repLen); + si += patLen; + di += repLen; + } + } + out [di] = in [si]; + si ++; + di ++; + } + if (si < inLen) + truncated = 1; + out [di] = '\0'; + return (! truncated); +} + +// Provide missing math routines for MSVC versions < 1800 (Visual Studio 2013). +#if defined(_MSC_VER) && _MSC_VER < 1800 +static double round (double val) { + if (val < 0.0) + return (ceil (val - 0.5)); + return (floor (val + 0.5)); +} + +static double fmin (double a, double b) { + return ((a < b) ? a : b); +} + +static double fmax (double a, double b) { + return ((a > b) ? a : b); +} +#endif + +// Simple clamp routine. +static double Clamp (const double val, const double lower, const double upper) { + return (fmin (fmax (val, lower), upper)); +} + +// Performs linear interpolation. +static double Lerp (const double a, const double b, const double f) { + return (a + (f * (b - a))); +} + +// Performs a high-passed triangular probability density function dither from +// a double to an integer. It assumes the input sample is already scaled. +static int HpTpdfDither (const double in, int * hpHist) { + const double PRNG_SCALE = 1.0 / (RAND_MAX + 1.0); + int prn; + double out; + + prn = rand (); + out = round (in + (PRNG_SCALE * (prn - (* hpHist)))); + (* hpHist) = prn; + return ((int) out); +} + +// Allocates an array of doubles. +static double * CreateArray (const size_t n) { + double * a = NULL; + + a = (double *) calloc (n, sizeof (double)); + if (a == NULL) { + fprintf (stderr, "Error: Out of memory.\n"); + exit (-1); + } + return (a); +} + +// Frees an array of doubles. +static void DestroyArray (const double * a) { + free ((void *) a); +} + +// Complex number routines. All outputs must be non-NULL. + +// Magnitude/absolute value. +static double ComplexAbs (const double r, const double i) { + return (sqrt ((r * r) + (i * i))); +} + +// Multiply. +static void ComplexMul (const double aR, const double aI, const double bR, const double bI, double * outR, double * outI) { + (* outR) = (aR * bR) - (aI * bI); + (* outI) = (aI * bR) + (aR * bI); +} + +// Base-e exponent. +static void ComplexExp (const double inR, const double inI, double * outR, double * outI) { + double e; + + e = exp (inR); + (* outR) = e * cos (inI); + (* outI) = e * sin (inI); +} + +/* Fast Fourier transform routines. The number of points must be a power of + * two. In-place operation is possible only if both the real and imaginary + * parts are in-place together. + */ + +// Performs bit-reversal ordering. +static void FftArrange (const uint n, const double * inR, const double * inI, double * outR, double * outI) { + uint rk, k, m; + double tempR, tempI; + + if ((inR == outR) && (inI == outI)) { + // Handle in-place arrangement. + rk = 0; + for (k = 0; k < n; k ++) { + if (rk > k) { + tempR = inR [rk]; + tempI = inI [rk]; + outR [rk] = inR [k]; + outI [rk] = inI [k]; + outR [k] = tempR; + outI [k] = tempI; + } + m = n; + while (rk & (m >>= 1)) + rk &= ~m; + rk |= m; + } + } else { + // Handle copy arrangement. + rk = 0; + for (k = 0; k < n; k ++) { + outR [rk] = inR [k]; + outI [rk] = inI [k]; + m = n; + while (rk & (m >>= 1)) + rk &= ~m; + rk |= m; + } + } +} + +// Performs the summation. +static void FftSummation (const uint n, const double s, double * re, double * im) { + double pi; + uint m, m2; + double vR, vI, wR, wI; + uint i, k, mk; + double tR, tI; + + pi = s * M_PI; + for (m = 1, m2 = 2; m < n; m <<= 1, m2 <<= 1) { + // v = Complex (-2.0 * sin (0.5 * pi / m) * sin (0.5 * pi / m), -sin (pi / m)) + vR = sin (0.5 * pi / m); + vR = -2.0 * vR * vR; + vI = -sin (pi / m); + // w = Complex (1.0, 0.0) + wR = 1.0; + wI = 0.0; + for (i = 0; i < m; i ++) { + for (k = i; k < n; k += m2) { + mk = k + m; + // t = ComplexMul (w, out [km2]) + tR = (wR * re [mk]) - (wI * im [mk]); + tI = (wR * im [mk]) + (wI * re [mk]); + // out [mk] = ComplexSub (out [k], t) + re [mk] = re [k] - tR; + im [mk] = im [k] - tI; + // out [k] = ComplexAdd (out [k], t) + re [k] += tR; + im [k] += tI; + } + // t = ComplexMul (v, w) + tR = (vR * wR) - (vI * wI); + tI = (vR * wI) + (vI * wR); + // w = ComplexAdd (w, t) + wR += tR; + wI += tI; + } + } +} + +// Performs a forward FFT. +static void FftForward (const uint n, const double * inR, const double * inI, double * outR, double * outI) { + FftArrange (n, inR, inI, outR, outI); + FftSummation (n, 1.0, outR, outI); +} + +// Performs an inverse FFT. +static void FftInverse (const uint n, const double * inR, const double * inI, double * outR, double * outI) { + double f; + uint i; + + FftArrange (n, inR, inI, outR, outI); + FftSummation (n, -1.0, outR, outI); + f = 1.0 / n; + for (i = 0; i < n; i ++) { + outR [i] *= f; + outI [i] *= f; + } +} + +/* Calculate the complex helical sequence (or discrete-time analytical + * signal) of the given input using the Hilbert transform. Given the + * negative natural logarithm of a signal's magnitude response, the imaginary + * components can be used as the angles for minimum-phase reconstruction. + */ +static void Hilbert (const uint n, const double * in, double * outR, double * outI) { + uint i; + + if (in == outR) { + // Handle in-place operation. + for (i = 0; i < n; i ++) + outI [i] = 0.0; + } else { + // Handle copy operation. + for (i = 0; i < n; i ++) { + outR [i] = in [i]; + outI [i] = 0.0; + } + } + FftForward (n, outR, outI, outR, outI); + /* Currently the Fourier routines operate only on point counts that are + * powers of two. If that changes and n is odd, the following conditional + * should be: i < (n + 1) / 2. + */ + for (i = 1; i < (n / 2); i ++) { + outR [i] *= 2.0; + outI [i] *= 2.0; + } + // If n is odd, the following increment should be skipped. + i ++; + for (; i < n; i ++) { + outR [i] = 0.0; + outI [i] = 0.0; + } + FftInverse (n, outR, outI, outR, outI); +} + +/* Calculate the magnitude response of the given input. This is used in + * place of phase decomposition, since the phase residuals are discarded for + * minimum phase reconstruction. The mirrored half of the response is also + * discarded. + */ +static void MagnitudeResponse (const uint n, const double * inR, const double * inI, double * out) { + const uint m = 1 + (n / 2); + uint i; + + for (i = 0; i < m; i ++) + out [i] = fmax (ComplexAbs (inR [i], inI [i]), EPSILON); +} + +/* Apply a range limit (in dB) to the given magnitude response. This is used + * to adjust the effects of the diffuse-field average on the equalization + * process. + */ +static void LimitMagnitudeResponse (const uint n, const double limit, const double * in, double * out) { + const uint m = 1 + (n / 2); + double halfLim; + uint i, lower, upper; + double ave; + + halfLim = limit / 2.0; + // Convert the response to dB. + for (i = 0; i < m; i ++) + out [i] = 20.0 * log10 (in [i]); + // Use six octaves to calculate the average magnitude of the signal. + lower = ((uint) ceil (n / pow (2.0, 8.0))) - 1; + upper = ((uint) floor (n / pow (2.0, 2.0))) - 1; + ave = 0.0; + for (i = lower; i <= upper; i ++) + ave += out [i]; + ave /= upper - lower + 1; + // Keep the response within range of the average magnitude. + for (i = 0; i < m; i ++) + out [i] = Clamp (out [i], ave - halfLim, ave + halfLim); + // Convert the response back to linear magnitude. + for (i = 0; i < m; i ++) + out [i] = pow (10.0, out [i] / 20.0); +} + +/* Reconstructs the minimum-phase component for the given magnitude response + * of a signal. This is equivalent to phase recomposition, sans the missing + * residuals (which were discarded). The mirrored half of the response is + * reconstructed. + */ +static void MinimumPhase (const uint n, const double * in, double * outR, double * outI) { + const uint m = 1 + (n / 2); + double * mags = NULL; + uint i; + double aR, aI; + + mags = CreateArray (n); + for (i = 0; i < m; i ++) { + mags [i] = fmax (in [i], EPSILON); + outR [i] = -log (mags [i]); + } + for (; i < n; i ++) { + mags [i] = mags [n - i]; + outR [i] = outR [n - i]; + } + Hilbert (n, outR, outR, outI); + // Remove any DC offset the filter has. + outR [0] = 0.0; + outI [0] = 0.0; + for (i = 1; i < n; i ++) { + ComplexExp (0.0, outI [i], & aR, & aI); + ComplexMul (mags [i], 0.0, aR, aI, & outR [i], & outI [i]); + } + DestroyArray (mags); +} + +/* This is the normalized cardinal sine (sinc) function. + * + * sinc(x) = { 1, x = 0 + * { sin(pi x) / (pi x), otherwise. + */ +static double Sinc (const double x) { + if (fabs (x) < EPSILON) + return (1.0); + return (sin (M_PI * x) / (M_PI * x)); +} + +/* The zero-order modified Bessel function of the first kind, used for the + * Kaiser window. + * + * I_0(x) = sum_{k=0}^inf (1 / k!)^2 (x / 2)^(2 k) + * = sum_{k=0}^inf ((x / 2)^k / k!)^2 + */ +static double BesselI_0 (const double x) { + double term, sum, x2, y, last_sum; + int k; + + // Start at k=1 since k=0 is trivial. + term = 1.0; + sum = 1.0; + x2 = x / 2.0; + k = 1; + // Let the integration converge until the term of the sum is no longer + // significant. + do { + y = x2 / k; + k ++; + last_sum = sum; + term *= y * y; + sum += term; + } while (sum != last_sum); + return (sum); +} + +/* Calculate a Kaiser window from the given beta value and a normalized k + * [-1, 1]. + * + * w(k) = { I_0(B sqrt(1 - k^2)) / I_0(B), -1 <= k <= 1 + * { 0, elsewhere. + * + * Where k can be calculated as: + * + * k = i / l, where -l <= i <= l. + * + * or: + * + * k = 2 i / M - 1, where 0 <= i <= M. + */ +static double Kaiser (const double b, const double k) { + double k2; + + k2 = Clamp (k, -1.0, 1.0); + if ((k < -1.0) || (k > 1.0)) + return (0.0); + k2 *= k2; + return (BesselI_0 (b * sqrt (1.0 - k2)) / BesselI_0 (b)); +} + +// Calculates the greatest common divisor of a and b. +static uint Gcd (const uint a, const uint b) { + uint x, y, z; + + x = a; + y = b; + while (y > 0) { + z = y; + y = x % y; + x = z; + } + return (x); +} + +/* Calculates the size (order) of the Kaiser window. Rejection is in dB and + * the transition width is normalized frequency (0.5 is nyquist). + * + * M = { ceil((r - 7.95) / (2.285 2 pi f_t)), r > 21 + * { ceil(5.79 / 2 pi f_t), r <= 21. + * + */ +static uint CalcKaiserOrder (const double rejection, const double transition) { + double w_t; + + w_t = 2.0 * M_PI * transition; + if (rejection > 21.0) + return ((uint) ceil ((rejection - 7.95) / (2.285 * w_t))); + return ((uint) ceil (5.79 / w_t)); +} + +// Calculates the beta value of the Kaiser window. Rejection is in dB. +static double CalcKaiserBeta (const double rejection) { + if (rejection > 50.0) + return (0.1102 * (rejection - 8.7)); + else if (rejection >= 21.0) + return ((0.5842 * pow (rejection - 21.0, 0.4)) + + (0.07886 * (rejection - 21.0))); + else + return (0.0); +} + +/* Calculates a point on the Kaiser-windowed sinc filter for the given half- + * width, beta, gain, and cutoff. The point is specified in non-normalized + * samples, from 0 to M, where M = (2 l + 1). + * + * w(k) 2 p f_t sinc(2 f_t x) + * + * x -- centered sample index (i - l) + * k -- normalized and centered window index (x / l) + * w(k) -- window function (Kaiser) + * p -- gain compensation factor when sampling + * f_t -- normalized center frequency (or cutoff; 0.5 is nyquist) + */ +static double SincFilter (const int l, const double b, const double gain, const double cutoff, const int i) { + return (Kaiser (b, ((double) (i - l)) / l) * 2.0 * gain * cutoff * Sinc (2.0 * cutoff * (i - l))); +} + +/* This is a polyphase sinc-filtered resampler. + * + * Upsample Downsample + * + * p/q = 3/2 p/q = 3/5 + * + * M-+-+-+-> M-+-+-+-> + * -------------------+ ---------------------+ + * p s * f f f f|f| | p s * f f f f f | + * | 0 * 0 0 0|0|0 | | 0 * 0 0 0 0|0| | + * v 0 * 0 0|0|0 0 | v 0 * 0 0 0|0|0 | + * s * f|f|f f f | s * f f|f|f f | + * 0 * |0|0 0 0 0 | 0 * 0|0|0 0 0 | + * --------+=+--------+ 0 * |0|0 0 0 0 | + * d . d .|d|. d . d ----------+=+--------+ + * d . . . .|d|. . . . + * q-> + * q-+-+-+-> + * + * P_f(i,j) = q i mod p + pj + * P_s(i,j) = floor(q i / p) - j + * d[i=0..N-1] = sum_{j=0}^{floor((M - 1) / p)} { + * { f[P_f(i,j)] s[P_s(i,j)], P_f(i,j) < M + * { 0, P_f(i,j) >= M. } + */ + +// Calculate the resampling metrics and build the Kaiser-windowed sinc filter +// that's used to cut frequencies above the destination nyquist. +static void ResamplerSetup (ResamplerT * rs, const uint srcRate, const uint dstRate) { + uint gcd, l; + double cutoff, width, beta; + int i; + + gcd = Gcd (srcRate, dstRate); + rs -> mP = dstRate / gcd; + rs -> mQ = srcRate / gcd; + /* The cutoff is adjusted by half the transition width, so the transition + * ends before the nyquist (0.5). Both are scaled by the downsampling + * factor. + */ + if (rs -> mP > rs -> mQ) { + cutoff = 0.45 / rs -> mP; + width = 0.1 / rs -> mP; + } else { + cutoff = 0.45 / rs -> mQ; + width = 0.1 / rs -> mQ; + } + // A rejection of -180 dB is used for the stop band. + l = CalcKaiserOrder (180.0, width) / 2; + beta = CalcKaiserBeta (180.0); + rs -> mM = (2 * l) + 1; + rs -> mL = l; + rs -> mF = CreateArray (rs -> mM); + for (i = 0; i < ((int) rs -> mM); i ++) + rs -> mF [i] = SincFilter ((int) l, beta, rs -> mP, cutoff, i); +} + +// Clean up after the resampler. +static void ResamplerClear (ResamplerT * rs) { + DestroyArray (rs -> mF); + rs -> mF = NULL; +} + +// Perform the upsample-filter-downsample resampling operation using a +// polyphase filter implementation. +static void ResamplerRun (ResamplerT * rs, const uint inN, const double * in, const uint outN, double * out) { + const uint p = rs -> mP, q = rs -> mQ, m = rs -> mM, l = rs -> mL; + const double * f = rs -> mF; + double * work = NULL; + uint i; + double r; + uint j_f, j_s; + + // Handle in-place operation. + if (in == out) + work = CreateArray (outN); + else + work = out; + // Resample the input. + for (i = 0; i < outN; i ++) { + r = 0.0; + // Input starts at l to compensate for the filter delay. This will + // drop any build-up from the first half of the filter. + j_f = (l + (q * i)) % p; + j_s = (l + (q * i)) / p; + while (j_f < m) { + // Only take input when 0 <= j_s < inN. This single unsigned + // comparison catches both cases. + if (j_s < inN) + r += f [j_f] * in [j_s]; + j_f += p; + j_s --; + } + work [i] = r; + } + // Clean up after in-place operation. + if (in == out) { + for (i = 0; i < outN; i ++) + out [i] = work [i]; + DestroyArray (work); + } +} + +// Read a binary value of the specified byte order and byte size from a file, +// storing it as a 32-bit unsigned integer. +static int ReadBin4 (FILE * fp, const char * filename, const ByteOrderT order, const uint bytes, uint4 * out) { + uint1 in [4]; + uint4 accum; + uint i; + + if (fread (in, 1, bytes, fp) != bytes) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); + return (0); + } + accum = 0; + switch (order) { + case BO_LITTLE : + for (i = 0; i < bytes; i ++) + accum = (accum << 8) | in [bytes - i - 1]; + break; + case BO_BIG : + for (i = 0; i < bytes; i ++) + accum = (accum << 8) | in [i]; + break; + default : + break; + } + (* out) = accum; + return (1); +} + +// Read a binary value of the specified byte order from a file, storing it as +// a 64-bit unsigned integer. +static int ReadBin8 (FILE * fp, const char * filename, const ByteOrderT order, uint8 * out) { + uint1 in [8]; + uint8 accum; + uint i; + + if (fread (in, 1, 8, fp) != 8) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); + return (0); + } + accum = 0ULL; + switch (order) { + case BO_LITTLE : + for (i = 0; i < 8; i ++) + accum = (accum << 8) | in [8 - i - 1]; + break; + case BO_BIG : + for (i = 0; i < 8; i ++) + accum = (accum << 8) | in [i]; + break; + default : + break; + } + (* out) = accum; + return (1); +} + +// Write an ASCII string to a file. +static int WriteAscii (const char * out, FILE * fp, const char * filename) { + size_t len; + + len = strlen (out); + if (fwrite (out, 1, len, fp) != len) { + fclose (fp); + fprintf (stderr, "Error: Bad write to file '%s'.\n", filename); + return (0); + } + return (1); +} + +// Write a binary value of the given byte order and byte size to a file, +// loading it from a 32-bit unsigned integer. +static int WriteBin4 (const ByteOrderT order, const uint bytes, const uint4 in, FILE * fp, const char * filename) { + uint1 out [4]; + uint i; + + switch (order) { + case BO_LITTLE : + for (i = 0; i < bytes; i ++) + out [i] = (in >> (i * 8)) & 0x000000FF; + break; + case BO_BIG : + for (i = 0; i < bytes; i ++) + out [bytes - i - 1] = (in >> (i * 8)) & 0x000000FF; + break; + default : + break; + } + if (fwrite (out, 1, bytes, fp) != bytes) { + fprintf (stderr, "Error: Bad write to file '%s'.\n", filename); + return (0); + } + return (1); +} + +/* Read a binary value of the specified type, byte order, and byte size from + * a file, converting it to a double. For integer types, the significant + * bits are used to normalize the result. The sign of bits determines + * whether they are padded toward the MSB (negative) or LSB (positive). + * Floating-point types are not normalized. + */ +static int ReadBinAsDouble (FILE * fp, const char * filename, const ByteOrderT order, const ElementTypeT type, const uint bytes, const int bits, double * out) { + union { + uint4 ui; + int4 i; + float f; + } v4; + union { + uint8 ui; + double f; + } v8; + + (* out) = 0.0; + if (bytes > 4) { + if (! ReadBin8 (fp, filename, order, & v8 . ui)) + return (0); + if (type == ET_FP) + (* out) = v8 . f; + } else { + if (! ReadBin4 (fp, filename, order, bytes, & v4 . ui)) + return (0); + if (type == ET_FP) { + (* out) = (double) v4 . f; + } else { + if (bits > 0) + v4 . ui >>= (8 * bytes) - ((uint) bits); + else + v4 . ui &= (0xFFFFFFFF >> (32 + bits)); + if (v4 . ui & ((uint) (1 << (abs (bits) - 1)))) + v4 . ui |= (0xFFFFFFFF << abs (bits)); + (* out) = v4 . i / ((double) (1 << (abs (bits) - 1))); + } + } + return (1); +} + +/* Read an ascii value of the specified type from a file, converting it to a + * double. For integer types, the significant bits are used to normalize the + * result. The sign of the bits should always be positive. This also skips + * up to one separator character before the element itself. + */ +static int ReadAsciiAsDouble (TokenReaderT * tr, const char * filename, const ElementTypeT type, const uint bits, double * out) { + int v; + + if (TrIsOperator (tr, ",")) + TrReadOperator (tr, ","); + else if (TrIsOperator (tr, ":")) + TrReadOperator (tr, ":"); + else if (TrIsOperator (tr, ";")) + TrReadOperator (tr, ";"); + else if (TrIsOperator (tr, "|")) + TrReadOperator (tr, "|"); + if (type == ET_FP) { + if (! TrReadFloat (tr, -HUGE_VAL, HUGE_VAL, out)) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); + return (0); + } + } else { + if (! TrReadInt (tr, -(1 << (bits - 1)), (1 << (bits - 1)) - 1, & v)) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); + return (0); + } + (* out) = v / ((double) ((1 << (bits - 1)) - 1)); + } + return (1); +} + +// Read the RIFF/RIFX WAVE format chunk from a file, validating it against +// the source parameters and data set metrics. +static int ReadWaveFormat (FILE * fp, const ByteOrderT order, const uint hrirRate, SourceRefT * src) { + uint4 fourCC, chunkSize; + uint4 format, channels, rate, dummy, block, size, bits; + + chunkSize = 0; + do { + if (chunkSize > 0) + fseek (fp, (long) chunkSize, SEEK_CUR); + if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || + (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) + return (0); + } while (fourCC != FOURCC_FMT); + if ((! ReadBin4 (fp, src -> mPath, order, 2, & format)) || + (! ReadBin4 (fp, src -> mPath, order, 2, & channels)) || + (! ReadBin4 (fp, src -> mPath, order, 4, & rate)) || + (! ReadBin4 (fp, src -> mPath, order, 4, & dummy)) || + (! ReadBin4 (fp, src -> mPath, order, 2, & block))) + return (0); + block /= channels; + if (chunkSize > 14) { + if (! ReadBin4 (fp, src -> mPath, order, 2, & size)) + return (0); + size /= 8; + if (block > size) + size = block; + } else { + size = block; + } + if (format == WAVE_FORMAT_EXTENSIBLE) { + fseek (fp, 2, SEEK_CUR); + if (! ReadBin4 (fp, src -> mPath, order, 2, & bits)) + return (0); + if (bits == 0) + bits = 8 * size; + fseek (fp, 4, SEEK_CUR); + if (! ReadBin4 (fp, src -> mPath, order, 2, & format)) + return (0); + fseek (fp, (long) (chunkSize - 26), SEEK_CUR); + } else { + bits = 8 * size; + if (chunkSize > 14) + fseek (fp, (long) (chunkSize - 16), SEEK_CUR); + else + fseek (fp, (long) (chunkSize - 14), SEEK_CUR); + } + if ((format != WAVE_FORMAT_PCM) && (format != WAVE_FORMAT_IEEE_FLOAT)) { + fprintf (stderr, "Error: Unsupported WAVE format in file '%s'.\n", src -> mPath); + return (0); + } + if (src -> mChannel >= channels) { + fprintf (stderr, "Error: Missing source channel in WAVE file '%s'.\n", src -> mPath); + return (0); + } + if (rate != hrirRate) { + fprintf (stderr, "Error: Mismatched source sample rate in WAVE file '%s'.\n", src -> mPath); + return (0); + } + if (format == WAVE_FORMAT_PCM) { + if ((size < 2) || (size > 4)) { + fprintf (stderr, "Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath); + return (0); + } + if ((bits < 16) || (bits > (8 * size))) { + fprintf (stderr, "Error: Bad significant bits in WAVE file '%s'.\n", src -> mPath); + return (0); + } + src -> mType = ET_INT; + } else { + if ((size != 4) && (size != 8)) { + fprintf (stderr, "Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath); + return (0); + } + src -> mType = ET_FP; + } + src -> mSize = size; + src -> mBits = (int) bits; + src -> mSkip = channels; + return (1); +} + +// Read a RIFF/RIFX WAVE data chunk, converting all elements to doubles. +static int ReadWaveData (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { + int pre, post, skip; + uint i; + + pre = (int) (src -> mSize * src -> mChannel); + post = (int) (src -> mSize * (src -> mSkip - src -> mChannel - 1)); + skip = 0; + for (i = 0; i < n; i ++) { + skip += pre; + if (skip > 0) + fseek (fp, skip, SEEK_CUR); + if (! ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i])) + return (0); + skip = post; + } + if (skip > 0) + fseek (fp, skip, SEEK_CUR); + return (1); +} + +// Read the RIFF/RIFX WAVE list or data chunk, converting all elements to +// doubles. +static int ReadWaveList (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { + uint4 fourCC, chunkSize, listSize, count; + uint block, skip, offset, i; + double lastSample; + + for (;;) { + if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || + (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) + return (0); + if (fourCC == FOURCC_DATA) { + block = src -> mSize * src -> mSkip; + count = chunkSize / block; + if (count < (src -> mOffset + n)) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", src -> mPath); + return (0); + } + fseek (fp, (long) (src -> mOffset * block), SEEK_CUR); + if (! ReadWaveData (fp, src, order, n, & hrir [0])) + return (0); + return (1); + } else if (fourCC == FOURCC_LIST) { + if (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) + return (0); + chunkSize -= 4; + if (fourCC == FOURCC_WAVL) + break; + } + if (chunkSize > 0) + fseek (fp, (long) chunkSize, SEEK_CUR); + } + listSize = chunkSize; + block = src -> mSize * src -> mSkip; + skip = src -> mOffset; + offset = 0; + lastSample = 0.0; + while ((offset < n) && (listSize > 8)) { + if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || + (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) + return (0); + listSize -= 8 + chunkSize; + if (fourCC == FOURCC_DATA) { + count = chunkSize / block; + if (count > skip) { + fseek (fp, (long) (skip * block), SEEK_CUR); + chunkSize -= skip * block; + count -= skip; + skip = 0; + if (count > (n - offset)) + count = n - offset; + if (! ReadWaveData (fp, src, order, count, & hrir [offset])) + return (0); + chunkSize -= count * block; + offset += count; + lastSample = hrir [offset - 1]; + } else { + skip -= count; + count = 0; + } + } else if (fourCC == FOURCC_SLNT) { + if (! ReadBin4 (fp, src -> mPath, order, 4, & count)) + return (0); + chunkSize -= 4; + if (count > skip) { + count -= skip; + skip = 0; + if (count > (n - offset)) + count = n - offset; + for (i = 0; i < count; i ++) + hrir [offset + i] = lastSample; + offset += count; + } else { + skip -= count; + count = 0; + } + } + if (chunkSize > 0) + fseek (fp, (long) chunkSize, SEEK_CUR); + } + if (offset < n) { + fprintf (stderr, "Error: Bad read from file '%s'.\n", src -> mPath); + return (0); + } + return (1); +} + +// Load a source HRIR from a RIFF/RIFX WAVE file. +static int LoadWaveSource (FILE * fp, SourceRefT * src, const uint hrirRate, const uint n, double * hrir) { + uint4 fourCC, dummy; + ByteOrderT order; + + if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || + (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & dummy))) + return (0); + if (fourCC == FOURCC_RIFF) { + order = BO_LITTLE; + } else if (fourCC == FOURCC_RIFX) { + order = BO_BIG; + } else { + fprintf (stderr, "Error: No RIFF/RIFX chunk in file '%s'.\n", src -> mPath); + return (0); + } + if (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) + return (0); + if (fourCC != FOURCC_WAVE) { + fprintf (stderr, "Error: Not a RIFF/RIFX WAVE file '%s'.\n", src -> mPath); + return (0); + } + if (! ReadWaveFormat (fp, order, hrirRate, src)) + return (0); + if (! ReadWaveList (fp, src, order, n, hrir)) + return (0); + return (1); +} + +// Load a source HRIR from a binary file. +static int LoadBinarySource (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { + uint i; + + fseek (fp, (long) src -> mOffset, SEEK_SET); + for (i = 0; i < n; i ++) { + if (! ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i])) + return (0); + if (src -> mSkip > 0) + fseek (fp, (long) src -> mSkip, SEEK_CUR); + } + return (1); +} + +// Load a source HRIR from an ASCII text file containing a list of elements +// separated by whitespace or common list operators (',', ';', ':', '|'). +static int LoadAsciiSource (FILE * fp, const SourceRefT * src, const uint n, double * hrir) { + TokenReaderT tr; + uint i, j; + double dummy; + + TrSetup (fp, NULL, & tr); + for (i = 0; i < src -> mOffset; i ++) { + if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & dummy)) + return (0); + } + for (i = 0; i < n; i ++) { + if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & hrir [i])) + return (0); + for (j = 0; j < src -> mSkip; j ++) { + if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & dummy)) + return (0); + } + } + return (1); +} + +// Load a source HRIR from a supported file type. +static int LoadSource (SourceRefT * src, const uint hrirRate, const uint n, double * hrir) { + FILE * fp = NULL; + int result; + + if (src -> mFormat == SF_ASCII) + fp = fopen (src -> mPath, "r"); + else + fp = fopen (src -> mPath, "rb"); + if (fp == NULL) { + fprintf (stderr, "Error: Could not open source file '%s'.\n", src -> mPath); + return (0); + } + if (src -> mFormat == SF_WAVE) + result = LoadWaveSource (fp, src, hrirRate, n, hrir); + else if (src -> mFormat == SF_BIN_LE) + result = LoadBinarySource (fp, src, BO_LITTLE, n, hrir); + else if (src -> mFormat == SF_BIN_BE) + result = LoadBinarySource (fp, src, BO_BIG, n, hrir); + else + result = LoadAsciiSource (fp, src, n, hrir); + fclose (fp); + return (result); +} + +// Calculate the onset time of an HRIR and average it with any existing +// timing for its elevation and azimuth. +static void AverageHrirOnset (const double * hrir, const double f, const uint ei, const uint ai, const HrirDataT * hData) { + double mag; + uint n, i, j; + + mag = 0.0; + n = hData -> mIrPoints; + for (i = 0; i < n; i ++) + mag = fmax (fabs (hrir [i]), mag); + mag *= 0.15; + for (i = 0; i < n; i ++) { + if (fabs (hrir [i]) >= mag) + break; + } + j = hData -> mEvOffset [ei] + ai; + hData -> mHrtds [j] = Lerp (hData -> mHrtds [j], ((double) i) / hData -> mIrRate, f); +} + +// Calculate the magnitude response of an HRIR and average it with any +// existing responses for its elevation and azimuth. +static void AverageHrirMagnitude (const double * hrir, const double f, const uint ei, const uint ai, const HrirDataT * hData) { + double * re = NULL, * im = NULL; + uint n, m, i, j; + + n = hData -> mFftSize; + re = CreateArray (n); + im = CreateArray (n); + for (i = 0; i < hData -> mIrPoints; i ++) { + re [i] = hrir [i]; + im [i] = 0.0; + } + for (; i < n; i ++) { + re [i] = 0.0; + im [i] = 0.0; + } + FftForward (n, re, im, re, im); + MagnitudeResponse (n, re, im, re); + m = 1 + (n / 2); + j = (hData -> mEvOffset [ei] + ai) * hData -> mIrSize; + for (i = 0; i < m; i ++) + hData -> mHrirs [j + i] = Lerp (hData -> mHrirs [j + i], re [i], f); + DestroyArray (im); + DestroyArray (re); +} + +/* Calculate the contribution of each HRIR to the diffuse-field average based + * on the area of its surface patch. All patches are centered at the HRIR + * coordinates on the unit sphere and are measured by solid angle. + */ +static void CalculateDfWeights (const HrirDataT * hData, double * weights) { + uint ei; + double evs, sum, ev, up_ev, down_ev, solidAngle; + + evs = 90.0 / (hData -> mEvCount - 1); + sum = 0.0; + for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) { + // For each elevation, calculate the upper and lower limits of the + // patch band. + ev = -90.0 + (ei * 2.0 * evs); + if (ei < (hData -> mEvCount - 1)) + up_ev = (ev + evs) * M_PI / 180.0; + else + up_ev = M_PI / 2.0; + if (ei > 0) + down_ev = (ev - evs) * M_PI / 180.0; + else + down_ev = -M_PI / 2.0; + // Calculate the area of the patch band. + solidAngle = 2.0 * M_PI * (sin (up_ev) - sin (down_ev)); + // Each weight is the area of one patch. + weights [ei] = solidAngle / hData -> mAzCount [ei]; + // Sum the total surface area covered by the HRIRs. + sum += solidAngle; + } + // Normalize the weights given the total surface coverage. + for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) + weights [ei] /= sum; +} + +/* Calculate the diffuse-field average from the given magnitude responses of + * the HRIR set. Weighting can be applied to compensate for the varying + * surface area covered by each HRIR. The final average can then be limited + * by the specified magnitude range (in positive dB; 0.0 to skip). + */ +static void CalculateDiffuseFieldAverage (const HrirDataT * hData, const int weighted, const double limit, double * dfa) { + double * weights = NULL; + uint ei, ai, count, step, start, end, m, j, i; + double weight; + + weights = CreateArray (hData -> mEvCount); + if (weighted) { + // Use coverage weighting to calculate the average. + CalculateDfWeights (hData, weights); + } else { + // If coverage weighting is not used, the weights still need to be + // averaged by the number of HRIRs. + count = 0; + for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) + count += hData -> mAzCount [ei]; + for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) + weights [ei] = 1.0 / count; + } + ei = hData -> mEvStart; + ai = 0; + step = hData -> mIrSize; + start = hData -> mEvOffset [ei] * step; + end = hData -> mIrCount * step; + m = 1 + (hData -> mFftSize / 2); + for (i = 0; i < m; i ++) + dfa [i] = 0.0; + for (j = start; j < end; j += step) { + // Get the weight for this HRIR's contribution. + weight = weights [ei]; + // Add this HRIR's weighted power average to the total. + for (i = 0; i < m; i ++) + dfa [i] += weight * hData -> mHrirs [j + i] * hData -> mHrirs [j + i]; + // Determine the next weight to use. + ai ++; + if (ai >= hData -> mAzCount [ei]) { + ei ++; + ai = 0; + } + } + // Finish the average calculation and keep it from being too small. + for (i = 0; i < m; i ++) + dfa [i] = fmax (sqrt (dfa [i]), EPSILON); + // Apply a limit to the magnitude range of the diffuse-field average if + // desired. + if (limit > 0.0) + LimitMagnitudeResponse (hData -> mFftSize, limit, dfa, dfa); + DestroyArray (weights); +} + +// Perform diffuse-field equalization on the magnitude responses of the HRIR +// set using the given average response. +static void DiffuseFieldEqualize (const double * dfa, const HrirDataT * hData) { + uint step, start, end, m, j, i; + + step = hData -> mIrSize; + start = hData -> mEvOffset [hData -> mEvStart] * step; + end = hData -> mIrCount * step; + m = 1 + (hData -> mFftSize / 2); + for (j = start; j < end; j += step) { + for (i = 0; i < m; i ++) + hData -> mHrirs [j + i] /= dfa [i]; + } +} + +// Perform minimum-phase reconstruction using the magnitude responses of the +// HRIR set. +static void ReconstructHrirs (const HrirDataT * hData) { + double * re = NULL, * im = NULL; + uint step, start, end, n, j, i; + + step = hData -> mIrSize; + start = hData -> mEvOffset [hData -> mEvStart] * step; + end = hData -> mIrCount * step; + n = hData -> mFftSize; + re = CreateArray (n); + im = CreateArray (n); + for (j = start; j < end; j += step) { + MinimumPhase (n, & hData -> mHrirs [j], re, im); + FftInverse (n, re, im, re, im); + for (i = 0; i < hData -> mIrPoints; i ++) + hData -> mHrirs [j + i] = re [i]; + } + DestroyArray (im); + DestroyArray (re); +} + +// Resamples the HRIRs for use at the given sampling rate. +static void ResampleHrirs (const uint rate, HrirDataT * hData) { + ResamplerT rs; + uint n, step, start, end, j; + + ResamplerSetup (& rs, hData -> mIrRate, rate); + n = hData -> mIrPoints; + step = hData -> mIrSize; + start = hData -> mEvOffset [hData -> mEvStart] * step; + end = hData -> mIrCount * step; + for (j = start; j < end; j += step) + ResamplerRun (& rs, n, & hData -> mHrirs [j], n, & hData -> mHrirs [j]); + ResamplerClear (& rs); + hData -> mIrRate = rate; +} + +/* Given an elevation index and an azimuth, calculate the indices of the two + * HRIRs that bound the coordinate along with a factor for calculating the + * continous HRIR using interpolation. + */ +static void CalcAzIndices (const HrirDataT * hData, const uint ei, const double az, uint * j0, uint * j1, double * jf) { + double af; + uint ai; + + af = ((2.0 * M_PI) + az) * hData -> mAzCount [ei] / (2.0 * M_PI); + ai = ((uint) af) % hData -> mAzCount [ei]; + af -= floor (af); + (* j0) = hData -> mEvOffset [ei] + ai; + (* j1) = hData -> mEvOffset [ei] + ((ai + 1) % hData -> mAzCount [ei]); + (* jf) = af; +} + +// Synthesize any missing onset timings at the bottom elevations. This just +// blends between slightly exaggerated known onsets. Not an accurate model. +static void SynthesizeOnsets (HrirDataT * hData) { + uint oi, e, a, j0, j1; + double t, of, jf; + + oi = hData -> mEvStart; + t = 0.0; + for (a = 0; a < hData -> mAzCount [oi]; a ++) + t += hData -> mHrtds [hData -> mEvOffset [oi] + a]; + hData -> mHrtds [0] = 1.32e-4 + (t / hData -> mAzCount [oi]); + for (e = 1; e < hData -> mEvStart; e ++) { + of = ((double) e) / hData -> mEvStart; + for (a = 0; a < hData -> mAzCount [e]; a ++) { + CalcAzIndices (hData, oi, a * 2.0 * M_PI / hData -> mAzCount [e], & j0, & j1, & jf); + hData -> mHrtds [hData -> mEvOffset [e] + a] = Lerp (hData -> mHrtds [0], Lerp (hData -> mHrtds [j0], hData -> mHrtds [j1], jf), of); + } + } +} + +/* Attempt to synthesize any missing HRIRs at the bottom elevations. Right + * now this just blends the lowest elevation HRIRs together and applies some + * attenuation and high frequency damping. It is a simple, if inaccurate + * model. + */ +static void SynthesizeHrirs (HrirDataT * hData) { + uint oi, a, e, step, n, i, j; + double of, b; + uint j0, j1; + double jf; + double lp [4], s0, s1; + + if (hData -> mEvStart <= 0) + return; + step = hData -> mIrSize; + oi = hData -> mEvStart; + n = hData -> mIrPoints; + for (i = 0; i < n; i ++) + hData -> mHrirs [i] = 0.0; + for (a = 0; a < hData -> mAzCount [oi]; a ++) { + j = (hData -> mEvOffset [oi] + a) * step; + for (i = 0; i < n; i ++) + hData -> mHrirs [i] += hData -> mHrirs [j + i] / hData -> mAzCount [oi]; + } + for (e = 1; e < hData -> mEvStart; e ++) { + of = ((double) e) / hData -> mEvStart; + b = (1.0 - of) * (3.5e-6 * hData -> mIrRate); + for (a = 0; a < hData -> mAzCount [e]; a ++) { + j = (hData -> mEvOffset [e] + a) * step; + CalcAzIndices (hData, oi, a * 2.0 * M_PI / hData -> mAzCount [e], & j0, & j1, & jf); + j0 *= step; + j1 *= step; + lp [0] = 0.0; + lp [1] = 0.0; + lp [2] = 0.0; + lp [3] = 0.0; + for (i = 0; i < n; i ++) { + s0 = hData -> mHrirs [i]; + s1 = Lerp (hData -> mHrirs [j0 + i], hData -> mHrirs [j1 + i], jf); + s0 = Lerp (s0, s1, of); + lp [0] = Lerp (s0, lp [0], b); + lp [1] = Lerp (lp [0], lp [1], b); + lp [2] = Lerp (lp [1], lp [2], b); + lp [3] = Lerp (lp [2], lp [3], b); + hData -> mHrirs [j + i] = lp [3]; + } + } + } + b = 3.5e-6 * hData -> mIrRate; + lp [0] = 0.0; + lp [1] = 0.0; + lp [2] = 0.0; + lp [3] = 0.0; + for (i = 0; i < n; i ++) { + s0 = hData -> mHrirs [i]; + lp [0] = Lerp (s0, lp [0], b); + lp [1] = Lerp (lp [0], lp [1], b); + lp [2] = Lerp (lp [1], lp [2], b); + lp [3] = Lerp (lp [2], lp [3], b); + hData -> mHrirs [i] = lp [3]; + } + hData -> mEvStart = 0; +} + +// The following routines assume a full set of HRIRs for all elevations. + +// Normalize the HRIR set and slightly attenuate the result. +static void NormalizeHrirs (const HrirDataT * hData) { + uint step, end, n, j, i; + double maxLevel; + + step = hData -> mIrSize; + end = hData -> mIrCount * step; + n = hData -> mIrPoints; + maxLevel = 0.0; + for (j = 0; j < end; j += step) { + for (i = 0; i < n; i ++) + maxLevel = fmax (fabs (hData -> mHrirs [j + i]), maxLevel); + } + maxLevel = 1.01 * maxLevel; + for (j = 0; j < end; j += step) { + for (i = 0; i < n; i ++) + hData -> mHrirs [j + i] /= maxLevel; + } +} + +// Calculate the left-ear time delay using a spherical head model. +static double CalcLTD (const double ev, const double az, const double rad, const double dist) { + double azp, dlp, l, al; + + azp = asin (cos (ev) * sin (az)); + dlp = sqrt ((dist * dist) + (rad * rad) + (2.0 * dist * rad * sin (azp))); + l = sqrt ((dist * dist) - (rad * rad)); + al = (0.5 * M_PI) + azp; + if (dlp > l) + dlp = l + (rad * (al - acos (rad / dist))); + return (dlp / 343.3); +} + +// Calculate the effective head-related time delays for each minimum-phase +// HRIR. +static void CalculateHrtds (const HeadModelT model, const double radius, HrirDataT * hData) { + double minHrtd, maxHrtd; + uint e, a, j; + double t; + + minHrtd = 1000.0; + maxHrtd = -1000.0; + for (e = 0; e < hData -> mEvCount; e ++) { + for (a = 0; a < hData -> mAzCount [e]; a ++) { + j = hData -> mEvOffset [e] + a; + if (model == HM_DATASET) { + t = hData -> mHrtds [j] * radius / hData -> mRadius; + } else { + t = CalcLTD ((-90.0 + (e * 180.0 / (hData -> mEvCount - 1))) * M_PI / 180.0, + (a * 360.0 / hData -> mAzCount [e]) * M_PI / 180.0, + radius, hData -> mDistance); + } + hData -> mHrtds [j] = t; + maxHrtd = fmax (t, maxHrtd); + minHrtd = fmin (t, minHrtd); + } + } + maxHrtd -= minHrtd; + for (j = 0; j < hData -> mIrCount; j ++) + hData -> mHrtds [j] -= minHrtd; + hData -> mMaxHrtd = maxHrtd; +} + +// Store the OpenAL Soft HRTF data set. +static int StoreMhr (const HrirDataT * hData, const char * filename) { + FILE * fp = NULL; + uint e, step, end, n, j, i; + int hpHist, v; + + if ((fp = fopen (filename, "wb")) == NULL) { + fprintf (stderr, "Error: Could not open MHR file '%s'.\n", filename); + return (0); + } + if (! WriteAscii (MHR_FORMAT, fp, filename)) + return (0); + if (! WriteBin4 (BO_LITTLE, 4, (uint4) hData -> mIrRate, fp, filename)) + return (0); + if (! WriteBin4 (BO_LITTLE, 1, (uint4) hData -> mIrPoints, fp, filename)) + return (0); + if (! WriteBin4 (BO_LITTLE, 1, (uint4) hData -> mEvCount, fp, filename)) + return (0); + for (e = 0; e < hData -> mEvCount; e ++) { + if (! WriteBin4 (BO_LITTLE, 1, (uint4) hData -> mAzCount [e], fp, filename)) + return (0); + } + step = hData -> mIrSize; + end = hData -> mIrCount * step; + n = hData -> mIrPoints; + srand (0x31DF840C); + for (j = 0; j < end; j += step) { + hpHist = 0; + for (i = 0; i < n; i ++) { + v = HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist); + if (! WriteBin4 (BO_LITTLE, 2, (uint4) v, fp, filename)) + return (0); + } + } + for (j = 0; j < hData -> mIrCount; j ++) { + v = (int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]), MAX_HRTD); + if (! WriteBin4 (BO_LITTLE, 1, (uint4) v, fp, filename)) + return (0); + } + fclose (fp); + return (1); +} + +// Store the OpenAL Soft built-in table. +static int StoreTable (const HrirDataT * hData, const char * filename) { + FILE * fp = NULL; + uint step, end, n, j, i; + int hpHist, v; + char text [128 + 1]; + + if ((fp = fopen (filename, "wb")) == NULL) { + fprintf (stderr, "Error: Could not open table file '%s'.\n", filename); + return (0); + } + snprintf (text, 128, "/* Elevation metrics */\n" + "static const ALubyte defaultAzCount[%u] = { ", hData -> mEvCount); + if (! WriteAscii (text, fp, filename)) + return (0); + for (i = 0; i < hData -> mEvCount; i ++) { + snprintf (text, 128, "%u, ", hData -> mAzCount [i]); + if (! WriteAscii (text, fp, filename)) + return (0); + } + snprintf (text, 128, "};\n" + "static const ALushort defaultEvOffset[%u] = { ", hData -> mEvCount); + if (! WriteAscii (text, fp, filename)) + return (0); + for (i = 0; i < hData -> mEvCount; i ++) { + snprintf (text, 128, "%u, ", hData -> mEvOffset [i]); + if (! WriteAscii (text, fp, filename)) + return (0); + } + step = hData -> mIrSize; + end = hData -> mIrCount * step; + n = hData -> mIrPoints; + snprintf (text, 128, "};\n\n" + "/* HRIR Coefficients */\n" + "static const ALshort defaultCoeffs[%u] =\n{\n", hData -> mIrCount * n); + if (! WriteAscii (text, fp, filename)) + return (0); + srand (0x31DF840C); + for (j = 0; j < end; j += step) { + if (! WriteAscii (" ", fp, filename)) + return (0); + hpHist = 0; + for (i = 0; i < n; i ++) { + v = HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist); + snprintf (text, 128, " %+d,", v); + if (! WriteAscii (text, fp, filename)) + return (0); + } + if (! WriteAscii ("\n", fp, filename)) + return (0); + } + snprintf (text, 128, "};\n\n" + "/* HRIR Delays */\n" + "static const ALubyte defaultDelays[%u] =\n{\n" + " ", hData -> mIrCount); + if (! WriteAscii (text, fp, filename)) + return (0); + for (j = 0; j < hData -> mIrCount; j ++) { + v = (int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]), MAX_HRTD); + snprintf (text, 128, " %d,", v); + if (! WriteAscii (text, fp, filename)) + return (0); + } + if (! WriteAscii ("\n};\n\n" + "/* Default HRTF Definition */\n", fp, filename)) + return (0); + snprintf (text, 128, "static const struct Hrtf DefaultHrtf = {\n" + " %u, %u, %u, defaultAzCount, defaultEvOffset,\n", + hData -> mIrRate, hData -> mIrPoints, hData -> mEvCount); + if (! WriteAscii (text, fp, filename)) + return (0); + if (! WriteAscii (" defaultCoeffs, defaultDelays, NULL\n" + "};\n", fp, filename)) + return (0); + fclose (fp); + return (1); +} + +// Process the data set definition to read and validate the data set metrics. +static int ProcessMetrics (TokenReaderT * tr, const uint fftSize, const uint truncSize, HrirDataT * hData) { + char ident [MAX_IDENT_LEN + 1]; + uint line, col; + int intVal; + uint points; + double fpVal; + int hasRate = 0, hasPoints = 0, hasAzimuths = 0; + int hasRadius = 0, hasDistance = 0; + + while (! (hasRate && hasPoints && hasAzimuths && hasRadius && hasDistance)) { + TrIndication (tr, & line, & col); + if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) + return (0); + if (strcasecmp (ident, "rate") == 0) { + if (hasRate) { + TrErrorAt (tr, line, col, "Redefinition of 'rate'.\n"); + return (0); + } + if (! TrReadOperator (tr, "=")) + return (0); + if (! TrReadInt (tr, MIN_RATE, MAX_RATE, & intVal)) + return (0); + hData -> mIrRate = (uint) intVal; + hasRate = 1; + } else if (strcasecmp (ident, "points") == 0) { + if (hasPoints) { + TrErrorAt (tr, line, col, "Redefinition of 'points'.\n"); + return (0); + } + if (! TrReadOperator (tr, "=")) + return (0); + TrIndication (tr, & line, & col); + if (! TrReadInt (tr, MIN_POINTS, MAX_POINTS, & intVal)) + return (0); + points = (uint) intVal; + if ((fftSize > 0) && (points > fftSize)) { + TrErrorAt (tr, line, col, "Value exceeds the overriden FFT size.\n"); + return (0); + } + if (points < truncSize) { + TrErrorAt (tr, line, col, "Value is below the truncation size.\n"); + return (0); + } + hData -> mIrPoints = points; + hData -> mFftSize = fftSize; + if (fftSize <= 0) { + points = 1; + while (points < (4 * hData -> mIrPoints)) + points <<= 1; + hData -> mFftSize = points; + hData -> mIrSize = 1 + (points / 2); + } else { + hData -> mFftSize = fftSize; + hData -> mIrSize = 1 + (fftSize / 2); + if (points > hData -> mIrSize) + hData -> mIrSize = points; + } + hasPoints = 1; + } else if (strcasecmp (ident, "azimuths") == 0) { + if (hasAzimuths) { + TrErrorAt (tr, line, col, "Redefinition of 'azimuths'.\n"); + return (0); + } + if (! TrReadOperator (tr, "=")) + return (0); + hData -> mIrCount = 0; + hData -> mEvCount = 0; + hData -> mEvOffset [0] = 0; + for (;;) { + if (! TrReadInt (tr, MIN_AZ_COUNT, MAX_AZ_COUNT, & intVal)) + return (0); + hData -> mAzCount [hData -> mEvCount] = (uint) intVal; + hData -> mIrCount += (uint) intVal; + hData -> mEvCount ++; + if (! TrIsOperator (tr, ",")) + break; + if (hData -> mEvCount >= MAX_EV_COUNT) { + TrError (tr, "Exceeded the maximum of %d elevations.\n", MAX_EV_COUNT); + return (0); + } + hData -> mEvOffset [hData -> mEvCount] = hData -> mEvOffset [hData -> mEvCount - 1] + ((uint) intVal); + TrReadOperator (tr, ","); + } + if (hData -> mEvCount < MIN_EV_COUNT) { + TrErrorAt (tr, line, col, "Did not reach the minimum of %d azimuth counts.\n", MIN_EV_COUNT); + return (0); + } + hasAzimuths = 1; + } else if (strcasecmp (ident, "radius") == 0) { + if (hasRadius) { + TrErrorAt (tr, line, col, "Redefinition of 'radius'.\n"); + return (0); + } + if (! TrReadOperator (tr, "=")) + return (0); + if (! TrReadFloat (tr, MIN_RADIUS, MAX_RADIUS, & fpVal)) + return (0); + hData -> mRadius = fpVal; + hasRadius = 1; + } else if (strcasecmp (ident, "distance") == 0) { + if (hasDistance) { + TrErrorAt (tr, line, col, "Redefinition of 'distance'.\n"); + return (0); + } + if (! TrReadOperator (tr, "=")) + return (0); + if (! TrReadFloat (tr, MIN_DISTANCE, MAX_DISTANCE, & fpVal)) + return (0); + hData -> mDistance = fpVal; + hasDistance = 1; + } else { + TrErrorAt (tr, line, col, "Expected a metric name.\n"); + return (0); + } + TrSkipWhitespace (tr); + } + return (1); +} + +// Parse an index pair from the data set definition. +static int ReadIndexPair (TokenReaderT * tr, const HrirDataT * hData, uint * ei, uint * ai) { + int intVal; + + if (! TrReadInt (tr, 0, (int) hData -> mEvCount, & intVal)) + return (0); + (* ei) = (uint) intVal; + if (! TrReadOperator (tr, ",")) + return (0); + if (! TrReadInt (tr, 0, (int) hData -> mAzCount [(* ei)], & intVal)) + return (0); + (* ai) = (uint) intVal; + return (1); +} + +// Match the source format from a given identifier. +static SourceFormatT MatchSourceFormat (const char * ident) { + if (strcasecmp (ident, "wave") == 0) + return (SF_WAVE); + else if (strcasecmp (ident, "bin_le") == 0) + return (SF_BIN_LE); + else if (strcasecmp (ident, "bin_be") == 0) + return (SF_BIN_BE); + else if (strcasecmp (ident, "ascii") == 0) + return (SF_ASCII); + return (SF_NONE); +} + +// Match the source element type from a given identifier. +static ElementTypeT MatchElementType (const char * ident) { + if (strcasecmp (ident, "int") == 0) + return (ET_INT); + else if (strcasecmp (ident, "fp") == 0) + return (ET_FP); + return (ET_NONE); +} + +// Parse and validate a source reference from the data set definition. +static int ReadSourceRef (TokenReaderT * tr, SourceRefT * src) { + uint line, col; + char ident [MAX_IDENT_LEN + 1]; + int intVal; + + TrIndication (tr, & line, & col); + if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) + return (0); + src -> mFormat = MatchSourceFormat (ident); + if (src -> mFormat == SF_NONE) { + TrErrorAt (tr, line, col, "Expected a source format.\n"); + return (0); + } + if (! TrReadOperator (tr, "(")) + return (0); + if (src -> mFormat == SF_WAVE) { + if (! TrReadInt (tr, 0, MAX_WAVE_CHANNELS, & intVal)) + return (0); + src -> mType = ET_NONE; + src -> mSize = 0; + src -> mBits = 0; + src -> mChannel = (uint) intVal; + src -> mSkip = 0; + } else { + TrIndication (tr, & line, & col); + if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) + return (0); + src -> mType = MatchElementType (ident); + if (src -> mType == ET_NONE) { + TrErrorAt (tr, line, col, "Expected a source element type.\n"); + return (0); + } + if ((src -> mFormat == SF_BIN_LE) || (src -> mFormat == SF_BIN_BE)) { + if (! TrReadOperator (tr, ",")) + return (0); + if (src -> mType == ET_INT) { + if (! TrReadInt (tr, MIN_BIN_SIZE, MAX_BIN_SIZE, & intVal)) + return (0); + src -> mSize = (uint) intVal; + if (TrIsOperator (tr, ",")) { + TrReadOperator (tr, ","); + TrIndication (tr, & line, & col); + if (! TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal)) + return (0); + if ((abs (intVal) < MIN_BIN_BITS) || (((uint) abs (intVal)) > (8 * src -> mSize))) { + TrErrorAt (tr, line, col, "Expected a value of (+/-) %d to %d.\n", MIN_BIN_BITS, 8 * src -> mSize); + return (0); + } + src -> mBits = intVal; + } else { + src -> mBits = (int) (8 * src -> mSize); + } + } else { + TrIndication (tr, & line, & col); + if (! TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal)) + return (0); + if ((intVal != 4) && (intVal != 8)) { + TrErrorAt (tr, line, col, "Expected a value of 4 or 8.\n"); + return (0); + } + src -> mSize = (uint) intVal; + src -> mBits = 0; + } + } else if ((src -> mFormat == SF_ASCII) && (src -> mType == ET_INT)) { + if (! TrReadOperator (tr, ",")) + return (0); + if (! TrReadInt (tr, MIN_ASCII_BITS, MAX_ASCII_BITS, & intVal)) + return (0); + src -> mSize = 0; + src -> mBits = intVal; + } else { + src -> mSize = 0; + src -> mBits = 0; + } + if (TrIsOperator (tr, ";")) { + TrReadOperator (tr, ";"); + if (! TrReadInt (tr, 0, 0x7FFFFFFF, & intVal)) + return (0); + src -> mSkip = (uint) intVal; + } else { + src -> mSkip = 0; + } + } + if (! TrReadOperator (tr, ")")) + return (0); + if (TrIsOperator (tr, "@")) { + TrReadOperator (tr, "@"); + if (! TrReadInt (tr, 0, 0x7FFFFFFF, & intVal)) + return (0); + src -> mOffset = (uint) intVal; + } else { + src -> mOffset = 0; + } + if (! TrReadOperator (tr, ":")) + return (0); + if (! TrReadString (tr, MAX_PATH_LEN, src -> mPath)) + return (0); + return (1); +} + +// Process the list of sources in the data set definition. +static int ProcessSources (const HeadModelT model, TokenReaderT * tr, HrirDataT * hData) { + uint * setCount = NULL, * setFlag = NULL; + double * hrir = NULL; + uint line, col, ei, ai; + SourceRefT src; + double factor; + + setCount = (uint *) calloc (hData -> mEvCount, sizeof (uint)); + setFlag = (uint *) calloc (hData -> mIrCount, sizeof (uint)); + hrir = CreateArray (hData -> mIrPoints); + while (TrIsOperator (tr, "[")) { + TrIndication (tr, & line, & col); + TrReadOperator (tr, "["); + if (ReadIndexPair (tr, hData, & ei, & ai)) { + if (TrReadOperator (tr, "]")) { + if (! setFlag [hData -> mEvOffset [ei] + ai]) { + if (TrReadOperator (tr, "=")) { + factor = 1.0; + for (;;) { + if (ReadSourceRef (tr, & src)) { + if (LoadSource (& src, hData -> mIrRate, hData -> mIrPoints, hrir)) { + if (model == HM_DATASET) + AverageHrirOnset (hrir, 1.0 / factor, ei, ai, hData); + AverageHrirMagnitude (hrir, 1.0 / factor, ei, ai, hData); + factor += 1.0; + if (! TrIsOperator (tr, "+")) + break; + TrReadOperator (tr, "+"); + continue; + } + } + DestroyArray (hrir); + free (setFlag); + free (setCount); + return (0); + } + setFlag [hData -> mEvOffset [ei] + ai] = 1; + setCount [ei] ++; + continue; + } + } else { + TrErrorAt (tr, line, col, "Redefinition of source.\n"); + } + } + } + DestroyArray (hrir); + free (setFlag); + free (setCount); + return (0); + } + ei = 0; + while ((ei < hData -> mEvCount) && (setCount [ei] < 1)) + ei ++; + if (ei < hData -> mEvCount) { + hData -> mEvStart = ei; + while ((ei < hData -> mEvCount) && (setCount [ei] == hData -> mAzCount [ei])) + ei ++; + if (ei >= hData -> mEvCount) { + if (! TrLoad (tr)) { + DestroyArray (hrir); + free (setFlag); + free (setCount); + return (1); + } else { + TrError (tr, "Errant data at end of source list.\n"); + } + } else { + TrError (tr, "Missing sources for elevation index %d.\n", ei); + } + } else { + TrError (tr, "Missing source references.\n"); + } + DestroyArray (hrir); + free (setFlag); + free (setCount); + return (0); +} + +/* Parse the data set definition and process the source data, storing the + * resulting data set as desired. If the input name is NULL it will read + * from standard input. + */ +static int ProcessDefinition (const char * inName, const uint outRate, const uint fftSize, const int equalize, const int surface, const double limit, const uint truncSize, const HeadModelT model, const double radius, const OutputFormatT outFormat, const char * outName) { + FILE * fp = NULL; + TokenReaderT tr; + HrirDataT hData; + double * dfa = NULL; + char rateStr [8 + 1], expName [MAX_PATH_LEN]; + + hData . mIrRate = 0; + hData . mIrPoints = 0; + hData . mFftSize = 0; + hData . mIrSize = 0; + hData . mIrCount = 0; + hData . mEvCount = 0; + hData . mRadius = 0; + hData . mDistance = 0; + fprintf (stdout, "Reading HRIR definition...\n"); + if (inName != NULL) { + fp = fopen (inName, "r"); + if (fp == NULL) { + fprintf (stderr, "Error: Could not open definition file '%s'\n", inName); + return (0); + } + TrSetup (fp, inName, & tr); + } else { + fp = stdin; + TrSetup (fp, "", & tr); + } + if (! ProcessMetrics (& tr, fftSize, truncSize, & hData)) { + if (inName != NULL) + fclose (fp); + return (0); + } + hData . mHrirs = CreateArray (hData . mIrCount * hData . mIrSize); + hData . mHrtds = CreateArray (hData . mIrCount); + if (! ProcessSources (model, & tr, & hData)) { + DestroyArray (hData . mHrtds); + DestroyArray (hData . mHrirs); + if (inName != NULL) + fclose (fp); + return (0); + } + if (inName != NULL) + fclose (fp); + if (equalize) { + dfa = CreateArray (1 + (hData . mFftSize / 2)); + fprintf (stdout, "Calculating diffuse-field average...\n"); + CalculateDiffuseFieldAverage (& hData, surface, limit, dfa); + fprintf (stdout, "Performing diffuse-field equalization...\n"); + DiffuseFieldEqualize (dfa, & hData); + DestroyArray (dfa); + } + fprintf (stdout, "Performing minimum phase reconstruction...\n"); + ReconstructHrirs (& hData); + if ((outRate != 0) && (outRate != hData . mIrRate)) { + fprintf (stdout, "Resampling HRIRs...\n"); + ResampleHrirs (outRate, & hData); + } + fprintf (stdout, "Truncating minimum-phase HRIRs...\n"); + hData . mIrPoints = truncSize; + fprintf (stdout, "Synthesizing missing elevations...\n"); + if (model == HM_DATASET) + SynthesizeOnsets (& hData); + SynthesizeHrirs (& hData); + fprintf (stdout, "Normalizing final HRIRs...\n"); + NormalizeHrirs (& hData); + fprintf (stdout, "Calculating impulse delays...\n"); + CalculateHrtds (model, (radius > DEFAULT_CUSTOM_RADIUS) ? radius : hData . mRadius, & hData); + snprintf (rateStr, 8, "%u", hData . mIrRate); + StrSubst (outName, "%r", rateStr, MAX_PATH_LEN, expName); + switch (outFormat) { + case OF_MHR : + fprintf (stdout, "Creating MHR data set file...\n"); + if (! StoreMhr (& hData, expName)) + return (0); + break; + case OF_TABLE : + fprintf (stderr, "Creating OpenAL Soft table file...\n"); + if (! StoreTable (& hData, expName)) + return (0); + break; + default : + break; + } + DestroyArray (hData . mHrtds); + DestroyArray (hData . mHrirs); + return (1); +} + +// Standard command line dispatch. +int main (const int argc, const char * argv []) { + const char * inName = NULL, * outName = NULL; + OutputFormatT outFormat; + int argi; + uint outRate, fftSize; + int equalize, surface; + double limit; + uint truncSize; + HeadModelT model; + double radius; + char * end = NULL; + + if (argc < 2) { + fprintf (stderr, "Error: No command specified. See '%s -h' for help.\n", argv [0]); + return (-1); + } + if ((strcmp (argv [1], "--help") == 0) || (strcmp (argv [1], "-h") == 0)) { + fprintf (stdout, "HRTF Processing and Composition Utility\n\n"); + fprintf (stdout, "Usage: %s [