예제 #1
0
        /// <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();
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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();                          //刷新
        }
예제 #5
0
        //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;
                    }
                }
            }
        }
예제 #6
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;
        }
예제 #7
0
        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));
        }
예제 #8
0
        /// <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;
            }
        }
예제 #9
0
        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;
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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();
        }
예제 #13
0
        /// <summary>
        /// 清除
        /// </summary>
        public void Clear()
        {
            this._plotDatas = null;
            this._plotPara  = null;

            //全部绘制
            Graphics graphics = this._grafx.Graphics;

            //清空所有已绘制的图形
            graphics.Clear(this.BackColor);

            this.RefreshInvalidateArea();//刷新
        }
예제 #14
0
        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);
        }
예제 #15
0
        /// <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();
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        /// <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();
        }
예제 #18
0
 /// <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);
 }
예제 #19
0
        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;
                }
            }
        }
예제 #20
0
        /// <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;
            }
        }
예제 #21
0
        /// <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();
        }