public ReverbState(ref ReverbParameter parameter, ulong workBuffer, bool isLongSizePreDelaySupported) { FdnDelayLines = new DelayLine[4]; DecayDelays = new DecayDelay[4]; EarlyDelayTime = new uint[EarlyModeCount]; EarlyGain = new float[EarlyModeCount]; HighFrequencyDecayDirectGain = new float[4]; HighFrequencyDecayPreviousGain = new float[4]; PreviousFeedbackOutput = new float[4]; ReadOnlySpan <float> fdnDelayTimes = GetFdnDelayTimesByLateMode(ReverbLateMode.Limit); ReadOnlySpan <float> decayDelayTimes = GetDecayDelayTimesByLateMode(ReverbLateMode.Limit); uint sampleRate = (uint)FixedPointHelper.ToFloat((uint)parameter.SampleRate, FixedPointPrecision); for (int i = 0; i < 4; i++) { FdnDelayLines[i] = new DelayLine(sampleRate, fdnDelayTimes[i]); DecayDelays[i] = new DecayDelay(new DelayLine(sampleRate, decayDelayTimes[i])); } float preDelayTimeMax = 150.0f; if (isLongSizePreDelaySupported) { preDelayTimeMax = 350.0f; } PreDelayLine = new DelayLine(sampleRate, preDelayTimeMax); FrontCenterDelayLine = new DelayLine(sampleRate, 5.0f); UpdateParameter(ref parameter); }
public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory <ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported) { Enabled = true; IsEffectEnabled = isEnabled; NodeId = nodeId; _parameter = parameter; State = state; WorkBuffer = workBuffer; InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; for (int i = 0; i < Parameter.ChannelCount; i++) { InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]); } IsLongSizePreDelaySupported = isLongSizePreDelaySupported; // NOTE: We do the opposite as Nintendo here for now to restore previous behaviour // TODO: Update reverb processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping. DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices); DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices); }
/// <summary> /// Generate a new <see cref="ReverbCommand"/>. /// </summary> /// <param name="bufferOffset">The target buffer offset.</param> /// <param name="parameter">The reverb parameter.</param> /// <param name="state">The reverb state.</param> /// <param name="isEnabled">Set to true if the effect should be active.</param> /// <param name="workBuffer">The work buffer to use for processing.</param> /// <param name="nodeId">The node id associated to this command.</param> /// <param name="isLongSizePreDelaySupported">If set to true, the long size pre-delay is supported.</param> /// <param name="newEffectChannelMappingSupported">If set to true, the new effect channel mapping for 5.1 is supported.</param> public void GenerateReverbEffect(uint bufferOffset, ReverbParameter parameter, Memory <ReverbState> state, bool isEnabled, CpuAddress workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported) { if (parameter.IsChannelCountValid()) { ReverbCommand command = new ReverbCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); AddCommand(command); } }
public void CreateReverbPresetInstance(ReverbParameter parameter) { ReverbPreset presetInstance = ScriptableObject.CreateInstance <ReverbPreset>(); parameter.OverwritePreset(presetInstance); string path = "Assets/Project_Larry/Audio/ReverbPresets"; string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/New" + typeof(ReverbPreset).ToString() + ".asset"); AssetDatabase.CreateAsset(presetInstance, assetPathAndName); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.FocusProjectWindow(); Selection.activeObject = presetInstance; parameter.reverbPreset = presetInstance; }
public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory <ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported) { Enabled = true; IsEffectEnabled = isEnabled; NodeId = nodeId; _parameter = parameter; State = state; WorkBuffer = workBuffer; InputBufferIndices = new ushort[RendererConstants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[RendererConstants.VoiceChannelCountMax]; for (int i = 0; i < Parameter.ChannelCount; i++) { InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]); } IsLongSizePreDelaySupported = isLongSizePreDelaySupported; }
public void UpdateParameter(ref ReverbParameter parameter) { uint sampleRate = (uint)FixedPointHelper.ToFloat((uint)parameter.SampleRate, FixedPointPrecision); float preDelayTimeInMilliseconds = FixedPointHelper.ToFloat(parameter.PreDelayTime, FixedPointPrecision); float earlyGain = FixedPointHelper.ToFloat(parameter.EarlyGain, FixedPointPrecision); float coloration = FixedPointHelper.ToFloat(parameter.Coloration, FixedPointPrecision); float decayTime = FixedPointHelper.ToFloat(parameter.DecayTime, FixedPointPrecision); for (int i = 0; i < 10; i++) { EarlyDelayTime[i] = Math.Min(IDelayLine.GetSampleCount(sampleRate, EarlyDelayTimes[i] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax) + 1; EarlyGain[i] = EarlyGainBase[i] * earlyGain; } if (parameter.ChannelCount == 2) { EarlyGain[4] = EarlyGain[4] * 0.5f; EarlyGain[5] = EarlyGain[5] * 0.5f; } PreDelayLineDelayTime = Math.Min(IDelayLine.GetSampleCount(sampleRate, PreDelayTimes[(int)parameter.EarlyMode] + preDelayTimeInMilliseconds), PreDelayLine.SampleCountMax); ReadOnlySpan <float> fdnDelayTimes = GetFdnDelayTimesByLateMode(parameter.LateMode); ReadOnlySpan <float> decayDelayTimes = GetDecayDelayTimesByLateMode(parameter.LateMode); float highFrequencyDecayRatio = FixedPointHelper.ToFloat(parameter.HighFrequencyDecayRatio, FixedPointPrecision); float highFrequencyUnknownValue = FloatingPointHelper.Cos(1280.0f / sampleRate); for (int i = 0; i < 4; i++) { FdnDelayLines[i].SetDelay(fdnDelayTimes[i]); DecayDelays[i].SetDelay(decayDelayTimes[i]); float tempA = -3 * (DecayDelays[i].CurrentSampleCount + FdnDelayLines[i].CurrentSampleCount); float tempB = tempA / (decayTime * sampleRate); float tempC; float tempD; if (highFrequencyDecayRatio < 0.995f) { float tempE = FloatingPointHelper.Pow10((((1.0f / highFrequencyDecayRatio) - 1.0f) * 2) / 100 * (tempB / 10)); float tempF = 1.0f - tempE; float tempG = 2.0f - (tempE * 2 * highFrequencyUnknownValue); float tempH = MathF.Sqrt((tempG * tempG) - (tempF * tempF * 4)); tempC = (tempG - tempH) / (tempF * 2); tempD = 1.0f - tempC; } else { // no high frequency decay ratio tempC = 0.0f; tempD = 1.0f; } HighFrequencyDecayDirectGain[i] = FloatingPointHelper.Pow10(tempB / 1000) * tempD * 0.7071f; HighFrequencyDecayPreviousGain[i] = tempC; PreviousFeedbackOutput[i] = 0.0f; DecayDelays[i].SetDecayRate(0.6f * (1.0f - coloration)); } }
public override void OnInspectorGUI() { //base.OnInspectorGUI(); // Set target to original script ReverbParameter mainScript = (ReverbParameter)target; if (mainScript == null) { return; } // Pointer var audioMixer = AudioSystem.Mixer; #region Choosing which Reverb to control EditorGUILayout.LabelField("Reverb To Control", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.LabelField("Reverb"); EditorGUI.BeginChangeCheck(); { mainScript.index = EditorGUILayout.Popup(mainScript.index, ReverbParameterEditor.reverbsToControl, EditorStyles.popup); } if (EditorGUI.EndChangeCheck()) { mainScript.SetStringsAndClamping(); } } EditorGUILayout.EndHorizontal(); #endregion EditorGUILayout.LabelField("Reverb Preset", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.LabelField("Preset"); EditorGUI.BeginChangeCheck(); { mainScript.reverbPreset = (ReverbPreset)EditorGUILayout.ObjectField(mainScript.reverbPreset, typeof(ReverbPreset), false); } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(mainScript.reverbPreset); if (mainScript.reverbPreset == null) { mainScript.resetParameterToZero(); } else { mainScript.GetPresetValue(mainScript.reverbPreset); } } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (mainScript.reverbPreset == null) { EditorGUILayout.HelpBox("Assign reverb preset to load values.", MessageType.Info); EditorGUILayout.Space(); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Main Parameters", EditorStyles.boldLabel); //Only turn on dry control for Random Ambience if (mainScript.index == 1) { mainScript.raDryLevel = EditorGUILayout.Slider("Dry Level", mainScript.raDryLevel, -10000f, 0f); } mainScript.room = EditorGUILayout.Slider("Room", mainScript.room, -10000f, 0f); mainScript.reflections = EditorGUILayout.Slider("Reflections", mainScript.reflections, -10000f, 1000f); mainScript.reverb = EditorGUILayout.Slider("Reverb", mainScript.reverb, -10000f, 2000f); EditorGUILayout.Space(); showAdvancedParam = EditorGUILayout.Foldout(showAdvancedParam, "Advanced Parameter"); if (showAdvancedParam) { // Controlling public variables in script to update in realtime mainScript.roomHF = EditorGUILayout.Slider("Room HF", mainScript.roomHF, -10000f, 0f); mainScript.decayTime = EditorGUILayout.Slider("Decay Time", mainScript.decayTime, 0.1f, 20f); mainScript.decayHFRatio = EditorGUILayout.Slider("Decay HF Ratio", mainScript.decayHFRatio, 0.1f, 2f); mainScript.reflectDelay = EditorGUILayout.Slider("Reflections Delay", mainScript.reflectDelay, 0f, 0.3f); mainScript.reverbDelay = EditorGUILayout.Slider("Reverb Delay", mainScript.reverbDelay, 0f, 0.1f); mainScript.diffusion = EditorGUILayout.Slider("Diffusion", mainScript.diffusion, 0f, 100f); mainScript.density = EditorGUILayout.Slider("Density", mainScript.density, 0f, 100f); mainScript.hFReference = EditorGUILayout.Slider("HF Reference", mainScript.hFReference, 20f, 20000f); mainScript.roomLF = EditorGUILayout.Slider("Room LF", mainScript.roomLF, -10000f, 0f); mainScript.lFReference = EditorGUILayout.Slider("LF Reference", mainScript.lFReference, 20f, 1000f); } if (audioMixer != null) { // Pass public variables to AudioMixer mainScript.SetReverbValueToAudioMixer(); } EditorGUILayout.Space(); if (GUILayout.Button("Reset parameter to zero")) { mainScript.resetParameterToZero(); } if (GUILayout.Button("Reset parameter to preset value")) { mainScript.GetPresetValue(mainScript.reverbPreset); } EditorGUILayout.Space(); EditorGUILayout.LabelField("Preset Management", EditorStyles.boldLabel); if (GUILayout.Button("Save value as a new preset")) { this.CreateReverbPresetInstance(mainScript); } if (GUILayout.Button("Overwrite current preset")) { if (EditorUtility.DisplayDialog("Warning!", "Are you sure you want to overwrite the preset " + mainScript.reverbPreset.name + "?", "Yes", "No")) { mainScript.OverwritePreset(mainScript.reverbPreset); } } if (GUI.changed) { if (!EditorApplication.isPlaying) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); } } }