11package funkin .vis .dsp ;
22
3+ import haxe .io .Bytes ;
4+ import lime .utils .UInt8Array ;
35import flixel .FlxG ;
46import flixel .math .FlxMath ;
57import funkin .vis ._internal .html5 .AnalyzerNode ;
@@ -8,6 +10,10 @@ import grig.audio.FFT;
810import grig .audio .FFTVisualization ;
911import lime .media .AudioSource ;
1012
13+ #if lime_vorbis
14+ import lime .media .vorbis .VorbisFile ;
15+ #end
16+
1117using grig .audio .lime .UInt8ArrayTools ;
1218
1319typedef Bar =
@@ -58,6 +64,9 @@ class SpectralAnalyzer
5864 #end
5965 private var _logGraphCache : Array <Int > = [];
6066 private var _mixedCache : Array <Float > = [];
67+ #if lime_vorbis
68+ private var vorbisBuffer : UInt8Array ;
69+ #end
6170
6271 private function freqToBin (freq : Float , mathType : MathType = Round ): Int
6372 {
@@ -193,8 +202,8 @@ class SpectralAnalyzer
193202
194203 return levels ;
195204 #else
196- var numOctets = Std .int (audioSource . buffer .bitsPerSample / 8 );
197- var wantedLength = fftN * numOctets * audioSource . buffer .channels ;
205+ var numOctets = Std .int (audioClip . audioBuffer .bitsPerSample / 8 );
206+ var wantedLength = fftN * numOctets * audioClip . audioBuffer .channels ;
198207 var startFrame = audioClip .currentFrame ;
199208
200209 if (startFrame < 0 )
@@ -203,9 +212,34 @@ class SpectralAnalyzer
203212 }
204213
205214 startFrame - = startFrame % numOctets ;
206- var segment = audioSource .buffer .data .subarray (startFrame , min (startFrame + wantedLength , audioSource .buffer .data .length ));
207215
208- getSignal (segment , audioSource .buffer .bitsPerSample ); // Sets _buffer
216+ var endFrame : Int = min (startFrame + wantedLength , audioClip .audioBuffer .length );
217+
218+ #if lime_vorbis
219+ if (audioClip .streamed )
220+ {
221+ @:privateAccess
222+ var vorbisFile = audioSource .buffer .__srcVorbisFile ;
223+
224+ // reading from VorbisFile will automatically move the position
225+ // which causes issues with playback, so we keep old time to go back to it
226+ var prevPos = vorbisFile .pcmTell ();
227+
228+ vorbisFile .pcmSeek (Std .int (startFrame / (numOctets + audioClip .audioBuffer .channels )));
229+
230+ // calling this updates the vorbisBuffer array
231+ readVorbisFileBuffer (vorbisFile , wantedLength );
232+
233+ vorbisFile .pcmSeek (prevPos );
234+
235+ getSignal (vorbisBuffer , audioClip .audioBuffer .bitsPerSample );
236+ }
237+ else
238+ #end
239+ {
240+ var segment : UInt8Array = audioSource .buffer .data .subarray (startFrame , endFrame );
241+ getSignal (segment , audioClip .audioBuffer .bitsPerSample );
242+ }
209243
210244 if (audioSource .buffer .channels > 1 ) {
211245 var wantedArrayLength = Std .int (_buffer .length / audioSource .buffer .channels );
@@ -290,6 +324,43 @@ class SpectralAnalyzer
290324 return _buffer ;
291325 }
292326
327+ #if lime_vorbis
328+ // Pretty much copied from
329+ // https://github.com/openfl/lime/blob/develop/src/lime/_internal/backend/native/NativeAudioSource.hx#L212
330+ function readVorbisFileBuffer (vorbisFile : VorbisFile , length : Int ): UInt8Array
331+ {
332+ if (vorbisBuffer == null || vorbisBuffer .length != length )
333+ vorbisBuffer = new UInt8Array (length );
334+
335+ var read : Int = 0 ;
336+ var total : Int = 0 ;
337+ var readMax : Int = 4096 ;
338+
339+ while (total < length )
340+ {
341+ readMax = 4096 ;
342+
343+ if (readMax > length - total )
344+ {
345+ readMax = length - total ;
346+ }
347+
348+ read = vorbisFile .read (vorbisBuffer .buffer , total , readMax );
349+
350+ if (read > 0 )
351+ {
352+ total + = read ;
353+ }
354+ else
355+ {
356+ break ;
357+ }
358+ }
359+
360+ return vorbisBuffer ;
361+ }
362+ #end
363+
293364 @:generic
294365 static inline function clamp <T : Float >(val : T , min : T , max : T ): T
295366 {
0 commit comments