Adding 'Audio' tab.
Volume indicator of MDM16AA display now working.
Adding server side dependency on NAudio.
It was decided to have a server side dependency so that we could implement
new fields control such as:
* Volume indicator
* Mute indicator
* Spectrum visualizer
* Meter visualizer
* Fancy visualizer
1.1 --- a/Server/MainForm.Designer.cs Sat Feb 07 21:16:33 2015 +0100
1.2 +++ b/Server/MainForm.Designer.cs Sun Feb 08 17:27:02 2015 +0100
1.3 @@ -90,6 +90,8 @@
1.4 this.checkBoxMinimizeToTray = new System.Windows.Forms.CheckBox();
1.5 this.checkBoxAutoStart = new System.Windows.Forms.CheckBox();
1.6 this.buttonUpdate = new System.Windows.Forms.Button();
1.7 + this.tabPageAudio = new System.Windows.Forms.TabPage();
1.8 + this.trackBarMasterVolume = new System.Windows.Forms.TrackBar();
1.9 this.labelFontWidth = new System.Windows.Forms.Label();
1.10 this.labelFontHeight = new System.Windows.Forms.Label();
1.11 this.pictureBoxDemo = new System.Windows.Forms.PictureBox();
1.12 @@ -103,6 +105,8 @@
1.13 this.tabControl.SuspendLayout();
1.14 this.tabPageDesign.SuspendLayout();
1.15 this.tabPageApp.SuspendLayout();
1.16 + this.tabPageAudio.SuspendLayout();
1.17 + ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).BeginInit();
1.18 ((System.ComponentModel.ISupportInitialize)(this.pictureBoxDemo)).BeginInit();
1.19 this.SuspendLayout();
1.20 //
1.21 @@ -504,6 +508,7 @@
1.22 this.tabControl.Controls.Add(this.tabPageClients);
1.23 this.tabControl.Controls.Add(this.tabPageDesign);
1.24 this.tabControl.Controls.Add(this.tabPageApp);
1.25 + this.tabControl.Controls.Add(this.tabPageAudio);
1.26 this.tabControl.Location = new System.Drawing.Point(12, 139);
1.27 this.tabControl.Name = "tabControl";
1.28 this.tabControl.SelectedIndex = 0;
1.29 @@ -683,6 +688,31 @@
1.30 this.buttonUpdate.UseVisualStyleBackColor = true;
1.31 this.buttonUpdate.Click += new System.EventHandler(this.buttonUpdate_Click);
1.32 //
1.33 + // tabPageAudio
1.34 + //
1.35 + this.tabPageAudio.Controls.Add(this.trackBarMasterVolume);
1.36 + this.tabPageAudio.Location = new System.Drawing.Point(4, 22);
1.37 + this.tabPageAudio.Name = "tabPageAudio";
1.38 + this.tabPageAudio.Padding = new System.Windows.Forms.Padding(3);
1.39 + this.tabPageAudio.Size = new System.Drawing.Size(592, 242);
1.40 + this.tabPageAudio.TabIndex = 5;
1.41 + this.tabPageAudio.Text = "Audio";
1.42 + this.tabPageAudio.UseVisualStyleBackColor = true;
1.43 + //
1.44 + // trackBarMasterVolume
1.45 + //
1.46 + this.trackBarMasterVolume.BackColor = System.Drawing.SystemColors.Window;
1.47 + this.trackBarMasterVolume.Location = new System.Drawing.Point(541, 6);
1.48 + this.trackBarMasterVolume.Maximum = 100;
1.49 + this.trackBarMasterVolume.Name = "trackBarMasterVolume";
1.50 + this.trackBarMasterVolume.Orientation = System.Windows.Forms.Orientation.Vertical;
1.51 + this.trackBarMasterVolume.Size = new System.Drawing.Size(45, 230);
1.52 + this.trackBarMasterVolume.TabIndex = 0;
1.53 + this.trackBarMasterVolume.TickFrequency = 10;
1.54 + this.trackBarMasterVolume.TickStyle = System.Windows.Forms.TickStyle.Both;
1.55 + this.toolTip.SetToolTip(this.trackBarMasterVolume, "Master Volume");
1.56 + this.trackBarMasterVolume.Scroll += new System.EventHandler(this.trackBarMasterVolume_Scroll);
1.57 + //
1.58 // labelFontWidth
1.59 //
1.60 this.labelFontWidth.AutoSize = true;
1.61 @@ -743,6 +773,9 @@
1.62 this.tabPageDesign.PerformLayout();
1.63 this.tabPageApp.ResumeLayout(false);
1.64 this.tabPageApp.PerformLayout();
1.65 + this.tabPageAudio.ResumeLayout(false);
1.66 + this.tabPageAudio.PerformLayout();
1.67 + ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).EndInit();
1.68 ((System.ComponentModel.ISupportInitialize)(this.pictureBoxDemo)).EndInit();
1.69 this.ResumeLayout(false);
1.70 this.PerformLayout();
1.71 @@ -806,6 +839,8 @@
1.72 private System.Windows.Forms.Label labelScrollingSpeed;
1.73 private System.Windows.Forms.MaskedTextBox maskedTextBoxScrollingSpeed;
1.74 private System.Windows.Forms.ToolTip toolTip;
1.75 + private System.Windows.Forms.TabPage tabPageAudio;
1.76 + private System.Windows.Forms.TrackBar trackBarMasterVolume;
1.77 }
1.78 }
1.79
2.1 --- a/Server/MainForm.cs Sat Feb 07 21:16:33 2015 +0100
2.2 +++ b/Server/MainForm.cs Sun Feb 08 17:27:02 2015 +0100
2.3 @@ -15,6 +15,10 @@
2.4 using System.Diagnostics;
2.5 using System.Deployment.Application;
2.6 using System.Reflection;
2.7 +//NAudio
2.8 +using NAudio.CoreAudioApi;
2.9 +using NAudio.CoreAudioApi.Interfaces;
2.10 +using System.Runtime.InteropServices;
2.11 //
2.12 using SharpDisplayClient;
2.13 using SharpDisplay;
2.14 @@ -31,12 +35,13 @@
2.15 public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList<DataField> aFields);
2.16 public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout);
2.17 public delegate void SetClientNameDelegate(string aSessionId, string aName);
2.18 + public delegate void PlainUpdateDelegate();
2.19
2.20
2.21 /// <summary>
2.22 /// Our Display manager main form
2.23 /// </summary>
2.24 - public partial class MainForm : Form
2.25 + public partial class MainForm : Form, IMMNotificationClient
2.26 {
2.27 DateTime LastTickTime;
2.28 Display iDisplay;
2.29 @@ -56,6 +61,10 @@
2.30 CoordinateTranslationDelegate iScreenX;
2.31 //Function pointer for pixel Y coordinate intercept
2.32 CoordinateTranslationDelegate iScreenY;
2.33 + //NAudio
2.34 + private MMDeviceEnumerator iMultiMediaDeviceEnumerator;
2.35 + private MMDevice iMultiMediaDevice;
2.36 +
2.37
2.38 /// <summary>
2.39 /// Manage run when Windows startup option
2.40 @@ -121,6 +130,12 @@
2.41 this.Text += " - development";
2.42 }
2.43
2.44 + //NAudio
2.45 + iMultiMediaDeviceEnumerator = new MMDeviceEnumerator();
2.46 + iMultiMediaDeviceEnumerator.RegisterEndpointNotificationCallback(this);
2.47 +
2.48 + UpdateAudioDeviceAndMasterVolumeThreadSafe();
2.49 +
2.50 //Setup notification icon
2.51 SetupTrayIcon();
2.52
2.53 @@ -167,10 +182,13 @@
2.54 //Initiate asynchronous request
2.55 iDisplay.RequestFirmwareRevision();
2.56
2.57 + //
2.58 + UpdateMasterVolumeThreadSafe();
2.59 +
2.60 #if DEBUG
2.61 //Testing icon in debug, no arm done if icon not supported
2.62 //iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconRecording, 0, 1);
2.63 - iDisplay.SetAllIconsStatus(2);
2.64 + //iDisplay.SetAllIconsStatus(2);
2.65 #endif
2.66
2.67 }
2.68 @@ -184,6 +202,135 @@
2.69 //Our display was just closed, update our UI consequently
2.70 UpdateStatus();
2.71 }
2.72 +
2.73 + /// <summary>
2.74 + /// Receive volume change notification and reflect changes on our slider.
2.75 + /// </summary>
2.76 + /// <param name="data"></param>
2.77 + public void OnVolumeNotificationThreadSafe(AudioVolumeNotificationData data)
2.78 + {
2.79 + UpdateMasterVolumeThreadSafe();
2.80 + }
2.81 +
2.82 + /// <summary>
2.83 + /// Update master volume when user moves our slider.
2.84 + /// </summary>
2.85 + /// <param name="sender"></param>
2.86 + /// <param name="e"></param>
2.87 + private void trackBarMasterVolume_Scroll(object sender, EventArgs e)
2.88 + {
2.89 + iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBarMasterVolume.Value / 100.0f;
2.90 + }
2.91 +
2.92 + /// <summary>
2.93 + /// Device State Changed
2.94 + /// </summary>
2.95 + public void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] string deviceId, [MarshalAs(UnmanagedType.I4)] DeviceState newState){}
2.96 +
2.97 + /// <summary>
2.98 + /// Device Added
2.99 + /// </summary>
2.100 + public void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId) { }
2.101 +
2.102 + /// <summary>
2.103 + /// Device Removed
2.104 + /// </summary>
2.105 + public void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] string deviceId) { }
2.106 +
2.107 + /// <summary>
2.108 + /// Default Device Changed
2.109 + /// </summary>
2.110 + public void OnDefaultDeviceChanged(DataFlow flow, Role role, [MarshalAs(UnmanagedType.LPWStr)] string defaultDeviceId)
2.111 + {
2.112 + if (role == Role.Multimedia && flow == DataFlow.Render)
2.113 + {
2.114 + UpdateAudioDeviceAndMasterVolumeThreadSafe();
2.115 + }
2.116 + }
2.117 +
2.118 + /// <summary>
2.119 + /// Property Value Changed
2.120 + /// </summary>
2.121 + /// <param name="pwstrDeviceId"></param>
2.122 + /// <param name="key"></param>
2.123 + public void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, PropertyKey key){}
2.124 +
2.125 +
2.126 +
2.127 +
2.128 + /// <summary>
2.129 + ///
2.130 + /// </summary>
2.131 + private void UpdateMasterVolumeThreadSafe()
2.132 + {
2.133 + if (this.InvokeRequired)
2.134 + {
2.135 + //Not in the proper thread, invoke ourselves
2.136 + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateMasterVolumeThreadSafe);
2.137 + this.Invoke(d, new object[] { });
2.138 + return;
2.139 + }
2.140 +
2.141 + float volumeLevelScalar = iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar;
2.142 + trackBarMasterVolume.Value = Convert.ToInt32(volumeLevelScalar * 100);
2.143 +
2.144 + //TODO: Check our display device too
2.145 + if (iDisplay.IsOpen())
2.146 + {
2.147 + int volumeIconCount = iDisplay.IconCount(Display.TMiniDisplayIconType.EMiniDisplayIconVolume);
2.148 + if (volumeIconCount > 0)
2.149 + {
2.150 + int currentVolume = Convert.ToInt32(volumeLevelScalar * volumeIconCount);
2.151 + for (int i = 0; i < volumeIconCount; i++)
2.152 + {
2.153 + if (i < currentVolume)
2.154 + {
2.155 + iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconVolume, i, 10);
2.156 + }
2.157 + else
2.158 + {
2.159 + iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconVolume, i, 0);
2.160 + }
2.161 + }
2.162 + }
2.163 + }
2.164 +
2.165 + }
2.166 +
2.167 + /// <summary>
2.168 + ///
2.169 + /// </summary>
2.170 + private void UpdateAudioDeviceAndMasterVolumeThreadSafe()
2.171 + {
2.172 + if (this.InvokeRequired)
2.173 + {
2.174 + //Not in the proper thread, invoke ourselves
2.175 + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateAudioDeviceAndMasterVolumeThreadSafe);
2.176 + this.Invoke(d, new object[] { });
2.177 + return;
2.178 + }
2.179 +
2.180 + //We are in the correct thread just go ahead.
2.181 + try
2.182 + {
2.183 + //Get our master volume
2.184 + iMultiMediaDevice = iMultiMediaDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
2.185 + //Show our volume in our track bar
2.186 + UpdateMasterVolumeThreadSafe();
2.187 +
2.188 + //Register to get volume modifications
2.189 + iMultiMediaDevice.AudioEndpointVolume.OnVolumeNotification += OnVolumeNotificationThreadSafe;
2.190 + //
2.191 + trackBarMasterVolume.Enabled = true;
2.192 + }
2.193 + catch (Exception ex)
2.194 + {
2.195 + Debug.WriteLine("Exception thrown in UpdateAudioDeviceAndMasterVolume");
2.196 + Debug.WriteLine(ex.ToString());
2.197 + //Something went wrong S/PDIF device ca throw exception I guess
2.198 + trackBarMasterVolume.Enabled = false;
2.199 + }
2.200 + }
2.201
2.202 /// <summary>
2.203 ///
3.1 --- a/Server/SharpDisplayManager.csproj Sat Feb 07 21:16:33 2015 +0100
3.2 +++ b/Server/SharpDisplayManager.csproj Sun Feb 08 17:27:02 2015 +0100
3.3 @@ -106,6 +106,9 @@
3.4 <ItemGroup>
3.5 <Reference Include="Microsoft.VisualBasic" />
3.6 <Reference Include="Microsoft.VisualBasic.PowerPacks.Vs, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
3.7 + <Reference Include="NAudio">
3.8 + <HintPath>..\packages\NAudio.1.7.2\lib\net35\NAudio.dll</HintPath>
3.9 + </Reference>
3.10 <Reference Include="System" />
3.11 <Reference Include="System.Configuration" />
3.12 <Reference Include="System.Core" />
3.13 @@ -169,6 +172,7 @@
3.14 <None Include="app.manifest">
3.15 <SubType>Designer</SubType>
3.16 </None>
3.17 + <None Include="packages.config" />
3.18 <None Include="Properties\Settings.settings">
3.19 <Generator>SettingsSingleFileGenerator</Generator>
3.20 <LastGenOutput>Settings.Designer.cs</LastGenOutput>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/Server/packages.config Sun Feb 08 17:27:02 2015 +0100
4.3 @@ -0,0 +1,4 @@
4.4 +<?xml version="1.0" encoding="utf-8"?>
4.5 +<packages>
4.6 + <package id="NAudio" version="1.7.2" targetFramework="net45" />
4.7 +</packages>
4.8 \ No newline at end of file