stream ogg from memory instead of disk
							parent
							
								
									5e2b8de2d3
								
							
						
					
					
						commit
						ba66ed4225
					
				|  | @ -12,7 +12,7 @@ namespace MoonWorks.Audio | ||||||
| 
 | 
 | ||||||
| 		protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings; | 		protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings; | ||||||
| 
 | 
 | ||||||
| 		protected bool is3D; | 		public bool Is3D { get; protected set; } | ||||||
| 
 | 
 | ||||||
| 		public abstract SoundState State { get; protected set; } | 		public abstract SoundState State { get; protected set; } | ||||||
| 
 | 
 | ||||||
|  | @ -33,7 +33,7 @@ namespace MoonWorks.Audio | ||||||
| 					_pan = 1f; | 					_pan = 1f; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (is3D) { return; } | 				if (Is3D) { return; } | ||||||
| 
 | 
 | ||||||
| 				SetPanMatrixCoefficients(); | 				SetPanMatrixCoefficients(); | ||||||
| 				FAudio.FAudioVoice_SetOutputMatrix( | 				FAudio.FAudioVoice_SetOutputMatrix( | ||||||
|  | @ -167,8 +167,7 @@ namespace MoonWorks.Audio | ||||||
| 			ushort bitsPerSample, | 			ushort bitsPerSample, | ||||||
| 			ushort blockAlign, | 			ushort blockAlign, | ||||||
| 			ushort channels, | 			ushort channels, | ||||||
| 			uint samplesPerSecond, | 			uint samplesPerSecond | ||||||
| 			bool is3D |  | ||||||
| 		) : base(device) | 		) : base(device) | ||||||
| 		{ | 		{ | ||||||
| 			var format = new FAudio.FAudioWaveFormatEx | 			var format = new FAudio.FAudioWaveFormatEx | ||||||
|  | @ -200,7 +199,6 @@ namespace MoonWorks.Audio | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			this.is3D = is3D; |  | ||||||
| 			InitDSPSettings(Format.nChannels); | 			InitDSPSettings(Format.nChannels); | ||||||
| 
 | 
 | ||||||
| 			// FIXME: not everything should be running through reverb... | 			// FIXME: not everything should be running through reverb... | ||||||
|  | @ -216,7 +214,7 @@ namespace MoonWorks.Audio | ||||||
| 
 | 
 | ||||||
| 		public void Apply3D(AudioListener listener, AudioEmitter emitter) | 		public void Apply3D(AudioListener listener, AudioEmitter emitter) | ||||||
| 		{ | 		{ | ||||||
| 			is3D = true; | 			Is3D = true; | ||||||
| 
 | 
 | ||||||
| 			emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar; | 			emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar; | ||||||
| 			emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount; | 			emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount; | ||||||
|  | @ -273,7 +271,7 @@ namespace MoonWorks.Audio | ||||||
| 		{ | 		{ | ||||||
| 			float doppler; | 			float doppler; | ||||||
| 			float dopplerScale = Device.DopplerScale; | 			float dopplerScale = Device.DopplerScale; | ||||||
| 			if (!is3D || dopplerScale == 0.0f) | 			if (!Is3D || dopplerScale == 0.0f) | ||||||
| 			{ | 			{ | ||||||
| 				doppler = 1.0f; | 				doppler = 1.0f; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -275,7 +275,7 @@ namespace MoonWorks.Audio | ||||||
| 		{ | 		{ | ||||||
| 			if (Instances.Count == 0) | 			if (Instances.Count == 0) | ||||||
| 			{ | 			{ | ||||||
| 				Instances.Push(new StaticSoundInstance(Device, this, false)); | 				Instances.Push(new StaticSoundInstance(Device, this)); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return Instances.Pop(); | 			return Instances.Pop(); | ||||||
|  |  | ||||||
|  | @ -32,9 +32,8 @@ namespace MoonWorks.Audio | ||||||
| 
 | 
 | ||||||
| 		internal StaticSoundInstance( | 		internal StaticSoundInstance( | ||||||
| 			AudioDevice device, | 			AudioDevice device, | ||||||
| 			StaticSound parent, | 			StaticSound parent | ||||||
| 			bool is3D | 		) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond) | ||||||
| 		) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond, is3D) |  | ||||||
| 		{ | 		{ | ||||||
| 			Parent = parent; | 			Parent = parent; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -22,9 +22,8 @@ namespace MoonWorks.Audio | ||||||
| 			ushort bitsPerSample, | 			ushort bitsPerSample, | ||||||
| 			ushort blockAlign, | 			ushort blockAlign, | ||||||
| 			ushort channels, | 			ushort channels, | ||||||
| 			uint samplesPerSecond, | 			uint samplesPerSecond | ||||||
| 			bool is3D | 		) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond) { } | ||||||
| 		) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond, is3D) { } |  | ||||||
| 
 | 
 | ||||||
| 		public override void Play(bool loop = false) | 		public override void Play(bool loop = false) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| using System; | using System; | ||||||
| using System.IO; | using System.IO; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Audio | namespace MoonWorks.Audio | ||||||
| { | { | ||||||
|  | @ -8,52 +9,51 @@ namespace MoonWorks.Audio | ||||||
| 		// FIXME: what should this value be? | 		// FIXME: what should this value be? | ||||||
| 		public const int BUFFER_SIZE = 1024 * 128; | 		public const int BUFFER_SIZE = 1024 * 128; | ||||||
| 
 | 
 | ||||||
| 		internal IntPtr FileHandle { get; } | 		private IntPtr VorbisHandle; | ||||||
| 		internal FAudio.stb_vorbis_info Info { get; } | 		private IntPtr FileDataPtr; | ||||||
|  | 		private FAudio.stb_vorbis_info Info; | ||||||
| 
 | 
 | ||||||
| 		private readonly float[] buffer; | 		private readonly float[] buffer; // currently decoded bytes | ||||||
| 
 | 
 | ||||||
| 		public override SoundState State { get; protected set; } | 		public override SoundState State { get; protected set; } | ||||||
| 
 | 
 | ||||||
| 		public static StreamingSoundOgg Load( | 		public static StreamingSoundOgg Load(AudioDevice device, string filePath) | ||||||
| 			AudioDevice device, |  | ||||||
| 			string filePath, |  | ||||||
| 			bool is3D = false |  | ||||||
| 		) |  | ||||||
| 		{ | 		{ | ||||||
| 			var fileHandle = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero); | 			var fileData = File.ReadAllBytes(filePath); | ||||||
|  | 			var fileDataPtr = (IntPtr) GCHandle.Alloc(fileData, GCHandleType.Pinned); | ||||||
|  | 			var vorbisHandle = FAudio.stb_vorbis_open_memory(fileDataPtr, fileData.Length, out int error, IntPtr.Zero); | ||||||
| 			if (error != 0) | 			if (error != 0) | ||||||
| 			{ | 			{ | ||||||
|  | 				((GCHandle) fileDataPtr).Free(); | ||||||
| 				Logger.LogError("Error opening OGG file!"); | 				Logger.LogError("Error opening OGG file!"); | ||||||
| 				throw new AudioLoadException("Error opening OGG file!"); | 				throw new AudioLoadException("Error opening OGG file!"); | ||||||
| 			} | 			} | ||||||
| 
 | 			var info = FAudio.stb_vorbis_get_info(vorbisHandle); | ||||||
| 			var info = FAudio.stb_vorbis_get_info(fileHandle); |  | ||||||
| 
 | 
 | ||||||
| 			return new StreamingSoundOgg( | 			return new StreamingSoundOgg( | ||||||
| 				device, | 				device, | ||||||
| 				fileHandle, | 				fileDataPtr, | ||||||
| 				info, | 				vorbisHandle, | ||||||
| 				is3D | 				info | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		internal StreamingSoundOgg( | 		internal StreamingSoundOgg( | ||||||
| 			AudioDevice device, | 			AudioDevice device, | ||||||
| 			IntPtr fileHandle, | 			IntPtr fileDataPtr, // MUST BE PINNED!! | ||||||
| 			FAudio.stb_vorbis_info info, | 			IntPtr vorbisHandle, | ||||||
| 			bool is3D | 			FAudio.stb_vorbis_info info | ||||||
| 		) : base( | 		) : base( | ||||||
| 			device, | 			device, | ||||||
| 			3, /* float type */ | 			3, /* float type */ | ||||||
| 			32, /* size of float */ | 			32, /* size of float */ | ||||||
| 			(ushort) (4 * info.channels), | 			(ushort) (4 * info.channels), | ||||||
| 			(ushort) info.channels, | 			(ushort) info.channels, | ||||||
| 			info.sample_rate, | 			info.sample_rate | ||||||
| 			is3D |  | ||||||
| 		) | 		) | ||||||
| 		{ | 		{ | ||||||
| 			FileHandle = fileHandle; | 			FileDataPtr = fileDataPtr; | ||||||
|  | 			VorbisHandle = vorbisHandle; | ||||||
| 			Info = info; | 			Info = info; | ||||||
| 			buffer = new float[BUFFER_SIZE]; | 			buffer = new float[BUFFER_SIZE]; | ||||||
| 
 | 
 | ||||||
|  | @ -71,7 +71,7 @@ namespace MoonWorks.Audio | ||||||
| 
 | 
 | ||||||
| 			/* NOTE: this function returns samples per channel, not total samples */ | 			/* NOTE: this function returns samples per channel, not total samples */ | ||||||
| 			var samples = FAudio.stb_vorbis_get_samples_float_interleaved( | 			var samples = FAudio.stb_vorbis_get_samples_float_interleaved( | ||||||
| 				FileHandle, | 				VorbisHandle, | ||||||
| 				Info.channels, | 				Info.channels, | ||||||
| 				buffer, | 				buffer, | ||||||
| 				buffer.Length | 				buffer.Length | ||||||
|  | @ -85,12 +85,13 @@ namespace MoonWorks.Audio | ||||||
| 
 | 
 | ||||||
| 		protected override void SeekStart() | 		protected override void SeekStart() | ||||||
| 		{ | 		{ | ||||||
| 			FAudio.stb_vorbis_seek_start(FileHandle); | 			FAudio.stb_vorbis_seek_start(VorbisHandle); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		protected override void Destroy() | 		protected override void Destroy() | ||||||
| 		{ | 		{ | ||||||
| 			FAudio.stb_vorbis_close(FileHandle); | 			((GCHandle) FileDataPtr).Free(); | ||||||
|  | 			FAudio.stb_vorbis_close(VorbisHandle); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue