Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/waveform/waveformrendersignal.cpp

Go to the documentation of this file.
00001 #include <QDebug>
00002 #include <QColor>
00003 #include <QDomNode>
00004 #include <QPaintEvent>
00005 #include <QPainter>
00006 #include <QObject>
00007 #include <QVector>
00008 #include <QLine>
00009 #include <qgl.h>
00010 
00011 #include "waveformrendersignal.h"
00012 #include "waveformrenderer.h"
00013 #include "controlobjectthreadmain.h"
00014 #include "controlobject.h"
00015 #include "widget/wskincolor.h"
00016 #include "widget/wwidget.h"
00017 #include "trackinfoobject.h"
00018 
00019 WaveformRenderSignal::WaveformRenderSignal(const char* group, WaveformRenderer *parent)
00020   : m_pParent(parent),
00021     m_iWidth(0),
00022     m_iHeight(0),
00023     m_fGain(1),
00024     m_lines(0),
00025     m_pTrack(NULL),
00026     signalColor(255,255,255) {
00027     m_pGain = new ControlObjectThreadMain(
00028         ControlObject::getControl(ConfigKey(group, "total_gain")));
00029     if (m_pGain != NULL) {
00030         connect(m_pGain, SIGNAL(valueChanged(double)),
00031                 this, SLOT(slotUpdateGain(double)));
00032     }
00033 }
00034 
00035 WaveformRenderSignal::~WaveformRenderSignal() {
00036     qDebug() << this << "~WaveformRenderSignal()";
00037     delete m_pGain;
00038 }
00039 
00040 void WaveformRenderSignal::resize(int w, int h) {
00041     m_iWidth = w;
00042     m_iHeight = h;
00043 }
00044 
00045 void WaveformRenderSignal::newTrack(TrackPointer pTrack) {
00046     m_pTrack = pTrack;
00047 }
00048 
00049 void WaveformRenderSignal::slotUpdateGain(double v) {
00050     m_fGain = v;
00051 }
00052 
00053 void WaveformRenderSignal::setup(QDomNode node) {
00054     signalColor.setNamedColor(WWidget::selectNodeQString(node, "SignalColor"));
00055     signalColor = WSkinColor::getCorrectColor(signalColor);
00056 }
00057 
00058 
00059 void WaveformRenderSignal::draw(QPainter *pPainter, QPaintEvent *event,
00060                                 QVector<float> *buffer, double dPlayPos,
00061                                 double rateAdjust) {
00062     if (buffer == NULL) {
00063         return;
00064     }
00065 
00066     const float* baseBuffer = buffer->constData();
00067 
00068     int numBufferSamples = buffer->size();
00069     int iCurPos = 0;
00070     iCurPos = (int)(dPlayPos*numBufferSamples);
00071 
00072     if ((iCurPos % 2) != 0)
00073         iCurPos--;
00074 
00075     pPainter->save();
00076 
00077     pPainter->setPen(signalColor);
00078 
00079     const double subpixelsPerPixel = m_pParent->getSubpixelsPerPixel() * (1.0 + rateAdjust);
00080 
00081     int subpixelWidth = int(m_iWidth * subpixelsPerPixel);
00082 
00083     // If the array is not large enough, expand it.
00084     // Amortize the cost of this by requesting a factor of 2 more.
00085     if(m_lines.size() < subpixelWidth) {
00086         m_lines.resize(2*subpixelWidth);
00087     }
00088 
00089     // Use the pointer to the QVector internal data to avoid range
00090     // checks. QVector<QLineF>::operator[] profiled very high. const_cast is
00091     // naughty but we just want Qt to leave us alone here. WARNING: calling
00092     // m_lines.data() will copy the entire vector in memory by calling
00093     // QVector<T>::detach(). QVector<T>::constData() does not do this.
00094     QLineF* lineData = const_cast<QLineF*>(m_lines.constData());
00095     int halfw = subpixelWidth/2;
00096     for(int i=0;i<subpixelWidth;i++) {
00097         // Start at curPos minus half the waveform viewer
00098         int thisIndex = iCurPos+2*(i-halfw);
00099         if(thisIndex >= 0 && (thisIndex+1) < numBufferSamples) {
00100             float sampl = baseBuffer[thisIndex] * m_fGain * m_iHeight * 0.5f;
00101             float sampr = -baseBuffer[thisIndex+1] * m_fGain * m_iHeight * 0.5f;
00102             const qreal xPos = i/subpixelsPerPixel;
00103             lineData[i].setLine(xPos, sampr, xPos, sampl);
00104         } else {
00105             lineData[i].setLine(0,0,0,0);
00106         }
00107     }
00108 
00109     // Only draw lines that we have provided
00110     pPainter->drawLines(lineData, subpixelWidth);
00111 
00112     // Some of the pre-roll is on screen. Draw little triangles to indicate
00113     // where the pre-roll is located.
00114     if (iCurPos < 2*halfw) {
00115         double start_index = 0;
00116         int end_index = (halfw - iCurPos/2);
00117         QPolygonF polygon;
00118         const int polyWidth = 80;
00119         polygon << QPointF(0, 0)
00120                 << QPointF(-polyWidth/subpixelsPerPixel, -m_iHeight/5)
00121                 << QPointF(-polyWidth/subpixelsPerPixel, m_iHeight/5);
00122         polygon.translate(end_index/subpixelsPerPixel, 0);
00123 
00124         int index = end_index;
00125         while (index > start_index) {
00126             pPainter->drawPolygon(polygon);
00127             polygon.translate(-polyWidth/subpixelsPerPixel, 0);
00128             index -= polyWidth;
00129         }
00130     }
00131     pPainter->restore();
00132 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines