1.1 --- a/Server/MainForm.cs Sat Feb 07 21:16:33 2015 +0100
1.2 +++ b/Server/MainForm.cs Sun Feb 08 17:27:02 2015 +0100
1.3 @@ -15,6 +15,10 @@
1.4 using System.Diagnostics;
1.5 using System.Deployment.Application;
1.6 using System.Reflection;
1.7 +//NAudio
1.8 +using NAudio.CoreAudioApi;
1.9 +using NAudio.CoreAudioApi.Interfaces;
1.10 +using System.Runtime.InteropServices;
1.11 //
1.12 using SharpDisplayClient;
1.13 using SharpDisplay;
1.14 @@ -31,12 +35,13 @@
1.15 public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList<DataField> aFields);
1.16 public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout);
1.17 public delegate void SetClientNameDelegate(string aSessionId, string aName);
1.18 + public delegate void PlainUpdateDelegate();
1.19
1.20
1.21 /// <summary>
1.22 /// Our Display manager main form
1.23 /// </summary>
1.24 - public partial class MainForm : Form
1.25 + public partial class MainForm : Form, IMMNotificationClient
1.26 {
1.27 DateTime LastTickTime;
1.28 Display iDisplay;
1.29 @@ -56,6 +61,10 @@
1.30 CoordinateTranslationDelegate iScreenX;
1.31 //Function pointer for pixel Y coordinate intercept
1.32 CoordinateTranslationDelegate iScreenY;
1.33 + //NAudio
1.34 + private MMDeviceEnumerator iMultiMediaDeviceEnumerator;
1.35 + private MMDevice iMultiMediaDevice;
1.36 +
1.37
1.38 /// <summary>
1.39 /// Manage run when Windows startup option
1.40 @@ -121,6 +130,12 @@
1.41 this.Text += " - development";
1.42 }
1.43
1.44 + //NAudio
1.45 + iMultiMediaDeviceEnumerator = new MMDeviceEnumerator();
1.46 + iMultiMediaDeviceEnumerator.RegisterEndpointNotificationCallback(this);
1.47 +
1.48 + UpdateAudioDeviceAndMasterVolumeThreadSafe();
1.49 +
1.50 //Setup notification icon
1.51 SetupTrayIcon();
1.52
1.53 @@ -167,10 +182,13 @@
1.54 //Initiate asynchronous request
1.55 iDisplay.RequestFirmwareRevision();
1.56
1.57 + //
1.58 + UpdateMasterVolumeThreadSafe();
1.59 +
1.60 #if DEBUG
1.61 //Testing icon in debug, no arm done if icon not supported
1.62 //iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconRecording, 0, 1);
1.63 - iDisplay.SetAllIconsStatus(2);
1.64 + //iDisplay.SetAllIconsStatus(2);
1.65 #endif
1.66
1.67 }
1.68 @@ -184,6 +202,135 @@
1.69 //Our display was just closed, update our UI consequently
1.70 UpdateStatus();
1.71 }
1.72 +
1.73 + /// <summary>
1.74 + /// Receive volume change notification and reflect changes on our slider.
1.75 + /// </summary>
1.76 + /// <param name="data"></param>
1.77 + public void OnVolumeNotificationThreadSafe(AudioVolumeNotificationData data)
1.78 + {
1.79 + UpdateMasterVolumeThreadSafe();
1.80 + }
1.81 +
1.82 + /// <summary>
1.83 + /// Update master volume when user moves our slider.
1.84 + /// </summary>
1.85 + /// <param name="sender"></param>
1.86 + /// <param name="e"></param>
1.87 + private void trackBarMasterVolume_Scroll(object sender, EventArgs e)
1.88 + {
1.89 + iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBarMasterVolume.Value / 100.0f;
1.90 + }
1.91 +
1.92 + /// <summary>
1.93 + /// Device State Changed
1.94 + /// </summary>
1.95 + public void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] string deviceId, [MarshalAs(UnmanagedType.I4)] DeviceState newState){}
1.96 +
1.97 + /// <summary>
1.98 + /// Device Added
1.99 + /// </summary>
1.100 + public void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId) { }
1.101 +
1.102 + /// <summary>
1.103 + /// Device Removed
1.104 + /// </summary>
1.105 + public void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] string deviceId) { }
1.106 +
1.107 + /// <summary>
1.108 + /// Default Device Changed
1.109 + /// </summary>
1.110 + public void OnDefaultDeviceChanged(DataFlow flow, Role role, [MarshalAs(UnmanagedType.LPWStr)] string defaultDeviceId)
1.111 + {
1.112 + if (role == Role.Multimedia && flow == DataFlow.Render)
1.113 + {
1.114 + UpdateAudioDeviceAndMasterVolumeThreadSafe();
1.115 + }
1.116 + }
1.117 +
1.118 + /// <summary>
1.119 + /// Property Value Changed
1.120 + /// </summary>
1.121 + /// <param name="pwstrDeviceId"></param>
1.122 + /// <param name="key"></param>
1.123 + public void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, PropertyKey key){}
1.124 +
1.125 +
1.126 +
1.127 +
1.128 + /// <summary>
1.129 + ///
1.130 + /// </summary>
1.131 + private void UpdateMasterVolumeThreadSafe()
1.132 + {
1.133 + if (this.InvokeRequired)
1.134 + {
1.135 + //Not in the proper thread, invoke ourselves
1.136 + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateMasterVolumeThreadSafe);
1.137 + this.Invoke(d, new object[] { });
1.138 + return;
1.139 + }
1.140 +
1.141 + float volumeLevelScalar = iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar;
1.142 + trackBarMasterVolume.Value = Convert.ToInt32(volumeLevelScalar * 100);
1.143 +
1.144 + //TODO: Check our display device too
1.145 + if (iDisplay.IsOpen())
1.146 + {
1.147 + int volumeIconCount = iDisplay.IconCount(Display.TMiniDisplayIconType.EMiniDisplayIconVolume);
1.148 + if (volumeIconCount > 0)
1.149 + {
1.150 + int currentVolume = Convert.ToInt32(volumeLevelScalar * volumeIconCount);
1.151 + for (int i = 0; i < volumeIconCount; i++)
1.152 + {
1.153 + if (i < currentVolume)
1.154 + {
1.155 + iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconVolume, i, 10);
1.156 + }
1.157 + else
1.158 + {
1.159 + iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconVolume, i, 0);
1.160 + }
1.161 + }
1.162 + }
1.163 + }
1.164 +
1.165 + }
1.166 +
1.167 + /// <summary>
1.168 + ///
1.169 + /// </summary>
1.170 + private void UpdateAudioDeviceAndMasterVolumeThreadSafe()
1.171 + {
1.172 + if (this.InvokeRequired)
1.173 + {
1.174 + //Not in the proper thread, invoke ourselves
1.175 + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateAudioDeviceAndMasterVolumeThreadSafe);
1.176 + this.Invoke(d, new object[] { });
1.177 + return;
1.178 + }
1.179 +
1.180 + //We are in the correct thread just go ahead.
1.181 + try
1.182 + {
1.183 + //Get our master volume
1.184 + iMultiMediaDevice = iMultiMediaDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
1.185 + //Show our volume in our track bar
1.186 + UpdateMasterVolumeThreadSafe();
1.187 +
1.188 + //Register to get volume modifications
1.189 + iMultiMediaDevice.AudioEndpointVolume.OnVolumeNotification += OnVolumeNotificationThreadSafe;
1.190 + //
1.191 + trackBarMasterVolume.Enabled = true;
1.192 + }
1.193 + catch (Exception ex)
1.194 + {
1.195 + Debug.WriteLine("Exception thrown in UpdateAudioDeviceAndMasterVolume");
1.196 + Debug.WriteLine(ex.ToString());
1.197 + //Something went wrong S/PDIF device ca throw exception I guess
1.198 + trackBarMasterVolume.Enabled = false;
1.199 + }
1.200 + }
1.201
1.202 /// <summary>
1.203 ///