Exemplo n.º 1
0
//////////////////////////////////////////////////////////////////////
// Called to update spectrum data for displaying on the screen
//////////////////////////////////////////////////////////////////////
void CPlotter::draw()
{
    int i,n;
    int w;
    int h;
    int xmin, xmax;

    if (m_DrawOverlay)
    {
        drawOverlay();
        m_DrawOverlay = false;
    }

    QPoint LineBuf[MAX_SCREENSIZE];

    if (!m_Running)
        return;

    // get/draw the waterfall
    w = m_WaterfallPixmap.width();
    h = m_WaterfallPixmap.height();

    // no need to draw if pixmap is invisible
    if ((w != 0) || (h != 0))
    {
        // move current data down one line(must do before attaching a QPainter object)
        m_WaterfallPixmap.scroll(0,1,0,0, w, h);

        QPainter painter1(&m_WaterfallPixmap);
        // get scaled FFT data
        getScreenIntegerFFTData(255, qMin(w, MAX_SCREENSIZE),
                                m_MaxdB, m_MindB,
                                m_FftCenter - (qint64)m_Span/2,
                                m_FftCenter + (qint64)m_Span/2,
                                m_wfData, m_fftbuf,
                                &xmin, &xmax);

        // draw new line of fft data at top of waterfall bitmap
        painter1.setPen(QColor(0, 0, 0));
        for (i = 0; i < xmin; i++)
            painter1.drawPoint(i,0);
        for (i = xmax; i < w; i++)
            painter1.drawPoint(i,0);
        for (i = xmin; i < xmax; i++)
        {
            painter1.setPen(m_ColorTbl[ 255-m_fftbuf[i] ]);
            painter1.drawPoint(i,0);
        }
    }

    // get/draw the 2D spectrum
    w = m_2DPixmap.width();
    h = m_2DPixmap.height();

    if ((w != 0) || (h != 0))
    {
        // first copy into 2Dbitmap the overlay bitmap.
        m_2DPixmap = m_OverlayPixmap.copy(0,0,w,h);

        QPainter painter2(&m_2DPixmap);

// workaround for "fixed" line drawing since Qt 5
// see http://stackoverflow.com/questions/16990326 
#if QT_VERSION >= 0x050000
        painter2.translate(0.5, 0.5);
#endif

        // get new scaled fft data
        getScreenIntegerFFTData(h, qMin(w, MAX_SCREENSIZE),
                                m_MaxdB, m_MindB,
                                m_FftCenter - (qint64)m_Span/2,
                                m_FftCenter + (qint64)m_Span/2,
                                m_fftData, m_fftbuf,
                                &xmin, &xmax);

        // draw the pandapter
        painter2.setPen(m_FftColor);
        n = xmax - xmin;
        for (i = 0; i < n; i++)
        {
            LineBuf[i].setX(i + xmin);
            LineBuf[i].setY(m_fftbuf[i + xmin]);
        }

        if (m_FftFill)
        {
            QLinearGradient linGrad(QPointF(xmin, h), QPointF(xmin, 0));
            linGrad.setColorAt(0.0, m_FftCol0);
            linGrad.setColorAt(1.0, m_FftCol1);
            painter2.setBrush(QBrush(QGradient(linGrad)));
            if (n < MAX_SCREENSIZE-2)
            {
                LineBuf[n].setX(xmax-1);
                LineBuf[n].setY(h);
                LineBuf[n+1].setX(xmin);
                LineBuf[n+1].setY(h);
                painter2.drawPolygon(LineBuf, n+2);
            }
            else
            {
                LineBuf[MAX_SCREENSIZE-2].setX(xmax-1);
                LineBuf[MAX_SCREENSIZE-2].setY(h);
                LineBuf[MAX_SCREENSIZE-1].setX(xmin);
                LineBuf[MAX_SCREENSIZE-1].setY(h);
                painter2.drawPolygon(LineBuf, n);
            }
        }
        else
        {
            painter2.drawPolyline(LineBuf, n);
        }
    }

    // trigger a new paintEvent
    update();
}
Exemplo n.º 2
0
//////////////////////////////////////////////////////////////////////
// Called to update spectrum data for displaying on the screen
//////////////////////////////////////////////////////////////////////
void CPlotter::draw()
{
    int i,n;
    int w;
    int h;
    int xmin, xmax;

    if (m_DrawOverlay)
    {
        drawOverlay();
        m_DrawOverlay = false;
    }

    QPoint LineBuf[MAX_SCREENSIZE];

    if (!m_Running)
        return;

    // get/draw the waterfall
    w = m_WaterfallPixmap.width();
    h = m_WaterfallPixmap.height();

    // no need to draw if pixmap is invisible
    if ((w != 0) || (h != 0))
    {
        // move current data down one line(must do before attaching a QPainter object)
        m_WaterfallPixmap.scroll(0,1,0,0, w, h);

        QPainter painter1(&m_WaterfallPixmap);
        // get scaled FFT data
        getScreenIntegerFFTData(255, qMin(w, MAX_SCREENSIZE),
                                m_MaxdB, m_MindB,
                                m_FftCenter - (qint64)m_Span/2,
                                m_FftCenter + (qint64)m_Span/2,
                                m_wfData, m_fftbuf,
                                &xmin, &xmax);

        // draw new line of fft data at top of waterfall bitmap
        painter1.setPen(QColor(0, 0, 0));
        for (i = 0; i < xmin; i++)
            painter1.drawPoint(i,0);
        for (i = xmax; i < w; i++)
            painter1.drawPoint(i,0);
        for (i = xmin; i < xmax; i++)
        {
            painter1.setPen(m_ColorTbl[ 255-m_fftbuf[i] ]);
            painter1.drawPoint(i,0);
        }
    }

    // get/draw the 2D spectrum
    w = m_2DPixmap.width();
    h = m_2DPixmap.height();

    if ((w != 0) || (h != 0))
    {
        // first copy into 2Dbitmap the overlay bitmap.
        m_2DPixmap = m_OverlayPixmap.copy(0,0,w,h);

        QPainter painter2(&m_2DPixmap);

// workaround for "fixed" line drawing since Qt 5
// see http://stackoverflow.com/questions/16990326 
#if QT_VERSION >= 0x050000
        painter2.translate(0.5, 0.5);
#endif

        // get new scaled fft data
        getScreenIntegerFFTData(h, qMin(w, MAX_SCREENSIZE),
                                m_MaxdB, m_MindB,
                                m_FftCenter - (qint64)m_Span/2,
                                m_FftCenter + (qint64)m_Span/2,
                                m_fftData, m_fftbuf,
                                &xmin, &xmax);

        // draw the pandapter
        painter2.setPen(m_FftColor);
        n = xmax - xmin;
        for (i = 0; i < n; i++)
        {
            LineBuf[i].setX(i + xmin);
            LineBuf[i].setY(m_fftbuf[i + xmin]);
        }

        if (m_FftFill)
        {
            QLinearGradient linGrad(QPointF(xmin, h), QPointF(xmin, 0));
            linGrad.setColorAt(0.0, m_FftCol0);
            linGrad.setColorAt(1.0, m_FftCol1);
            painter2.setBrush(QBrush(QGradient(linGrad)));
            if (n < MAX_SCREENSIZE-2)
            {
                LineBuf[n].setX(xmax-1);
                LineBuf[n].setY(h);
                LineBuf[n+1].setX(xmin);
                LineBuf[n+1].setY(h);
                painter2.drawPolygon(LineBuf, n+2);
            }
            else
            {
                LineBuf[MAX_SCREENSIZE-2].setX(xmax-1);
                LineBuf[MAX_SCREENSIZE-2].setY(h);
                LineBuf[MAX_SCREENSIZE-1].setX(xmin);
                LineBuf[MAX_SCREENSIZE-1].setY(h);
                painter2.drawPolygon(LineBuf, n);
            }
        }
        else
        {
            painter2.drawPolyline(LineBuf, n);
        }

        //Peak detection
        if (m_PeakDetection > 0)
        {
            m_Peaks.clear();

            float   mean = 0;
            float   sum_of_sq = 0;
            for (i = 0; i < n; i++)
            {
                mean += m_fftbuf[i + xmin];
                sum_of_sq += m_fftbuf[i + xmin] * m_fftbuf[i + xmin];
            }
            mean /= n;
            float stdev= sqrt( sum_of_sq/n-mean*mean );

            int lastPeak=-1;
            for (i = 0; i < n; i++)
            {
                //m_PeakDetection times the std over the mean or better than current peak
                float d = (lastPeak==-1) ? (mean - m_PeakDetection * stdev) :
                                           m_fftbuf[lastPeak+xmin];

                if (m_fftbuf[i + xmin] < d)
                    lastPeak=i;

                if (lastPeak != -1 && (i - lastPeak > PEAK_H_TOLERANCE || i == n-1))
                {
                    m_Peaks.insert(lastPeak+xmin, m_fftbuf[lastPeak + xmin]);
                    painter2.drawEllipse(lastPeak+xmin-5, m_fftbuf[lastPeak + xmin]-5, 10, 10);
                    lastPeak=-1;
                }
            }
        }

        //Peak hold
        if (m_PeakHoldActive)
        {
            for (i = 0; i < n; i++)
            {
                if(!m_PeakHoldValid || m_fftbuf[i] < m_fftPeakHoldBuf[i])
                    m_fftPeakHoldBuf[i] = m_fftbuf[i];

                LineBuf[i].setX(i + xmin);
                LineBuf[i].setY(m_fftPeakHoldBuf[i + xmin]);
            }
            painter2.setPen(m_PeakHoldColor);
            painter2.drawPolyline(LineBuf, n);

            m_PeakHoldValid=true;
        }

		painter2.end();

    }

    // trigger a new paintEvent
    update();
}