Beispiel #1
0
            private void SetFilterPreprocessor(IntPtr preprocessor)
            {
                using (var handle = _handle.Lock())
                {
                    if (handle.Value == IntPtr.Zero)
                    {
                        throw Log.CreatePossibleBugException("Attempted  to access a null WebRtc Preprocessor encoder", "3BA66D46-A7A6-41E8-BE38-52AFE5212ACD");
                    }

                    Log.Debug("Exchanging preprocessor instance in playback filter...");

                    if (!AudioPluginDissonanceNative.Dissonance_PreprocessorExchangeInstance(IntPtr.Zero, handle.Value))
                    {
                        throw Log.CreatePossibleBugException("Cannot associate preprocessor with Playback filter - one already exists", "D5862DD2-B44E-4605-8D1C-29DD2C72A70C");
                    }

                    Log.Debug("...Exchanged preprocessor instance in playback filter");

                    var state = (AudioPluginDissonanceNative.FilterState)AudioPluginDissonanceNative.Dissonance_GetFilterState();
                    if (state == AudioPluginDissonanceNative.FilterState.FilterNotRunning)
                    {
                        Log.Debug("Associated preprocessor with playback filter - but filter is not running");
                    }

                    Bind(s => s.DenoiseAmount, "DenoiseAmount", v => NoiseSuppressionLevel             = (NoiseSuppressionLevels)v);
                    Bind(s => s.AecSuppressionAmount, "AecSuppressionAmount", v => AecSuppressionLevel = (AecSuppressionLevels)v);
                    Bind(s => s.AecmRoutingMode, "AecmRoutingMode", v => AecmSuppressionLevel          = (AecmRoutingMode)v);
                    Bind(s => s.VadSensitivity, "VadSensitivity", v => VadSensitivityLevel             = v);
                }
            }
Beispiel #2
0
 private void ReleaseUnmanagedResources()
 {
     using (var handle = _handle.Lock())
     {
         if (handle.Value != IntPtr.Zero)
         {
             AudioPluginDissonanceNative.Dissonance_DestroyRnnoiseState(handle.Value);
             handle.Value = IntPtr.Zero;
         }
     }
 }
Beispiel #3
0
            public int GetGains(float[] output)
            {
                using (var handle = _handle.Lock())
                {
                    if (handle.Value == IntPtr.Zero)
                    {
                        return(0);
                    }

                    return(AudioPluginDissonanceNative.Dissonance_RnnoiseGetGains(handle.Value, output, output.Length));
                }
            }
Beispiel #4
0
            private void ReleaseUnmanagedResources()
            {
                using (var handle = _handle.Lock())
                {
                    if (handle.Value != IntPtr.Zero)
                    {
                        ClearFilterPreprocessor(throwOnError: false);

                        AudioPluginDissonanceNative.Dissonance_DestroyPreprocessor(handle.Value);
                        handle.Value = IntPtr.Zero;
                    }
                }
            }
Beispiel #5
0
            public void Reset()
            {
                using (var handle = _handle.Lock())
                {
                    Log.Debug("Resetting RnnoisePreprocessor");

                    if (handle.Value != IntPtr.Zero)
                    {
                        //Destroy it
                        AudioPluginDissonanceNative.Dissonance_DestroyRnnoiseState(handle.Value);
                        handle.Value = IntPtr.Zero;
                    }

                    //Create a new one
                    handle.Value = AudioPluginDissonanceNative.Dissonance_CreateRnnoiseState();
                }
            }
Beispiel #6
0
            private IntPtr CreatePreprocessor()
            {
                var instance = VoiceSettings.Instance;

                //Disable one of the echo cancellers, depending upon platform
                var pcLevel  = AecSuppressionLevel;
                var mobLevel = AecmSuppressionLevel;

                if (_useMobileAec)
                {
                    pcLevel = AecSuppressionLevels.Disabled;
                }
                else
                {
                    mobLevel = AecmRoutingMode.Disabled;
                }

                Log.Debug("Creating new preprocessor instance - Mob:{0} NS:{1} AEC:{2} DelayAg:{3} Ext:{4}, Refined:{5} Aecm:{6}, Comfort:{7}",
                          _useMobileAec,
                          NoiseSuppressionLevel,
                          pcLevel,
                          instance.AecDelayAgnostic,
                          instance.AecExtendedFilter,
                          instance.AecRefinedAdaptiveFilter,
                          mobLevel,
                          instance.AecmComfortNoise
                          );

                var handle = AudioPluginDissonanceNative.Dissonance_CreatePreprocessor(
                    NoiseSuppressionLevel,
                    pcLevel,
                    instance.AecDelayAgnostic,
                    instance.AecExtendedFilter,
                    instance.AecRefinedAdaptiveFilter,
                    mobLevel,
                    instance.AecmComfortNoise
                    );

                AudioPluginDissonanceNative.Dissonance_ConfigureVadSensitivity(handle, instance.VadSensitivity);

                return(handle);
            }
