Haydn: Part 1 (#2007)

* Haydn: Part 1

Based on my reverse of audio 11.0.0.

As always, core implementation under LGPLv3 for the same reasons as for Amadeus.

This place the bases of a more flexible audio system while making audout & audin accurate.

This have the following improvements:
- Complete reimplementation of audout and audin.
- Audin currently only have a dummy backend.
- Dramatically reduce CPU usage by up to 50% in common cases (SoundIO and OpenAL).
- Audio Renderer now can output to 5.1 devices when supported.
- Audio Renderer init its backend on demand instead of keeping two up all the time.
- All backends implementation are now in their own project.
- Ryujinx.Audio.Renderer was renamed Ryujinx.Audio and was refactored because of this.

As a note, games having issues with OpenAL haven't improved and will not
because of OpenAL design (stopping when buffers finish playing causing
possible audio "pops" when buffers are very small).

* Update for latest hexkyz's edits on Switchbrew

* audren: Rollback channel configuration changes

* Address gdkchan's comments

* Fix typo in OpenAL backend driver

* Address last comments

* Fix a nit

* Address gdkchan's comments
This commit is contained in:
Mary 2021-02-26 01:11:56 +01:00 committed by GitHub
parent 1c49089ff0
commit f556c80d02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
249 changed files with 5614 additions and 2712 deletions

View file

@ -1,98 +0,0 @@
using Ryujinx.Audio;
using Ryujinx.Audio.Renderer;
using Ryujinx.Audio.Renderer.Integration;
using System;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer
{
public class AalHardwareDevice : HardwareDevice
{
private IAalOutput _output;
private int _trackId;
private int _bufferTag;
private int _nextTag;
private AutoResetEvent _releaseEvent;
private uint _channelCount;
private uint _sampleRate;
private short[] _buffer;
private Queue<long> _releasedTags;
public AalHardwareDevice(int bufferTag, IAalOutput output, uint channelCount, uint sampleRate)
{
_bufferTag = bufferTag;
_channelCount = channelCount;
_sampleRate = sampleRate;
_output = output;
_releaseEvent = new AutoResetEvent(true);
_trackId = _output.OpenTrack((int)sampleRate, (int)channelCount, AudioCallback);
_releasedTags = new Queue<long>();
_buffer = new short[RendererConstants.TargetSampleCount * channelCount];
_output.Start(_trackId);
}
private void AudioCallback()
{
long[] released = _output.GetReleasedBuffers(_trackId, int.MaxValue);
lock (_releasedTags)
{
foreach (long tag in released)
{
_releasedTags.Enqueue(tag);
}
}
}
private long GetReleasedTag()
{
lock (_releasedTags)
{
if (_releasedTags.Count > 0)
{
return _releasedTags.Dequeue();
}
return (_bufferTag << 16) | (_nextTag++);
}
}
public void AppendBuffer(ReadOnlySpan<short> data, uint channelCount)
{
data.CopyTo(_buffer.AsSpan());
_output.AppendBuffer(_trackId, GetReleasedTag(), _buffer);
}
public uint GetChannelCount()
{
return _channelCount;
}
public uint GetSampleRate()
{
return _sampleRate;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_output.Stop(_trackId);
_output.CloseTrack(_trackId);
_releaseEvent.Dispose();
}
}
}
}

View file

@ -1,4 +1,4 @@
using Ryujinx.Audio.Renderer.Integration;
using Ryujinx.Audio.Integration;
using Ryujinx.HLE.HOS.Kernel.Threading;
namespace Ryujinx.HLE.HOS.Services.Audio.AudioRenderer

View file

@ -1,4 +1,4 @@
using Ryujinx.Audio.Renderer.Integration;
using Ryujinx.Audio.Integration;
using Ryujinx.Audio.Renderer.Server;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;