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; }
/// <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); }
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); }