private static void UnloadSteamAudio() { IPL.DestroyBinauralEffect(ref iplBinauralEffect); IPL.DestroyBinauralRenderer(ref iplBinauralRenderer); IPL.DestroyContext(ref iplContext); IPL.Cleanup(); }
//SteamAudio private static void PrepareSteamAudio() { //Steam Audio Initialization IPL.CreateContext(null, null, null, out iplContext); Console.WriteLine("Created SteamAudio context."); iplRenderingSettings = new IPL.RenderingSettings { samplingRate = SamplingRate, frameSize = AudioFrameSize }; //Binaural Renderer var hrtfParams = new IPL.HrtfParams { type = IPL.HrtfDatabaseType.Default }; IPL.CreateBinauralRenderer(iplContext, iplRenderingSettings, hrtfParams, out iplBinauralRenderer); //Audio Formats iplFormatMono = new IPL.AudioFormat { channelLayoutType = IPL.ChannelLayoutType.Speakers, channelLayout = IPL.ChannelLayout.Mono, channelOrder = IPL.ChannelOrder.Interleaved }; iplFormatStereo = new IPL.AudioFormat { channelLayoutType = IPL.ChannelLayoutType.Speakers, channelLayout = IPL.ChannelLayout.Stereo, channelOrder = IPL.ChannelOrder.Interleaved }; //Binaural Effect IPL.CreateBinauralEffect(iplBinauralRenderer, iplFormatMono, iplFormatStereo, out iplBinauralEffect); //Audio Buffers iplInputBuffer = new IPL.AudioBuffer { format = iplFormatMono, numSamples = iplRenderingSettings.frameSize, interleavedBuffer = IntPtr.Zero //Will be assigned before use. }; IntPtr outputDataPtr = Marshal.AllocHGlobal(AudioFrameSizeInBytes * 2); iplOutputBuffer = new IPL.AudioBuffer { format = iplFormatStereo, numSamples = iplRenderingSettings.frameSize, interleavedBuffer = outputDataPtr }; Console.WriteLine("SteamAudio is ready."); }
unsafe static void Main(string[] args) { Console.WriteLine($"Working Directory: {Path.GetFullPath(".")}"); try { var stopwatch = new Stopwatch(); byte[] bytes = LoadRawAudio(string.Join(' ', args)); using var audioStream = new MemoryStream(bytes); PrepareOpenAL(); #if !NO_PROCESSING PrepareSteamAudio(); #endif uint[] alBuffers = new uint[2]; byte[] frameInputBuffer = new byte[AudioFrameSizeInBytes]; AL.GenBuffers(alBuffers.Length, alBuffers); AL.GenSource(out uint sourceId); stopwatch.Start(); void StreamBuffer(uint bufferId, Vector3 position) { int bytesRead = audioStream.Read(frameInputBuffer, 0, frameInputBuffer.Length); //Loop the audio on stream end. if (bytesRead < frameInputBuffer.Length) { audioStream.Position = 0; audioStream.Read(frameInputBuffer, 0, frameInputBuffer.Length - bytesRead); } #if !NO_PROCESSING fixed(byte *ptr = frameInputBuffer) { iplInputBuffer.interleavedBuffer = (IntPtr)ptr; IPL.ApplyBinauralEffect(iplBinauralEffect, iplBinauralRenderer, iplInputBuffer, new IPL.Vector3(position.X, position.Y, position.Z), IPL.HrtfInterpolation.Nearest, 1f, iplOutputBuffer); } AL.BufferData(bufferId, BufferFormatStereoFloat32, iplOutputBuffer.interleavedBuffer, AudioFrameSizeInBytes * 2, iplRenderingSettings.samplingRate); #else AL.BufferData(bufferId, BufferFormatMonoFloat32, frameInputBuffer, frameInputBuffer.Length, SamplingRate); #endif CheckALErrors(); } Console.WriteLine(); int cursorPosX = Console.CursorLeft; int cursorPosY = Console.CursorTop; Console.CursorVisible = false; while (true) { var position = GetRotatingAudioPosition((float)stopwatch.Elapsed.TotalSeconds); //Display information Console.SetCursorPosition(cursorPosX, cursorPosY); Console.WriteLine($"Sound position: {position: 0.00;-0.00; 0.00}"); TimeSpan streamPositionTimeSpan = TimeSpan.FromSeconds((int)(audioStream.Position / sizeof(float) / SamplingRate)); TimeSpan streamLengthTimeSpan = TimeSpan.FromSeconds((int)(audioStream.Length / sizeof(float) / SamplingRate)); Console.WriteLine($"Stream position: {streamPositionTimeSpan.Minutes:D2}:{streamPositionTimeSpan.Seconds:D2} / {streamLengthTimeSpan.Minutes:D2}:{streamLengthTimeSpan.Seconds:D2}"); //Update streamed audio AL.GetSource(sourceId, AL.GetSourceInt.BuffersProcessed, out int numProcessedBuffers); AL.GetSource(sourceId, AL.GetSourceInt.BuffersQueued, out int numQueuedBuffers); int buffersToAdd = alBuffers.Length - numQueuedBuffers + numProcessedBuffers; while (buffersToAdd > 0) { uint bufferId = alBuffers[buffersToAdd - 1]; if (numProcessedBuffers > 0) { AL.SourceUnqueueBuffers(sourceId, 1, &bufferId); numProcessedBuffers--; } StreamBuffer(bufferId, position); AL.SourceQueueBuffers(sourceId, 1, &bufferId); CheckALErrors(); buffersToAdd--; } //Start playback whenever it stops AL.GetSource(sourceId, AL.GetSourceInt.SourceState, out int sourceState); if ((AL.SourceState)sourceState != AL.SourceState.Playing) { AL.SourcePlay(sourceId); } CheckALErrors(); //Sleep to not stress the CPU. Thread.Sleep(1); } } catch (Exception e) { Console.WriteLine($"{e.GetType().Name}: {e.Message}"); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } try { UnloadSteamAudio(); UnloadOpenAL(); } catch { } }