private void timerUpdateSpectrogram_Tick(object sender, EventArgs e) { if (spec is null) { return; } // capture new FFTs and note their indexes int fftsBefore = spec.FftsProcessed; spec.Add(audioControl1.listener.GetNewAudio()); int fftsAfter = spec.FftsProcessed; int newFftCount = fftsAfter - fftsBefore; int[] newFftIndexes = Enumerable.Range(spec.Width - newFftCount - 1, newFftCount).ToArray(); var ffts = spec.GetFFTs(); // optionally apply some sort of filter or AGC if (settings.agcMode == 1) { foreach (int fftIndex in newFftIndexes) { ffts[fftIndex] = AGC.Method1_SortedFloorMean(ffts[fftIndex], power: settings.agcPower); } } else if (settings.agcMode == 2) { foreach (int fftIndex in newFftIndexes) { ffts[fftIndex] = AGC.Method2_QuicksortFloor(ffts[fftIndex], power: settings.agcPower); } } // display the annotated spectrogram var spotsToShow = spots.Where(x => x.ageSec < (11 * 60)).ToList(); Annotate.Spectrogram(spec, band, spotsToShow, bmpSpectrogram, bmpVericalScale, cbBands.Checked, true, settings); pictureBox1.Refresh(); GC.Collect(); }
private void SaveGrab(bool uploadToo = false) { int pxTop = spec.PixelY(band.upperFreq - band.dialFreq, settings.verticalReduction) - settings.grabSavePxAbove; int pxBot = spec.PixelY(band.lowerFreq - 200 - band.dialFreq, settings.verticalReduction) + settings.grabSavePxBelow; int height = pxBot - pxTop; int widthWithScale = spec.Width + verticalScaleWidth; using (Bitmap bmpFull = new Bitmap(widthWithScale, spec.Height, PixelFormat.Format32bppPArgb)) using (Bitmap bmpCropped = new Bitmap(widthWithScale, height, PixelFormat.Format32bppPArgb)) using (Graphics gfx = Graphics.FromImage(bmpCropped)) { // annotate a full-size spectrogram var spotsToShow = spots.Where(x => x.ageSec < (11 * 60)).ToList(); Annotate.Spectrogram(spec, band, spotsToShow, bmpFull, bmpVericalScale, false, false, settings); // draw the full-size spectrogram on the cropped Bitmap gfx.DrawImage(bmpFull, 0, -pxTop); // decorate the cropped bitmap string msg = $"FSKview {version.Major}.{version.Minor}.{version.Build}: " + $"{settings.stationInformation} {UtcDateStamp} {UtcTimeStampNoSec} UTC"; Annotate.Logo(gfx, msg, 3, height - 3); Annotate.TimeTicks(gfx, height, spec.SecPerPx); // ensure output folders exist string pathSaveWeb = $"{appPath}/grabs-web"; string pathSaveAll = $"{appPath}/grabs-all"; if (!Directory.Exists(pathSaveWeb)) { Directory.CreateDirectory(pathSaveWeb); } if (!Directory.Exists(pathSaveAll)) { Directory.CreateDirectory(pathSaveAll); } // save the cropped image for the web ImageFormat imgFmt = ImageFormat.Bmp; if (settings.grabFileName.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { imgFmt = ImageFormat.Png; } else if (settings.grabFileName.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) { imgFmt = ImageFormat.Jpeg; } else if (settings.grabFileName.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) { imgFmt = ImageFormat.Gif; } bmpCropped.Save($"{pathSaveWeb}/{settings.grabFileName}", imgFmt); // save the cropped bitmap for stitching string stitchFileName = $"{pathSaveAll}/{UtcDateStamp.Replace("-", "")}-{UtcTimeStamp.Replace(":", "")}.png"; if (settings.showScaleOnAllGrabs) { bmpCropped.Save(stitchFileName, ImageFormat.Png); } else { using (Bitmap bmpCropped2 = new Bitmap(spec.Width, height, PixelFormat.Format32bppPArgb)) using (Graphics gfx2 = Graphics.FromImage(bmpCropped2)) { gfx2.DrawImage(bmpCropped, 0, 0); bmpCropped2.Save(stitchFileName, ImageFormat.Png); } } Status($"Saved spectrogram as {settings.grabFileName}"); if (uploadToo) { Enabled = false; Status($"Performing FTP upload..."); Application.DoEvents(); string result = FTP.Upload(settings.ftpServerAddress, settings.ftpRemoteSubfolder, settings.ftpUsername, settings.DeObfuscate(settings.ftpObfuscatedPassword), $"{pathSaveWeb}/{settings.grabFileName}"); if (result.Contains("Not logged in")) { result = "Incorrect username/password"; } else if (result.Contains("File name not allowed")) { result = "Invalid path (does the target folder exist?)"; } else if (result == "upload successful") { result = "FTP upload successful"; } else { result = "FTP ERROR (get full message in settings)\n" + result; } Status(result); Enabled = true; } } }