From 40ca729b48f05f3ac4fa32b97dac8333b32c299c Mon Sep 17 00:00:00 2001 From: "J.D. Purcell" Date: Sun, 6 Sep 2015 17:13:31 -0400 Subject: [PATCH] Cleanup WaveformPaint. --- src/Controls/AudioVisualizer.cs | 223 ++++++++++++-------------------- 1 file changed, 80 insertions(+), 143 deletions(-) diff --git a/src/Controls/AudioVisualizer.cs b/src/Controls/AudioVisualizer.cs index d37e9221b..dedd0918e 100644 --- a/src/Controls/AudioVisualizer.cs +++ b/src/Controls/AudioVisualizer.cs @@ -126,7 +126,7 @@ namespace Nikse.SubtitleEdit.Controls else if (value > ZoomMaximum) _zoomFactor = ZoomMaximum; else - _zoomFactor = value; + _zoomFactor = (float)Math.Round(value, 2); // round to prevent accumulated rounding errors Invalidate(); } } @@ -416,7 +416,6 @@ namespace Nikse.SubtitleEdit.Controls var selectedParagraphs = new List(); if (_selectedIndices != null) { - var n = _wavePeaks.Header.SampleRate * _zoomFactor; try { foreach (int index in _selectedIndices) @@ -426,8 +425,8 @@ namespace Nikse.SubtitleEdit.Controls { p = new Paragraph(p); // not really frames... just using them as position markers for better performance - p.StartFrame = (int)(p.StartTime.TotalSeconds * n); - p.EndFrame = (int)(p.EndTime.TotalSeconds * n); + p.StartFrame = SecondsToXPositionNoZoom(p.StartTime.TotalSeconds); + p.EndFrame = SecondsToXPositionNoZoom(p.EndTime.TotalSeconds); selectedParagraphs.Add(p); } } @@ -436,20 +435,6 @@ namespace Nikse.SubtitleEdit.Controls { } } - //var otherParagraphs = new List(); - //var nOther = _wavePeaks.Header.SampleRate * _zoomFactor; - //try - //{ - // foreach (Paragraph p in _subtitle.Paragraphs) //int index in _selectedIndices) - // { - // var p2 = new Paragraph(p) { StartFrame = (int)(p.StartTime.TotalSeconds*nOther), EndFrame = (int)(p.EndTime.TotalSeconds*nOther) }; - // // not really frames... just using them as position markers for better performance - // otherParagraphs.Add(p2); - // } - //} - //catch - //{ - //} if (StartPositionSeconds < 0) StartPositionSeconds = 0; @@ -458,25 +443,10 @@ namespace Nikse.SubtitleEdit.Controls StartPositionSeconds = _wavePeaks.Header.LengthInSeconds - ((Width / (double)_wavePeaks.Header.SampleRate) / _zoomFactor); Graphics graphics = e.Graphics; - int begin = SecondsToXPosition(StartPositionSeconds); - var beginNoZoomFactor = (int)Math.Round(StartPositionSeconds * _wavePeaks.Header.SampleRate); // do not use zoom factor here! - int start = -1; - int end = -1; - if (_selectedParagraph != null) - { - start = SecondsToXPosition(_selectedParagraph.StartTime.TotalSeconds); - end = SecondsToXPosition(_selectedParagraph.EndTime.TotalSeconds); - } int imageHeight = Height; - var maxHeight = (int)(Math.Max(Math.Abs(_wavePeaks.DataMinValue), Math.Abs(_wavePeaks.DataMaxValue)) + 0.5); - maxHeight = (int)(maxHeight * VerticalZoomPercent); - if (maxHeight < 0) - maxHeight = 1000; DrawBackground(graphics); - int x = 0; - int y = Height / 2; if (IsSpectrogramAvailable && ShowSpectrogram) { @@ -485,131 +455,94 @@ namespace Nikse.SubtitleEdit.Controls imageHeight -= SpectrogramDisplayHeight; } - // using (var penOther = new Pen(ParagraphColor)) - using (var penNormal = new Pen(Color)) - using (var penSelected = new Pen(SelectedColor)) // selected paragraph + // waveform + if (ShowWaveform) { - var pen = penNormal; - int lastCurrentEnd = -1; - // int lastOtherCurrentEnd = -1; - - if (ShowWaveform) + using (var penNormal = new Pen(Color)) + using (var penSelected = new Pen(SelectedColor)) // selected paragraph { - if (_zoomFactor > 0.9999 && ZoomFactor < 1.00001) + var pen = penNormal; + int maxHeight = (int)(Math.Max(Math.Abs(_wavePeaks.DataMinValue), Math.Abs(_wavePeaks.DataMaxValue)) * VerticalZoomPercent); + int start = SecondsToXPositionNoZoom(StartPositionSeconds); + int selectionStart = _selectedParagraph != null ? SecondsToXPositionNoZoom(_selectedParagraph.StartTime.TotalSeconds) : -1; + int selectionEnd = _selectedParagraph != null ? SecondsToXPositionNoZoom(_selectedParagraph.EndTime.TotalSeconds) : -1; + int lastCurrentEnd = -1; + float xPrev = 0; + int yPrev = Height / 2; + float x = 0; + int y; + for (int i = 0; i < _wavePeaks.AllSamples.Count - start && x < Width; i++) { - for (int i = 0; i < _wavePeaks.AllSamples.Count && i < Width; i++) - { - int n = begin + i; - if (n < _wavePeaks.AllSamples.Count) - { - int newY = CalculateHeight(_wavePeaks.AllSamples[n], imageHeight, maxHeight); - //for (int tempX = x; tempX <= i; tempX++) - // graphics.DrawLine(pen, tempX, y, tempX, newY); - graphics.DrawLine(pen, x, y, i, newY); - //graphics.FillRectangle(new SolidBrush(Color), x, y, 1, 1); // draw pixel instead of line - - x = i; - y = newY; - if (n <= end && n >= start) - pen = penSelected; - else if (IsSelectedIndex(n, ref lastCurrentEnd, selectedParagraphs)) - pen = penSelected; - //else if (IsSelectedIndex(n, ref lastOtherCurrentEnd, otherParagraphs)) - // pen = penOther; - else - pen = penNormal; - } - } + int n = start + i; + x = (float)(_zoomFactor * i); + y = CalculateHeight(_wavePeaks.AllSamples[n], imageHeight, maxHeight); + graphics.DrawLine(pen, xPrev, yPrev, x, y); + xPrev = x; + yPrev = y; + bool isSelected = (n >= selectionStart && n <= selectionEnd) || + IsSelectedIndex(n, ref lastCurrentEnd, selectedParagraphs); + pen = isSelected ? penSelected : penNormal; } - else + } + } + + // time line + DrawTimeLine(StartPositionSeconds, e, imageHeight); + + // scene changes + if (_sceneChanges != null) + { + foreach (double time in _sceneChanges) + { + int pos = SecondsToXPosition(time - StartPositionSeconds); + if (pos > 0 && pos < Width) { - // calculate lines with zoom factor - float x2 = 0; - float x3 = 0; - for (int i = 0; i < _wavePeaks.AllSamples.Count && ((int)Math.Round(x3)) < Width; i++) + using (var p = new Pen(Color.AntiqueWhite)) { - if (beginNoZoomFactor + i < _wavePeaks.AllSamples.Count) - { - int newY = CalculateHeight(_wavePeaks.AllSamples[beginNoZoomFactor + i], imageHeight, maxHeight); - x3 = (float)(_zoomFactor * i); - graphics.DrawLine(pen, x2, y, x3, newY); - x2 = x3; - y = newY; - var n = (int)(begin + x3); - if (n <= end && n >= start) - pen = penSelected; - else if (IsSelectedIndex(n, ref lastCurrentEnd, selectedParagraphs)) - pen = penSelected; - //else if (IsSelectedIndex(n, ref lastOtherCurrentEnd, otherParagraphs)) - // pen = penOther; - else - pen = penNormal; - } + graphics.DrawLine(p, pos, 0, pos, Height); } } } - DrawTimeLine(StartPositionSeconds, e, imageHeight); + } - // scene changes - if (_sceneChanges != null) + // current video position + if (_currentVideoPositionSeconds > 0) + { + int pos = SecondsToXPosition(_currentVideoPositionSeconds - StartPositionSeconds); + if (pos > 0 && pos < Width) { - foreach (var d in _sceneChanges) + using (var p = new Pen(Color.Turquoise)) { - if (d > StartPositionSeconds && d < StartPositionSeconds + 20) - { - int pos = SecondsToXPosition(d) - begin; - if (pos > 0 && pos < Width) - { - using (var p = new Pen(Color.AntiqueWhite)) - { - graphics.DrawLine(p, pos, 0, pos, Height); - } - } - } + graphics.DrawLine(p, pos, 0, pos, Height); } } + } - // current video position - if (_currentVideoPositionSeconds > 0) + // paragraphs + using (var textBrush = new SolidBrush(TextColor)) + { + DrawParagraph(_currentParagraph, e, textBrush); + foreach (Paragraph p in _previousAndNextParagraphs) + DrawParagraph(p, e, textBrush); + } + + // current selection + if (NewSelectionParagraph != null) + { + int currentRegionLeft = SecondsToXPosition(NewSelectionParagraph.StartTime.TotalSeconds - StartPositionSeconds); + int currentRegionRight = SecondsToXPosition(NewSelectionParagraph.EndTime.TotalSeconds - StartPositionSeconds); + int currentRegionWidth = currentRegionRight - currentRegionLeft; + using (var brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255))) { - int videoPosition = SecondsToXPosition(_currentVideoPositionSeconds); - videoPosition -= begin; - if (videoPosition > 0 && videoPosition < Width) + if (currentRegionLeft >= 0 && currentRegionLeft <= Width) { - using (var p = new Pen(Color.Turquoise)) + graphics.FillRectangle(brush, currentRegionLeft, 0, currentRegionWidth, graphics.VisibleClipBounds.Height); + + if (currentRegionWidth > 40) { - graphics.DrawLine(p, videoPosition, 0, videoPosition, Height); - } - } - } - - // mark paragraphs - using (var textBrush = new SolidBrush(TextColor)) - { - DrawParagraph(_currentParagraph, e, begin, textBrush); - foreach (Paragraph p in _previousAndNextParagraphs) - DrawParagraph(p, e, begin, textBrush); - } - - // current selection - if (NewSelectionParagraph != null) - { - int currentRegionLeft = SecondsToXPosition(NewSelectionParagraph.StartTime.TotalSeconds - StartPositionSeconds); - int currentRegionRight = SecondsToXPosition(NewSelectionParagraph.EndTime.TotalSeconds - StartPositionSeconds); - - int currentRegionWidth = currentRegionRight - currentRegionLeft; - using (var brush = new SolidBrush(Color.FromArgb(128, 255, 255, 255))) - { - if (currentRegionLeft >= 0 && currentRegionLeft <= Width) - { - graphics.FillRectangle(brush, currentRegionLeft, 0, currentRegionWidth, graphics.VisibleClipBounds.Height); - - if (currentRegionWidth > 40) + using (var tBrush = new SolidBrush(Color.Turquoise)) { - using (var tBrush = new SolidBrush(Color.Turquoise)) - { - graphics.DrawString(string.Format("{0:0.###} {1}", ((double)currentRegionWidth / _wavePeaks.Header.SampleRate / _zoomFactor), Configuration.Settings.Language.Waveform.Seconds), Font, tBrush, new PointF(currentRegionLeft + 3, Height - 32)); - } + graphics.DrawString(string.Format("{0:0.###} {1}", ((double)currentRegionWidth / _wavePeaks.Header.SampleRate / _zoomFactor), Configuration.Settings.Language.Waveform.Seconds), Font, tBrush, new PointF(currentRegionLeft + 3, Height - 32)); } } } @@ -624,7 +557,6 @@ namespace Nikse.SubtitleEdit.Controls { using (var textFont = new Font(Font.FontFamily, 8)) { - if (Width > 90) { e.Graphics.DrawString(WaveformNotLoadedText, textFont, textBrush, new PointF(Width / 2 - 65, Height / 2 - 10)); @@ -729,15 +661,15 @@ namespace Nikse.SubtitleEdit.Controls return string.Format("{0:00}:{1:00}:{2:00}", ts.Hours, ts.Minutes, ts.Seconds); } - private void DrawParagraph(Paragraph paragraph, PaintEventArgs e, int begin, SolidBrush textBrush) + private void DrawParagraph(Paragraph paragraph, PaintEventArgs e, SolidBrush textBrush) { if (paragraph == null) { return; } - int currentRegionLeft = SecondsToXPosition(paragraph.StartTime.TotalSeconds) - begin; - int currentRegionRight = SecondsToXPosition(paragraph.EndTime.TotalSeconds) - begin; + int currentRegionLeft = SecondsToXPosition(paragraph.StartTime.TotalSeconds - StartPositionSeconds); + int currentRegionRight = SecondsToXPosition(paragraph.EndTime.TotalSeconds - StartPositionSeconds); int currentRegionWidth = currentRegionRight - currentRegionLeft; var drawingStyle = TextBold ? FontStyle.Bold : FontStyle.Regular; using (var brush = new SolidBrush(Color.FromArgb(42, 255, 255, 255))) // back color for paragraphs @@ -831,6 +763,11 @@ namespace Nikse.SubtitleEdit.Controls return (int)Math.Round(seconds * _wavePeaks.Header.SampleRate * _zoomFactor); } + private int SecondsToXPositionNoZoom(double seconds) + { + return (int)Math.Round(seconds * _wavePeaks.Header.SampleRate); + } + private void WaveformMouseDown(object sender, MouseEventArgs e) { if (_wavePeaks == null)