diff --git a/Audio Router UWP/Audio Router/MainPage.xaml.cs b/Audio Router UWP/Audio Router/MainPage.xaml.cs index 98924c0..d5eb7ef 100644 --- a/Audio Router UWP/Audio Router/MainPage.xaml.cs +++ b/Audio Router UWP/Audio Router/MainPage.xaml.cs @@ -147,6 +147,8 @@ namespace Audio_Router InputAudioComboBox.Items.Add(sourceDevices[i].Name); } } + + // Set output device & add to inputs too for (int i = 0; i < targetDevices.Count; i++) { if(targetDevices[i].Id == defaultOutput.Id) @@ -211,7 +213,6 @@ namespace Audio_Router }; result = await AudioGraph.CreateAsync(settings); ag = result.Graph; - if (result.Status != AudioGraphCreationStatus.Success) { return; diff --git a/Audio Router WPF/AudioGraphConnection.cs b/Audio Router WPF/AudioGraphConnection.cs index 7d39aaa..1169db3 100644 --- a/Audio Router WPF/AudioGraphConnection.cs +++ b/Audio Router WPF/AudioGraphConnection.cs @@ -25,10 +25,11 @@ namespace Audio_Router_WPF Dispatcher uiDispatcher { get; set; } - TextBlock latencyLabel { get; set; } + TextBlock latencyLabel { get; set; } = new TextBlock(); - int quantaCount = 0; + int quantaCount; +#pragma warning disable CS8618 // Cannot convert null literal to non-nullable reference type. public AudioGraphConnection(AudioGraph graph, AudioDeviceOutputNode targetDevice, AudioDeviceInputNode sourceDevice, Dispatcher uiDispatcher) { Graph = graph; @@ -128,23 +129,43 @@ namespace Audio_Router_WPF private void Graph_QuantumProcessed(AudioGraph sender, object args) { // updates aren't urgent, only process after some time (this is 1s, with the Windows default of 10 ms / quanta - if (quantaCount++ == 100) + if (quantaCount % 100 == 0) { - string result = (Graph.LatencyInSamples / (double)Graph.SamplesPerQuantum * SamplesPerMS).ToString("0.#") + " ms"; if (latencyLabel is null) return; + string result = (Graph.LatencyInSamples / (double)Graph.SamplesPerQuantum * SamplesPerMS).ToString("0.#") + " ms"; + uiDispatcher.Invoke(() => { try { + // Try to set the label, otherwise it may have already been destroyed latencyLabel.Text = result; } - catch + catch (NullReferenceException) { } }, DispatcherPriority.Background); - quantaCount = 0; + result = null; } + /// ---------------------- + /// || About this: || + /// ---------------------- + /// Running AudioGraph in WPF causes what seems to be the captured audio data to + /// never go out of scope (this does not happen in UWP, as shown in the near-identical code from the + /// UWP project), so the memory allocations for the project keep increasing. + /// Stopping the AudioGraph causes these allocations to finalise, so frees up the space. + /// we can call ResetAllNodes() periodically (i.e.: every 10s (1000 * 10 ms)) to reset the + /// nodes + /// + if (quantaCount == 1000) + { + //SourceDevice.Reset(); + Graph.ResetAllNodes(); + // GC.Collect(); // We can let the GC handle itself + } + quantaCount++; + quantaCount %= 1001; } private void VolumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) @@ -153,10 +174,12 @@ namespace Audio_Router_WPF SourceDevice.OutgoingGain = e.NewValue; } + #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. private void DestroyButton_Click(object sender, RoutedEventArgs e) { - latencyLabel = null; Graph.QuantumProcessed -= Graph_QuantumProcessed; + Graph.ResetAllNodes(); + latencyLabel = null; Graph.Stop(); TargetDevice.Dispose(); SourceDevice.Dispose(); @@ -172,6 +195,7 @@ namespace Audio_Router_WPF public void OnHide() { latencyLabel = null; + Graph.QuantumProcessed -= Graph_QuantumProcessed; } } } diff --git a/Audio Router WPF/MainWindow.xaml b/Audio Router WPF/MainWindow.xaml index 5bc2e3c..55368a8 100644 --- a/Audio Router WPF/MainWindow.xaml +++ b/Audio Router WPF/MainWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Audio_Router_WPF" mc:Ignorable="d" - Title="MainWindow" Height="450" Width="800"> + Title="Audio Router WPF" Height="450" Width="800"> @@ -18,10 +18,10 @@ - - + + -