예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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;
        }
예제 #5
0
        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;
        }
예제 #6
0
        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();
                }
            }
        }