Browse Source

Playing with streaming audio...

Mark Sibly 9 years ago
parent
commit
6a4d7bd58d
1 changed files with 76 additions and 49 deletions
  1. 76 49
      modules/mojo/audio/audio.monkey2

+ 76 - 49
modules/mojo/audio/audio.monkey2

@@ -163,32 +163,38 @@ Class Channel
 	#end
 	#end
 	Property Playing:Bool()
 	Property Playing:Bool()
 		If Not _alSource Return False
 		If Not _alSource Return False
-		UpdateALState()
-		Return _alState=AL_PLAYING Or _alState=AL_PAUSED
+		
+		Local state:=ALState()
+		Return state=AL_PLAYING Or state=AL_PAUSED
 	End
 	End
 	
 	
 	#rem monkeydoc True if channel is paused.
 	#rem monkeydoc True if channel is paused.
 	#end
 	#end
 	Property Paused:Bool()
 	Property Paused:Bool()
 		If Not _alSource Return False
 		If Not _alSource Return False
-		UpdateALState()
-		Return _alState=AL_PAUSED
+		
+		Return ALState()=AL_PAUSED
+		
 	Setter( paused:Bool )
 	Setter( paused:Bool )
 		If Not Playing Return
 		If Not Playing Return
+		
 		If paused
 		If paused
 			alSourcePause( _alSource )
 			alSourcePause( _alSource )
 		Else
 		Else
 			alSourcePlay( _alSource )
 			alSourcePlay( _alSource )
 		Endif
 		Endif
-		UpdateALState()
 	End
 	End
 	
 	
 	#rem monkeydoc Channel volume in the range 0 to 1.
 	#rem monkeydoc Channel volume in the range 0 to 1.
 	#end
 	#end
 	Property Volume:Float()
 	Property Volume:Float()
+		If Not _alSource Return 0
+	
 		Return _volume
 		Return _volume
+		
 	Setter( volume:Float )
 	Setter( volume:Float )
 		If Not _alSource Return
 		If Not _alSource Return
+		
 		_volume=Clamp( volume,0.0,1.0 )
 		_volume=Clamp( volume,0.0,1.0 )
 		alSourcef( _alSource,AL_GAIN,_volume )
 		alSourcef( _alSource,AL_GAIN,_volume )
 	End
 	End
@@ -196,9 +202,13 @@ Class Channel
 	#rem monkeydoc Channel playback rate.
 	#rem monkeydoc Channel playback rate.
 	#end	
 	#end	
 	Property Rate:Float()
 	Property Rate:Float()
+		If Not _alSource Return 0
+
 		Return _rate
 		Return _rate
+		
 	Setter( rate:Float )
 	Setter( rate:Float )
 		If Not _alSource Return
 		If Not _alSource Return
+		
 		_rate=rate
 		_rate=rate
 		alSourcef( _alSource,AL_PITCH,_rate )
 		alSourcef( _alSource,AL_PITCH,_rate )
 	End
 	End
@@ -206,9 +216,13 @@ Class Channel
 	#rem monkeydoc Channel pan in the range -1 (left) to 1 (right).
 	#rem monkeydoc Channel pan in the range -1 (left) to 1 (right).
 	#end	
 	#end	
 	Property Pan:Float()
 	Property Pan:Float()
+		If Not _alSource Return 0
+	
 		Return _pan
 		Return _pan
+		
 	Setter( pan:Float)
 	Setter( pan:Float)
 		If Not _alSource Return
 		If Not _alSource Return
+		
 		_pan=Clamp( pan,-1.0,1.0 )
 		_pan=Clamp( pan,-1.0,1.0 )
 		Local x:=Sin( _pan ),z:=-Cos( _pan )
 		Local x:=Sin( _pan ),z:=-Cos( _pan )
 		alSource3f( _alSource,AL_POSITION,x,0,z )
 		alSource3f( _alSource,AL_POSITION,x,0,z )
@@ -218,6 +232,7 @@ Class Channel
 	#end
 	#end
 	Method Discard()
 	Method Discard()
 		If Not _alSource Return
 		If Not _alSource Return
+		
 		alDeleteSources( 1,Varptr _alSource )
 		alDeleteSources( 1,Varptr _alSource )
 		_alSource=0
 		_alSource=0
 	End
 	End
@@ -235,57 +250,63 @@ Class Channel
 	End
 	End
 	
 	
 	#rem monkeydoc @hidden - Highly experimental!!!!!
 	#rem monkeydoc @hidden - Highly experimental!!!!!
+	
 	#end
 	#end