Beispiel #7
0
            public void Process(AudioPluginDissonanceNative.SampleRates inputSampleRate, float[] input, float[] output)
            {
                if (Enabled)
                {
                    using (var handle = _handle.Lock())
                    {
                        if (handle.Value == IntPtr.Zero)
                        {
                            throw Log.CreatePossibleBugException("Attempted to access a null WebRtc Rnnoise", "1014ecad-f1cf-4377-a2cd-31e46df55b08");
                        }

                        // Allocate a temporary buffer to store the output of rnnoise
                        if (_temp == null || _temp.Length != output.Length)
                        {
                            _temp = new float[output.Length];
                        }

                        if (!AudioPluginDissonanceNative.Dissonance_RnnoiseProcessFrame(handle.Value, input.Length, (int)inputSampleRate, input, _temp))
                        {
                            Log.Warn("Dissonance_RnnoiseProcessFrame returned false");
                        }

                        // Linear crossfade between input(dry) and _temp(wet). This is a linear crossfade instead of an
                        // equal power crossfade because input and wet are very highly correlated in most cases. Also
                        // the AGC runs after this, so a slight drop in amplitude won't really matter.
                        var wetmix = _wetMix;
                        var drymix = 1 - wetmix;
                        for (var i = 0; i < input.Length; i++)
                        {
                            output[i] = input[i] * drymix + _temp[i] * wetmix;
                        }
                    }
                }
                else
                {
                    if (input != output)
                    {
                        Array.Copy(input, output, input.Length);
                    }
                }
            }
Beispiel #8
0
            public bool Process(AudioPluginDissonanceNative.SampleRates inputSampleRate, float[] input, float[] output, int estimatedStreamDelay, bool isOutputMuted)
            {
                using (var handle = _handle.Lock())
                {
                    if (handle.Value == IntPtr.Zero)
                    {
                        throw Log.CreatePossibleBugException("Attempted  to access a null WebRtc Preprocessor encoder", "5C97EF6A-353B-4B96-871F-1073746B5708");
                    }

                    AudioPluginDissonanceNative.Dissonance_SetAgcIsOutputMutedState(handle.Value, isOutputMuted);
                    Log.Trace("Set IsOutputMuted to `{0}`", isOutputMuted);

                    var result = AudioPluginDissonanceNative.Dissonance_PreprocessCaptureFrame(handle.Value, (int)inputSampleRate, input, output, estimatedStreamDelay);
                    if (result != AudioPluginDissonanceNative.ProcessorErrors.Ok)
                    {
                        throw Log.CreatePossibleBugException(string.Format("Preprocessor error: '{0}'", result), "0A89A5E7-F527-4856-BA01-5A19578C6D88");
                    }

                    return(AudioPluginDissonanceNative.Dissonance_GetVadSpeechState(handle.Value));
                }
            }
Beispiel #9
0
            private bool ClearFilterPreprocessor(bool throwOnError = true)
            {
                using (var handle = _handle.Lock())
                {
                    if (handle.Value == IntPtr.Zero)
                    {
                        throw Log.CreatePossibleBugException("Attempted to access a null WebRtc Preprocessor encoder", "2DBC7779-F1B9-45F2-9372-3268FD8D7EBA");
                    }

                    Log.Debug("Clearing preprocessor instance in playback filter...");

                    //Clear binding in native code
                    if (!AudioPluginDissonanceNative.Dissonance_PreprocessorExchangeInstance(handle.Value, IntPtr.Zero))
                    {
                        if (throwOnError)
                        {
                            throw Log.CreatePossibleBugException("Cannot clear preprocessor from Playback filter. Editor restart required!", "6323106A-04BD-4217-9ECA-6FD49BF04FF0");
                        }
                        else
                        {
                            Log.Error("Failed to clear preprocessor from playback filter. Editor restart required!", "CBC6D727-BE07-4073-AA5A-F750A0CC023D");
                        }

                        return(false);
                    }

                    //Clear event handlers from voice settings
                    var settings = VoiceSettings.Instance;
                    for (var i = 0; i < _subscribed.Count; i++)
                    {
                        settings.PropertyChanged -= _subscribed[i];
                    }
                    _subscribed.Clear();

                    Log.Debug("...Cleared preprocessor instance in playback filter");
                    return(true);
                }
            }
Beispiel #10
0
            public void Reset()
            {
                using (var handle = _handle.Lock())
                {
                    Log.Debug("Resetting WebRtcPreprocessor");

                    if (handle.Value != IntPtr.Zero)
                    {
                        //Clear from playback filter. This internally acquires a lock and will not complete until it is safe to (i.e. no one else is using the preprocessor concurrently).
                        ClearFilterPreprocessor();

                        //Destroy it
                        AudioPluginDissonanceNative.Dissonance_DestroyPreprocessor(handle.Value);
                        handle.Value = IntPtr.Zero;
                    }

                    //Create a new one
                    handle.Value = CreatePreprocessor();

                    //Associate with playback filter
                    SetFilterPreprocessor(handle.Value);
                }
            }
Beispiel #11
0
 internal static AudioPluginDissonanceNative.FilterState GetAecFilterState()
 {
     return((AudioPluginDissonanceNative.FilterState)AudioPluginDissonanceNative.Dissonance_GetFilterState());
 }