HamBook – Blame information for rev 53

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