HamBook – Blame information for rev 10

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