private void ChangeAudioClip([NotNull] AudioClip clip)
        {
            if (clip.channels != 1)
            {
                Debug.LogError("Audio clip must be mono!");
                return;
            }
            _clip = clip;
            var format = new WaveFormat(clip.frequency, 1);

            var sub = GetComponent <MicSubscriberPlayer>();

            sub.SetFormat(format);

            if (_preprocessor != null)
            {
                _preprocessor.Dispose();
                _preprocessor = null;
            }

            _preprocessor = new WebRtcPreprocessingPipeline(format, false);
            _preprocessor.Subscribe(GetComponent <MicSubscriberPlayer>());
            _preprocessor.Start();

            VoiceActivationStop();
            _preprocessor.Subscribe(this);

            _pendingSamples = -clip.frequency * 5;
            _readHead       = 0;
            _clip           = clip;
        }
Esempio n. 2
0
 /// <summary>
 /// Get the current state of the AEC output filter
 /// </summary>
 /// <returns></returns>
 public static AecState GetState()
 {
     return((AecState)WebRtcPreprocessingPipeline.GetAecFilterState());
 }
        public override bool OnGUI([NotNull] IAudioEffectPlugin plugin)
        {
            if (!_initialized)
            {
                Initialize();
            }

            GUILayout.Label(_logo);
            EditorGUILayout.HelpBox("This filter captures data to drive acoustic echo cancellation. All audio which passes through this filter will be played through your " +
                                    "speakers, the filter will watch you microphone for this audio coming back as an echo and remove it", MessageType.Info);

            if (Application.isPlaying)
            {
                var state = WebRtcPreprocessingPipeline.GetAecFilterState();
                switch (state)
                {
                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNoInstance:
                    EditorGUILayout.HelpBox("AEC filter is running, but it is not associated with a microphone preprocessor - Microphone not running?", MessageType.Info);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNoSamplesSubmitted:
                    EditorGUILayout.HelpBox("AEC filter is running, but no samples were submitted in the last frame - Could indicate audio thread starvation", MessageType.Warning);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNotRunning:
                    EditorGUILayout.HelpBox("AEC filter is not running - Audio device not initialized?", MessageType.Warning);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterOk:
                    EditorGUILayout.HelpBox("AEC filter is running.", MessageType.Info);
                    break;

                default:
                    EditorGUILayout.HelpBox("Unknown Filter State!", MessageType.Error);
                    break;
                }

                float[] data;
                if (plugin.GetFloatBuffer("AecMetrics", out data, 10))
                {
                    EditorGUILayout.LabelField(
                        "Delay Median (samples)",
                        data[0].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Delay Deviation",
                        data[1].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Fraction Poor Delays",
                        (data[2] * 100).ToString(CultureInfo.InvariantCulture) + "%"
                        );

                    EditorGUILayout.LabelField(
                        "Echo Return Loss",
                        data[3].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Echo Return Loss Enhancement",
                        data[6].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Residual Echo Likelihood",
                        (data[9] * 100).ToString("0.0", CultureInfo.InvariantCulture) + "%"
                        );
                }
            }

            return(false);
        }
