mirror of
https://git.ryujinx.app/kenji-nx/ryujinx.git
synced 2025-12-12 19:37:06 +00:00
SDK20 and REV15 support
* Fixed an issue where games would boot loop because of an incorrect HID state.
* Turns out the SamplingNumber of the atomic input storage doesn't match the SamplingNumber of the input state held by the atomic storage, instead it is exactly double the value in the input state.
* Added new Condition struct to the HID Shared memory and populate it with dummy data to fix the no-controller crash (already merged).
* The audio renderer has been mostly updated to rev15, allowing rev15 games to launch.
* Biquad filters now use floats.
* Several structures have been renamed to match the SDK names, making it easier to compare functionality. A few names are still missing and will be changed at a later date.
* The new commands from rev15 have been added to the CommandType enum, but they are still missing from the code itself.
* Due to changes in the SDK layout, the time estimation functions are either missing or very well hidden (or Ghidra search functionality is useless). We can't fully implement the new commands until the timing data has been located.
* A few minor tweaks to the code have been made to more accurately match the SDK.
This commit is contained in:
parent
6ba8ae53f2
commit
c0b7452cb5
83 changed files with 2343 additions and 1195 deletions
|
|
@ -1,5 +1,6 @@
|
|||
using Ryujinx.Audio.Common;
|
||||
using Ryujinx.Audio.Renderer.Common;
|
||||
using Ryujinx.Audio.Renderer.Dsp;
|
||||
using Ryujinx.Audio.Renderer.Dsp.Command;
|
||||
using Ryujinx.Audio.Renderer.Dsp.State;
|
||||
using Ryujinx.Audio.Renderer.Parameter;
|
||||
|
|
@ -41,27 +42,27 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
_commandBuffer.GenerateClearMixBuffer(Constants.InvalidNodeId);
|
||||
}
|
||||
|
||||
private void GenerateDataSource(ref VoiceState voiceState, Memory<VoiceUpdateState> dspState, int channelIndex)
|
||||
private void GenerateDataSource(ref VoiceInfo voiceInfo, Memory<VoiceState> dspState, int channelIndex)
|
||||
{
|
||||
if (voiceState.MixId != Constants.UnusedMixId)
|
||||
if (voiceInfo.MixId != Constants.UnusedMixId)
|
||||
{
|
||||
ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
|
||||
ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
|
||||
|
||||
_commandBuffer.GenerateDepopPrepare(
|
||||
dspState,
|
||||
_rendererContext.DepopBuffer,
|
||||
mix.BufferCount,
|
||||
mix.BufferOffset,
|
||||
voiceState.NodeId,
|
||||
voiceState.WasPlaying);
|
||||
voiceInfo.NodeId,
|
||||
voiceInfo.WasPlaying);
|
||||
}
|
||||
else if (voiceState.SplitterId != Constants.UnusedSplitterId)
|
||||
else if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
|
||||
{
|
||||
int destinationId = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId++);
|
||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId++);
|
||||
|
||||
if (destination.IsNull)
|
||||
{
|
||||
|
|
@ -74,15 +75,17 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||
{
|
||||
ref MixState mix = ref _mixContext.GetState(mixId);
|
||||
ref MixInfo mix = ref _mixContext.GetState(mixId);
|
||||
|
||||
// _commandBuffer.GenerateFillBuffer();
|
||||
|
||||
_commandBuffer.GenerateDepopPrepare(
|
||||
dspState,
|
||||
_rendererContext.DepopBuffer,
|
||||
mix.BufferCount,
|
||||
mix.BufferOffset,
|
||||
voiceState.NodeId,
|
||||
voiceState.WasPlaying);
|
||||
voiceInfo.NodeId,
|
||||
voiceInfo.WasPlaying);
|
||||
|
||||
destination.MarkAsNeedToUpdateInternalState();
|
||||
}
|
||||
|
|
@ -90,71 +93,71 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
}
|
||||
|
||||
if (!voiceState.WasPlaying)
|
||||
if (!voiceInfo.WasPlaying)
|
||||
{
|
||||
Debug.Assert(voiceState.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
|
||||
Debug.Assert(voiceInfo.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
|
||||
|
||||
if (_rendererContext.BehaviourContext.IsWaveBufferVersion2Supported())
|
||||
if (_rendererContext.BehaviourInfo.IsWaveBufferVersion2Supported())
|
||||
{
|
||||
_commandBuffer.GenerateDataSourceVersion2(
|
||||
ref voiceState,
|
||||
ref voiceInfo,
|
||||
dspState,
|
||||
(ushort)_rendererContext.MixBufferCount,
|
||||
(ushort)channelIndex,
|
||||
voiceState.NodeId);
|
||||
voiceInfo.NodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (voiceState.SampleFormat)
|
||||
switch (voiceInfo.SampleFormat)
|
||||
{
|
||||
case SampleFormat.PcmInt16:
|
||||
_commandBuffer.GeneratePcmInt16DataSourceVersion1(
|
||||
ref voiceState,
|
||||
ref voiceInfo,
|
||||
dspState,
|
||||
(ushort)_rendererContext.MixBufferCount,
|
||||
(ushort)channelIndex,
|
||||
voiceState.NodeId);
|
||||
voiceInfo.NodeId);
|
||||
break;
|
||||
case SampleFormat.PcmFloat:
|
||||
_commandBuffer.GeneratePcmFloatDataSourceVersion1(
|
||||
ref voiceState,
|
||||
ref voiceInfo,
|
||||
dspState,
|
||||
(ushort)_rendererContext.MixBufferCount,
|
||||
(ushort)channelIndex,
|
||||
voiceState.NodeId);
|
||||
voiceInfo.NodeId);
|
||||
break;
|
||||
case SampleFormat.Adpcm:
|
||||
_commandBuffer.GenerateAdpcmDataSourceVersion1(
|
||||
ref voiceState,
|
||||
ref voiceInfo,
|
||||
dspState,
|
||||
(ushort)_rendererContext.MixBufferCount,
|
||||
voiceState.NodeId);
|
||||
voiceInfo.NodeId);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"Unsupported data source {voiceState.SampleFormat}");
|
||||
throw new NotImplementedException($"Unsupported data source {voiceInfo.SampleFormat}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory<VoiceUpdateState> state, int baseIndex, int bufferOffset, int nodeId)
|
||||
private void GenerateBiquadFilterForVoice(ref VoiceInfo voiceInfo, Memory<VoiceState> state, int baseIndex, int bufferOffset, int nodeId)
|
||||
{
|
||||
bool supportsOptimizedPath = _rendererContext.BehaviourContext.UseMultiTapBiquadFilterProcessing();
|
||||
bool supportsOptimizedPath = _rendererContext.BehaviourInfo.UseMultiTapBiquadFilterProcessing();
|
||||
|
||||
Span<BiquadFilterParameter> biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
|
||||
Span<BiquadFilterParameter2> biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
|
||||
|
||||
if (supportsOptimizedPath && biquadFiltersSpan[0].Enable && biquadFiltersSpan[1].Enable)
|
||||
{
|
||||
Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state)[..(Unsafe.SizeOf<BiquadFilterState>() * Constants.VoiceBiquadFilterCount)];
|
||||
Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory);
|
||||
|
||||
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
|
||||
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceInfo.BiquadFilterNeedInitialization, nodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < biquadFiltersSpan.Length; i++)
|
||||
{
|
||||
ref BiquadFilterParameter filter = ref biquadFiltersSpan[i];
|
||||
ref BiquadFilterParameter2 filter = ref biquadFiltersSpan[i];
|
||||
|
||||
if (filter.Enable)
|
||||
{
|
||||
|
|
@ -167,7 +170,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
stateMemory.Slice(i, 1),
|
||||
bufferOffset,
|
||||
bufferOffset,
|
||||
!voiceState.BiquadFilterNeedInitialization[i],
|
||||
!voiceInfo.BiquadFilterNeedInitialization[i],
|
||||
nodeId);
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +179,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
private void GenerateVoiceMixWithSplitter(
|
||||
SplitterDestination destination,
|
||||
Memory<VoiceUpdateState> state,
|
||||
Memory<VoiceState> state,
|
||||
uint bufferOffset,
|
||||
uint bufferCount,
|
||||
uint bufferIndex,
|
||||
|
|
@ -185,8 +188,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
ReadOnlySpan<float> mixVolumes = destination.MixBufferVolume;
|
||||
ReadOnlySpan<float> previousMixVolumes = destination.PreviousMixBufferVolume;
|
||||
|
||||
ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||
ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||
ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||
ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||
|
||||
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
||||
|
||||
|
|
@ -270,7 +273,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
private void GenerateVoiceMix(
|
||||
ReadOnlySpan<float> mixVolumes,
|
||||
ReadOnlySpan<float> previousMixVolumes,
|
||||
Memory<VoiceUpdateState> state,
|
||||
Memory<VoiceState> state,
|
||||
uint bufferOffset,
|
||||
uint bufferCount,
|
||||
uint bufferIndex,
|
||||
|
|
@ -309,27 +312,27 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
}
|
||||
|
||||
private void GenerateVoice(ref VoiceState voiceState)
|
||||
private void GenerateVoice(ref VoiceInfo voiceInfo)
|
||||
{
|
||||
int nodeId = voiceState.NodeId;
|
||||
uint channelsCount = voiceState.ChannelsCount;
|
||||
int nodeId = voiceInfo.NodeId;
|
||||
uint channelsCount = voiceInfo.ChannelsCount;
|
||||
|
||||
Span<int> channelResourceIdsSpan = voiceState.ChannelResourceIds.AsSpan();
|
||||
Span<BiquadFilterParameter> biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
|
||||
Span<int> channelResourceIdsSpan = voiceInfo.ChannelResourceIds.AsSpan();
|
||||
Span<BiquadFilterParameter2> biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
|
||||
|
||||
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
|
||||
{
|
||||
Memory<VoiceUpdateState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
|
||||
Memory<VoiceState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
|
||||
|
||||
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(channelResourceIdsSpan[channelIndex]);
|
||||
|
||||
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
|
||||
|
||||
if (voiceState.SampleFormat == SampleFormat.PcmInt16)
|
||||
if (voiceInfo.SampleFormat == SampleFormat.PcmInt16)
|
||||
{
|
||||
dataSourceDetailType = PerformanceDetailType.PcmInt16;
|
||||
}
|
||||
else if (voiceState.SampleFormat == SampleFormat.PcmFloat)
|
||||
else if (voiceInfo.SampleFormat == SampleFormat.PcmFloat)
|
||||
{
|
||||
dataSourceDetailType = PerformanceDetailType.PcmFloat;
|
||||
}
|
||||
|
|
@ -345,18 +348,18 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||
}
|
||||
|
||||
GenerateDataSource(ref voiceState, dspStateMemory, channelIndex);
|
||||
GenerateDataSource(ref voiceInfo, dspStateMemory, channelIndex);
|
||||
|
||||
if (performanceInitialized)
|
||||
{
|
||||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
||||
}
|
||||
|
||||
if (voiceState.WasPlaying)
|
||||
if (voiceInfo.WasPlaying)
|
||||
{
|
||||
voiceState.PreviousVolume = 0.0f;
|
||||
voiceInfo.PreviousVolume = 0.0f;
|
||||
}
|
||||
else if (voiceState.HasAnyDestination())
|
||||
else if (voiceInfo.HasAnyDestination())
|
||||
{
|
||||
performanceInitialized = false;
|
||||
|
||||
|
|
@ -367,7 +370,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||
}
|
||||
|
||||
GenerateBiquadFilterForVoice(ref voiceState, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
|
||||
GenerateBiquadFilterForVoice(ref voiceInfo, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
|
||||
|
||||
if (performanceInitialized)
|
||||
{
|
||||
|
|
@ -384,8 +387,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
|
||||
_commandBuffer.GenerateVolumeRamp(
|
||||
voiceState.PreviousVolume,
|
||||
voiceState.Volume,
|
||||
voiceInfo.PreviousVolume,
|
||||
voiceInfo.Volume,
|
||||
_rendererContext.MixBufferCount + (uint)channelIndex,
|
||||
nodeId);
|
||||
|
||||
|
|
@ -394,17 +397,17 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
|
||||
}
|
||||
|
||||
voiceState.PreviousVolume = voiceState.Volume;
|
||||
voiceInfo.PreviousVolume = voiceInfo.Volume;
|
||||
|
||||
if (voiceState.MixId == Constants.UnusedMixId)
|
||||
if (voiceInfo.MixId == Constants.UnusedMixId)
|
||||
{
|
||||
if (voiceState.SplitterId != Constants.UnusedSplitterId)
|
||||
if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
|
||||
{
|
||||
int destinationId = channelIndex;
|
||||
|
||||
while (true)
|
||||
{
|
||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId);
|
||||
SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId);
|
||||
|
||||
if (destination.IsNull)
|
||||
{
|
||||
|
|
@ -419,7 +422,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||
{
|
||||
ref MixState mix = ref _mixContext.GetState(mixId);
|
||||
ref MixInfo mix = ref _mixContext.GetState(mixId);
|
||||
|
||||
if (destination.IsBiquadFilterEnabled())
|
||||
{
|
||||
|
|
@ -451,7 +454,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
else
|
||||
{
|
||||
ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
|
||||
ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
|
||||
|
||||
performanceInitialized = false;
|
||||
|
||||
|
|
@ -479,9 +482,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
channelResource.UpdateState();
|
||||
}
|
||||
|
||||
for (int i = 0; i < voiceState.BiquadFilterNeedInitialization.Length; i++)
|
||||
for (int i = 0; i < voiceInfo.BiquadFilterNeedInitialization.Length; i++)
|
||||
{
|
||||
voiceState.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
|
||||
voiceInfo.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -491,11 +494,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
{
|
||||
for (int i = 0; i < _voiceContext.GetCount(); i++)
|
||||
{
|
||||
ref VoiceState sortedState = ref _voiceContext.GetSortedState(i);
|
||||
ref VoiceInfo sortedInfo = ref _voiceContext.GetSortedState(i);
|
||||
|
||||
if (!sortedState.ShouldSkip() && sortedState.UpdateForCommandGeneration(_voiceContext))
|
||||
if (!sortedInfo.ShouldSkip() && sortedInfo.UpdateForCommandGeneration(_voiceContext))
|
||||
{
|
||||
int nodeId = sortedState.NodeId;
|
||||
int nodeId = sortedInfo.NodeId;
|
||||
|
||||
PerformanceEntryAddresses performanceEntry = new();
|
||||
|
||||
|
|
@ -508,7 +511,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||
}
|
||||
|
||||
GenerateVoice(ref sortedState);
|
||||
GenerateVoice(ref sortedInfo);
|
||||
|
||||
if (performanceInitialized)
|
||||
{
|
||||
|
|
@ -639,9 +642,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
if (effect.IsEnabled)
|
||||
{
|
||||
bool needInitialization = effect.Parameter.Status == UsageState.Invalid ||
|
||||
(effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourContext.IsBiquadFilterEffectStateClearBugFixed());
|
||||
(effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
|
||||
|
||||
BiquadFilterParameter parameter = new()
|
||||
BiquadFilterParameter2 parameter = new()
|
||||
{
|
||||
Enable = true,
|
||||
};
|
||||
|
|
@ -683,7 +686,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
ulong workBuffer = effect.GetWorkBuffer(-1);
|
||||
|
||||
if (_rendererContext.BehaviourContext.IsEffectInfoVersion2Supported())
|
||||
if (_rendererContext.BehaviourInfo.IsEffectInfoVersion2Supported())
|
||||
{
|
||||
Memory<EffectResultState> dspResultState;
|
||||
|
||||
|
|
@ -777,7 +780,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
nodeId);
|
||||
}
|
||||
|
||||
private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect)
|
||||
private void GenerateEffect(ref MixInfo mix, int effectId, BaseEffect effect)
|
||||
{
|
||||
int nodeId = mix.NodeId;
|
||||
|
||||
|
|
@ -807,13 +810,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
|
||||
break;
|
||||
case EffectType.Delay:
|
||||
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
||||
break;
|
||||
case EffectType.Reverb:
|
||||
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
||||
break;
|
||||
case EffectType.Reverb3d:
|
||||
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
|
||||
break;
|
||||
case EffectType.BiquadFilter:
|
||||
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
|
||||
|
|
@ -839,7 +842,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
effect.UpdateForCommandGeneration();
|
||||
}
|
||||
|
||||
private void GenerateEffects(ref MixState mix)
|
||||
private void GenerateEffects(ref MixInfo mix)
|
||||
{
|
||||
ReadOnlySpan<int> effectProcessingOrderArray = mix.EffectProcessingOrderArray;
|
||||
|
||||
|
|
@ -875,8 +878,8 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
ref bool isFirstMixBuffer,
|
||||
int nodeId)
|
||||
{
|
||||
ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||
ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||
ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
|
||||
ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
|
||||
|
||||
Memory<BiquadFilterState> bqfState = _splitterContext.GetBiquadFilterState(destination);
|
||||
|
||||
|
|
@ -888,7 +891,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
inputBufferIndex,
|
||||
outputBufferIndex,
|
||||
0,
|
||||
Memory<VoiceUpdateState>.Empty,
|
||||
Memory<VoiceState>.Empty,
|
||||
ref bqf0,
|
||||
ref bqf1,
|
||||
bqfState[..1],
|
||||
|
|
@ -912,7 +915,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
inputBufferIndex,
|
||||
outputBufferIndex,
|
||||
0,
|
||||
Memory<VoiceUpdateState>.Empty,
|
||||
Memory<VoiceState>.Empty,
|
||||
ref bqf0,
|
||||
bqfState[..1],
|
||||
bqfState.Slice(1, 1),
|
||||
|
|
@ -931,7 +934,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
inputBufferIndex,
|
||||
outputBufferIndex,
|
||||
0,
|
||||
Memory<VoiceUpdateState>.Empty,
|
||||
Memory<VoiceState>.Empty,
|
||||
ref bqf1,
|
||||
bqfState[..1],
|
||||
bqfState.Slice(1, 1),
|
||||
|
|
@ -946,7 +949,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
isFirstMixBuffer = false;
|
||||
}
|
||||
|
||||
private void GenerateMix(ref MixState mix)
|
||||
private void GenerateMix(ref MixInfo mix)
|
||||
{
|
||||
if (mix.HasAnyDestination())
|
||||
{
|
||||
|
|
@ -975,7 +978,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
|
||||
{
|
||||
ref MixState destinationMix = ref _mixContext.GetState(mixId);
|
||||
ref MixInfo destinationMix = ref _mixContext.GetState(mixId);
|
||||
|
||||
uint inputBufferIndex = mix.BufferOffset + ((uint)destinationIndex % mix.BufferCount);
|
||||
|
||||
|
|
@ -1014,7 +1017,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
else
|
||||
{
|
||||
ref MixState destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
|
||||
ref MixInfo destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
|
||||
|
||||
for (uint bufferIndex = 0; bufferIndex < mix.BufferCount; bufferIndex++)
|
||||
{
|
||||
|
|
@ -1036,7 +1039,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
}
|
||||
|
||||
private void GenerateSubMix(ref MixState subMix)
|
||||
private void GenerateSubMix(ref MixInfo subMix)
|
||||
{
|
||||
_commandBuffer.GenerateDepopForMixBuffers(
|
||||
_rendererContext.DepopBuffer,
|
||||
|
|
@ -1072,11 +1075,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
{
|
||||
for (int id = 0; id < _mixContext.GetCount(); id++)
|
||||
{
|
||||
ref MixState sortedState = ref _mixContext.GetSortedState(id);
|
||||
ref MixInfo sortedInfo = ref _mixContext.GetSortedState(id);
|
||||
|
||||
if (sortedState.IsUsed && sortedState.MixId != Constants.FinalMixId)
|
||||
if (sortedInfo.IsUsed && sortedInfo.MixId != Constants.FinalMixId)
|
||||
{
|
||||
int nodeId = sortedState.NodeId;
|
||||
int nodeId = sortedInfo.NodeId;
|
||||
|
||||
PerformanceEntryAddresses performanceEntry = new();
|
||||
|
||||
|
|
@ -1089,7 +1092,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
|
||||
}
|
||||
|
||||
GenerateSubMix(ref sortedState);
|
||||
GenerateSubMix(ref sortedInfo);
|
||||
|
||||
if (performanceInitialized)
|
||||
{
|
||||
|
|
@ -1101,7 +1104,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
private void GenerateFinalMix()
|
||||
{
|
||||
ref MixState finalMix = ref _mixContext.GetFinalState();
|
||||
ref MixInfo finalMix = ref _mixContext.GetFinalState();
|
||||
|
||||
_commandBuffer.GenerateDepopForMixBuffers(
|
||||
_rendererContext.DepopBuffer,
|
||||
|
|
@ -1180,16 +1183,16 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
}
|
||||
}
|
||||
|
||||
private void GenerateCircularBuffer(CircularBufferSink sink, ref MixState finalMix)
|
||||
private void GenerateCircularBuffer(CircularBufferSink sink, ref MixInfo finalMix)
|
||||
{
|
||||
_commandBuffer.GenerateCircularBuffer(finalMix.BufferOffset, sink, Constants.InvalidNodeId);
|
||||
}
|
||||
|
||||
private void GenerateDevice(DeviceSink sink, ref MixState finalMix)
|
||||
private void GenerateDevice(DeviceSink sink, ref MixInfo finalMix)
|
||||
{
|
||||
if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerState == null)
|
||||
if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerInfo == null)
|
||||
{
|
||||
sink.UpsamplerState = _rendererContext.UpsamplerManager.Allocate();
|
||||
sink.UpsamplerInfo = _rendererContext.UpsamplerManager.Allocate();
|
||||
}
|
||||
|
||||
bool useCustomDownMixingCommand = _rendererContext.ChannelCount == 2 && sink.Parameter.DownMixParameterEnabled;
|
||||
|
|
@ -1216,11 +1219,11 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
CommandList commandList = _commandBuffer.CommandList;
|
||||
|
||||
if (sink.UpsamplerState != null)
|
||||
if (sink.UpsamplerInfo != null)
|
||||
{
|
||||
_commandBuffer.GenerateUpsample(
|
||||
finalMix.BufferOffset,
|
||||
sink.UpsamplerState,
|
||||
sink.UpsamplerInfo,
|
||||
sink.Parameter.InputCount,
|
||||
sink.Parameter.Input.AsSpan(),
|
||||
commandList.BufferCount,
|
||||
|
|
@ -1237,7 +1240,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
Constants.InvalidNodeId);
|
||||
}
|
||||
|
||||
private void GenerateSink(BaseSink sink, ref MixState finalMix)
|
||||
private void GenerateSink(BaseSink sink, ref MixInfo finalMix)
|
||||
{
|
||||
bool performanceInitialized = false;
|
||||
|
||||
|
|
@ -1275,7 +1278,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||
|
||||
public void GenerateSinks()
|
||||
{
|
||||
ref MixState finalMix = ref _mixContext.GetFinalState();
|
||||
ref MixInfo finalMix = ref _mixContext.GetFinalState();
|
||||
|
||||
for (int i = 0; i < _sinkContext.GetCount(); i++)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue