using Ryujinx.Audio.Common; using System; using System.Runtime.InteropServices; namespace Ryujinx.Audio.Integration { public class HardwareDeviceImpl : IHardwareDevice { private readonly IHardwareDeviceSession _session; private readonly uint _channelCount; private readonly uint _sampleRate; private uint _currentBufferTag; private readonly byte[] _buffer; public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate, float volume) { _session = deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, null, SampleFormat.PcmInt16, sampleRate, channelCount, volume); _channelCount = channelCount; _sampleRate = sampleRate; _currentBufferTag = 0; _buffer = new byte[Constants.TargetSampleCount * channelCount * sizeof(ushort)]; _session.Start(); } public void AppendBuffer(ReadOnlySpan data, uint channelCount) { data.CopyTo(MemoryMarshal.Cast(_buffer)); _session.QueueBuffer(new AudioBuffer { DataPointer = _currentBufferTag++, Data = _buffer, DataSize = (ulong)_buffer.Length, }); _currentBufferTag %= 4; } public void SetVolume(float volume) { _session.SetVolume(volume); } public float GetVolume() { return _session.GetVolume(); } public uint GetChannelCount() { return _channelCount; } public uint GetSampleRate() { return _sampleRate; } public void Dispose() { GC.SuppressFinalize(this); Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { _session.Dispose(); } } } }