start reimplementing streaming audio on voice API
							parent
							
								
									c2cb83f93f
								
							
						
					
					
						commit
						a0408a863c
					
				|  | @ -159,6 +159,8 @@ namespace MoonWorks.Audio | |||
| 			previousTickTime = TickStopwatch.Elapsed.Ticks; | ||||
| 			float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond; | ||||
| 
 | ||||
| 			// TODO: call an Update on all active voices | ||||
| 
 | ||||
| 			for (var i = autoUpdateStreamingSoundReferences.Count - 1; i >= 0; i -= 1) | ||||
| 			{ | ||||
| 				var streamingSound = autoUpdateStreamingSoundReferences[i]; | ||||
|  | @ -206,6 +208,8 @@ namespace MoonWorks.Audio | |||
| 			FAudio.FAudio_CommitChanges(Handle, syncGroup); | ||||
| 		} | ||||
| 
 | ||||
| 		// TODO: is pooling SourceVoices generically a good idea? there are a lot of different kinds | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Obtains an appropriate source voice from the voice pool. | ||||
| 		/// </summary> | ||||
|  |  | |||
|  | @ -160,11 +160,6 @@ namespace MoonWorks.Audio | |||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		public void Submit(StreamingSound streamingSound) | ||||
| 		{ | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Designates that this source voice will return to the voice pool once all its buffers are exhausted. | ||||
| 		/// </summary> | ||||
|  |  | |||
|  | @ -165,7 +165,7 @@ namespace MoonWorks.Audio | |||
| 			queuedBufferCount = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		protected unsafe void AddBuffer() | ||||
| 		public unsafe void AddBuffer() | ||||
| 		{ | ||||
| 			var buffer = buffers[nextBufferIndex]; | ||||
| 			nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT; | ||||
|  |  | |||
|  | @ -0,0 +1,92 @@ | |||
| using System; | ||||
| 
 | ||||
| namespace MoonWorks.Audio | ||||
| { | ||||
| 	public abstract class StreamingVoice : SourceVoice | ||||
| 	{ | ||||
| 		private const int BUFFER_COUNT = 3; | ||||
| 		private readonly IntPtr[] buffers; | ||||
| 		private int nextBufferIndex = 0; | ||||
| 		private uint BufferSize; | ||||
| 
 | ||||
| 		public bool Loop { get; set; } | ||||
| 
 | ||||
| 		public StreamingVoice(AudioDevice device, Format format, uint bufferSize) : base(device, format) | ||||
| 		{ | ||||
| 			BufferSize = bufferSize; | ||||
| 		} | ||||
| 
 | ||||
| 		internal unsafe void Update() | ||||
| 		{ | ||||
| 			lock (StateLock) | ||||
| 			{ | ||||
| 				if (!IsDisposed) | ||||
| 				{ | ||||
| 					if (State != SoundState.Playing) | ||||
| 					{ | ||||
| 						return; | ||||
| 					} | ||||
| 
 | ||||
| 					QueueBuffers(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		protected void QueueBuffers() | ||||
| 		{ | ||||
| 			var buffersQueued = BuffersQueued; | ||||
| 			for (int i = 0; i < BUFFER_COUNT - buffersQueued; i += 1) | ||||
| 			{ | ||||
| 				AddBuffer(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		protected unsafe void AddBuffer() | ||||
| 		{ | ||||
| 			var buffer = buffers[nextBufferIndex]; | ||||
| 			nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT; | ||||
| 
 | ||||
| 			FillBuffer( | ||||
| 				(void*) buffer, | ||||
| 				(int) BufferSize, | ||||
| 				out int filledLengthInBytes, | ||||
| 				out bool reachedEnd | ||||
| 			); | ||||
| 
 | ||||
| 			if (filledLengthInBytes > 0) | ||||
| 			{ | ||||
| 				var buf = new FAudio.FAudioBuffer | ||||
| 				{ | ||||
| 					AudioBytes = (uint) filledLengthInBytes, | ||||
| 					pAudioData = buffer, | ||||
| 					PlayLength = ( | ||||
| 						(uint) (filledLengthInBytes / | ||||
| 						Format.Channels / | ||||
| 						(uint) (Format.BitsPerSample / 8)) | ||||
| 					) | ||||
| 				}; | ||||
| 
 | ||||
| 				Submit(buf); | ||||
| 			} | ||||
| 
 | ||||
| 			if (reachedEnd) | ||||
| 			{ | ||||
| 				/* We have reached the end of the data, what do we do? */ | ||||
| 				if (Loop) | ||||
| 				{ | ||||
| 					SeekStart(); | ||||
| 					AddBuffer(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		protected unsafe abstract void FillBuffer( | ||||
| 			void* buffer, | ||||
| 			int bufferLengthInBytes, /* in bytes */ | ||||
| 			out int filledLengthInBytes, /* in bytes */ | ||||
| 			out bool reachedEnd | ||||
| 		); | ||||
| 
 | ||||
| 		protected abstract void SeekStart(); | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue