HamBook – Blame information for rev 54

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