HamBook – Blame information for rev 15

Subversion Repositories:
Rev:
Rev Author Line No. Line
10 office 1 using Configuration;
2 using FftSharp;
3 using HamBook.Utilities;
4 using NAudio.Utils;
5 using NAudio.Wave;
6 using Org.BouncyCastle.Math.EC.Multiplier;
7 using Spectrogram;
8 using System;
9 using System.Collections.Generic;
10 using System.ComponentModel;
11 using System.Data;
12 using System.Drawing;
13 using System.IO;
14 using System.Linq;
15 using System.Runtime.InteropServices;
16 using System.Text;
17 using System.Threading;
18 using System.Threading.Tasks;
19 using System.Windows.Forms;
14 office 20 using static System.Windows.Forms.VisualStyles.VisualStyleElement;
10 office 21  
22 namespace HamBook
23 {
24 public partial class SpectrogramForm : Form
25 {
26 #region Natives
27 [DllImport("user32.dll")]
28 private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
29  
30 private static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
31 private static readonly IntPtr HWND_TOP = new IntPtr(0);
32 private const UInt32 SWP_NOSIZE = 0x0001;
33 private const UInt32 SWP_NOMOVE = 0x0002;
34 private const UInt32 SWP_NOACTIVATE = 0x0010;
35  
36 #endregion
37  
15 office 38 private Configuration.Configuration Configuration { get; set; }
10 office 39 private CancellationToken _cancellationToken;
40 SpectrogramGenerator _spectrogramGenerator;
41 private WaveIn _waveIn;
42 private CancellationTokenSource _renderCancellationTokenSource;
43 private CancellationToken _renderCancellationToken;
44 private ScheduledContinuation _windowZOrderScheduledContinuation;
45 private volatile bool _mouseDown;
46 private Point _formLocation;
47  
48 public SpectrogramForm()
49 {
50 InitializeComponent();
51  
52 _renderCancellationTokenSource = new CancellationTokenSource();
53 _renderCancellationToken = _renderCancellationTokenSource.Token;
54 _windowZOrderScheduledContinuation = new ScheduledContinuation();
55  
56 }
57  
58 public SpectrogramForm(Configuration.Configuration configuration, CancellationToken cancellationToken) : this()
59 {
15 office 60 Configuration = configuration;
10 office 61 _cancellationToken = cancellationToken;
14 office 62  
15 office 63 _spectrogramGenerator = new SpectrogramGenerator(Configuration.Visualisations.Spectrogram.SampleRate, fftSize: Configuration.Visualisations.Spectrogram.FFTSamples, stepSize: Configuration.Visualisations.Spectrogram.FFTSamples / Configuration.Visualisations.Spectrogram.AudioBufferTimespan);
14 office 64 _spectrogramGenerator.Colormap = Colormap.Viridis;
65  
66 pictureBox2.Image = _spectrogramGenerator.GetVerticalScale(pictureBox2.Width);
10 office 67 }
68  
69 /// <summary>
70 /// Clean up any resources being used.
71 /// </summary>
72 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
73 protected override void Dispose(bool disposing)
74 {
75 if (disposing && (components != null))
76 {
77 if(_waveIn != null)
78 {
79 if (_renderCancellationTokenSource != null)
80 {
81 _renderCancellationTokenSource.Cancel();
82 }
83  
84 _waveIn.DataAvailable -= _waveIn_DataAvailable;
85 _waveIn.StopRecording();
86 _waveIn.Dispose();
87 _waveIn = null;
88 }
89  
90 components.Dispose();
91 }
92 base.Dispose(disposing);
93 }
94  
95 private void SpectrogramForm_Load(object sender, EventArgs e)
96 {
15 office 97 pinToDesktopToolStripMenuItem.Checked = Configuration.Visualisations.Spectrogram.PinToDesktop;
14 office 98  
15 office 99 if (Configuration.Visualisations.Spectrogram.PinToDesktop)
10 office 100 {
14 office 101 _windowZOrderScheduledContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
10 office 102 {
14 office 103 this.InvokeIfRequired(form =>
104 {
105 SetWindowPos(Handle, HWND_BOTTOM, 0, 0, Location.X, Location.Y, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
106 });
107 }, _renderCancellationToken);
108 }
10 office 109  
110 foreach (var deviceNumber in Enumerable.Range(0, WaveIn.DeviceCount))
111 {
112 var capabilities = WaveIn.GetCapabilities(deviceNumber);
15 office 113 if(!string.Equals(capabilities.ProductName, Configuration.Audio.InputDeviceFriendlyName))
10 office 114 {
115 continue;
116 }
117  
118 _waveIn = new WaveIn();
119 _waveIn.DeviceNumber = deviceNumber;
15 office 120 _waveIn.BufferMilliseconds = Configuration.Visualisations.Spectrogram.AudioBufferTimespan;
10 office 121  
122 _waveIn.DataAvailable += _waveIn_DataAvailable;
123 _waveIn.StartRecording();
124 break;
125 }
126 }
127  
128 private void _waveIn_DataAvailable(object sender, WaveInEventArgs e)
129 {
130 int bytesPerSample = _waveIn.WaveFormat.BitsPerSample / 8;
131 int newSampleCount = e.BytesRecorded / bytesPerSample;
132 double[] buffer = new double[newSampleCount];
133 double peak = 0;
134 for (int i = 0; i < newSampleCount; i++)
135 {
136 buffer[i] = BitConverter.ToInt16(e.Buffer, i * bytesPerSample);
137 peak = Math.Max(peak, buffer[i]);
138 }
139  
140 var AmplitudeFrac = peak / (1 << 15);
141  
142 _spectrogramGenerator.Add(buffer, false);
143 }
144  
145 private void timer1_Tick(object sender, EventArgs e)
146 {
147 if(_spectrogramGenerator.FftsToProcess == 0)
148 {
149 return;
150 }
151  
152 _spectrogramGenerator.Process();
153 _spectrogramGenerator.SetFixedWidth(pictureBox1.Width);
154 var bmpSpec = new Bitmap(_spectrogramGenerator.Width, _spectrogramGenerator.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
15 office 155 using (var bmpSpecIndexed = _spectrogramGenerator.GetBitmap(Configuration.Visualisations.Spectrogram.SpectrumIntensity))
10 office 156 using (var gfx = Graphics.FromImage(bmpSpec))
157 using (var pen = new Pen(Color.White))
158 {
159 gfx.DrawImage(bmpSpecIndexed, 0, 0);
160 if (false)
161 {
162 //gfx.DrawLine(pen, spec.NextColumnIndex, 0, spec.NextColumnIndex, pbSpectrogram.Height);
163 }
164 }
165  
166 pictureBox1.Image?.Dispose();
167 pictureBox1.Image = bmpSpec;
168 }
169  
170 private void SpectrogramForm_MouseClick(object sender, MouseEventArgs e)
171 {
172 switch(e.Button)
173 {
174 case MouseButtons.Right:
175 var control = (Control)sender;
176 var screenPoint = control.PointToScreen(e.Location);
177 contextMenuStrip1.Show(screenPoint);
178 break;
179 case MouseButtons.Left:
180 break;
181 }
182 }
183  
184 private void closeToolStripMenuItem_Click(object sender, EventArgs e)
185 {
186 Close();
187 }
188  
189 private void SpectrogramForm_MouseDown(object sender, MouseEventArgs e)
190 {
191 if(e.Button != MouseButtons.Left)
192 {
193 return;
194 }
195  
196 if(e.Clicks != 1)
197 {
198 return;
199 }
200  
201 _mouseDown = true;
202 _formLocation = new Point(e.X, e.Y);
203 }
204  
205 private void SpectrogramForm_MouseMove(object sender, MouseEventArgs e)
206 {
207 if (e.Button != MouseButtons.Left)
208 {
209 return;
210 }
211  
212 if (!_mouseDown)
213 {
214 return;
215 }
216  
217 var control = (Control)sender;
218 var screenPoint = control.PointToScreen(e.Location);
219  
220 Location = new Point(screenPoint.X - _formLocation.X, screenPoint.Y - _formLocation.Y);
221  
222 }
223  
224 private void SpectrogramForm_MouseUp(object sender, MouseEventArgs e)
225 {
226 if (e.Button != MouseButtons.Left)
227 {
228 return;
229 }
230  
231 _mouseDown = false;
232 }
233  
234 private void SpectrogramForm_Activated(object sender, EventArgs e)
235 {
236 // Make form bottom most.
237 //SetWindowPos(Handle, HWND_BOTTOM, 0, 0, Location.X, Location.Y, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
238 }
239  
240 private void SpectrogramForm_MouseEnter(object sender, EventArgs e)
241 {
15 office 242 if (Configuration.Visualisations.Spectrogram.PinToDesktop)
10 office 243 {
14 office 244 _windowZOrderScheduledContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
10 office 245 {
14 office 246 this.InvokeIfRequired(form =>
247 {
248 SetWindowPos(Handle, HWND_TOP, 0, 0, Location.X, Location.Y, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
249 });
250 }, _renderCancellationToken);
251 }
10 office 252 }
253  
254 private void SpectrogramForm_MouseLeave(object sender, EventArgs e)
255 {
15 office 256 if (Configuration.Visualisations.Spectrogram.PinToDesktop)
10 office 257 {
14 office 258 _windowZOrderScheduledContinuation.Schedule(TimeSpan.FromSeconds(1), () =>
10 office 259 {
14 office 260 this.InvokeIfRequired(form =>
261 {
262 SetWindowPos(form.Handle, HWND_BOTTOM, 0, 0, Location.X, Location.Y, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
263 });
264  
265 }, _renderCancellationToken);
266 }
10 office 267 }
14 office 268  
269 private void pinToDesktopToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
270 {
271 var toolStripMenuItem = (ToolStripMenuItem)sender;
272  
273 switch(toolStripMenuItem.CheckState)
274 {
275 case CheckState.Checked:
15 office 276 Configuration.Visualisations.Spectrogram.PinToDesktop = true;
14 office 277 break;
278 case CheckState.Unchecked:
15 office 279 Configuration.Visualisations.Spectrogram.PinToDesktop = false;
14 office 280 break;
281 }
282 }
10 office 283 }
284 }