Skip to content

Commit 3a88e78

Browse files
committed
Implement FlxSound.pan for stereo sounds
1 parent 4d73ec3 commit 3a88e78

File tree

4 files changed

+93
-22
lines changed

4 files changed

+93
-22
lines changed

source/lime/_internal/backend/html5/HTML5AudioSource.hx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,6 @@ class HTML5AudioSource
251251

252252
public function getPosition():Vector4
253253
{
254-
#if lime_howlerjs
255-
// This should work, but it returns null (But checking the inside of the howl, the _pos is actually null... so ¯\_(ツ)_/¯)
256-
/*
257-
var arr = parent.buffer.__srcHowl.pos())
258-
position.x = arr[0];
259-
position.y = arr[1];
260-
position.z = arr[2];
261-
*/
262-
#end
263-
264254
return position;
265255
}
266256

@@ -278,4 +268,16 @@ class HTML5AudioSource
278268

279269
return position;
280270
}
271+
272+
public function getPan():Float
273+
{
274+
return position.x;
275+
}
276+
277+
public function setPan(value:Float):Float
278+
{
279+
position.setTo(value, 0, -Math.sqrt(1 - value * value));
280+
if (parent.buffer != null && parent.buffer.__srcHowl != null && parent.buffer.__srcHowl.stereo != null) parent.buffer.__srcHowl.stereo(value, id);
281+
return value;
282+
}
281283
}

source/lime/_internal/backend/native/NativeAudioSource.hx

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import lime.media.vorbis.Vorbis;
1313
import lime.media.vorbis.VorbisFile;
1414
#end
1515

16+
import lime.math.Vector2;
1617
import lime.math.Vector4;
1718
import lime.media.AudioBuffer;
1819
import lime.media.AudioSource;
@@ -30,6 +31,11 @@ class NativeAudioSource {
3031
private static var STREAM_TIMER_FREQUENCY:Int = 100;
3132
private static var STREAM_BUFFER_FREQUENCY:Int = 3;
3233

34+
private static var moreFormatsSupported:Null<Bool>;
35+
private static var stereoAnglesExtensionSupported:Null<Bool>;
36+
private static var loopPointsSupported:Null<Bool>; // TODO: implement loop Points for looped static sources
37+
private static var latencyExtensionSupported:Null<Bool>;
38+
3339
private var parent:AudioSource;
3440
private var disposed:Bool;
3541
private var streamed:Bool;
@@ -54,7 +60,9 @@ class NativeAudioSource {
5460
private var streamEnded:Bool;
5561
private var dataLength:Float;
5662

57-
private var position:Vector4 = new Vector4();
63+
private var position:Vector4;
64+
private var angles:Vector2;
65+
private var anglesArray:Array<Float>;
5866
private var length:Null<Float>;
5967
private var loopTime:Null<Float>;
6068
private var loops:Int;
@@ -65,6 +73,10 @@ class NativeAudioSource {
6573
disposed = true;
6674
stop();
6775

76+
position = null;
77+
angles = null;
78+
anglesArray = null;
79+
6880
if (handle != null) {
6981
AL.sourcei(handle, AL.BUFFER, AL.NONE);
7082
AL.deleteSource(handle);
@@ -81,16 +93,26 @@ class NativeAudioSource {
8193

8294
public function init() {
8395
if (handle != null) return;
84-
8596
if (disposed = (handle = AL.createSource()) == null) return;
97+
98+
if (position == null) position = new Vector4();
99+
if (angles == null) angles = new Vector2(Math.PI / 6, -Math.PI / 6); // https://github.com/kcat/openal-soft/issues/1032
100+
anglesArray = [0, 0];
101+
102+
if (moreFormatsSupported == null) moreFormatsSupported = AL.isExtensionPresent("AL_EXT_MCFORMATS");
103+
if (stereoAnglesExtensionSupported == null) stereoAnglesExtensionSupported = AL.isExtensionPresent("AL_EXT_STEREO_ANGLES");
104+
if (latencyExtensionSupported == null) latencyExtensionSupported = AL.isExtensionPresent("AL_SOFT_source_latency");
105+
if (loopPointsSupported == null) loopPointsSupported = AL.isExtensionPresent("AL_SOFT_loop_points");
106+
86107
AL.sourcef(handle, AL.MAX_GAIN, 10);
108+
AL.distanceModel(AL.NONE);
87109

88110
var buffer = parent.buffer;
89111
var channels = buffer.channels, bitsPerSample = buffer.bitsPerSample;
90112

91113
// Default is just AL.FORMAT_MONO8 if it doesn't match any to avoid yo ears getting blasted
92114
var isCreativeXFi = AL.getString(AL.RENDERER) == "X-Fi";
93-
if (channels > 2 && (isCreativeXFi || AL.isExtensionPresent("AL_EXT_MCFORMATS"))) { // https://github.com/openalext/openalext/blob/master/AL_EXT_MCFORMATS.txt
115+
if (channels > 2 && (isCreativeXFi || moreFormatsSupported)) { // https://github.com/openalext/openalext/blob/master/AL_EXT_MCFORMATS.txt
94116
if (channels == 3) format = bitsPerSample == 32 ? 0x1209 : (bitsPerSample == 16 ? 0x1208 : 0x1207);
95117
else if (channels == 4) format = bitsPerSample == 32 ? 0x1206 : (bitsPerSample == 16 ? 0x1205 : 0x1204);
96118
else if (channels == 6) format = bitsPerSample == 32 ? 0x120C : (bitsPerSample == 16 ? 0x120B : 0x120A);
@@ -466,29 +488,65 @@ class NativeAudioSource {
466488

467489
public function getLatency():Float {
468490
/*#if (lime >= "8.3.0")
469-
if (AL.isExtensionPresent("AL_SOFT_source_latency")) {
491+
if (latencyExtensionSupported) {
470492
final offsets = AL.getSourcedvSOFT(handle, AL.SEC_OFFSET_LATENCY_SOFT, 2);
471493
if (offsets != null) return offsets[1] * 1000;
472494
}
473495
#end*/
474496
return 0;
475497
}
476498

477-
public function getPosition():Vector4 return position;
499+
public function getAngles():Vector2 {
500+
if (angles == null) angles = new Vector2(Math.PI / 6, -Math.PI / 6);
501+
return angles;
502+
}
503+
504+
public function setAngles(left:Float, right:Float):Vector2 {
505+
if (angles == null) angles = new Vector2(left, right);
506+
else angles.setTo(left, right);
507+
508+
if (!disposed) {
509+
anglesArray[0] = angles.x;
510+
anglesArray[1] = angles.y;
511+
AL.sourcei(handle, 0x1214/*AL.SOURCE_SPATIALIZE_SOFT*/, AL.FALSE);
512+
AL.sourcefv(handle, 0x1030/*AL.STEREO_ANGLES*/, anglesArray);
513+
}
514+
return angles;
515+
}
516+
517+
public function getPosition():Vector4 {
518+
if (position == null) position = new Vector4();
519+
return position;
520+
}
478521

479522
public function setPosition(value:Vector4):Vector4 {
480523
position.x = value.x;
481524
position.y = value.y;
482525
position.z = value.z;
483526
position.w = value.w;
484527

528+
// OpenAL Soft Positions doesn't seem to do anything but panning?
485529
if (!disposed) {
486-
AL.distanceModel(AL.NONE);
530+
AL.sourcei(handle, 0x1214/*AL.SOURCE_SPATIALIZE_SOFT*/, Math.abs(position.x) > 1e-04 ? AL.TRUE : AL.FALSE);
531+
AL.sourcei(handle, AL.MAX_DISTANCE, 1);
487532
AL.source3f(handle, AL.POSITION, position.x, position.y, position.z);
488533
}
489534
return position;
490535
}
491536

537+
public function getPan():Float return getPosition().x;
538+
539+
public function setPan(value:Float):Float {
540+
getPosition().setTo(value, 0, -Math.sqrt(1 - value * value));
541+
if (!disposed) {
542+
if (parent.buffer.channels > 1 && stereoAnglesExtensionSupported)
543+
setAngles(Math.PI * (Math.min(-value * 2 + 1, 1)) / 6, -Math.PI * Math.min(value * 2 + 1, 1) / 6);
544+
else
545+
setPosition(position);
546+
}
547+
return value;
548+
}
549+
492550
inline private function getFloat(x:Int64):Float return x.high * 4294967296. + (x.low >> 0);
493551
inline private function getSamples(ms:Float):Int64 return Int64.fromFloat(Math.max(0, Math.min(ms / 1000 * parent.buffer.sampleRate, samples)));
494552
}

source/lime/media/AudioSource.hx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ class AudioSource
8080
**/
8181
public var position(get, set):Vector4;
8282

83+
/**
84+
The stereo pan of the audio source.
85+
**/
86+
public var pan(get, set):Float;
87+
8388
/**
8489
The latency of the audio source.
8590
**/
@@ -229,6 +234,16 @@ class AudioSource
229234
return __backend.setPosition(value);
230235
}
231236

237+
@:noCompletion inline private function get_pan():Float
238+
{
239+
return __backend.getPan();
240+
}
241+
242+
@:noCompletion inline private function set_pan(value:Float):Float
243+
{
244+
return __backend.setPan(value);
245+
}
246+
232247
@:noCompletion inline private function get_latency():Float
233248
{
234249
return __backend.getLatency();

source/openfl/media/SoundChannel.hx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,9 @@ import lime.media.openal.AL;
273273
if (__isValid)
274274
{
275275
#if lime
276+
// TODO: implement SoundTransform.leftToRight, etc. with Native setAngles?
276277
__source.gain = volume;
277-
278-
var position = __source.position;
279-
position.x = pan;
280-
position.z = -1 * Math.sqrt(1 - Math.pow(pan, 2));
281-
__source.position = position;
282-
278+
__source.pan = pan;
283279
return value;
284280
#end
285281
}

0 commit comments

Comments
 (0)