![]() |
Mixxx
|
00001 00007 #include <QDebug> 00008 #include <QDomNode> 00009 #include <QImage> 00010 #include <QObject> 00011 #include <qgl.h> 00012 00013 #include "glwaveformrenderer.h" 00014 #include "waveformrenderbeat.h" 00015 #include "trackinfoobject.h" 00016 #include "soundsourceproxy.h" 00017 #include "controlobjectthreadmain.h" 00018 #include "controlobject.h" 00019 #include "widget/wwidget.h" 00020 #include "widget/wskincolor.h" 00021 00022 #define DEFAULT_SECONDS_TO_DISPLAY 4 00023 #define SCALE_TEST 4 00024 00025 GLWaveformRenderer::GLWaveformRenderer(const char* group) : 00026 m_iWidth(0), 00027 m_iHeight(0), 00028 m_iMax(0), 00029 m_iMin(0), 00030 m_iNumSamples(0), 00031 bgColor(0,0,0), 00032 signalColor(255,255,255), 00033 colorMarker(255,255,255), 00034 colorBeat(255,255,255), 00035 colorCue(255,255,255), 00036 m_iDesiredSecondsToDisplay(DEFAULT_SECONDS_TO_DISPLAY), 00037 m_pSampleBuffer(NULL), 00038 m_pInternalBuffer(NULL), 00039 m_iInternalBufferSize(0) 00040 { 00041 m_pPlayPos = new ControlObjectThreadMain(ControlObject::getControl(ConfigKey(group,"playposition"))); 00042 connect(m_pPlayPos, SIGNAL(valueChanged(double)), this, SLOT(slotUpdatePlayPos(double))); 00043 00044 m_pCOVisualResample = new ControlObject(ConfigKey(group,"VisualResample")); 00045 m_pCOVerticalScale = new ControlObject(ConfigKey(group, "VisualVerticalScale")); 00046 } 00047 00048 00049 GLWaveformRenderer::~GLWaveformRenderer() { 00050 if(m_pCOVisualResample) 00051 delete m_pCOVisualResample; 00052 m_pCOVisualResample = NULL; 00053 00054 if(m_pCOVerticalScale) 00055 delete m_pCOVerticalScale; 00056 m_pCOVerticalScale = NULL; 00057 00058 if(m_pPlayPos) 00059 delete m_pPlayPos; 00060 m_pPlayPos = NULL; 00061 00062 } 00063 00064 void GLWaveformRenderer::slotUpdatePlayPos(double v) { 00065 m_dPlayPos = v; 00066 } 00067 00068 00069 void GLWaveformRenderer::resize(int w, int h) { 00070 m_iWidth = w; 00071 m_iHeight = h; 00072 00073 m_pInternalBuffer = new GLfloat[w*3*5]; 00074 m_iInternalBufferSize = w*5; 00075 00076 for(int i=0; i<w*5; i++) { 00077 m_pInternalBuffer[i*3+0] = i-10; 00078 m_pInternalBuffer[i*3+1] = 0.5; 00079 m_pInternalBuffer[i*3+2] = 1.0; 00080 00081 00082 } 00083 00084 glMatrixMode(GL_PROJECTION); 00085 glLoadIdentity(); 00086 gluPerspective(60.0, 1.0, 1.0, 1000.0); 00087 glViewport(0,0,w,h); 00088 00089 gluLookAt(0,0,15.0, // look along z-axis 00090 0,0,0, // from the origin 00091 0,1.0,0); // with y being 'up' 00092 00093 setupControlObjects(); 00094 } 00095 00096 void GLWaveformRenderer::setupControlObjects() { 00097 00098 // the max positive value of a sample is 32767, (2**15-1) 00099 // we want the waveforms normalized so that 0-32767 maps to 0-m_iHeight/2 00100 // (m_iHeight/2) = (32767) / x => x = 32767/(m_iHeight/2) 00101 int verticalScale = ((1<<15)-1)*2/ m_iHeight; 00102 m_pCOVerticalScale->set(verticalScale); 00103 00104 00105 // the resample rate is the number of seconds that correspond to one pixel 00106 // on the visual waveform display. 00107 00108 // the reason for using seconds is that we do not know the 00109 // sample rate of the song that will be loaded. 00110 00111 // we calculate this as follows: 00112 00113 // secondsPerPixel = desiredSecondsToDisplay / m_iWidth 00114 00115 // for now just send the width.. meh 00116 double secondsPerPixel = double(m_iDesiredSecondsToDisplay)/m_iWidth; 00117 //m_pCOVisualResample->set(secondsPerPixel); 00118 00119 m_pCOVisualResample->set(m_iWidth); 00120 00121 qDebug() << "GLWaveformRenderer::setupControlObjects - VisualResample: " << secondsPerPixel << " VerticalScale: " << verticalScale; 00122 00123 } 00124 00125 void GLWaveformRenderer::setup(QDomNode node) { 00126 00127 bgColor.setNamedColor(WWidget::selectNodeQString(node, "BgColor")); 00128 bgColor = WSkinColor::getCorrectColor(bgColor); 00129 00130 qDebug() << "Got bgColor " << bgColor; 00131 00132 signalColor.setNamedColor(WWidget::selectNodeQString(node, "SignalColor")); 00133 signalColor = WSkinColor::getCorrectColor(signalColor); 00134 00135 qDebug() << "Got signalColor " << signalColor; 00136 00137 colorMarker.setNamedColor(WWidget::selectNodeQString(node, "MarkerColor")); 00138 colorMarker = WSkinColor::getCorrectColor(colorMarker); 00139 00140 colorBeat.setNamedColor(WWidget::selectNodeQString(node, "BeatColor")); 00141 colorBeat = WSkinColor::getCorrectColor(colorBeat); 00142 00143 colorCue.setNamedColor(WWidget::selectNodeQString(node, "CueColor")); 00144 colorCue = WSkinColor::getCorrectColor(colorCue); 00145 00146 } 00147 00148 00149 void GLWaveformRenderer::precomputePixmap() { 00150 00151 } 00152 00153 bool GLWaveformRenderer::fetchWaveformFromTrack() { 00154 00155 if(!m_pTrack) 00156 return false; 00157 00158 QVector<float> *buffer = m_pTrack->getVisualWaveform(); 00159 00160 if(buffer == NULL) 00161 return false; 00162 00163 m_pSampleBuffer = buffer; 00164 m_iNumSamples = buffer->size(); 00165 00166 return true; 00167 } 00168 00169 00170 00171 void GLWaveformRenderer::drawSignalLines() { 00172 00173 if(m_pSampleBuffer == NULL) { 00174 return; 00175 } 00176 00177 int iCurPos = 0; 00178 if(m_dPlayPos != -1) { 00179 iCurPos = (int)(m_dPlayPos*m_iNumSamples); 00180 } 00181 00182 if((iCurPos % 2) != 0) 00183 iCurPos--; 00184 00185 00186 int halfw = m_iInternalBufferSize/2; 00187 00188 for(int i=0;i<m_iInternalBufferSize;i++) { 00189 int thisIndex = iCurPos+2*(i-halfw); 00190 if(thisIndex >= 0 && (thisIndex+1) < m_iNumSamples) { 00191 float sampl = (*m_pSampleBuffer)[thisIndex]; 00192 float sampr = (*m_pSampleBuffer)[thisIndex+1]; 00193 00194 m_pInternalBuffer[i*3+1] = sampl; 00195 } 00196 00197 00198 } 00199 00200 /* 00201 pPainter->scale(1.0/float(SCALE_TEST),m_iHeight*0.40); 00202 int halfw = m_iWidth*SCALE_TEST/2; 00203 for(int i=0;i<m_iWidth*SCALE_TEST;i++) { 00204 //pPainter->drawLine(QPoint(i,0), QPoint(i, i/sca)); 00205 int thisIndex = iCurPos+2*(i-halfw); 00206 if(thisIndex >= 0 && (thisIndex+1) < m_iNumSamples) { 00207 float sampl = (*m_pSampleBuffer)[thisIndex]; 00208 float sampr = (*m_pSampleBuffer)[thisIndex+1]; 00209 00210 // Old cruft 00211 //pPainter->drawLine(QPoint(i,m_iHeight/4), QPoint(i,m_iHeight/4+sampl/scaley2)); 00212 //pPainter->drawLine(QPoint(i,-m_iHeight/4), QPoint(i,-m_iHeight/4+sampr/scaley2)); 00213 00214 // These are decent 00215 //pPainter->drawLine(QPoint(i,0), QPoint(i, sampl/scaley)); 00216 //pPainter->drawLine(QPoint(i,0), QPoint(i, -sampr/scaley)); 00217 00218 //m_lines[i] = QLineF(i,-sampr,i,sampl); 00219 } else { 00220 //m_lines[i] = QLineF(0,0,0,0); 00221 } 00222 } 00223 00224 //pPainter->drawLines(m_lines); 00225 00226 pPainter->restore(); 00227 */ 00228 } 00229 00230 void GLWaveformRenderer::drawSignalPixmap(QPainter *pPainter) { 00231 00232 } 00233 00234 void GLWaveformRenderer::glDraw() { 00235 00236 if(m_iWidth == 0 || m_iHeight == 0) 00237 return; 00238 00239 if(m_pSampleBuffer == NULL) { 00240 fetchWaveformFromTrack(); 00241 if(m_pSampleBuffer != NULL) 00242 qDebug() << "Received waveform from track"; 00243 } 00244 00245 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00246 glMatrixMode(GL_MODELVIEW); 00247 glLoadIdentity(); 00248 00249 gluLookAt(0,0,15, 00250 0,0,0, 00251 0,1,0); 00252 00253 glDrawBuffer(GL_BACK); 00254 00255 00256 glPushMatrix(); 00257 00258 glScalef(1.0/5.0,m_iHeight/2, 1.0); 00259 00260 drawSignalLines(); 00261 00262 glBegin(GL_LINES); 00263 00264 glVertex3f(0,0,1.0); 00265 glVertex3f(0,1.0,1.0); 00266 00267 00268 glEnd(); 00269 00270 glEnableClientState(GL_VERTEX_ARRAY); 00271 glVertexPointer(3, GL_FLOAT, 0, m_pInternalBuffer); 00272 glDrawArrays(GL_LINE_LOOP,0,m_iInternalBufferSize); 00273 00274 glPopMatrix(); 00275 00276 00277 00278 glFlush(); 00279 } 00280 00281 void GLWaveformRenderer::draw(QPainter* pPainter, QPaintEvent *pEvent) { 00282 pPainter->fillRect(pEvent->rect(), QBrush(bgColor)); 00283 pPainter->setPen(signalColor); 00284 00285 if(m_iWidth == 0 || m_iHeight == 0) 00286 return; 00287 00288 //int scaley = 32767*2/ m_iHeight; 00289 //int scaley2 = 32767*4/ m_iHeight; 00290 //int sca = m_iWidth*2/ m_iHeight; 00291 00292 00293 if(m_pSampleBuffer == NULL) { 00294 fetchWaveformFromTrack(); 00295 if(m_pSampleBuffer != NULL) 00296 qDebug() << "Received waveform from track"; 00297 } 00298 00299 00300 00301 //drawSignalPixmap(pPainter); 00302 00303 00304 00305 pPainter->translate(0,m_iHeight/2); 00306 pPainter->scale(1.0,-1.0); 00307 //drawSignalLines(pPainter); 00308 00309 00310 // Draw various markers. 00311 pPainter->setPen(colorMarker); 00312 00313 pPainter->drawLine(QLine(0,0,m_iWidth,0)); 00314 pPainter->drawLine(QLine(m_iWidth/2,m_iHeight/2,m_iWidth/2,-m_iHeight/2)); 00315 //pPainter->drawLine(QPoint(-h,0), QPoint(h,0)); 00316 //pPainter->drawLine(QPoint(h,m_iHeight/2), QPoint(h,-m_iHeight/2)); 00317 00318 00319 } 00320 00321 void GLWaveformRenderer::newTrack(TrackPointer pTrack) { 00322 m_pTrack = pTrack; 00323 m_pSampleBuffer = 0; 00324 m_iNumSamples = 0; 00325 00326 } 00327 00328 int GLWaveformRenderer::getDesiredSecondsToDisplay() { 00329 return m_iDesiredSecondsToDisplay; 00330 } 00331 00332 void GLWaveformRenderer::setDesiredSecondsToDisplay(int secondsToDisplay) { 00333 m_iDesiredSecondsToDisplay = secondsToDisplay; 00334 }