From 08b27b6c1fff5eb32ca71535daea06190d83cd3b Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 13 Jun 2024 17:35:59 -0400 Subject: [PATCH] Audio spatialization and OpenAL-soft fixes. --- project/src/media/openal/OpenALBindings.cpp | 30 +++++++++++++++++++ .../backend/html5/HTML5AudioSource.hx | 8 ++--- .../backend/native/NativeAudioSource.hx | 18 +++++++---- .../_internal/backend/native/NativeCFFI.hx | 9 ++++++ src/lime/media/OpenALAudioContext.hx | 5 ++++ src/lime/media/openal/AL.hx | 25 ++++++++++++++++ 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/project/src/media/openal/OpenALBindings.cpp b/project/src/media/openal/OpenALBindings.cpp index fe549149df..bd758ff59f 100644 --- a/project/src/media/openal/OpenALBindings.cpp +++ b/project/src/media/openal/OpenALBindings.cpp @@ -2103,6 +2103,34 @@ namespace lime { } + value lime_al_get_sourcedv_soft (value source, int param, int count) + { + #ifdef LIME_OPENALSOFT + ALuint id = (ALuint)(uintptr_t)val_data (source); + ALdouble* values = new ALdouble[count]; + alGetSourcedvSOFT(id, param, values); + + value result = alloc_array (count); + + for (int i = 0; i < count; i++) + { + val_array_set_i(result, i, alloc_float(values[i])); + } + + delete[] values; + return result; + #endif + } + + HL_PRIM varray* HL_NAME(hl_al_get_sourcedv_soft) (HL_CFFIPointer* source, int param, int count) + { + #ifdef LIME_OPENALSOFT + ALuint id = (ALuint)(uintptr_t)source->ptr; + varray* result = hl_alloc_array(&hlt_f64, count); + alGetSourcedvSOFT(id, param, hl_aptr (result, double)); + return result; + #endif + } value lime_al_get_sourcei (value source, int param) { @@ -3579,6 +3607,7 @@ namespace lime { DEFINE_PRIME2 (lime_al_get_source3i); DEFINE_PRIME2 (lime_al_get_sourcef); DEFINE_PRIME3 (lime_al_get_sourcefv); + DEFINE_PRIME3 (lime_al_get_sourcedv_soft); DEFINE_PRIME2 (lime_al_get_sourcei); DEFINE_PRIME3 (lime_al_get_sourceiv); DEFINE_PRIME1 (lime_al_get_string); @@ -3703,6 +3732,7 @@ namespace lime { DEFINE_HL_PRIM (_ARR, hl_al_get_source3i, _TCFFIPOINTER _I32); DEFINE_HL_PRIM (_F32, hl_al_get_sourcef, _TCFFIPOINTER _I32); DEFINE_HL_PRIM (_ARR, hl_al_get_sourcefv, _TCFFIPOINTER _I32 _I32); + DEFINE_HL_PRIM (_ARR, hl_al_get_sourcedv_soft, _TCFFIPOINTER _I32 _I32); DEFINE_HL_PRIM (_DYN, hl_al_get_sourcei, _TCFFIPOINTER _I32); DEFINE_HL_PRIM (_ARR, hl_al_get_sourceiv, _TCFFIPOINTER _I32 _I32); DEFINE_HL_PRIM (_BYTES, hl_al_get_string, _I32); diff --git a/src/lime/_internal/backend/html5/HTML5AudioSource.hx b/src/lime/_internal/backend/html5/HTML5AudioSource.hx index bde1499be9..c88d589cc0 100644 --- a/src/lime/_internal/backend/html5/HTML5AudioSource.hx +++ b/src/lime/_internal/backend/html5/HTML5AudioSource.hx @@ -50,7 +50,7 @@ class HTML5AudioSource untyped parent.buffer.__srcHowl._volume = cacheVolume; // setGain (parent.gain); - setPosition(parent.position); + // setPosition(parent.position); parent.buffer.__srcHowl.on("end", howl_onEnd, id); @@ -218,10 +218,10 @@ class HTML5AudioSource #if lime_howlerjs parent.buffer.__srcHowl.rate(value); #end - + return getPitch(); } - + public function getPosition():Vector4 { @@ -246,7 +246,7 @@ class HTML5AudioSource position.w = value.w; #if lime_howlerjs - if (parent.buffer != null && parent.buffer.__srcHowl != null && parent.buffer.__srcHowl.pos != null) parent.buffer.__srcHowl.pos(position.x, position.y, position.z, id); + // if (parent.buffer != null && parent.buffer.__srcHowl != null && parent.buffer.__srcHowl.pos != null) parent.buffer.__srcHowl.pos(position.x, position.y, position.z, id); // There are more settings to the position of the sound on the "pannerAttr()" function of howler. Maybe somebody who understands sound should look into it? #end diff --git a/src/lime/_internal/backend/native/NativeAudioSource.hx b/src/lime/_internal/backend/native/NativeAudioSource.hx index ab85e0e002..3b282eeaf2 100644 --- a/src/lime/_internal/backend/native/NativeAudioSource.hx +++ b/src/lime/_internal/backend/native/NativeAudioSource.hx @@ -377,15 +377,23 @@ class NativeAudioSource } else { - var offset = AL.getSourcei(handle, AL.BYTE_OFFSET); - var ratio = (offset / dataLength); - var totalSeconds = samples / parent.buffer.sampleRate; + // var offset = AL.getSourcei(handle, AL.BYTE_OFFSET); + // var ratio = (offset / dataLength); + // var totalSeconds = samples / parent.buffer.sampleRate; - var time = Std.int(totalSeconds * ratio * 1000) - parent.offset; + // var sampleTime = AL.getSourcef(handle, AL.SAMPLE_OFFSET); + // var time = (sampleTime / parent.buffer.sampleRate * 1000) - + // var time = Std.int(totalSeconds * ratio * 1000) - parent.offset; // var time = Std.int (AL.getSourcef (handle, AL.SEC_OFFSET) * 1000) - parent.offset; + + var value = AL.getSourcedvSOFT(handle, AL.SEC_OFFSET_LATENCY_SOFT, 2); + var deviceOffset:Float = value[1]; + var realOffset:Float = value[0]; + var time:Float = ((realOffset - deviceOffset) * 1000) - parent.offset; + if (time < 0) return 0; - return time; + return Std.int(time); } } diff --git a/src/lime/_internal/backend/native/NativeCFFI.hx b/src/lime/_internal/backend/native/NativeCFFI.hx index e92a4e685a..220de08198 100644 --- a/src/lime/_internal/backend/native/NativeCFFI.hx +++ b/src/lime/_internal/backend/native/NativeCFFI.hx @@ -1761,6 +1761,8 @@ class NativeCFFI private static var lime_al_get_sourcef = new cpp.CallableInt->cpp.Float32>(cpp.Prime._loadPrime("lime", "lime_al_get_sourcef", "oif", false)); private static var lime_al_get_sourcefv = new cpp.CallableInt->Int->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_al_get_sourcefv", "oiio", false)); + private static var lime_al_get_sourcedv_soft = new cpp.CallableInt->Int->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_al_get_sourcedv_soft", + "oiio", false)); private static var lime_al_get_sourcei = new cpp.CallableInt->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_al_get_sourcei", "oio", false)); private static var lime_al_get_sourceiv = new cpp.CallableInt->Int->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_al_get_sourceiv", "oiio", false)); @@ -1902,6 +1904,7 @@ class NativeCFFI private static var lime_al_get_source3i = CFFI.load("lime", "lime_al_get_source3i", 2); private static var lime_al_get_sourcef = CFFI.load("lime", "lime_al_get_sourcef", 2); private static var lime_al_get_sourcefv = CFFI.load("lime", "lime_al_get_sourcefv", 3); + private static var lime_al_get_sourcedv_soft = CFFI.load("lime", "lime_al_get_sourcedv_soft", 3); private static var lime_al_get_sourcei = CFFI.load("lime", "lime_al_get_sourcei", 2); private static var lime_al_get_sourceiv = CFFI.load("lime", "lime_al_get_sourceiv", 3); private static var lime_al_get_string = CFFI.load("lime", "lime_al_get_string", 1); @@ -2159,6 +2162,12 @@ class NativeCFFI return null; } + + @:hlNative("lime", "hl_al_get_sourcedv_soft") private static function lime_al_get_sourcedv_soft(source:CFFIPointer, param:Int, count:Int):hl.NativeArray + { + return null; + } + @:hlNative("lime", "hl_al_get_sourcei") private static function lime_al_get_sourcei(source:CFFIPointer, param:Int):Dynamic { return null; diff --git a/src/lime/media/OpenALAudioContext.hx b/src/lime/media/OpenALAudioContext.hx index d731f72397..649d6edc77 100644 --- a/src/lime/media/OpenALAudioContext.hx +++ b/src/lime/media/OpenALAudioContext.hx @@ -371,6 +371,11 @@ class OpenALAudioContext return AL.getProcAddress(fname); } + public function getSourcedvSOFT(source:ALSource, param:Int, count:Int = 1):Array + { + return AL.getSourcedvSOFT(source, param, count); + } + public function getSource3f(source:ALSource, param:Int):Array { return AL.getSource3f(source, param); diff --git a/src/lime/media/openal/AL.hx b/src/lime/media/openal/AL.hx index f8fced192e..7b00a289ed 100644 --- a/src/lime/media/openal/AL.hx +++ b/src/lime/media/openal/AL.hx @@ -233,6 +233,13 @@ class AL public static inline var FILTER_HIGHPASS:Int = 0x0002; public static inline var FILTER_BANDPASS:Int = 0x0003; + public static inline var DEVICE_CLOCK_SOFT:Int = 0x1600; + public static inline var DEVICE_LATENCY_SOFT:Int = 0x1601; + public static inline var DEVICE_CLOCK_LATENCY_SOFT:Int = 0x1602; + + public static inline var SEC_OFFSET_LATENCY_SOFT:Int = 0x1201; + public static inline var SEC_OFFSET_CLOCK_SOFT:Int = 0x1203; + public static function removeDirectFilter(source:ALSource) { #if (lime_cffi && lime_openal && !macro) @@ -968,6 +975,24 @@ class AL #end } + public static function getSourcedvSOFT(source:ALSource, param:Int, count:Int = 2):Array + { + #if (lime_cffi && lime_openal && !macro) + var result = NativeCFFI.lime_al_get_sourcedv_soft(source, param, count); + #if hl + if (result == null) return []; + var _result:Array = []; + for (i in 0...result.length) + _result[i] = result[i]; + return _result; + #else + return result; + #end + #else + return null; + #end + } + public static function getSourcei(source:ALSource, param:Int):Dynamic { #if (lime_cffi && lime_openal && !macro)