namespace Sandbox; public sealed partial class SoundStream : IHandle, IDisposable { internal CAudioStreamManaged native; #region IHandle void IHandle.HandleInit( IntPtr ptr ) { native = ptr; } void IHandle.HandleDestroy() { native = IntPtr.Zero; } bool IHandle.HandleValid() => !native.IsNull; #endregion /// /// Number of samples per second, as set during its creation. /// public int SampleRate { get; internal set; } /// /// Number of audio channels, as set during its creation. /// public int Channels { get; internal set; } public int QueuedSampleCount => native.IsValid ? (int)native.QueuedSampleCount() : 0; public int MaxWriteSampleCount => native.IsValid ? (int)native.MaxWriteSampleCount() : 0; public int LatencySamplesCount => native.IsValid ? (int)native.LatencySamplesCount() : 0; internal SoundStream() { } internal SoundStream( HandleCreationData _ ) { } public SoundStream( int sampleRate = 44100, int channels = 1 ) : this() { if ( Application.IsHeadless || Application.IsUnitTest ) return; if ( channels <= 0 || channels > 16 ) throw new ArgumentException( "Invalid number of channels" ); if ( sampleRate < 1024 ) throw new ArgumentException( "Invalid sample rate" ); using ( var h = IHandle.MakeNextHandle( this ) ) { var stream = CAudioStreamManaged.Create( channels, (uint)sampleRate ); stream.Channels = channels; stream.SampleRate = sampleRate; } } ~SoundStream() { Dispose(); } public unsafe void WriteData( Span data ) { if ( !native.IsValid ) throw new ArgumentException( "Invalid sound stream" ); if ( data.Length <= 0 ) return; fixed ( short* data_ptr = data ) { native.WriteAudioData( (IntPtr)data_ptr, (uint)(data.Length / Channels), (uint)Channels ); } } public void Dispose() { if ( native.IsValid ) { native.Destroy(); native = IntPtr.Zero; } } /// /// Play sound of the stream. /// public SoundHandle Play( float volume = 1.0f, float pitch = 1.0f ) { if ( !native.IsValid ) return default; CSfxTable table = native.GetSfxTable(); if ( table.IsNull ) return default; return Sound.PlayFile( table, volume, pitch, 0, "Sound Stream" ); } /// /// Play sound of the stream. /// [Obsolete( "Decibels are obsolete" )] public SoundHandle Play( float volume, float pitch, float decibels ) => Play( volume, pitch ); }