Adjust naming conventions and general refactoring in HLE Project (#490)

* Rename enum fields

* Naming conventions

* Remove unneeded ".this"

* Remove unneeded semicolons

* Remove unused Usings

* Don't use var

* Remove unneeded enum underlying types

* Explicitly label class visibility

* Remove unneeded @ prefixes

* Remove unneeded commas

* Remove unneeded if expressions

* Method doesn't use unsafe code

* Remove unneeded casts

* Initialized objects don't need an empty constructor

* Remove settings from DotSettings

* Revert "Explicitly label class visibility"

This reverts commit ad5eb5787cc5b27a4631cd46ef5f551c4ae95e51.

* Small changes

* Revert external enum renaming

* Changes from feedback

* Remove unneeded property setters
This commit is contained in:
Alex Barney 2018-12-04 14:23:37 -06:00 committed by gdkchan
parent c86aacde76
commit 85dbb9559a
299 changed files with 12268 additions and 12276 deletions

View file

@ -22,33 +22,33 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
//high latency).
private const int MixBufferSamplesCount = 960;
private Dictionary<int, ServiceProcessRequest> m_Commands;
private Dictionary<int, ServiceProcessRequest> _commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private KEvent UpdateEvent;
private KEvent _updateEvent;
private MemoryManager Memory;
private MemoryManager _memory;
private IAalOutput AudioOut;
private IAalOutput _audioOut;
private AudioRendererParameter Params;
private AudioRendererParameter _params;
private MemoryPoolContext[] MemoryPools;
private MemoryPoolContext[] _memoryPools;
private VoiceContext[] Voices;
private VoiceContext[] _voices;
private int Track;
private int _track;
private PlayState PlayState;
private PlayState _playState;
public IAudioRenderer(
Horizon System,
MemoryManager Memory,
IAalOutput AudioOut,
Horizon system,
MemoryManager memory,
IAalOutput audioOut,
AudioRendererParameter Params)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
_commands = new Dictionary<int, ServiceProcessRequest>
{
{ 0, GetSampleRate },
{ 1, GetSampleCount },
@ -60,75 +60,75 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{ 7, QuerySystemEvent }
};
UpdateEvent = new KEvent(System);
_updateEvent = new KEvent(system);
this.Memory = Memory;
this.AudioOut = AudioOut;
this.Params = Params;
_memory = memory;
_audioOut = audioOut;
_params = Params;
Track = AudioOut.OpenTrack(
_track = audioOut.OpenTrack(
AudioConsts.HostSampleRate,
AudioConsts.HostChannelsCount,
AudioCallback);
MemoryPools = CreateArray<MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);
_memoryPools = CreateArray<MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4);
Voices = CreateArray<VoiceContext>(Params.VoiceCount);
_voices = CreateArray<VoiceContext>(Params.VoiceCount);
InitializeAudioOut();
PlayState = PlayState.Stopped;
_playState = PlayState.Stopped;
}
// GetSampleRate() -> u32
public long GetSampleRate(ServiceCtx Context)
public long GetSampleRate(ServiceCtx context)
{
Context.ResponseData.Write(Params.SampleRate);
context.ResponseData.Write(_params.SampleRate);
return 0;
}
// GetSampleCount() -> u32
public long GetSampleCount(ServiceCtx Context)
public long GetSampleCount(ServiceCtx context)
{
Context.ResponseData.Write(Params.SampleCount);
context.ResponseData.Write(_params.SampleCount);
return 0;
}
// GetMixBufferCount() -> u32
public long GetMixBufferCount(ServiceCtx Context)
public long GetMixBufferCount(ServiceCtx context)
{
Context.ResponseData.Write(Params.MixCount);
context.ResponseData.Write(_params.MixCount);
return 0;
}
// GetState() -> u32
private long GetState(ServiceCtx Context)
private long GetState(ServiceCtx context)
{
Context.ResponseData.Write((int)PlayState);
context.ResponseData.Write((int)_playState);
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. Renderer State: {Enum.GetName(typeof(PlayState), PlayState)}");
Logger.PrintStub(LogClass.ServiceAudio, $"Stubbed. Renderer State: {Enum.GetName(typeof(PlayState), _playState)}");
return 0;
}
private void AudioCallback()
{
UpdateEvent.ReadableEvent.Signal();
_updateEvent.ReadableEvent.Signal();
}
private static T[] CreateArray<T>(int Size) where T : new()
private static T[] CreateArray<T>(int size) where T : new()
{
T[] Output = new T[Size];
T[] output = new T[size];
for (int Index = 0; Index < Size; Index++)
for (int index = 0; index < size; index++)
{
Output[Index] = new T();
output[index] = new T();
}
return Output;
return output;
}
private void InitializeAudioOut()
@ -137,258 +137,258 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
AppendMixedBuffer(1);
AppendMixedBuffer(2);
AudioOut.Start(Track);
_audioOut.Start(_track);
}
public long RequestUpdateAudioRenderer(ServiceCtx Context)
public long RequestUpdateAudioRenderer(ServiceCtx context)
{
long OutputPosition = Context.Request.ReceiveBuff[0].Position;
long OutputSize = Context.Request.ReceiveBuff[0].Size;
long outputPosition = context.Request.ReceiveBuff[0].Position;
long outputSize = context.Request.ReceiveBuff[0].Size;
MemoryHelper.FillWithZeros(Context.Memory, OutputPosition, (int)OutputSize);
MemoryHelper.FillWithZeros(context.Memory, outputPosition, (int)outputSize);
long InputPosition = Context.Request.SendBuff[0].Position;
long inputPosition = context.Request.SendBuff[0].Position;
StructReader Reader = new StructReader(Context.Memory, InputPosition);
StructWriter Writer = new StructWriter(Context.Memory, OutputPosition);
StructReader reader = new StructReader(context.Memory, inputPosition);
StructWriter writer = new StructWriter(context.Memory, outputPosition);
UpdateDataHeader InputHeader = Reader.Read<UpdateDataHeader>();
UpdateDataHeader inputHeader = reader.Read<UpdateDataHeader>();
Reader.Read<BehaviorIn>(InputHeader.BehaviorSize);
reader.Read<BehaviorIn>(inputHeader.BehaviorSize);
MemoryPoolIn[] MemoryPoolsIn = Reader.Read<MemoryPoolIn>(InputHeader.MemoryPoolSize);
MemoryPoolIn[] memoryPoolsIn = reader.Read<MemoryPoolIn>(inputHeader.MemoryPoolSize);
for (int Index = 0; Index < MemoryPoolsIn.Length; Index++)
for (int index = 0; index < memoryPoolsIn.Length; index++)
{
MemoryPoolIn MemoryPool = MemoryPoolsIn[Index];
MemoryPoolIn memoryPool = memoryPoolsIn[index];
if (MemoryPool.State == MemoryPoolState.RequestAttach)
if (memoryPool.State == MemoryPoolState.RequestAttach)
{
MemoryPools[Index].OutStatus.State = MemoryPoolState.Attached;
_memoryPools[index].OutStatus.State = MemoryPoolState.Attached;
}
else if (MemoryPool.State == MemoryPoolState.RequestDetach)
else if (memoryPool.State == MemoryPoolState.RequestDetach)
{
MemoryPools[Index].OutStatus.State = MemoryPoolState.Detached;
_memoryPools[index].OutStatus.State = MemoryPoolState.Detached;
}
}
Reader.Read<VoiceChannelResourceIn>(InputHeader.VoiceResourceSize);
reader.Read<VoiceChannelResourceIn>(inputHeader.VoiceResourceSize);
VoiceIn[] VoicesIn = Reader.Read<VoiceIn>(InputHeader.VoiceSize);
VoiceIn[] voicesIn = reader.Read<VoiceIn>(inputHeader.VoiceSize);
for (int Index = 0; Index < VoicesIn.Length; Index++)
for (int index = 0; index < voicesIn.Length; index++)
{
VoiceIn Voice = VoicesIn[Index];
VoiceIn voice = voicesIn[index];
VoiceContext VoiceCtx = Voices[Index];
VoiceContext voiceCtx = _voices[index];
VoiceCtx.SetAcquireState(Voice.Acquired != 0);
voiceCtx.SetAcquireState(voice.Acquired != 0);
if (Voice.Acquired == 0)
if (voice.Acquired == 0)
{
continue;
}
if (Voice.FirstUpdate != 0)
if (voice.FirstUpdate != 0)
{
VoiceCtx.AdpcmCtx = GetAdpcmDecoderContext(
Voice.AdpcmCoeffsPosition,
Voice.AdpcmCoeffsSize);
voiceCtx.AdpcmCtx = GetAdpcmDecoderContext(
voice.AdpcmCoeffsPosition,
voice.AdpcmCoeffsSize);
VoiceCtx.SampleFormat = Voice.SampleFormat;
VoiceCtx.SampleRate = Voice.SampleRate;
VoiceCtx.ChannelsCount = Voice.ChannelsCount;
voiceCtx.SampleFormat = voice.SampleFormat;
voiceCtx.SampleRate = voice.SampleRate;
voiceCtx.ChannelsCount = voice.ChannelsCount;
VoiceCtx.SetBufferIndex(Voice.BaseWaveBufferIndex);
voiceCtx.SetBufferIndex(voice.BaseWaveBufferIndex);
}
VoiceCtx.WaveBuffers[0] = Voice.WaveBuffer0;
VoiceCtx.WaveBuffers[1] = Voice.WaveBuffer1;
VoiceCtx.WaveBuffers[2] = Voice.WaveBuffer2;
VoiceCtx.WaveBuffers[3] = Voice.WaveBuffer3;
VoiceCtx.Volume = Voice.Volume;
VoiceCtx.PlayState = Voice.PlayState;
voiceCtx.WaveBuffers[0] = voice.WaveBuffer0;
voiceCtx.WaveBuffers[1] = voice.WaveBuffer1;
voiceCtx.WaveBuffers[2] = voice.WaveBuffer2;
voiceCtx.WaveBuffers[3] = voice.WaveBuffer3;
voiceCtx.Volume = voice.Volume;
voiceCtx.PlayState = voice.PlayState;
}
UpdateAudio();
UpdateDataHeader OutputHeader = new UpdateDataHeader();
UpdateDataHeader outputHeader = new UpdateDataHeader();
int UpdateHeaderSize = Marshal.SizeOf<UpdateDataHeader>();
int updateHeaderSize = Marshal.SizeOf<UpdateDataHeader>();
OutputHeader.Revision = IAudioRendererManager.RevMagic;
OutputHeader.BehaviorSize = 0xb0;
OutputHeader.MemoryPoolSize = (Params.EffectCount + Params.VoiceCount * 4) * 0x10;
OutputHeader.VoiceSize = Params.VoiceCount * 0x10;
OutputHeader.EffectSize = Params.EffectCount * 0x10;
OutputHeader.SinkSize = Params.SinkCount * 0x20;
OutputHeader.PerformanceManagerSize = 0x10;
OutputHeader.TotalSize = UpdateHeaderSize +
OutputHeader.BehaviorSize +
OutputHeader.MemoryPoolSize +
OutputHeader.VoiceSize +
OutputHeader.EffectSize +
OutputHeader.SinkSize +
OutputHeader.PerformanceManagerSize;
outputHeader.Revision = IAudioRendererManager.RevMagic;
outputHeader.BehaviorSize = 0xb0;
outputHeader.MemoryPoolSize = (_params.EffectCount + _params.VoiceCount * 4) * 0x10;
outputHeader.VoiceSize = _params.VoiceCount * 0x10;
outputHeader.EffectSize = _params.EffectCount * 0x10;
outputHeader.SinkSize = _params.SinkCount * 0x20;
outputHeader.PerformanceManagerSize = 0x10;
outputHeader.TotalSize = updateHeaderSize +
outputHeader.BehaviorSize +
outputHeader.MemoryPoolSize +
outputHeader.VoiceSize +
outputHeader.EffectSize +
outputHeader.SinkSize +
outputHeader.PerformanceManagerSize;
Writer.Write(OutputHeader);
writer.Write(outputHeader);
foreach (MemoryPoolContext MemoryPool in MemoryPools)
foreach (MemoryPoolContext memoryPool in _memoryPools)
{
Writer.Write(MemoryPool.OutStatus);
writer.Write(memoryPool.OutStatus);
}
foreach (VoiceContext Voice in Voices)
foreach (VoiceContext voice in _voices)
{
Writer.Write(Voice.OutStatus);
writer.Write(voice.OutStatus);
}
return 0;
}
public long StartAudioRenderer(ServiceCtx Context)
public long StartAudioRenderer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
PlayState = PlayState.Playing;
_playState = PlayState.Playing;
return 0;
}
public long StopAudioRenderer(ServiceCtx Context)
public long StopAudioRenderer(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceAudio, "Stubbed.");
PlayState = PlayState.Stopped;
_playState = PlayState.Stopped;
return 0;
}
public long QuerySystemEvent(ServiceCtx Context)
public long QuerySystemEvent(ServiceCtx context)
{
if (Context.Process.HandleTable.GenerateHandle(UpdateEvent.ReadableEvent, out int Handle) != KernelResult.Success)
if (context.Process.HandleTable.GenerateHandle(_updateEvent.ReadableEvent, out int handle) != KernelResult.Success)
{
throw new InvalidOperationException("Out of handles!");
}
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
return 0;
}
private AdpcmDecoderContext GetAdpcmDecoderContext(long Position, long Size)
private AdpcmDecoderContext GetAdpcmDecoderContext(long position, long size)
{
if (Size == 0)
if (size == 0)
{
return null;
}
AdpcmDecoderContext Context = new AdpcmDecoderContext();
AdpcmDecoderContext context = new AdpcmDecoderContext();
Context.Coefficients = new short[Size >> 1];
context.Coefficients = new short[size >> 1];
for (int Offset = 0; Offset < Size; Offset += 2)
for (int offset = 0; offset < size; offset += 2)
{
Context.Coefficients[Offset >> 1] = Memory.ReadInt16(Position + Offset);
context.Coefficients[offset >> 1] = _memory.ReadInt16(position + offset);
}
return Context;
return context;
}
private void UpdateAudio()
{
long[] Released = AudioOut.GetReleasedBuffers(Track, 2);
long[] released = _audioOut.GetReleasedBuffers(_track, 2);
for (int Index = 0; Index < Released.Length; Index++)
for (int index = 0; index < released.Length; index++)
{
AppendMixedBuffer(Released[Index]);
AppendMixedBuffer(released[index]);
}
}
private unsafe void AppendMixedBuffer(long Tag)
private void AppendMixedBuffer(long tag)
{
int[] MixBuffer = new int[MixBufferSamplesCount * AudioConsts.HostChannelsCount];
int[] mixBuffer = new int[MixBufferSamplesCount * AudioConsts.HostChannelsCount];
foreach (VoiceContext Voice in Voices)
foreach (VoiceContext voice in _voices)
{
if (!Voice.Playing)
if (!voice.Playing)
{
continue;
}
int OutOffset = 0;
int PendingSamples = MixBufferSamplesCount;
float Volume = Voice.Volume;
int outOffset = 0;
int pendingSamples = MixBufferSamplesCount;
float volume = voice.Volume;
while (PendingSamples > 0)
while (pendingSamples > 0)
{
int[] Samples = Voice.GetBufferData(Memory, PendingSamples, out int ReturnedSamples);
int[] samples = voice.GetBufferData(_memory, pendingSamples, out int returnedSamples);
if (ReturnedSamples == 0)
if (returnedSamples == 0)
{
break;
}
PendingSamples -= ReturnedSamples;
pendingSamples -= returnedSamples;
for (int Offset = 0; Offset < Samples.Length; Offset++)
for (int offset = 0; offset < samples.Length; offset++)
{
MixBuffer[OutOffset++] += (int)(Samples[Offset] * Voice.Volume);
mixBuffer[outOffset++] += (int)(samples[offset] * voice.Volume);
}
}
}
AudioOut.AppendBuffer(Track, Tag, GetFinalBuffer(MixBuffer));
_audioOut.AppendBuffer(_track, tag, GetFinalBuffer(mixBuffer));
}
private unsafe static short[] GetFinalBuffer(int[] Buffer)
private static unsafe short[] GetFinalBuffer(int[] buffer)
{
short[] Output = new short[Buffer.Length];
short[] output = new short[buffer.Length];
int Offset = 0;
int offset = 0;
// Perform Saturation using SSE2 if supported
if (Sse2.IsSupported)
{
fixed (int* inptr = Buffer)
fixed (short* outptr = Output)
fixed (int* inptr = buffer)
fixed (short* outptr = output)
{
for (; Offset + 32 <= Buffer.Length; Offset += 32)
for (; offset + 32 <= buffer.Length; offset += 32)
{
// Unroll the loop a little to ensure the CPU pipeline
// is always full.
Vector128<int> block1A = Sse2.LoadVector128(inptr + Offset + 0);
Vector128<int> block1B = Sse2.LoadVector128(inptr + Offset + 4);
Vector128<int> block1A = Sse2.LoadVector128(inptr + offset + 0);
Vector128<int> block1B = Sse2.LoadVector128(inptr + offset + 4);
Vector128<int> block2A = Sse2.LoadVector128(inptr + Offset + 8);
Vector128<int> block2B = Sse2.LoadVector128(inptr + Offset + 12);
Vector128<int> block2A = Sse2.LoadVector128(inptr + offset + 8);
Vector128<int> block2B = Sse2.LoadVector128(inptr + offset + 12);
Vector128<int> block3A = Sse2.LoadVector128(inptr + Offset + 16);
Vector128<int> block3B = Sse2.LoadVector128(inptr + Offset + 20);
Vector128<int> block3A = Sse2.LoadVector128(inptr + offset + 16);
Vector128<int> block3B = Sse2.LoadVector128(inptr + offset + 20);
Vector128<int> block4A = Sse2.LoadVector128(inptr + Offset + 24);
Vector128<int> block4B = Sse2.LoadVector128(inptr + Offset + 28);
Vector128<int> block4A = Sse2.LoadVector128(inptr + offset + 24);
Vector128<int> block4B = Sse2.LoadVector128(inptr + offset + 28);
Vector128<short> output1 = Sse2.PackSignedSaturate(block1A, block1B);
Vector128<short> output2 = Sse2.PackSignedSaturate(block2A, block2B);
Vector128<short> output3 = Sse2.PackSignedSaturate(block3A, block3B);
Vector128<short> output4 = Sse2.PackSignedSaturate(block4A, block4B);
Sse2.Store(outptr + Offset + 0, output1);
Sse2.Store(outptr + Offset + 8, output2);
Sse2.Store(outptr + Offset + 16, output3);
Sse2.Store(outptr + Offset + 24, output4);
Sse2.Store(outptr + offset + 0, output1);
Sse2.Store(outptr + offset + 8, output2);
Sse2.Store(outptr + offset + 16, output3);
Sse2.Store(outptr + offset + 24, output4);
}
}
}
// Process left overs
for (; Offset < Buffer.Length; Offset++)
for (; offset < buffer.Length; offset++)
{
Output[Offset] = DspUtils.Saturate(Buffer[Offset]);
output[offset] = DspUtils.Saturate(buffer[offset]);
}
return Output;
return output;
}
public void Dispose()
@ -396,11 +396,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
protected virtual void Dispose(bool disposing)
{
if (Disposing)
if (disposing)
{
AudioOut.CloseTrack(Track);
_audioOut.CloseTrack(_track);
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{
enum MemoryPoolState : int
enum MemoryPoolState
{
Invalid = 0,
Unknown = 1,

View file

@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
static class Resampler
{
#region "LookUp Tables"
private static short[] CurveLut0 = new short[]
private static short[] _curveLut0 = new short[]
{
6600, 19426, 6722, 3, 6479, 19424, 6845, 9, 6359, 19419, 6968, 15, 6239, 19412, 7093, 22,
6121, 19403, 7219, 28, 6004, 19391, 7345, 34, 5888, 19377, 7472, 41, 5773, 19361, 7600, 48,
@ -41,7 +41,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600
};
private static short[] CurveLut1 = new short[]
private static short[] _curveLut1 = new short[]
{
-68, 32639, 69, -5, -200, 32630, 212, -15, -328, 32613, 359, -26, -450, 32586, 512, -36,
-568, 32551, 669, -47, -680, 32507, 832, -58, -788, 32454, 1000, -69, -891, 32393, 1174, -80,
@ -77,7 +77,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
-36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68
};
private static short[] CurveLut2 = new short[]
private static short[] _curveLut2 = new short[]
{
3195, 26287, 3329, -32, 3064, 26281, 3467, -34, 2936, 26270, 3608, -38, 2811, 26253, 3751, -42,
2688, 26230, 3897, -46, 2568, 26202, 4046, -50, 2451, 26169, 4199, -54, 2338, 26130, 4354, -58,
@ -115,77 +115,77 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
#endregion
public static int[] Resample2Ch(
int[] Buffer,
int SrcSampleRate,
int DstSampleRate,
int SamplesCount,
ref int FracPart)
int[] buffer,
int srcSampleRate,
int dstSampleRate,
int samplesCount,
ref int fracPart)
{
if (Buffer == null)
if (buffer == null)
{
throw new ArgumentNullException(nameof(Buffer));
throw new ArgumentNullException(nameof(buffer));
}
if (SrcSampleRate <= 0)
if (srcSampleRate <= 0)
{
throw new ArgumentOutOfRangeException(nameof(SrcSampleRate));
throw new ArgumentOutOfRangeException(nameof(srcSampleRate));
}
if (DstSampleRate <= 0)
if (dstSampleRate <= 0)
{
throw new ArgumentOutOfRangeException(nameof(DstSampleRate));
throw new ArgumentOutOfRangeException(nameof(dstSampleRate));
}
double Ratio = (double)SrcSampleRate / DstSampleRate;
double ratio = (double)srcSampleRate / dstSampleRate;
int NewSamplesCount = (int)(SamplesCount / Ratio);
int newSamplesCount = (int)(samplesCount / ratio);
int Step = (int)(Ratio * 0x8000);
int step = (int)(ratio * 0x8000);
int[] Output = new int[NewSamplesCount * 2];
int[] output = new int[newSamplesCount * 2];
short[] Lut;
short[] lut;
if (Step > 0xaaaa)
if (step > 0xaaaa)
{
Lut = CurveLut0;
lut = _curveLut0;
}
else if (Step <= 0x8000)
else if (step <= 0x8000)
{
Lut = CurveLut1;
lut = _curveLut1;
}
else
{
Lut = CurveLut2;
lut = _curveLut2;
}
int InOffs = 0;
int inOffs = 0;
for (int OutOffs = 0; OutOffs < Output.Length; OutOffs += 2)
for (int outOffs = 0; outOffs < output.Length; outOffs += 2)
{
int LutIndex = (FracPart >> 8) * 4;
int lutIndex = (fracPart >> 8) * 4;
int Sample0 = Buffer[(InOffs + 0) * 2 + 0] * Lut[LutIndex + 0] +
Buffer[(InOffs + 1) * 2 + 0] * Lut[LutIndex + 1] +
Buffer[(InOffs + 2) * 2 + 0] * Lut[LutIndex + 2] +
Buffer[(InOffs + 3) * 2 + 0] * Lut[LutIndex + 3];
int sample0 = buffer[(inOffs + 0) * 2 + 0] * lut[lutIndex + 0] +
buffer[(inOffs + 1) * 2 + 0] * lut[lutIndex + 1] +
buffer[(inOffs + 2) * 2 + 0] * lut[lutIndex + 2] +
buffer[(inOffs + 3) * 2 + 0] * lut[lutIndex + 3];
int Sample1 = Buffer[(InOffs + 0) * 2 + 1] * Lut[LutIndex + 0] +
Buffer[(InOffs + 1) * 2 + 1] * Lut[LutIndex + 1] +
Buffer[(InOffs + 2) * 2 + 1] * Lut[LutIndex + 2] +
Buffer[(InOffs + 3) * 2 + 1] * Lut[LutIndex + 3];
int sample1 = buffer[(inOffs + 0) * 2 + 1] * lut[lutIndex + 0] +
buffer[(inOffs + 1) * 2 + 1] * lut[lutIndex + 1] +
buffer[(inOffs + 2) * 2 + 1] * lut[lutIndex + 2] +
buffer[(inOffs + 3) * 2 + 1] * lut[lutIndex + 3];
int NewOffset = FracPart + Step;
int newOffset = fracPart + step;
InOffs += NewOffset >> 15;
inOffs += newOffset >> 15;
FracPart = NewOffset & 0x7fff;
fracPart = newOffset & 0x7fff;
Output[OutOffs + 0] = Sample0 >> 15;
Output[OutOffs + 1] = Sample1 >> 15;
output[outOffs + 0] = sample0 >> 15;
output[outOffs + 1] = sample1 >> 15;
}
return Output;
return output;
}
}
}

View file

@ -6,13 +6,13 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
{
class VoiceContext
{
private bool Acquired;
private bool BufferReload;
private bool _acquired;
private bool _bufferReload;
private int ResamplerFracPart;
private int _resamplerFracPart;
private int BufferIndex;
private int Offset;
private int _bufferIndex;
private int _offset;
public int SampleRate;
public int ChannelsCount;
@ -29,138 +29,138 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
public VoiceOut OutStatus;
private int[] Samples;
private int[] _samples;
public bool Playing => Acquired && PlayState == PlayState.Playing;
public bool Playing => _acquired && PlayState == PlayState.Playing;
public VoiceContext()
{
WaveBuffers = new WaveBuffer[4];
}
public void SetAcquireState(bool NewState)
public void SetAcquireState(bool newState)
{
if (Acquired && !NewState)
if (_acquired && !newState)
{
//Release.
Reset();
}
Acquired = NewState;
_acquired = newState;
}
private void Reset()
{
BufferReload = true;
_bufferReload = true;
BufferIndex = 0;
Offset = 0;
_bufferIndex = 0;
_offset = 0;
OutStatus.PlayedSamplesCount = 0;
OutStatus.PlayedWaveBuffersCount = 0;
OutStatus.VoiceDropsCount = 0;
}
public int[] GetBufferData(MemoryManager Memory, int MaxSamples, out int SamplesCount)
public int[] GetBufferData(MemoryManager memory, int maxSamples, out int samplesCount)
{
if (!Playing)
{
SamplesCount = 0;
samplesCount = 0;
return null;
}
if (BufferReload)
if (_bufferReload)
{
BufferReload = false;
_bufferReload = false;
UpdateBuffer(Memory);
UpdateBuffer(memory);
}
WaveBuffer Wb = WaveBuffers[BufferIndex];
WaveBuffer wb = WaveBuffers[_bufferIndex];
int MaxSize = Samples.Length - Offset;
int maxSize = _samples.Length - _offset;
int Size = MaxSamples * AudioConsts.HostChannelsCount;
int size = maxSamples * AudioConsts.HostChannelsCount;
if (Size > MaxSize)
if (size > maxSize)
{
Size = MaxSize;
size = maxSize;
}
int[] Output = new int[Size];
int[] output = new int[size];
Array.Copy(Samples, Offset, Output, 0, Size);
Array.Copy(_samples, _offset, output, 0, size);
SamplesCount = Size / AudioConsts.HostChannelsCount;
samplesCount = size / AudioConsts.HostChannelsCount;
OutStatus.PlayedSamplesCount += SamplesCount;
OutStatus.PlayedSamplesCount += samplesCount;
Offset += Size;
_offset += size;
if (Offset == Samples.Length)
if (_offset == _samples.Length)
{
Offset = 0;
_offset = 0;
if (Wb.Looping == 0)
if (wb.Looping == 0)
{
SetBufferIndex((BufferIndex + 1) & 3);
SetBufferIndex((_bufferIndex + 1) & 3);
}
OutStatus.PlayedWaveBuffersCount++;
if (Wb.LastBuffer != 0)
if (wb.LastBuffer != 0)
{
PlayState = PlayState.Paused;
}
}
return Output;
return output;
}
private void UpdateBuffer(MemoryManager Memory)
private void UpdateBuffer(MemoryManager memory)
{
//TODO: Implement conversion for formats other
//than interleaved stereo (2 channels).
//As of now, it assumes that HostChannelsCount == 2.
WaveBuffer Wb = WaveBuffers[BufferIndex];
WaveBuffer wb = WaveBuffers[_bufferIndex];
if (Wb.Position == 0)
if (wb.Position == 0)
{
Samples = new int[0];
_samples = new int[0];
return;
}
if (SampleFormat == SampleFormat.PcmInt16)
{
int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount));
int samplesCount = (int)(wb.Size / (sizeof(short) * ChannelsCount));
Samples = new int[SamplesCount * AudioConsts.HostChannelsCount];
_samples = new int[samplesCount * AudioConsts.HostChannelsCount];
if (ChannelsCount == 1)
{
for (int Index = 0; Index < SamplesCount; Index++)
for (int index = 0; index < samplesCount; index++)
{
short Sample = Memory.ReadInt16(Wb.Position + Index * 2);
short sample = memory.ReadInt16(wb.Position + index * 2);
Samples[Index * 2 + 0] = Sample;
Samples[Index * 2 + 1] = Sample;
_samples[index * 2 + 0] = sample;
_samples[index * 2 + 1] = sample;
}
}
else
{
for (int Index = 0; Index < SamplesCount * 2; Index++)
for (int index = 0; index < samplesCount * 2; index++)
{
Samples[Index] = Memory.ReadInt16(Wb.Position + Index * 2);
_samples[index] = memory.ReadInt16(wb.Position + index * 2);
}
}
}
else if (SampleFormat == SampleFormat.Adpcm)
{
byte[] Buffer = Memory.ReadBytes(Wb.Position, Wb.Size);
byte[] buffer = memory.ReadBytes(wb.Position, wb.Size);
Samples = AdpcmDecoder.Decode(Buffer, AdpcmCtx);
_samples = AdpcmDecoder.Decode(buffer, AdpcmCtx);
}
else
{
@ -172,24 +172,24 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
//TODO: We should keep the frames being discarded (see the 4 below)
//on a buffer and include it on the next samples buffer, to allow
//the resampler to do seamless interpolation between wave buffers.
int SamplesCount = Samples.Length / AudioConsts.HostChannelsCount;
int samplesCount = _samples.Length / AudioConsts.HostChannelsCount;
SamplesCount = Math.Max(SamplesCount - 4, 0);
samplesCount = Math.Max(samplesCount - 4, 0);
Samples = Resampler.Resample2Ch(
Samples,
_samples = Resampler.Resample2Ch(
_samples,
SampleRate,
AudioConsts.HostSampleRate,
SamplesCount,
ref ResamplerFracPart);
samplesCount,
ref _resamplerFracPart);
}
}
public void SetBufferIndex(int Index)
public void SetBufferIndex(int index)
{
BufferIndex = Index & 3;
_bufferIndex = index & 3;
BufferReload = true;
_bufferReload = true;
}
}
}