-	Method Queue( data:AudioData )
 	
 	
-		If _waiting Return
+	Method WaitQueued( queued:Int )
+	
+		While _queued>queued
 		
 		
-		If Not _buffers
+			FlushProcessed()
+			
+			If _queued<=queued Return
 		
 		
-			Local n_bufs:=4	'need some work on these magic numbers!
+			_waiting=True
+			
+			_future.Get()
 		
 		
-			_buffers=New ALuint[n_bufs]
-			_ubuffers=New ALuint[n_bufs]
-			_pbuffers=New Stack<ALuint>
+		Wend
 
 
-			For Local i:=0 Until n_bufs
-				Local buf:ALuint
-				alGenBuffers( 1,Varptr buf )
-				_buffers[i]=buf
-				_pbuffers.Push( buf )
-			Next
-			
+	End
+	
+	#rem monkeydoc @hidden - Highly experimental!!!!!
+	
+	#end
+	Method Queue( data:AudioData )
+	
+		Local buf:ALuint
+		
+		If Not _tmpBuffers
+		
+			_tmpBuffers=New Stack<ALuint>
+			_freeBuffers=New Stack<ALuint>
 			_future=New Future<Int>
 			_future=New Future<Int>
-			
 			_waiting=False
 			_waiting=False
+			_queued=0
 			
 			
-			_timer=New Timer( 25,Lambda()
-			
+			_timer=New Timer( 20,Lambda()
 				FlushProcessed()
 				FlushProcessed()
 			End )
 			End )
-			
-		Endif
-		
-		If _pbuffers.Empty
+
+		Endif		
 		
 		
-			FlushProcessed()
-			
-			If _pbuffers.Empty
-				_waiting=True
-				If Not _future.Get() Return
-			Endif
+		If _freeBuffers.Empty
 			
 			
-		Endif
+			alGenBuffers( 1,Varptr buf )
+			_tmpBuffers.Push( buf )
 		
 		
-		Local buf:=_pbuffers.Pop()
+		Else
+			buf=_freeBuffers.Pop()
+		Endif
 		
 		
 		alBufferData( buf,ALFormat( data.Format ),data.Data,data.Size,data.Hertz )
 		alBufferData( buf,ALFormat( data.Format ),data.Data,data.Size,data.Hertz )
 		
 		
 		alSourceQueueBuffers( _alSource,1,Varptr buf )
 		alSourceQueueBuffers( _alSource,1,Varptr buf )
+		_queued+=1
 		
 		
-		UpdateALState()
-		If _alState=AL_INITIAL Or _alState=AL_STOPPED alSourcePlay( _alSource )
-		
+		Local state:=ALState()
+		If state=AL_INITIAL Or state=AL_STOPPED alSourcePlay( _alSource )
+	
 	End
 	End
 	
 	
 	#rem monkeydoc Stops channel.
 	#rem monkeydoc Stops channel.
@@ -298,29 +319,34 @@ Class Channel
 	Private
 	Private
 	
 	
 	Field _alSource:ALuint
 	Field _alSource:ALuint
-	Field _alState:ALenum=AL_INITIAL
 	Field _volume:Float=1
 	Field _volume:Float=1
 	Field _rate:Float=1
 	Field _rate:Float=1
 	Field _pan:Float=0
 	Field _pan:Float=0
 	
 	
-	Field _buffers:ALuint[]
-	Field _ubuffers:ALuint[]
-	Field _pbuffers:Stack<ALuint>
+	Field _tmpBuffers:Stack<ALuint>
+	Field _freeBuffers:Stack<ALuint>
 	Field _future:Future<Int>
 	Field _future:Future<Int>
 	Field _waiting:Bool
 	Field _waiting:Bool
+	Field _queued:Int
 	Field _timer:Timer
 	Field _timer:Timer
 	
 	
 	Method FlushProcessed:Int()
 	Method FlushProcessed:Int()
 	
 	
 		Local proc:ALint
 		Local proc:ALint
 		alGetSourcei( _alSource,AL_BUFFERS_PROCESSED,Varptr proc )
 		alGetSourcei( _alSource,AL_BUFFERS_PROCESSED,Varptr proc )
+		
 '		Print "processed: "+proc
 '		Print "processed: "+proc
+
 		If Not proc Return 0
 		If Not proc Return 0
-				
-		alSourceUnqueueBuffers( _alSource,proc,_ubuffers.Data )
-				
+		
 		For Local i:=0 Until proc
 		For Local i:=0 Until proc
-			_pbuffers.Push( _ubuffers[i] )
+		
+			Local buf:ALuint
+			
+			alSourceUnqueueBuffers( _alSource,1,Varptr buf )
+			_queued-=1
+			
+			If _tmpBuffers.Contains( buf ) _freeBuffers.Push( buf )
 		Next
 		Next
 
 
 		If _waiting 
 		If _waiting 
@@ -329,12 +355,13 @@ Class Channel
 		Endif
 		Endif
 		
 		
 		Return proc
 		Return proc
-		
+
 	End
 	End
 	
 	
-	Method UpdateALState:ALenum()
-		alGetSourcei( _alSource,AL_SOURCE_STATE,Varptr _alState )
-		Return _alState
+	Method ALState:ALenum()
+		Local state:ALenum
+		alGetSourcei( _alSource,AL_SOURCE_STATE,Varptr state )
+		Return state
 	End
 	End
 	
 	
 End
 End