Esempio n. 4
0
        public override bool OnGUI([NotNull] IAudioEffectPlugin plugin)
        {
            if (!_initialized)
            {
                Initialize();
            }

            GUILayout.Label(_logo);
            EditorGUILayout.HelpBox("This filter captures data to drive acoustic echo cancellation. All audio which passes through this filter will be played through your " +
                                    "speakers. When the audio enters your microphone (as echo) it will be removed.", MessageType.Info);

            if (Application.isPlaying)
            {
                var state = WebRtcPreprocessingPipeline.GetAecFilterState();
                switch (state)
                {
                case AudioPluginDissonanceNative.FilterState.FilterNoInstance:
                    EditorGUILayout.HelpBox("AEC filter is running, but it is not associated with a microphone preprocessor - Microphone not running?", MessageType.Info);
                    break;

                case AudioPluginDissonanceNative.FilterState.FilterNoSamplesSubmitted:
                    EditorGUILayout.HelpBox("AEC filter is running, but no samples were submitted in the last frame - Could indicate audio thread starvation", MessageType.Warning);
                    break;

                case AudioPluginDissonanceNative.FilterState.FilterNotRunning:
                    EditorGUILayout.HelpBox("AEC filter is not running - Audio device not initialized?", MessageType.Warning);
                    break;

                case AudioPluginDissonanceNative.FilterState.FilterOk:
                    break;

                default:
                    EditorGUILayout.HelpBox("Unknown Filter State!", MessageType.Error);
                    break;
                }

                // `GetFloatBuffer` (a built in Unity method) causes a null reference exception when called. This bug seems to be limited to Unity 2019.3 on MacOS.
                // See tracking issue: https://github.com/Placeholder-Software/Dissonance/issues/177
#if (UNITY_EDITOR_OSX && UNITY_2019_3)
                EditorGUILayout.HelpBox("Cannot show detailed statistics in Unity 2019.3 due to an editor bug. Please update to Unity 2019.4 or newer!", MessageType.Error);
#else
                float[] data;
                if (plugin.GetFloatBuffer("AecMetrics", out data, 10))
                {
                    EditorGUILayout.LabelField(
                        new GUIContent("Delay Median (samples)"),
                        FormatNumber(data[0])
                        );

                    EditorGUILayout.LabelField(
                        new GUIContent("Delay Deviation"),
                        FormatNumber(data[1])
                        );

                    EditorGUILayout.LabelField(
                        new GUIContent("Fraction Poor Delays"),
                        FormatPercentage(data[2])
                        );

                    EditorGUILayout.LabelField(
                        new GUIContent("Echo Return Loss"),
                        FormatNumber(data[3])
                        );

                    EditorGUILayout.LabelField(
                        new GUIContent("Echo Return Loss Enhancement"),
                        FormatNumber(data[6])
                        );

                    EditorGUILayout.LabelField(
                        new GUIContent("Residual Echo Likelihood"),
                        FormatPercentage(data[9])
                        );

                    ShowHints(data);
                }
#endif
            }

            return(false);
        }
        public override bool OnGUI([NotNull] IAudioEffectPlugin plugin)
        {
            if (!_initialized)
            {
                Initialize();
            }

            GUILayout.Label(_logo);
            EditorGUILayout.HelpBox("This filter captures data to drive acoustic echo cancellation. All audio which passes through this filter will be played through your " +
                                    "speakers, the filter will watch you microphone for this audio coming back as an echo and remove it", MessageType.Info);

            if (Application.isPlaying)
            {
                var state = WebRtcPreprocessingPipeline.GetAecFilterState();
                switch (state)
                {
                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNoInstance:
                    EditorGUILayout.HelpBox("AEC filter is running, but it is not associated with a microphone preprocessor - Microphone not running?", MessageType.Info);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNoSamplesSubmitted:
                    EditorGUILayout.HelpBox("AEC filter is running, but no samples were submitted in the last frame - Could indicate audio thread starvation", MessageType.Warning);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterNotRunning:
                    EditorGUILayout.HelpBox("AEC filter is not running - Audio device not initialized?", MessageType.Warning);
                    break;

                case WebRtcPreprocessingPipeline.WebRtcPreprocessor.FilterState.FilterOk:
                    EditorGUILayout.HelpBox("AEC filter is running.", MessageType.Info);
                    break;

                default:
                    EditorGUILayout.HelpBox("Unknown Filter State!", MessageType.Error);
                    break;
                }

                // `GetFloatBuffer` (a built in Unity method) causes a null reference exception when called. This bug seems to be limited to Unity 2019.3 on MacOS.
                // See tracking issue: https://github.com/Placeholder-Software/Dissonance/issues/177
#if !(UNITY_EDITOR_OSX && UNITY_2019_3_OR_NEWER)
                float[] data;
                if (plugin.GetFloatBuffer("AecMetrics", out data, 10))
                {
                    EditorGUILayout.LabelField(
                        "Delay Median (samples)",
                        data[0].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Delay Deviation",
                        data[1].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Fraction Poor Delays",
                        (data[2] * 100).ToString(CultureInfo.InvariantCulture) + "%"
                        );

                    EditorGUILayout.LabelField(
                        "Echo Return Loss",
                        data[3].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Echo Return Loss Enhancement",
                        data[6].ToString(CultureInfo.InvariantCulture)
                        );

                    EditorGUILayout.LabelField(
                        "Residual Echo Likelihood",
                        (data[9] * 100).ToString("0.0", CultureInfo.InvariantCulture) + "%"
                        );
                }
#endif
            }

            return(false);
        }