Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for audioendpoints.cs

(view source code of audioendpoints.cs as plain text)

  1. using NAudio;
  2. using NAudio.CoreAudioApi;
  3. using NAudio.Wave;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Drawing;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10. using System.Windows.Forms;
  11.  
  12.  
  13. namespace RobvanderWoude
  14. {
  15. 	internal class AudioEndPoints
  16. 	{
  17. 		static readonly string progver = "2.04";
  18.  
  19.  
  20. 		#region Global Variables
  21.  
  22. 		static bool bgcolors = true;
  23. 		static bool fgcolors = false;
  24. 		static bool helprequested = false;
  25. 		static bool norecordingdevice = false;
  26. 		static bool statusintitlebar = false;
  27. 		static bool stereo = true;
  28. 		static bool topmost = false;
  29. 		static DataGridView datagrid;
  30. 		static readonly Dictionary<DeviceState, Color> foregroundcolors = new Dictionary<DeviceState, Color>
  31. 		{
  32. 			[DeviceState.Active] = Color.Green,
  33. 			[DeviceState.Disabled] = Color.Orange,
  34. 			[DeviceState.NotPresent] = Color.SlateGray,
  35. 			[DeviceState.Unplugged] = Color.Red
  36. 		};
  37. 		static readonly Dictionary<DeviceState, Color> backgroundcolors = new Dictionary<DeviceState, Color>
  38. 		{
  39. 			[DeviceState.Active] = Color.LightGreen,
  40. 			[DeviceState.Disabled] = Color.Yellow,
  41. 			[DeviceState.NotPresent] = Color.LightGray,
  42. 			[DeviceState.Unplugged] = Color.Red
  43. 		};
  44. 		static Dictionary<int, AudioEndPoint> audioendpoints;
  45. 		static Form form;
  46. 		static int interval = 0;
  47. 		static Timer timer = new Timer( );
  48. 		static WaveIn recorder;
  49. 		static readonly string titletext = "AudioEndPoints.exe, \u00A0 Version " + progver + " \u00A0?\u00A0 \u00A0 Copyright \u00A9 2025 Rob van der Woude";
  50.  
  51. 		private static readonly IntPtr HWND_TOPMOST = new IntPtr( -1 );
  52. 		private const UInt32 SWP_NOSIZE = 0x0001;
  53. 		private const UInt32 SWP_NOMOVE = 0x0002;
  54. 		private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
  55.  
  56. 		#endregion Global Variables
  57.  
  58.  
  59. 		[STAThread]
  60. 		static int Main( string[] args )
  61. 		{
  62. 			#region Parse Command Line
  63.  
  64. 			foreach ( string arg in args )
  65. 			{
  66. 				string[] kvp = arg.Split( ":=".ToCharArray( ), 2 );
  67. 				string key = kvp[0].ToUpper( );
  68. 				string val = ( kvp.Length == 2 ? kvp[1] : string.Empty );
  69. 				switch ( key )
  70. 				{
  71. 					case "/?":
  72. 						return ShowHelp( true );
  73. 					case "/B":
  74. 						bgcolors = false;
  75. 						fgcolors = false;
  76. 						break;
  77. 					case "/F":
  78. 						bgcolors = false;
  79. 						fgcolors = true;
  80. 						break;
  81. 					case "/M":
  82. 						stereo = false;
  83. 						break;
  84. 					case "/R":
  85. 						interval = 1;
  86. 						if ( string.IsNullOrWhiteSpace( val ) )
  87. 						{
  88. 							interval = 1;
  89. 						}
  90. 						else if ( !int.TryParse( val, out interval ) )
  91. 						{
  92. 							interval = 1;
  93. 						}
  94. 						if ( interval < 1 )
  95. 						{
  96. 							interval = 1;
  97. 						}
  98. 						timer.Interval = interval * 1000;
  99. 						timer.Tick += Timer_Tick;
  100. 						timer.Start( );
  101. 						break;
  102. 					case "/S":
  103. 						statusintitlebar = true;
  104. 						break;
  105. 					case "/T":
  106. 						topmost = true;
  107. 						break;
  108. 					default:
  109. 						return ShowHelp( true );
  110. 				}
  111. 			}
  112.  
  113. 			#endregion Parse Command Line
  114.  
  115.  
  116. 			Application.EnableVisualStyles( );
  117.  
  118. 			form = new Form
  119. 			{
  120. 				BackColor = Color.White,
  121. 				Font = new Font( FontFamily.GenericSansSerif, 12 ),
  122. 				Size = new Size( 1380, 840 ),
  123. 				StartPosition = FormStartPosition.CenterScreen,
  124. 				Text = titletext,
  125. 				Visible = true
  126. 			};
  127. 			form.FormClosing += Form_FormClosing;
  128. 			if ( topmost )
  129. 			{
  130. 				SetWindowPos( form.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS );
  131. 			}
  132.  
  133. 			Console.CursorVisible = false;
  134.  
  135. 			audioendpoints = new Dictionary<int, AudioEndPoint>( );
  136. 			recorder = new WaveIn( );
  137. 			recorder.RecordingStopped += Recorder_RecordingStopped;
  138.  
  139. 			Console.ForegroundColor = ConsoleColor.Yellow;
  140. 			Console.WriteLine( "Monitoring output levels" );
  141. 			Console.ResetColor( );
  142.  
  143. 			RestartRecorder( );
  144. 			SetupDataGrid( );
  145. 			PopulateDataGrid( );
  146.  
  147. 			while ( form.Enabled )
  148. 			{
  149. 				Application.DoEvents( );
  150. 			}
  151.  
  152. 			Console.CursorVisible = true;
  153.  
  154. 			return 0;
  155. 		}
  156.  
  157.  
  158. 		private static void Datagrid_KeyUp( object sender, KeyEventArgs e )
  159. 		{
  160. 			if ( e.KeyCode == Keys.F1 )
  161. 			{
  162. 				ShowHelp( false );
  163. 			}
  164. 			if ( e.KeyCode == Keys.F5 )
  165. 			{
  166. 				RefreshDataGrid( );
  167. 			}
  168. 			if ( e.KeyCode == Keys.Escape )
  169. 			{
  170. 				form.Close( );
  171. 			}
  172. 			if ( e.Control && e.KeyCode == Keys.P )
  173. 			{
  174. 				PrintDataGrid( );
  175. 			}
  176. 			if ( e.Control && e.KeyCode == Keys.S )
  177. 			{
  178. 				string filename = string.Format( "AudioEndPoints.{0}.{1}.txt", Environment.GetEnvironmentVariable( "COMPUTERNAME" ), DateTime.Now.ToString( "yyyy-MM-dd_HHmmss" ) );
  179. 				string outfile = Path.Combine( Environment.CurrentDirectory, filename );
  180. 				SaveDataGrid( outfile );
  181. 				MessageBox.Show( "Saved as \"" + filename + "\" in folder \"" + Path.GetDirectoryName( outfile ) + "\"", "File Saved", MessageBoxButtons.OK, MessageBoxIcon.Information );
  182. 			}
  183. 		}
  184.  
  185.  
  186. 		private static void Datagrid_SortCompare( object sender, DataGridViewSortCompareEventArgs e )
  187. 		{
  188. 			if ( e.Column.Index == 0 )
  189. 			{
  190. 				e.SortResult = int.Parse( e.CellValue1.ToString( ) ).CompareTo( int.Parse( e.CellValue2.ToString( ) ) );
  191. 				e.Handled = true; // skip the default sorting
  192. 			}
  193. 		}
  194.  
  195.  
  196. 		private static void Form_FormClosing( object sender, FormClosingEventArgs e )
  197. 		{
  198. 			try
  199. 			{
  200. 				timer.Stop( );
  201. 			}
  202. 			catch { }
  203. 			try
  204. 			{
  205. 				recorder.StopRecording( );
  206. 			}
  207. 			catch { }
  208. 			if ( helprequested )
  209. 			{
  210. 				ShowHelp( true );
  211. 			}
  212. 			form.Enabled = false;
  213. 		}
  214.  
  215.  
  216. 		private static void Recorder_RecordingStopped( object sender, StoppedEventArgs e )
  217. 		{
  218. 			RestartRecorder( );
  219. 		}
  220.  
  221.  
  222. 		private static void Timer_Tick( object sender, EventArgs e )
  223. 		{
  224. 			RefreshDataGrid( );
  225. 		}
  226.  
  227.  
  228. 		private static void InventoryAudioEndPoints( )
  229. 		{
  230. 			MMDeviceEnumerator enumerator = new MMDeviceEnumerator( );
  231. 			int index = 0;
  232. 			foreach ( MMDevice endpoint in enumerator.EnumerateAudioEndPoints( DataFlow.All, DeviceState.All ) )
  233. 			{
  234. 				AudioEndPoint audioendpoint = new AudioEndPoint
  235. 				{
  236. 					Index = index,
  237. 					InOut = endpoint.DataFlow,
  238. 					Name = endpoint.FriendlyName,
  239. 					State = endpoint.State,
  240. 					ID = endpoint.ID,
  241. 				};
  242. 				if ( audioendpoint.State == DeviceState.Active )
  243. 				{
  244. 					audioendpoint.MasterVolumeLevelScalar = endpoint.AudioEndpointVolume.MasterVolumeLevelScalar;
  245. 					audioendpoint.MasterPeakValue = endpoint.AudioMeterInformation.MasterPeakValue;
  246. 					audioendpoint.PeakValues = endpoint.AudioMeterInformation.PeakValues;
  247. 				}
  248. 				else
  249. 				{
  250. 					audioendpoint.MasterVolumeLevelScalar = 0f;
  251. 					audioendpoint.MasterPeakValue = 0f;
  252. 					audioendpoint.PeakValues = null;
  253. 				}
  254. 				audioendpoints[index] = audioendpoint;
  255. 				index++;
  256. 			}
  257. 			if ( norecordingdevice )
  258. 			{
  259. 				RestartRecorder( );
  260. 			}
  261. 		}
  262.  
  263.  
  264. 		private static void PopulateDataGrid( )
  265. 		{
  266. 			InventoryAudioEndPoints( );
  267. 			foreach ( AudioEndPoint endpoint in audioendpoints.Values )
  268. 			{
  269. 				PopulateDataGridRow( endpoint );
  270. 			}
  271. 			for ( int i = 0; i < datagrid.ColumnCount; i++ )
  272. 			{
  273. 				if ( i == datagrid.ColumnCount - 1 )
  274. 				{
  275. 					datagrid.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
  276. 				}
  277. 				else
  278. 				{
  279. 					datagrid.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
  280. 				}
  281. 			}
  282. 		}
  283.  
  284.  
  285. 		private static void PopulateDataGridRow( AudioEndPoint endpoint )
  286. 		{
  287. 			string[] line;
  288. 			if ( stereo )
  289. 			{
  290. 				line = new string[] { endpoint.Index.ToString( ), ( endpoint.InOut == DataFlow.Capture ? "IN" : "OUT" ), endpoint.Name, endpoint.State.ToString( ), endpoint.ID, endpoint.GetVolume( ), endpoint.GetPeakLevel( 0 ), endpoint.GetPeakLevel( 1 ) };
  291. 			}
  292. 			else
  293. 			{
  294. 				line = new string[] { endpoint.Index.ToString( ), ( endpoint.InOut == DataFlow.Capture ? "IN" : "OUT" ), endpoint.Name, endpoint.State.ToString( ), endpoint.ID, endpoint.GetVolume( ), endpoint.GetPeakLevel( -1 ) };
  295. 			}
  296. 			int row;
  297. 			if ( endpoint.Index < datagrid.Rows.Count - 1 )
  298. 			{
  299. 				row = endpoint.Index;
  300. 				datagrid.Rows[row].SetValues( line );
  301. 			}
  302. 			else
  303. 			{
  304. 				row = datagrid.Rows.Count - 1;
  305. 				datagrid.Rows.Add( line );
  306. 			}
  307. 			if ( bgcolors )
  308. 			{
  309. 				datagrid.Rows[row].DefaultCellStyle.BackColor = backgroundcolors[endpoint.State];
  310. 			}
  311. 			if ( fgcolors )
  312. 			{
  313. 				datagrid.Rows[row].DefaultCellStyle.ForeColor = foregroundcolors[endpoint.State];
  314. 			}
  315. 		}
  316.  
  317.  
  318. 		private static void PrintDataGrid( )
  319. 		{
  320. 			string printout = Path.GetTempFileName( );
  321. 			SaveDataGrid( printout );
  322. 			ProcessStartInfo psi = new ProcessStartInfo
  323. 			{
  324. 				UseShellExecute = false,
  325. 				Arguments = string.Format( "/p \"{0}\"", printout ),
  326. 				FileName = "notepad.exe"
  327. 			};
  328. 			Process proc = Process.Start( psi );
  329. 			proc.WaitForExit( );
  330. 			File.Delete( printout );
  331. 		}
  332.  
  333.  
  334. 		private static void RefreshDataGrid( )
  335. 		{
  336. 			PopulateDataGrid( );
  337. 		}
  338.  
  339.  
  340. 		private static void RestartRecorder( )
  341. 		{
  342. 			string message;
  343. 			try
  344. 			{
  345. 				recorder.StartRecording( );
  346. 				norecordingdevice = false;
  347. 				message = "Monitoring input levels" + new string( ' ', 30 );
  348. 				Console.SetCursorPosition( 0, Console.CursorTop );
  349. 				Console.ForegroundColor = ConsoleColor.Green;
  350. 				Console.Write( message );
  351. 				Console.ResetColor( );
  352. 			}
  353. 			catch ( MmException )
  354. 			{
  355. 				norecordingdevice = true;
  356. 				message = "Unable to monitor input levels" + new string( ' ', 30 );
  357. 				Console.SetCursorPosition( 0, Console.CursorTop );
  358. 				Console.ForegroundColor = ConsoleColor.Red;
  359. 				Console.Error.Write( message );
  360. 				Console.ResetColor( );
  361. 			}
  362. 			form.Text = titletext + " \u00A0?\u00A0 \u00A0 " + message.Trim( );
  363. 		}
  364.  
  365.  
  366. 		private static void SaveDataGrid( string outfile )
  367. 		{
  368. 			// line out colums
  369. 			int[] cw;
  370. 			if ( stereo )
  371. 			{
  372. 				cw = new int[] { 5, 6, 0, 0, 0, 6, 6, 6 };
  373. 			}
  374. 			else
  375. 			{
  376. 				cw = new int[] { 5, 6, 0, 0, 0, 6, 4 };
  377. 			}
  378. 			for ( int i = 0; i < datagrid.Columns.Count; i++ )
  379. 			{
  380. 				for ( int j = 0; j < datagrid.Rows.Count; j++ )
  381. 				{
  382. 					if ( datagrid.Rows[j].Cells[i].Value != null && datagrid.Rows[j].Cells[i].Value.ToString( ).Length > cw[i] )
  383. 					{
  384. 						cw[i] = datagrid.Rows[j].Cells[i].Value.ToString( ).Length;
  385. 					}
  386. 				}
  387. 			}
  388.  
  389. 			// format printout
  390. 			List<string> lines = new List<string>( );
  391. 			string linetemplate;
  392. 			if ( stereo )
  393. 			{
  394. 				linetemplate = "{0,-" + cw[0] + "}    {1,-" + cw[1] + "}    {2,-" + cw[2] + "}    {3,-" + cw[3] + "}    {4,-" + cw[4] + "}    {5," + cw[5] + "}    {6," + cw[6] + "}    {7," + cw[7] + "}";
  395. 			}
  396. 			else
  397. 			{
  398. 				linetemplate = "{0,-" + cw[0] + "}    {1,-" + cw[1] + "}    {2,-" + cw[2] + "}    {3,-" + cw[3] + "}    {4,-" + cw[4] + "}    {5," + cw[5] + "}    {6," + cw[6] + "}";
  399. 			}
  400. 			// header
  401. 			var cols = datagrid.Columns;
  402. 			string headerline;
  403. 			if ( stereo )
  404. 			{
  405. 				headerline = string.Format( linetemplate, cols[0].HeaderText, cols[1].HeaderText.Replace( "\u00A0", "" ), cols[2].HeaderText, cols[3].HeaderText, cols[4].HeaderText, cols[5].HeaderText, cols[6].HeaderText, cols[7].HeaderText );
  406. 			}
  407. 			else
  408. 			{
  409. 				headerline = string.Format( linetemplate, cols[0].HeaderText, cols[1].HeaderText.Replace( "\u00A0", "" ), cols[2].HeaderText, cols[3].HeaderText, cols[4].HeaderText, cols[5].HeaderText, cols[6].HeaderText );
  410. 			}
  411. 			lines.Add( headerline );
  412. 			// rows
  413. 			for ( int i = 0; i < datagrid.Rows.Count; i++ )
  414. 			{
  415. 				var cells = datagrid.Rows[i].Cells;
  416. 				string line;
  417. 				if ( stereo )
  418. 				{
  419. 					line = string.Format( linetemplate, cells[0].Value, cells[1].Value, cells[2].Value, cells[3].Value, cells[4].Value, cells[5].Value, cells[6].Value, cells[7].Value );
  420.  
  421. 				}
  422. 				else
  423. 				{
  424. 					line = string.Format( linetemplate, cells[0].Value, cells[1].Value, cells[2].Value, cells[3].Value, cells[4].Value, cells[5].Value, cells[6].Value );
  425. 				}
  426. 				lines.Add( line );
  427. 			}
  428.  
  429. 			using ( StreamWriter print = new StreamWriter( outfile ) )
  430. 			{
  431. 				for ( int i = 0; i < lines.Count; i++ )
  432. 				{
  433. 					print.WriteLine( lines[i] );
  434. 				}
  435. 			}
  436. 		}
  437.  
  438.  
  439. 		private static void SetupDataGrid( )
  440. 		{
  441. 			datagrid = new DataGridView
  442. 			{
  443. 				Location = new Point( 0, 0 ),
  444. 				Size = new Size( 1200, 250 ),
  445. 				AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders,
  446. 				ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single,
  447. 				CellBorderStyle = DataGridViewCellBorderStyle.Single,
  448. 				GridColor = Color.Black,
  449. 				RowHeadersVisible = false,
  450. 				SelectionMode = DataGridViewSelectionMode.FullRowSelect,
  451. 				MultiSelect = false,
  452. 				Dock = DockStyle.Fill
  453. 			};
  454. 			if ( stereo )
  455. 			{
  456. 				datagrid.ColumnCount = 8;
  457. 			}
  458. 			else
  459. 			{
  460. 				datagrid.ColumnCount = 7;
  461. 				form.Width -= 85;
  462. 			}
  463. 			datagrid.ColumnHeadersDefaultCellStyle.BackColor = Color.Navy;
  464. 			datagrid.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
  465. 			datagrid.ColumnHeadersDefaultCellStyle.Font = new Font( FontFamily.GenericSansSerif, 12, FontStyle.Bold );
  466. 			datagrid.Columns[0].Name = "Index";
  467. 			datagrid.Columns[1].Name = "In\u00A0/\u00A0Out";
  468. 			datagrid.Columns[2].Name = "Name";
  469. 			datagrid.Columns[3].Name = "Status";
  470. 			datagrid.Columns[4].Name = "ID";
  471. 			datagrid.Columns[5].Name = "Volume";
  472. 			datagrid.Columns[5].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
  473. 			if ( stereo )
  474. 			{
  475. 				datagrid.Columns[6].Name = "Peak\u00A0L";
  476. 				datagrid.Columns[6].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
  477. 				datagrid.Columns[7].Name = "Peak\u00A0R";
  478. 				datagrid.Columns[7].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
  479. 			}
  480. 			else
  481. 			{
  482. 				datagrid.Columns[6].Name = "Peak";
  483. 				datagrid.Columns[6].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
  484. 			}
  485. 			datagrid.KeyUp += Datagrid_KeyUp;
  486. 			datagrid.SortCompare += Datagrid_SortCompare;
  487.  
  488. 			form.Controls.Add( datagrid );
  489. 			datagrid.Focus( );
  490. 		}
  491.  
  492.  
  493. 		private static int ShowHelp( bool cli = false )
  494. 		{
  495. 			string message = string.Format( "\nAudioEndPoints.exe,  Version {0}\n", progver );
  496. 			message += "List the local computer's audio endpoints\n\n";
  497. 			message += "Usage:\tAudioEndPoints.exe\t[ options ]\n\n";
  498. 			message += "Options:\t            \t/?     \tdisplay this help text and exit\n";
  499. 			message += "        \t            \t/F     \tuse status dependent\n";
  500. 			message += "        \t            \t       \tFOREGROUND colors,\n";
  501. 			message += "        \t            \t/B     \tuse BLACK and WHITE,\n";
  502. 			message += "        \t            \t       \tdefault is status dependent\n";
  503. 			message += "        \t            \t       \tBACKGROUND colors\n";
  504. 			message += "        \t            \t/M     \tpeak levels for L and R combined,\n";
  505. 			message += "        \t            \t       \tdefault is separate peak levels\n";
  506. 			message += "        \t            \t/R[:nn]\trefresh values every nn seconds,\n";
  507. 			message += "        \t            \t       \tdefault interval is 1 second\n";
  508. 			message += "        \t            \t/S     \tStatus information in title bar too\n";
  509. 			message += "        \t            \t       \t(default: show in console only)\n";
  510. 			message += "        \t            \t/T     \tkeep window always on Top\n\n";
  511. 			message += "Click on ANY column header to sort the table by that column.\n";
  512. 			message += "Note that the table's sort order will be reset to its default at\n";
  513. 			message += "every refresh, be it by pressing F5 or by specifying a refresh\n";
  514. 			message += "interval with the /R command line switch.\n";
  515. 			message += "You can edit all cells, if you like.\n\n";
  516. 			message += "Keys:   \tCtrl+C will copy the SELECTED LINE to the clipboard,\n";
  517. 			message += "        \tCtrl+P will print the list,\n";
  518. 			message += "        \tCtrl+S will save it in a text file,\n";
  519. 			message += "        \tF1 will show this help text,\n";
  520. 			message += "        \tF5 will refresh volume and peak level values,\n";
  521. 			message += "        \tEscape will abort the program.\n\n";
  522. 			message += "Credits:\tTo access audio endpoints, this program uses\n";
  523. 			message += "        \tNAudio created by Mark Heath:\n";
  524. 			message += "        \thttps://github.com/naudio/NAudio\n";
  525. 			message += "        \tVolume reading based on code by Mike de Klerk:\n";
  526. 			message += "        \thttps://stackoverflow.com/a/12534584\n\n";
  527. 			message += "Written by Rob van der Woude\n";
  528. 			message += "https://www.robvanderwoude.com\n";
  529.  
  530. 			if ( cli )
  531. 			{
  532. 				Console.Error.WriteLine( message );
  533. 			}
  534. 			else
  535. 			{
  536. 				helprequested = true;
  537. 				MessageBox.Show( message, "AudioEndPoints.exe, \u00A0 Version " + progver );
  538. 			}
  539. 			return -1;
  540. 		}
  541.  
  542.  
  543. 		// Tip to keep window on top by clamum on StackOverflow.com
  544. 		// https://stackoverflow.com/a/34703664
  545. 		[DllImport( "user32.dll" )]
  546. 		[return: MarshalAs( UnmanagedType.Bool )]
  547. 		public static extern bool SetWindowPos( IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags );
  548. 	}
  549.  
  550.  
  551. 	public class AudioEndPoint
  552. 	{
  553. 		public int Index
  554. 		{
  555. 			get; set;
  556. 		}
  557.  
  558. 		public DataFlow InOut
  559. 		{
  560. 			get; set;
  561. 		}
  562.  
  563. 		public string Name
  564. 		{
  565. 			get; set;
  566. 		}
  567.  
  568. 		public DeviceState State
  569. 		{
  570. 			get; set;
  571. 		}
  572.  
  573. 		public string ID
  574. 		{
  575. 			get; set;
  576. 		}
  577.  
  578. 		public float MasterVolumeLevelScalar
  579. 		{
  580. 			get; set;
  581. 		}
  582.  
  583. 		public float MasterPeakValue
  584. 		{
  585. 			get; set;
  586. 		}
  587.  
  588. 		public AudioMeterInformationChannels PeakValues
  589. 		{
  590. 			get; set;
  591. 		}
  592.  
  593. 		public string GetVolume( )
  594. 		{
  595. 			if ( State == DeviceState.Active )
  596. 			{
  597. 				return string.Format( "{0} %", (int) ( MasterVolumeLevelScalar * 100 ) );
  598. 			}
  599. 			else
  600. 			{
  601. 				return string.Empty;
  602. 			}
  603. 		}
  604.  
  605. 		public string GetPeakLevel( int channel = -1 )
  606. 		{
  607. 			if ( State == DeviceState.Active )
  608. 			{
  609. 				switch ( channel )
  610. 				{
  611. 					case 0:
  612. 						if ( PeakValues.Count > 0 )
  613. 						{
  614. 							return string.Format( "{0} %", (int) ( 100 * float.Parse( PeakValues[0].ToString( ) ) ) );
  615. 						}
  616. 						else
  617. 						{
  618. 							return string.Empty;
  619. 						}
  620. 					case 1:
  621. 						if ( PeakValues.Count > 1 )
  622. 						{
  623. 							return string.Format( "{0} %", (int) ( 100 * float.Parse( PeakValues[1].ToString( ) ) ) );
  624. 						}
  625. 						else
  626. 						{
  627. 							return string.Empty;
  628. 						}
  629. 					default:
  630. 						return string.Format( "{0} %", (int) ( 100 * MasterPeakValue ) );
  631. 				}
  632. 			}
  633. 			else
  634. 			{
  635. 				return string.Empty;
  636. 			}
  637. 		}
  638. 	}
  639. }

page last modified: 2025-10-11; loaded in 0.0116 seconds