# HG changeset patch
# User StephaneLenclud
# Date 1483874375 -3600
# Node ID 2481c46d1f933a0af7b665d780fdcd73a79e1603
# Parent 71ba0dd622a5394dbd4119bf002a0015b4b4d68a
Reading audio output is stopped when audio visualizers are not in used.
diff -r 71ba0dd622a5 -r 2481c46d1f93 Server/AudioManager.cs
--- a/Server/AudioManager.cs Sat Jan 07 20:21:42 2017 +0100
+++ b/Server/AudioManager.cs Sun Jan 08 12:19:35 2017 +0100
@@ -32,13 +32,47 @@
private WasapiCapture iSoundIn;
private IWaveSource iWaveSource;
private LineSpectrum iLineSpectrum;
-
+ private int iVisualizerCount = 0;
public LineSpectrum Spectrum { get { return iLineSpectrum; } }
public AudioEndpointVolume Volume { get { return iAudioEndpointVolume; } }
public MMDevice DefaultDevice { get { return iMultiMediaDevice; } }
///
+ /// Increment our visualizer count
+ ///
+ public void AddVisualizer()
+ {
+ if (iVisualizerCount == 0)
+ {
+ // If we need at least one visualizer then we need to start our engine.
+ StartAudioVisualization();
+ }
+
+ //TODO: Check bounds?
+ iVisualizerCount++;
+ }
+
+ ///
+ /// Decrement our visualizer counter.
+ ///
+ public void RemoveVisualizer()
+ {
+ if (iVisualizerCount == 1)
+ {
+ // When reaching zero visualization is not need and we stop our engine
+ StopAudioVisualization();
+ iVisualizerCount = 0;
+ }
+ // Defensive: Make sure we don't go below zero
+ else if (iVisualizerCount>0)
+ {
+ iVisualizerCount--;
+ }
+ }
+
+
+ ///
///
///
///
@@ -57,7 +91,11 @@
iAudioEndpointVolumeCallback.NotifyRecived += iVolumeChangedHandler = aVolumeChangedHandler;
iAudioEndpointVolume.RegisterControlChangeNotify(iAudioEndpointVolumeCallback);
- StartAudioVisualization();
+ if (iVisualizerCount > 0)
+ {
+ // We probably got restarted, make sure visualization is running if needed
+ StartAudioVisualization();
+ }
}
///
@@ -130,11 +168,11 @@
iLineSpectrum = new LineSpectrum(fftSize)
{
SpectrumProvider = spectrumProvider,
- UseAverage = false,
+ UseAverage = false, // Does not matter since we hacked it
BarCount = 16,
BarSpacing = 1,
- IsXLogScale = true,
- ScalingStrategy = ScalingStrategy.Decibel
+ IsXLogScale = true, // Does not matter since we hacked it
+ ScalingStrategy = ScalingStrategy.Decibel // Does not matter since we hacked it
};
@@ -164,7 +202,12 @@
///
private void StopAudioVisualization()
{
- if (iWaveSource != null)
+ if (iSoundIn != null)
+ {
+ iSoundIn.Stop();
+ }
+
+ if (iWaveSource != null)
{
iWaveSource.Dispose();
iWaveSource = null;
@@ -172,11 +215,11 @@
if (iSoundIn != null)
{
- iSoundIn.Stop();
iSoundIn.Dispose();
iSoundIn = null;
}
+ iLineSpectrum = null;
}
diff -r 71ba0dd622a5 -r 2481c46d1f93 Server/FormMain.cs
--- a/Server/FormMain.cs Sat Jan 07 20:21:42 2017 +0100
+++ b/Server/FormMain.cs Sun Jan 08 12:19:35 2017 +0100
@@ -256,6 +256,7 @@
#if !DEBUG
//When not debugging we want the screen to be empty until a client takes over
ClearLayout();
+ iCurrentClientData = null;
#else
//When developing we want at least one client for testing
StartNewClient("abcdefghijklmnopqrst-0123456789", "ABCDEFGHIJKLMNOPQRST-0123456789");
@@ -656,7 +657,7 @@
}
// Update our math
- if (iAudioManager==null || !iAudioManager.Spectrum.Update())
+ if (iAudioManager==null || iAudioManager.Spectrum==null || !iAudioManager.Spectrum.Update())
{
//Nothing changed no need to render
return;
@@ -1560,6 +1561,7 @@
if (iClients.Count == 0)
{
ClearLayout();
+ iCurrentClientData = null;
}
}
@@ -1568,10 +1570,22 @@
///
private void ClearLayout()
{
+ // For each loop did not work as calling Dispose on a control removes it from the collection.
+ // We make sure every control are disposed of notably to turn off visualizer when no more needed.
+ // That's the only way we found to make sure Control.Disposed is called in a timely fashion.
+ // Though that loop is admetitly dangerous as if one of the control does not removes itself from the list we end up with infinite loop.
+ // That's what happened with our MarqueeLabel until we fixed it's Dispose override.
+ while (iTableLayoutPanel.Controls.Count>0)
+ {
+ // Dispose our last item
+ iTableLayoutPanel.Controls[iTableLayoutPanel.Controls.Count-1].Dispose();
+ }
+
iTableLayoutPanel.Controls.Clear();
iTableLayoutPanel.RowStyles.Clear();
iTableLayoutPanel.ColumnStyles.Clear();
- iCurrentClientData = null;
+ iTableLayoutPanel.RowCount = 0;
+ iTableLayoutPanel.ColumnCount = 0;
}
///
@@ -1751,6 +1765,7 @@
{
//Clear our screen when last client disconnects
ClearLayout();
+ iCurrentClientData = null;
if (iClosing)
{
@@ -2208,11 +2223,7 @@
TableLayout layout = aClient.Layout;
//First clean our current panel
- iTableLayoutPanel.Controls.Clear();
- iTableLayoutPanel.RowStyles.Clear();
- iTableLayoutPanel.ColumnStyles.Clear();
- iTableLayoutPanel.RowCount = 0;
- iTableLayoutPanel.ColumnCount = 0;
+ ClearLayout();
//Then recreate our rows...
while (iTableLayoutPanel.RowCount < layout.Rows.Count)
@@ -2331,6 +2342,21 @@
picture.Location = new System.Drawing.Point(1, 1);
picture.Margin = new System.Windows.Forms.Padding(0);
picture.Name = "pictureBox" + aField;
+
+ // Make sure visualization is running
+ iAudioManager.AddVisualizer();
+
+ // Notify audio manager when we don't need audio visualizer anymore
+ picture.Disposed += (sender, e) =>
+ {
+ if (iAudioManager != null)
+ {
+ // Make sure we stop visualization when not needed
+ iAudioManager.RemoveVisualizer();
+ }
+ };
+
+ // Create a new bitmap when control size changes
picture.SizeChanged += (sender, e) =>
{
// Somehow bitmap created when our from is invisible are not working
diff -r 71ba0dd622a5 -r 2481c46d1f93 Server/MarqueeLabel.cs
--- a/Server/MarqueeLabel.cs Sat Jan 07 20:21:42 2017 +0100
+++ b/Server/MarqueeLabel.cs Sun Jan 08 12:19:35 2017 +0100
@@ -411,12 +411,23 @@
return false;
}
+ ///
+ /// See Dispose Pattern reference:
+ /// https://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
+ ///
+ ///
protected override void Dispose(bool disposing)
{
+ // My sure we hook the rest of the framework.
+ // That's most important for controls since they do things like removing themselves from containers upon disposal.
+ base.Dispose(disposing);
+ // My understanding is that one is not supose to Dispose other objects unless disposing is true.
if (disposing)
{
if (Timer != null)
+ {
Timer.Dispose();
+ }
}
Timer = null;
}
diff -r 71ba0dd622a5 -r 2481c46d1f93 Server/Spectrum/SpectrumBase.cs
--- a/Server/Spectrum/SpectrumBase.cs Sat Jan 07 20:21:42 2017 +0100
+++ b/Server/Spectrum/SpectrumBase.cs Sun Jan 08 12:19:35 2017 +0100
@@ -162,10 +162,10 @@
{
var dataPoints = new List();
- double value0 = 0, value = 0;
- double lastValue = 0;
- double actualMaxValue = maxValue;
- int spectrumPointIndex = 0;
+ //double value0 = 0, value = 0;
+ //double lastValue = 0;
+ //double actualMaxValue = maxValue;
+ //int spectrumPointIndex = 0;
int b0 = _minimumFrequencyIndex;
int x, y;