/// <summary> /// 部分绘制-波形线密度改变 /// /// </summary> private void PartDraw_DrawDensityChanged() { //全部绘制 Graphics graphics = this._grafx.Graphics; //清空所有已绘制的图形 graphics.Clear(this.BackColor); WavePlotPara plotPara = this._plotPara; IEnumerable <ChannelPlotData> plotDatas = this._plotDatas; if (plotPara == null) { return; } //全局视图 this.DrawGlobalView(graphics, plotPara, plotDatas); this.AddPartRefreshArea(this._globalView); //波形图 this.DrawWaveSpecturum(graphics, plotPara, plotDatas); this.AddPartRefreshArea(this._content.Area); this.RefreshInvalidateArea(); }
/// <summary> /// 获取指定点所对应在UI中的区域 /// </summary> /// <param name="point">指定点</param> /// <param name="plotPara"></param> /// <param name="selectedInfo"></param> /// <returns>指定点所对应在UI中的区域</returns> internal UIArea GetUIArea(Point point, WavePlotPara plotPara, SelectedInfo selectedInfo) { if (this.Inner(point, this._globalView)) { if (plotPara != null) { double unitWidth = this._content.Area.Width / plotPara.DurationMillisecond; double sbx = unitWidth * plotPara.SBTOMillisecond; double sex = unitWidth * plotPara.GetSETOMillisecond(); if (point.X - sbx > PlotConstant.ZEROR_D && point.X - sex < PlotConstant.ZEROR_D) { return(UIArea.GlobalViewZoomDisplay); } } return(UIArea.GlobalView); } if (this.Inner(point, this._xAxis)) { return(UIArea.TimeArea); } if (this.Inner(point, this._content)) { return(UIArea.Wave); } return(UIArea.Other); }
private RectangleF?DrawWaveSpecturum(Graphics graphics, WavePlotPara plotPara, IEnumerable <ChannelPlotData> plotDatas) { PlotElementInfoAbs wave = this._content; if (wave == null) { return(null); } //填充主波形背景 if (wave.BackgroudColor != null) { graphics.FillRectangle(wave.BackgroudColor, wave.Area); } if (plotPara == null || plotDatas == null) { return(null); } double sbto = plotPara.SBTOMillisecond; //显示区域起始时间 double seto = plotPara.GetSETOMillisecond(); //显示区域结束时间 RectangleF?wavSelectedArea = this.GetSelectedAreaBackground(wave.Area, plotPara, sbto, seto); if (wavSelectedArea.HasValue) { //填充主波形选中背景 graphics.FillRectangle(this._seleactionAreaBrush, wavSelectedArea.Value); } //绘制波形图 this.DrawWaveDb(graphics, wave, plotPara, plotDatas, false); return(wavSelectedArea); }
/// <summary> /// 全部绘制 /// </summary> private void AllDraw() { if (this._grafx == null) { return; } //全部绘制 Graphics graphics = this._grafx.Graphics; ////重置平移 //graphics.ResetTransform(); //清空所有已绘制的图形 graphics.Clear(this.BackColor); WavePlotPara plotPara = this._plotPara; IEnumerable <ChannelPlotData> plotDatas = this._plotDatas; if (plotPara == null || plotDatas == null || (plotDatas != null && plotDatas.Count() == 0)) { return; } this.DrawGlobalView(graphics, plotPara, plotDatas); //绘制全局视图 this.DrawTimeAxis(graphics, plotPara); //绘制X轴 this.DrawWaveSpecturum(graphics, plotPara, plotDatas); //绘制波形图 this.DrawWaveSpecturumAxis(graphics, plotDatas); //绘制Y轴 this.RefreshInvalidateArea(); //刷新 }
//private void CalVoiceSpecturumArea(WavePlotPara plotPara, out int begeinIndex, out int endIndex) //{ // int frameCount = plotPara.FrameCount; // begeinIndex = (int)(frameCount * plotPara.SBTOMillisecond / plotPara.DurationMillisecond); // endIndex = (int)(frameCount * plotPara.GetSETOMillisecond() / plotPara.DurationMillisecond); // if (begeinIndex < 0) // { // int offset = Math.Abs(begeinIndex); // begeinIndex = 0; // endIndex += offset; // if (endIndex > frameCount) // { // endIndex = frameCount; // } // } // else // { // if (endIndex > frameCount) // { // begeinIndex = begeinIndex - (endIndex - frameCount); // endIndex = frameCount; // if (begeinIndex < 0) // { // begeinIndex = 0; // } // } // } //} private void CalWavSpecturumArea(WavePlotPara plotPara, out int begeinIndex, out int endIndex) { int sourceFFTDataLength = plotPara.SourcePcmDataLength; begeinIndex = (int)(sourceFFTDataLength * plotPara.SBTOMillisecond / plotPara.DurationMillisecond); endIndex = (int)(sourceFFTDataLength * plotPara.GetSETOMillisecond() / plotPara.DurationMillisecond); if (begeinIndex < 0) { int offset = Math.Abs(begeinIndex); begeinIndex = 0; endIndex += offset; if (endIndex > sourceFFTDataLength) { endIndex = sourceFFTDataLength; } } else { if (endIndex > sourceFFTDataLength) { begeinIndex = begeinIndex - (endIndex - sourceFFTDataLength); endIndex = sourceFFTDataLength; if (begeinIndex < 0) { begeinIndex = 0; } } } }
private void SizeChangedResample() { WavePlotPara plotPara = this._plotPara; if (plotPara == null) { return; } int globalViewFFTDataLength = 0; var fftDatas = this._plotDatas; if (fftDatas != null) { int targetCount = this.GetResamplePointCount(); foreach (ChannelPlotData channelFFTData in fftDatas) { if (channelFFTData.PCMData == null) { continue; } channelFFTData.GlobalViewData = channelFFTData.PrimitiveResample(targetCount, 0, channelFFTData.PCMData.Length); if (globalViewFFTDataLength == 0 || globalViewFFTDataLength < channelFFTData.GlobalViewData.Length) { globalViewFFTDataLength = channelFFTData.GlobalViewData.Length; } } } plotPara.GlobalViewPcmDataLength = globalViewFFTDataLength; }
private RectangleF?GetSelectedAreaBackground(RectangleF waveRectangle, WavePlotPara plotPara, double beginMillisecond, double endMillisecond) { if (this._selectedInfo == null) { return(null); } double sb = this._selectedInfo.BeginMillisecond; //选中区域起始时间 double se = this._selectedInfo.EndMillisecond; //选中区域结束时间 if (se - sb <= PlotConstant.ZEROR_D) { //至少选中,如果没有选中区域,则不需要绘制该区域背景 return(null); } /******************************************************************************************* * 选中与显示有以下五种场景,分别为ABCDE: * A B C D E * |+++++++| |+++++++++| |+++++++++| |+++++++++| |+++++++++| * |-----|-------|--|--|------|-----|---------|-------|---|-----|-----|---------| * |-------------------|----------------------------------|-----------------------| * 0 sbto seto end *******************************************************************************************/ if (se - beginMillisecond < PlotConstant.ZEROR_D || sb - endMillisecond > PlotConstant.ZEROR_D) { //场景A和E return(null); } float x1; if (sb - beginMillisecond < PlotConstant.ZEROR_D) { //场景B x1 = 0f; } else { //场景C或D x1 = waveRectangle.X + (float)((waveRectangle.Width / (endMillisecond - beginMillisecond)) * (sb - beginMillisecond)); } float x2; if (sb - endMillisecond > PlotConstant.ZEROR_D) { //场景D x2 = waveRectangle.X + waveRectangle.Width; } else { //场景A或B x2 = waveRectangle.X + (float)((waveRectangle.Width / (endMillisecond - beginMillisecond)) * (se - beginMillisecond)); } return(new RectangleF(x1, waveRectangle.Y, x2 - x1, waveRectangle.Height)); }
/// <summary> /// /// </summary> /// <param name="graphics"></param> /// <param name="wave"></param> /// <param name="plotPara"></param> /// <param name="pcmDatas"></param> /// <param name="dataType">true:GlobalViewData;alse:DrawData</param> private void DrawWave_A(Graphics graphics, PlotElementInfoAbs wave, WavePlotPara plotPara, IEnumerable <ChannelPlotData> pcmDatas, bool dataType) { PointF[] points; if (dataType) { points = new PointF[plotPara.GlobalViewPcmDataLength]; } else { points = new PointF[plotPara.DrawPcmDataLength]; } if (points.Length == 0) { return; } int channeCount = pcmDatas.Count(); float channelWaveAreaHeight = wave.Area.Height / channeCount; float channelWaveHalfHeight = channelWaveAreaHeight / 2; float separatorY = wave.Area.Y + channelWaveHalfHeight; float lx, y; bool drawSeparator = false; short[] pcmData; float xStep = this.CalXStep(points.Length); foreach (ChannelPlotData channelPlotData in pcmDatas) { if (drawSeparator) { graphics.DrawLine(this._channelSeparatorPen, 0f, separatorY, wave.Area.Width, separatorY); } if (dataType) { pcmData = channelPlotData.GlobalViewData; } else { pcmData = channelPlotData.DrawData; } lx = 0f; for (int i = 0; i < points.Length && i < pcmData.Length; i++) { y = separatorY - ((float)pcmData[i] / short.MaxValue) * channelWaveHalfHeight; points[i] = new PointF(lx, y); lx = lx + xStep; } graphics.DrawLines(wave.Pen, points); separatorY += channelWaveAreaHeight; drawSeparator = true; } }
private void Resample() { WavePlotPara plotPara = this._plotPara; if (plotPara == null) { return; } //计算重采样数据起始-结束索引 int wavBegeinIndex, wavEndIndex; this.CalWavSpecturumArea(plotPara, out wavBegeinIndex, out wavEndIndex); //int voiceBegeinIndex, voiceEndIndex; //this.CalVoiceSpecturumArea(plotPara, out voiceBegeinIndex, out voiceEndIndex); //重采样 int srcFFTDataLength = 0, drawFFTDataLength = 0; var fftDatas = this._plotDatas; if (fftDatas != null) { int resampleTargetCount = this.GetResamplePointCount(); foreach (ChannelPlotData channelFFTData in fftDatas) { if (channelFFTData.PCMData == null) { continue; } if (srcFFTDataLength == 0) { srcFFTDataLength = channelFFTData.PCMData.Length; } else { if (srcFFTDataLength != channelFFTData.PCMData.Length) { throw new ArgumentException("FFT数据长度不一致"); } } channelFFTData.Resample(resampleTargetCount, wavBegeinIndex, wavEndIndex); //channelFFTData.GlobalViewData = channelFFTData.DrawData; if (drawFFTDataLength < channelFFTData.DrawData.Length) { drawFFTDataLength = channelFFTData.DrawData.Length; } } } plotPara.DrawPcmDataLength = drawFFTDataLength; }
private void UpdatePlotPara(WavePlotPara plotPara) { double setoMillisecond = plotPara.GetSETOMillisecond(); double middle = plotPara.SBTOMillisecond + (setoMillisecond - plotPara.SBTOMillisecond) / 2; double showAreaMillisecond = plotPara.DurationMillisecond / this._zoomMultiple; double showAreaHalfMillisecond = showAreaMillisecond / 2; plotPara.SBTOMillisecond = middle - showAreaHalfMillisecond; plotPara.UpdateSETOMillisecond(middle + showAreaHalfMillisecond); }
/// <summary> /// 放大 /// </summary> /// <param name="plotPara"></param> /// <param name="minPointCount">图上最少点数</param> internal void ZoomIn(WavePlotPara plotPara, uint minPointCount = 5) { if (plotPara.SourcePcmDataLength / this._zoomMultiple <= minPointCount) { return; } this._zoomMultiple *= 2; this.UpdatePlotPara(plotPara); }
private void SelectedAreaChangeDraw(SelectedInfo oldSelectedInfo) { //全部绘制 Graphics graphics = this._grafx.Graphics; //重置平移 graphics.ResetTransform(); //清空所有已绘制的图形 //graphics.Clear(this.BackColor); WavePlotPara plotPara = this._plotPara; IEnumerable <ChannelPlotData> plotDatas = this._plotDatas; if (plotPara == null) { return; } if (oldSelectedInfo != null) { this.AddPartRefreshArea(oldSelectedInfo.LastGlobalViewSelectedArea); this.AddPartRefreshArea(oldSelectedInfo.LastWaveSelectedArea); } SelectedInfo selectedInfo = this._selectedInfo; RectangleF? selectedArea; //理论上选择区域改变,是不需要重新绘制时间的,但是在某种情况下,时间时间区域会消失,只好重绘,以后如果找到原因了,再删除这个case内的代码 this.DrawTimeAxis(graphics, plotPara); this.AddPartRefreshArea(this._xAxis); selectedArea = this.DrawGlobalView(graphics, plotPara, plotDatas); this.AddPartRefreshArea(selectedArea); if (selectedInfo != null) { selectedInfo.LastGlobalViewSelectedArea = selectedArea; } selectedArea = this.DrawWaveSpecturum(graphics, plotPara, plotDatas); this.AddPartRefreshArea(selectedArea); if (selectedInfo != null) { selectedInfo.LastWaveSelectedArea = selectedArea; } this.RefreshInvalidateArea(); }
/// <summary> /// 清除 /// </summary> public void Clear() { this._plotDatas = null; this._plotPara = null; //全部绘制 Graphics graphics = this._grafx.Graphics; //清空所有已绘制的图形 graphics.Clear(this.BackColor); this.RefreshInvalidateArea();//刷新 }
private RectangleF?DrawGlobalView(Graphics graphics, WavePlotPara plotPara, IEnumerable <ChannelPlotData> plotDatas) { GlobalViewPlotElementInfo globalView = this._globalView; if (globalView == null) { return(null); } //填充整体视图波形背景 if (globalView.BackgroudColor != null) { graphics.FillRectangle(globalView.BackgroudColor, globalView.Area); } if (plotDatas == null) { return(null); } //整体视图中缩放后显示区域 RectangleF?globalViewZoomArea = null; if (this._zoomInfo.HasZoom()) { float x1 = (float)(globalView.Area.Width * plotPara.SBTOMillisecond / plotPara.DurationMillisecond); float x2 = (float)(globalView.Area.Width * plotPara.GetSETOMillisecond() / plotPara.DurationMillisecond); globalViewZoomArea = new RectangleF(x1, globalView.Area.Y, x2 - x1, globalView.Area.Height); graphics.FillRectangle(globalView.GlobalViewZoomAreaBackBrush, globalViewZoomArea.Value); } RectangleF?wavSelectedArea = this.GetSelectedAreaBackground(globalView.Area, plotPara, PlotConstant.ZEROR_D, plotPara.DurationMillisecond); if (wavSelectedArea.HasValue) { //填充选中背景 graphics.FillRectangle(this._seleactionGlobalViewAreaBrush, wavSelectedArea.Value); } //绘制整体视图波形 this.DrawWaveDb(graphics, globalView, plotPara, plotDatas, true); if (globalViewZoomArea.HasValue) { this.DrawDisplayAreaStyle(globalView, graphics, globalViewZoomArea.Value); } return(wavSelectedArea); }
/// <summary> /// /// </summary> /// <param name="fftDatas"> /// 声道数据集合 /// 单声道:L /// 双声道:L-R /// 四声道:L-R-LS-RS /// 5.1声道FFT数据顺序: L-R-C-LFE-LS-RS /// 7.1声道FFT数据顺序: L-R-C-LFE-LS-RS-不晓得了 /// </param> /// <param name="plotPara">绘图参数</param> public void UpdateData(IEnumerable <ChannelPlotData> fftDatas, WavePlotPara plotPara) { if (plotPara == null) { throw new ArgumentNullException(nameof(plotPara)); } this._plotPara = plotPara; int srcPcmMaxDataLength = 0, drawPcmMaxDataLength = 0; if (fftDatas != null) { int targetCount = this.GetResamplePointCount(); foreach (ChannelPlotData channelFFTData in fftDatas) { if (channelFFTData == null || channelFFTData.PCMData == null) { continue; } if (srcPcmMaxDataLength == 0) { srcPcmMaxDataLength = channelFFTData.PCMData.Length; } else { if (srcPcmMaxDataLength != channelFFTData.PCMData.Length) { throw new ArgumentException("FFT数据长度不一致"); } } channelFFTData.Resample(targetCount, 0, channelFFTData.PCMData.Length); channelFFTData.GlobalViewData = channelFFTData.DrawData; if (drawPcmMaxDataLength < channelFFTData.DrawData.Length) { drawPcmMaxDataLength = channelFFTData.DrawData.Length; } } } this._plotDatas = fftDatas; plotPara.SourcePcmDataLength = srcPcmMaxDataLength; plotPara.DrawPcmDataLength = drawPcmMaxDataLength; plotPara.GlobalViewPcmDataLength = drawPcmMaxDataLength; this.AllDraw(); }
/// <summary> /// 缩小 /// </summary> internal void ZoomOut(WavePlotPara plotPara) { if (this._zoomMultiple <= _NONE) { return; } this._zoomMultiple /= 2; if (this._zoomMultiple <= _NONE) { plotPara.SBTOMillisecond = PlotConstant.ZEROR_D; plotPara.UpdateSETOMillisecond(PlotConstant.ZEROR_D); return; } this.UpdatePlotPara(plotPara); }
/// <summary> /// 完整绘制:整体视图-时间线-波形图 /// 用于缩放-平移场景 /// </summary> private void PartDraw_ZoomMove() { //完整绘制:整体视图-时间线-波形图 //全部绘制 Graphics graphics = this._grafx.Graphics; //清空所有已绘制的图形 graphics.Clear(this.BackColor); WavePlotPara plotPara = this._plotPara; IEnumerable <ChannelPlotData> plotDatas = this._plotDatas; if (plotPara == null) { return; } RectangleF? selectedArea; SelectedInfo selectedInfo = this._selectedInfo; selectedArea = this.DrawGlobalView(graphics, plotPara, plotDatas); this.AddPartRefreshArea(this._globalView); if (selectedInfo != null) { selectedInfo.LastGlobalViewSelectedArea = selectedArea; } this.DrawTimeAxis(graphics, plotPara); this.AddPartRefreshArea(this._xAxis); selectedArea = this.DrawWaveSpecturum(graphics, plotPara, plotDatas); if (selectedInfo != null) { selectedInfo.LastWaveSelectedArea = selectedArea; } this.AddPartRefreshArea(this._content); this.RefreshInvalidateArea(); }
/// <summary> /// /// </summary> /// <param name="plotPara">绘图参数</param> /// <param name="pcmData">pcm数据</param> public void UpdateData(WavePlotPara plotPara, short[] pcmData) { this.UpdateData(new ChannelPlotData[] { new ChannelPlotData(pcmData, null) }, plotPara); }
private void DrawTimeAxis(Graphics graphics, WavePlotPara plotPara) { XAxisPlotElementInfo axisX = this._xAxis; if (axisX == null) { return; } //时间图背景 RectangleF rectangleTimeArea = axisX.Area; graphics.FillRectangle(axisX.BackgroudColor, rectangleTimeArea); if (plotPara == null) { return; } //边框 //graphics.DrawLine(this._borderPen, rectangleTimeArea.X, rectangleTimeArea.Y, rectangleTimeArea.X, rectangleTimeArea.Y + rectangleTimeArea.Height); //float borderX = rectangleTimeArea.X + rectangleTimeArea.Width - this._borderPen.Width; //graphics.DrawLine(this._borderPen, borderX, rectangleTimeArea.Y, borderX, rectangleTimeArea.Y + rectangleTimeArea.Height); //graphics.DrawLine(this._borderPen, rectangleTimeArea.X, rectangleTimeArea.Y, rectangleTimeArea.X + rectangleTimeArea.Width, rectangleTimeArea.Y); //绘制起始时间-毫秒 double beginTimeMillisecond = plotPara.SBTOMillisecond; //绘制结束时间-毫秒 double endTimeMillisecond = plotPara.GetSETOMillisecond(); //绘制总时长 double durationTimeMillisecond = endTimeMillisecond - beginTimeMillisecond; if (durationTimeMillisecond <= 0d) { return; } //绘制时间间隔 double separatorSecond = this.CalSegDurationSecond(axisX, graphics, durationTimeMillisecond); //绘制起始时间-秒 double beginTimeSecond = beginTimeMillisecond / 1000; //绘制时间-秒 double timeSecond = PlotConstant.ZEROR_D; if (beginTimeMillisecond > PlotConstant.ZEROR_D) { int mult = (int)(beginTimeSecond / separatorSecond); double mod = beginTimeSecond % separatorSecond; if (mod - separatorSecond < PlotConstant.ZEROR_D) { mult = mult + 1; } timeSecond = separatorSecond * mult; } //绘制时间 DateTime time = plotPara.BaseTime.AddSeconds(timeSecond); DateTime endTime = plotPara.BaseTime.AddMilliseconds(endTimeMillisecond); float labelHeight = rectangleTimeArea.Height / 3; float y1 = rectangleTimeArea.Y + rectangleTimeArea.Height; float y2 = y1 - labelHeight; float y3 = y1 - labelHeight / 2; float labelX, labelSmallX; double separatorSecondHalf = separatorSecond / 2; float secondLength = (float)(axisX.Area.Width / (durationTimeMillisecond / 1000)); string labelText; SizeF labelTextSize; float labelTextX, lastLabelTextRightX = 0f; float labelTextY = rectangleTimeArea.Y + labelHeight / 2; AxisLabelLocation labelTextLocation = AxisLabelLocation.First; var contentWidth = axisX.Area.Width; Pen pen = axisX.Pen; while (true) { //刻度-x labelX = (float)(secondLength * (timeSecond - beginTimeSecond)); labelSmallX = (float)(secondLength * (timeSecond - beginTimeSecond - separatorSecondHalf)); //绘制刻度文本 labelText = this.GetLabelText(time, separatorSecond); labelTextSize = graphics.MeasureString(labelText, axisX.Font); labelTextX = labelX - labelTextSize.Width / 2; switch (labelTextLocation) { case AxisLabelLocation.First: if (labelTextX < PlotConstant.ZEROR_D && beginTimeMillisecond <= PlotConstant.ZEROR_D) { labelTextX = (float)PlotConstant.ZEROR_D; } labelTextLocation = AxisLabelLocation.Middle; break; case AxisLabelLocation.Middle: if (labelTextX + labelTextSize.Width - contentWidth > PlotConstant.ZEROR_D) { labelTextX = contentWidth - labelTextSize.Width; } break; case AxisLabelLocation.Last: if (labelTextX + labelTextSize.Width - contentWidth > PlotConstant.ZEROR_D) { labelTextX = contentWidth - labelTextSize.Width; if (labelTextX - lastLabelTextRightX < PlotConstant.ZEROR_D) { if (labelSmallX - contentWidth < PlotConstant.ZEROR_D) { graphics.DrawLine(pen, labelSmallX, y1, labelSmallX, y3); } return; } } break; default: throw new NotImplementedException(); } graphics.DrawString(labelText, axisX.Font, axisX.ForeColor, labelTextX, labelTextY); lastLabelTextRightX = labelTextX + labelTextSize.Width; //绘制刻度 if (labelSmallX > PlotConstant.ZEROR_D) { graphics.DrawLine(pen, labelSmallX, y1, labelSmallX, y3); } if (labelX - contentWidth < PlotConstant.ZEROR_D) { graphics.DrawLine(pen, labelX, y1, labelX, y2); } if (labelTextLocation == AxisLabelLocation.Last) { break; } timeSecond += separatorSecond; time = plotPara.BaseTime.AddSeconds(timeSecond); if (time >= endTime) { time = endTime; labelTextLocation = AxisLabelLocation.Last; } } }
/// <summary> /// /// </summary> /// <param name="graphics"></param> /// <param name="wave"></param> /// <param name="plotPara"></param> /// <param name="pcmDatas"></param> /// <param name="dataType">true:GlobalViewData;alse:DrawData</param> private void DrawWaveDb(Graphics graphics, PlotElementInfoAbs wave, WavePlotPara plotPara, IEnumerable <ChannelPlotData> pcmDatas, bool dataType) { PointF[] points; if (dataType) { points = new PointF[plotPara.GlobalViewPcmDataLength]; } else { points = new PointF[plotPara.DrawPcmDataLength]; } if (points.Length == 0) { return; } int channeCount = pcmDatas.Count(); float channelWaveAreaHeight = wave.Area.Height / channeCount; float channelWaveHalfHeight = channelWaveAreaHeight / 2; float separatorY = wave.Area.Y + channelWaveHalfHeight; float lx, y; bool drawSeparator = false; //float value; //float db; short[] pcmData; //bool negativePoint; float xStep = this.CalXStep(points.Length); ////const float DB_MAX = 10.397177190355384f; // = Math.Log(short.MaxValue); //const float DB_MAX = 4.5154366811416988f; // = Math.Log10(short.MaxValue); foreach (ChannelPlotData channelPlotData in pcmDatas) { if (drawSeparator) { graphics.DrawLine(this._channelSeparatorPen, 0f, separatorY, wave.Area.Width, separatorY); } if (dataType) { pcmData = channelPlotData.GlobalViewData; } else { pcmData = channelPlotData.DrawData; } lx = 0f; //float minY = 0f, maxY = 0f; //float dbMin = 0f, dbMax = 0f; for (int i = 0; i < points.Length && i < pcmData.Length; i++) { y = separatorY - ((float)pcmData[i] / short.MaxValue) * channelWaveHalfHeight; //转分呗后画出的波形似乎不太对啊 //if (pcmData[i] == 0) //{ // y = separatorY; //} //else //{ // value = (float)pcmData[i]; // if (value < 0) // { // negativePoint = true; // value = Math.Abs(value); // } // else // { // negativePoint = false; // } // //dB = 20 * log(A1 / A2) => db = log(A) // //value = 20 * (float)(Math.Log10(value / short.MaxValue)); // //db = (float)(Math.Log(value)); // db = (float)(Math.Log10(value)); // if (db < dbMin) // { // dbMin = db; // } // if (db > dbMax) // { // dbMax = db; // } // if (negativePoint) // { // y = separatorY + channelWaveHalfHeight * db / DB_MAX; // } // else // { // y = separatorY - channelWaveHalfHeight * db / DB_MAX; // } // if (y < minY) // { // minY = y; // } // if (y > maxY) // { // maxY = y; // } //} points[i] = new PointF(lx, y); lx = lx + xStep; } graphics.DrawLines(wave.Pen, points); separatorY += channelWaveAreaHeight; drawSeparator = true; } }
/// <summary> /// 更新播放位置指示线 /// </summary> /// <param name="plotPara"></param> /// <param name="offsetTimeMilliseconds">播放时间</param> private void PrimitiveUpdatePostionLine(WavePlotPara plotPara, double offsetTimeMilliseconds) { if (!this._playPositionLine) { return; } this.AddPartRefreshArea(this._globalViewLastPlayPositionLineArea); this.AddPartRefreshArea(this._waveLastPlayPositionLineArea); //全部绘制 Graphics graphics = this._grafx.Graphics; IEnumerable <ChannelPlotData> plotDatas = this._plotDatas; //全局视图 this.DrawGlobalView(graphics, plotPara, plotDatas); //波形图 this.DrawWaveSpecturum(graphics, plotPara, plotDatas); ContentPlotElementInfo content = this._content; float maxX = content.Area.X + content.Area.Width; const int OFFSET1 = 1; const int OFFSET2 = 2; //缩略波形图播放位置指示线 var globalView = this._globalView; if (globalView != null) { float globalViewX = (float)(content.Area.Width * offsetTimeMilliseconds / plotPara.DurationMillisecond); if (globalViewX + globalView.PlayLineChannelPen.Width < maxX) { PointF zoomP1 = new PointF(globalViewX, globalView.Area.Y); PointF zoomP2 = new PointF(globalViewX, globalView.Area.Y + globalView.Area.Height); graphics.DrawLine(globalView.PlayLineChannelPen, zoomP1, zoomP2); this._globalViewLastPlayPositionLineArea = new RectangleF(globalViewX - OFFSET1, globalView.Area.Y - OFFSET1, globalView.PlayLineChannelPen.Width + OFFSET2, globalView.Area.Height + OFFSET2); this.AddPartRefreshArea(this._globalViewLastPlayPositionLineArea); } } else { this._globalViewLastPlayPositionLineArea = null; } //主波形图播放位置指示线 double sbto = plotPara.SBTOMillisecond; double seto = plotPara.GetSETOMillisecond(); double timeArea = seto - sbto; float contentX = (float)(content.Area.Width * (offsetTimeMilliseconds - sbto) / timeArea); bool drawWavePlayLine = plotPara.ContainsShowTime(offsetTimeMilliseconds); if (drawWavePlayLine && contentX > PlotConstant.ZEROR_D && this.Width - contentX > PlotConstant.ZEROR_D) { if (contentX + content.PlayLineChannelPen.Width - maxX < PlotConstant.ZEROR_D) { var contentArea = content.Area; PointF wavP1 = new PointF(contentX, contentArea.Y); PointF wavP2 = new PointF(contentX, contentArea.Y + contentArea.Height); graphics.DrawLine(content.PlayLineChannelPen, wavP1, wavP2); this._waveLastPlayPositionLineArea = new RectangleF(contentX - OFFSET1, contentArea.Y - OFFSET1, content.PlayLineChannelPen.Width + OFFSET2, contentArea.Height + OFFSET2); this.AddPartRefreshArea(this._waveLastPlayPositionLineArea); } } else { this._waveLastPlayPositionLineArea = null; } this.RefreshInvalidateArea(); }