Adding 'Audio' tab.
authorStephaneLenclud
Sun, 08 Feb 2015 17:27:02 +0100
changeset 11257b1c6507bd7
parent 111 1b6de6f9b7c6
child 113 0846e5112dd7
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
Server/MainForm.Designer.cs
Server/MainForm.cs
Server/SharpDisplayManager.csproj
Server/packages.config
     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