private void ProcessReverbSurround(ref ReverbState state, ReadOnlySpan <IntPtr> outputBuffers, ReadOnlySpan <IntPtr> inputBuffers, uint sampleCount) { ProcessReverbGeneric(ref state, outputBuffers, inputBuffers, sampleCount, OutputEarlyIndicesTableSurround, TargetEarlyDelayLineIndicesTableSurround, TargetOutputFeedbackIndicesTableSurround, OutputIndicesTableSurround); }
private void ProcessReverb(CommandList context, ref ReverbState state) { Debug.Assert(Parameter.IsChannelCountValid()); if (IsEffectEnabled && Parameter.IsChannelCountValid()) { Span <IntPtr> inputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; Span <IntPtr> outputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; for (int i = 0; i < Parameter.ChannelCount; i++) { inputBuffers[i] = context.GetBufferPointer(InputBufferIndices[i]); outputBuffers[i] = context.GetBufferPointer(OutputBufferIndices[i]); } switch (Parameter.ChannelCount) { case 1: ProcessReverbMono(ref state, outputBuffers, inputBuffers, context.SampleCount); break; case 2: ProcessReverbStereo(ref state, outputBuffers, inputBuffers, context.SampleCount); break; case 4: ProcessReverbQuadraphonic(ref state, outputBuffers, inputBuffers, context.SampleCount); break; case 6: ProcessReverbSurround(ref state, outputBuffers, inputBuffers, context.SampleCount); break; default: throw new NotImplementedException(Parameter.ChannelCount.ToString()); } } else { for (int i = 0; i < Parameter.ChannelCount; i++) { if (InputBufferIndices[i] != OutputBufferIndices[i]) { context.CopyBuffer(OutputBufferIndices[i], InputBufferIndices[i]); } } } }
public void Save() { ReverbState reverbState = new ReverbState(); reverbState.zones = new ReverbZoneState[zones.Length]; ReverbState reverbState2 = reverbState; for (int i = 0; i < zones.Length; i++) { reverbState2.zones[i] = Serialize(zones[i]); } string contents = JsonUtility.ToJson(reverbState2, prettyPrint: true); string path = GetPath(); File.WriteAllText(path, contents); }
private void LoadJson(ReverbState state) { for (int i = 0; i < state.zones.Length; i++) { ReverbZoneState reverbZoneState = state.zones[i]; ReverbZone reverbZone = null; for (int j = 0; j < zones.Length; j++) { if (zones[j].name == reverbZoneState.id) { reverbZone = zones[j]; break; } } if (!(reverbZone == null)) { Deserialize(reverbZone, reverbZoneState); } } }
private unsafe void ProcessReverbGeneric(ref ReverbState state, ReadOnlySpan <IntPtr> outputBuffers, ReadOnlySpan <IntPtr> inputBuffers, uint sampleCount, ReadOnlySpan <int> outputEarlyIndicesTable, ReadOnlySpan <int> targetEarlyDelayLineIndicesTable, ReadOnlySpan <int> targetOutputFeedbackIndicesTable, ReadOnlySpan <int> outputIndicesTable) { bool isSurround = Parameter.ChannelCount == 6; float reverbGain = FixedPointHelper.ToFloat(Parameter.ReverbGain, FixedPointPrecision); float lateGain = FixedPointHelper.ToFloat(Parameter.LateGain, FixedPointPrecision); float outGain = FixedPointHelper.ToFloat(Parameter.OutGain, FixedPointPrecision); float dryGain = FixedPointHelper.ToFloat(Parameter.DryGain, FixedPointPrecision); Span <float> outputValues = stackalloc float[Constants.ChannelCountMax]; Span <float> feedbackValues = stackalloc float[4]; Span <float> feedbackOutputValues = stackalloc float[4]; Span <float> channelInput = stackalloc float[Parameter.ChannelCount]; for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) { outputValues.Fill(0); for (int i = 0; i < targetEarlyDelayLineIndicesTable.Length; i++) { int earlyDelayIndex = targetEarlyDelayLineIndicesTable[i]; int outputIndex = outputEarlyIndicesTable[i]; float tapOutput = state.PreDelayLine.TapUnsafe(state.EarlyDelayTime[earlyDelayIndex], 0); outputValues[outputIndex] += tapOutput * state.EarlyGain[earlyDelayIndex]; } if (isSurround) { outputValues[5] *= 0.2f; } float targetPreDelayValue = 0; for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++) { channelInput[channelIndex] = *((float *)inputBuffers[channelIndex] + sampleIndex) * 64; targetPreDelayValue += channelInput[channelIndex] * reverbGain; } state.PreDelayLine.Update(targetPreDelayValue); float lateValue = state.PreDelayLine.Tap(state.PreDelayLineDelayTime) * lateGain; for (int i = 0; i < state.FdnDelayLines.Length; i++) { feedbackOutputValues[i] = state.FdnDelayLines[i].Read() * state.HighFrequencyDecayDirectGain[i] + state.PreviousFeedbackOutput[i] * state.HighFrequencyDecayPreviousGain[i]; state.PreviousFeedbackOutput[i] = feedbackOutputValues[i]; } feedbackValues[0] = feedbackOutputValues[2] + feedbackOutputValues[1]; feedbackValues[1] = -feedbackOutputValues[0] - feedbackOutputValues[3]; feedbackValues[2] = feedbackOutputValues[0] - feedbackOutputValues[3]; feedbackValues[3] = feedbackOutputValues[1] - feedbackOutputValues[2]; for (int i = 0; i < state.FdnDelayLines.Length; i++) { feedbackOutputValues[i] = state.DecayDelays[i].Update(feedbackValues[i] + lateValue); state.FdnDelayLines[i].Update(feedbackOutputValues[i]); } for (int i = 0; i < targetOutputFeedbackIndicesTable.Length; i++) { int targetOutputFeedbackIndex = targetOutputFeedbackIndicesTable[i]; int outputIndex = outputIndicesTable[i]; if (targetOutputFeedbackIndex >= 0) { outputValues[outputIndex] += feedbackOutputValues[targetOutputFeedbackIndex]; } } if (isSurround) { outputValues[4] += state.FrontCenterDelayLine.Update((feedbackOutputValues[2] - feedbackOutputValues[3]) * 0.5f); } for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++) { *((float *)outputBuffers[channelIndex] + sampleIndex) = (outputValues[channelIndex] * outGain + channelInput[channelIndex] * dryGain) / 64; } } }
public void LoadJson(string json) { ReverbState state = JsonUtility.FromJson <ReverbState>(json); LoadJson(state); }