@@ -41,6 +41,7 @@ class NativeAudioSource {
4141 public static var STREAM_BUFFER_SAMPLES : Int = 0x2000 ; // how much buffers will be generating every frequency (doesnt have to be pow of 2?).
4242 public static var STREAM_MIN_BUFFERS : Int = 2 ; // how much buffers can a stream hold on minimum or starting.
4343 public static var STREAM_MAX_BUFFERS : Int = 8 ; // how much limit of a buffers can be used for streamed audios, must be higher than minimum.
44+ public static var STREAM_FLUSH_BUFFERS : Int = 3 ; // how much buffers can it play.
4445 public static var STREAM_PROCESS_BUFFERS : Int = 2 ; // how much buffers can be processed in a frequency tick.
4546 public static var STREAM_TIMER_CHECK_MS : Int = 100 ; // determines how milliseconds to update the buffers if available.
4647 public static var MAX_POOL_BUFFERS : Int = 32 ; // how much buffers for the pool to hold.
@@ -88,18 +89,6 @@ class NativeAudioSource {
8889
8990 inline private static function getFloat (x : Int64 ): Float return x .high * 4294967296. + (x .low >> 0);
9091
91- #if audio_stream_async
92- static var threadRunning : Bool = false ;
93- static var streamSources : Array <NativeAudioSource > = [];
94- static var queuedStreamSources : Array <NativeAudioSource > = [];
95-
96- static var streamHandlerTimer : Timer ;
97- static var streamMutex : Mutex = new Mutex ();
98- static var streamThread : Thread ;
99-
100- var streamRemove : Bool ;
101- #end
102-
10392 // Backward Compatibility Variables
10493 var handle (get , set ): ALSource ; inline function get_handle () return source ; inline function set_handle (v ) return source = v ;
10594 var timer (get , set ): Timer ; inline function get_timer () return completeTimer ; inline function set_timer (v ) return completeTimer = v ;
@@ -128,7 +117,6 @@ class NativeAudioSource {
128117 var dataLength : Int ;
129118 var duration : Float ;
130119
131- #if !audio_stream_async var streamTimer : Timer ; #end
132120 var completeTimer : Timer ;
133121 var source : ALSource ;
134122 var buffer : ALBuffer ;
@@ -137,6 +125,20 @@ class NativeAudioSource {
137125 var arrayType : TypedArrayType ;
138126 var loopPoints : Array <Int >; // In Samples
139127
128+ #if audio_stream_async
129+ static var threadRunning : Bool = false ;
130+ static var streamSources : Array <NativeAudioSource > = [];
131+ static var queuedStreamSources : Array <NativeAudioSource > = [];
132+
133+ static var streamHandlerTimer : Timer ;
134+ static var streamMutex : Mutex = new Mutex ();
135+ static var streamThread : Thread ;
136+
137+ var streamRemove : Bool ;
138+ #else
139+ var streamTimer : Timer ;
140+ #end
141+
140142 var bufferLength : Int ; // Size in bytes for current streamed audio buffers.
141143 var requestBuffers : Int ;
142144 var queuedBuffers : Int ;
@@ -160,6 +162,11 @@ class NativeAudioSource {
160162 }
161163
162164 public function dispose () {
165+ #if audio_stream_async
166+ streamMutex .acquire ();
167+ removeStream ();
168+ #end
169+
163170 stop ();
164171 disposed = true ;
165172
@@ -168,7 +175,9 @@ class NativeAudioSource {
168175 anglesArray = null ;
169176
170177 if (source != null ) {
171- AL .sourcei (source , AL .BUFFER , AL .NONE );
178+ if (streamed ) AL .sourceUnqueueBuffers (source , AL .getSourcei (source , AL .BUFFERS_QUEUED ));
179+ else AL .sourcei (source , AL .BUFFER , AL .NONE );
180+
172181 AL .deleteSource (source );
173182 source = null ;
174183 }
@@ -196,6 +205,8 @@ class NativeAudioSource {
196205
197206 bufferTimes = null ;
198207 bufferLengths = null ;
208+
209+ #if audio_stream_async streamMutex .release (); #end
199210 }
200211
201212 public function init () {
@@ -213,9 +224,18 @@ class NativeAudioSource {
213224
214225 public function resetBuffer () {
215226 if (parent .buffer == null ) return ;
227+
228+ #if audio_stream_async
229+ streamMutex .acquire ();
230+ removeStream ();
231+ #end
232+
216233 stop ();
217234
218- AL .sourcei (source , AL .BUFFER , AL .NONE );
235+ if (streamed ) AL .sourceUnqueueBuffers (source , AL .getSourcei (source , AL .BUFFERS_QUEUED ));
236+ else AL .sourcei (source , AL .BUFFER , AL .NONE );
237+
238+ #if audio_stream_async streamMutex .release (); #end
219239
220240 final audioBuffer = parent .buffer ;
221241 channels = audioBuffer .channels ;
@@ -256,7 +276,7 @@ class NativeAudioSource {
256276 final length = STREAM_BUFFER_SAMPLES * channels ;
257277 bufferLength = length * wordSize ;
258278
259- if (buffers == null ) buffers = AL .genBuffers (STREAM_MAX_BUFFERS );
279+ if (buffers == null ) buffers = AL .genBuffers (STREAM_FLUSH_BUFFERS );
260280 if (bufferDatas == null ) {
261281 bufferDatas = [];
262282 bufferTimes = [];
@@ -388,7 +408,7 @@ class NativeAudioSource {
388408 }
389409 }
390410 catch (e : haxe. Exception ) {
391- trace (' NativeAudioSource readToBufferData Bug! error: ${e .message } | ${e .stack }, streamEnded: $streamEnded , total: $total , n: $n ' );
411+ trace (' NativeAudioSource readToBufferData Bug! error: ${e .message } | ${e .stack . toString () }, streamEnded: $streamEnded , total: $total , n: $n ' );
392412 return result ;
393413 }
394414
@@ -402,9 +422,7 @@ class NativeAudioSource {
402422 function fillBuffers (n : Int ) {
403423 final max = STREAM_MAX_BUFFERS - 1 ;
404424 var i : Int , j : Int , data : ArrayBufferView , pcm : Int64 , decoded : Int ;
405- while (n -- > 0 && requestBuffers < STREAM_MAX_BUFFERS && ! streamEnded
406- && (decoded = readToBufferData (data = bufferDatas [i = max - requestBuffers ], pcm = streamTell ())) > 0 )
407- {
425+ while (n -- > 0 && ! streamEnded && (decoded = readToBufferData (data = bufferDatas [i = max - requestBuffers ], pcm = streamTell ())) > 0 ) {
408426 j = i ;
409427 while (i < max ) {
410428 bufferDatas [i ] = bufferDatas [++ j ];
@@ -421,12 +439,12 @@ class NativeAudioSource {
421439
422440 inline function flushBuffers () {
423441 var i = STREAM_MAX_BUFFERS - (requestBuffers - queuedBuffers );
424- while (queuedBuffers < requestBuffers ) {
442+ while (queuedBuffers < STREAM_FLUSH_BUFFERS && queuedBuffers < requestBuffers ) {
425443 AL .bufferData (buffers [nextBuffer ], format , bufferDatas [i ], bufferLengths [i ], sampleRate );
426444 AL .sourceQueueBuffer (source , buffers [nextBuffer ]);
427- if (++ nextBuffer == STREAM_MAX_BUFFERS ) nextBuffer = 0 ;
428- i ++ ;
445+ if (++ nextBuffer == STREAM_FLUSH_BUFFERS ) nextBuffer = 0 ;
429446 queuedBuffers ++ ;
447+ i ++ ;
430448 }
431449 }
432450
@@ -438,24 +456,23 @@ class NativeAudioSource {
438456 function snapBuffersToTime (time : Float , force : Bool ) {
439457 if (source == null || parent .buffer == null || parent .buffer .__srcVorbisFile == null ) return ;
440458
459+ #if audio_stream_async streamMutex .acquire (); #end
460+
441461 final sec = time / 1000 ;
442462 if (! force ) {
443463 var bufferTime : Float ;
444- for (i in (STREAM_MAX_BUFFERS - queuedBuffers )... STREAM_MAX_BUFFERS )
464+ for (i in (STREAM_MAX_BUFFERS - requestBuffers )... ( STREAM_MAX_BUFFERS - STREAM_MIN_BUFFERS ) )
445465 if (sec >= (bufferTime = bufferTimes [i ]) && sec < bufferTime + (bufferLengths [i ] / wordSize / channels / sampleRate ))
446466 {
447- #if audio_stream_async streamMutex .acquire (); #end
448- skipBuffers (i - STREAM_MAX_BUFFERS + queuedBuffers );
467+ skipBuffers (i - STREAM_MAX_BUFFERS + requestBuffers );
449468 AL .sourcei (source , AL .SAMPLE_OFFSET , Math .floor ((sec - bufferTime ) * sampleRate ));
450- fillBuffers (STREAM_MIN_BUFFERS - STREAM_MAX_BUFFERS + i );
451469 #if audio_stream_async streamMutex .release (); #end
452- return flushBuffers () ;
470+ return ;
453471 }
454472 }
455473
456474 AL .sourceUnqueueBuffers (source , AL .getSourcei (source , AL .BUFFERS_QUEUED ));
457475
458- #if audio_stream_async streamMutex .acquire (); #end
459476 streamEnded = false ;
460477 streamSeek (Int64 .fromFloat (sec * sampleRate ));
461478
@@ -467,17 +484,20 @@ class NativeAudioSource {
467484
468485 #if audio_stream_async
469486 static function streamThreadRun () {
470- var i : Int , source : NativeAudioSource , process : Int ;
487+ var i : Int , source : NativeAudioSource , process : Int , v : Int ;
471488
472489 while ((i = Thread .readMessage (true )) != 0 ) {
473490 streamMutex .acquire ();
474491 while (i -- > 0 ) {
475- if ((source = streamSources [i ]).parent .buffer == null ) {
492+ if ((source = streamSources [i ]).streamRemove ) continue ;
493+ else if (source .parent .buffer == null ) {
476494 source .stopStream ();
477495 continue ;
478496 }
497+
479498 process = source .requestBuffers < STREAM_MIN_BUFFERS ? STREAM_MIN_BUFFERS - source .requestBuffers : 0 ;
480- source .fillBuffers (STREAM_PROCESS_BUFFERS > process ? STREAM_PROCESS_BUFFERS : process );
499+ process = STREAM_PROCESS_BUFFERS > process ? STREAM_PROCESS_BUFFERS : process ;
500+ if ((process = (v = STREAM_MAX_BUFFERS - source .requestBuffers ) > process ? process : v ) > 0 ) source .fillBuffers (process );
481501 }
482502 streamMutex .release ();
483503 }
@@ -488,9 +508,14 @@ class NativeAudioSource {
488508 static function streamHandlerRun () {
489509 if (! streamMutex .tryAcquire ()) return ;
490510
491- var i = streamSources .length , source : NativeAudioSource ;
511+ var i = queuedStreamSources .length , source : NativeAudioSource ;
512+ while (i -- > 0 ) streamSources .push (queuedStreamSources [i ]);
513+ queuedStreamSources .resize (0 );
514+
515+ i = streamSources .length ;
492516 while (i -- > 0 ) {
493- if ((source = streamSources [i ]).source == null ) source .stopStream ();
517+ if ((source = streamSources [i ]).streamRemove || source .source == null )
518+ source .removeStream ();
494519 else {
495520 source .skipBuffers (AL .getSourcei (source .source , AL .BUFFERS_PROCESSED ));
496521 source .flushBuffers ();
@@ -499,32 +524,32 @@ class NativeAudioSource {
499524 AL .sourcePlay (source .source );
500525 source .updateCompleteTimer ();
501526 }
502- if (source .streamEnded ) source .stopStream ();
527+ if (source .streamEnded ) source .removeStream ();
503528 }
504-
505- if (source .streamRemove ) streamSources .remove (source );
506529 }
507530
508- i = queuedStreamSources .length ;
509- while (i -- > 0 ) streamSources .push (queuedStreamSources [i ]);
510- queuedStreamSources .resize (0 );
511-
512531 streamMutex .release ();
513532
514533 if (streamSources .length == 0 ) streamHandlerTimer .stop ();
515534 else if (threadRunning || (threadRunning = (streamThread = Thread .create (streamThreadRun )) != null ))
516535 streamThread .sendMessage (streamSources .length );
517536 }
518537
519- function stopStream () {
538+ function removeStream () {
539+ streamRemove = false ;
520540 queuedStreamSources .remove (this );
541+ streamSources .remove (this );
542+ }
543+
544+ function stopStream () {
521545 streamRemove = true ;
546+ queuedStreamSources .remove (this );
522547 }
523548
524549 function resetStream () {
550+ streamRemove = false ;
525551 if (! queuedStreamSources .contains (this ) && ! streamSources .contains (this )) {
526552 queuedStreamSources .push (this );
527- streamRemove = false ;
528553 if (streamHandlerTimer == null || ! streamHandlerTimer .mRunning )
529554 streamHandlerTimer = resetTimer (streamHandlerTimer , STREAM_TIMER_CHECK_MS , streamHandlerRun );
530555 }
@@ -536,8 +561,9 @@ class NativeAudioSource {
536561
537562 skipBuffers (AL .getSourcei (source , AL .BUFFERS_PROCESSED ));
538563
539- final process = requestBuffers < STREAM_MIN_BUFFERS ? STREAM_MIN_BUFFERS - requestBuffers : 0 ;
540- fillBuffers (STREAM_PROCESS_BUFFERS > process ? STREAM_PROCESS_BUFFERS : process );
564+ var process = requestBuffers < STREAM_MIN_BUFFERS ? STREAM_MIN_BUFFERS - requestBuffers : 0 , v = STREAM_MAX_BUFFERS - requestBuffers ;
565+ process = STREAM_PROCESS_BUFFERS > process ? STREAM_PROCESS_BUFFERS : process ;
566+ if ((process = v > process ? process : v ) > 0 ) fillBuffers (process );
541567 flushBuffers ();
542568
543569 if (AL .getSourcei (source , AL .SOURCE_STATE ) == AL .STOPPED ) {
0 commit comments