void CorrelationWidget::paintEvent( QPaintEvent * ) { Channel *active = gdata->getActiveChannel(); AnalysisData *data = NULL; int chunk=0; double dh2 = double(height()-1) / 2.0; double pixelStep; int j, x, y; beginDrawing(false); if(active) { pixelStep = double(active->nsdfData.size()) / double(width()); active->lock(); chunk = active->currentChunk(); data = active->dataAtChunk(chunk); //int centerX = width() / 2; if(data) { double freq = data->fundamentalFreq; double period = double(active->rate()) / freq; //double numPeriods = double(active->size()) / period; double scaleX = period * double(width()) / double(active->nsdfData.size()); //pixels per period //draw alternating background color indicating period if(gdata->view->backgroundShading() && period > 4.0 && period < double(active->nsdfData.size())) { int n = int(ceil(double(width()) / scaleX)); //number of colored patches p.setPen(Qt::NoPen); QColor color1 = colorBetween(gdata->backgroundColor(), gdata->shading1Color(), data->correlation()); QColor color2 = colorBetween(gdata->backgroundColor(), gdata->shading2Color(), data->correlation()); for(j = 0; j<n; j++) { x = toInt(scaleX*double(j)); p.setBrush((j%2) ? color1 : color2); p.drawRect(x, 0, toInt(scaleX*double(j+1)) - toInt(scaleX*double(j)), height()); } p.setPen(colorBetween(gdata->backgroundColor(), Qt::black, 0.3*data->correlation())); for(j = 0; j<n; j++) { x = toInt(scaleX*double(j)); p.drawLine(x, 0, x, height()); } } else { clearBackground(); } QString numPeriodsText; numPeriodsText.sprintf("Period = %lf", period); p.setPen(Qt::black); p.drawText(5, height() - 8, numPeriodsText); } else { clearBackground(); } } else { clearBackground(); } //draw the horizontal center line p.setPen(QPen(colorBetween(colorGroup().background(), Qt::black, 0.3), 0)); p.drawLine(0, toInt(dh2), width(), toInt(dh2)); if(active) { if(gdata->doingFreqAnalysis()) { int w = width() / 2; //only do every second pixel (for speed) //draw the waveform if(int(pointArray.size()) != w) pointArray.resize(w); if(lookup.size() != w) lookup.resize(w); NoteData *currentNote = active->getCurrentNote(); Array1d<float> *input = &(active->nsdfData); if(currentNote) { if(aggregateMode == 1) input = ¤tNote->nsdfAggregateData; else if(aggregateMode == 2) input = ¤tNote->nsdfAggregateDataScaled; } //bresenham1d(*input, lookup); maxAbsDecimate1d(*input, lookup); for(int j=0; j<w; j++) { pointArray.setPoint(j, j*2, toInt(dh2 - lookup[j]*dh2)); } p.setPen(QPen(active->color, 0)); p.drawPolyline(pointArray); } if(data && (aggregateMode == 0)) { double ratio = double(width()) / double(active->nsdfData.size()); //pixels per index //float highest = active->nsdfData.at(data->highestCorrelationIndex); //float chosen = active->nsdfData.at(data->chosenCorrelationIndex); //draw a dot at all the period estimates p.setPen(Qt::blue); p.setBrush(Qt::blue); for(j=0; j<int(data->periodEstimates.size()); j++) { x = toInt(double(data->periodEstimates[j]) * ratio); y = toInt(dh2 - data->periodEstimatesAmp[j] * dh2); p.drawEllipse(x-2, y-2, 5, 5); } if(data->highestCorrelationIndex >= 0) { float highest = data->periodEstimatesAmp[data->highestCorrelationIndex]; //draw threshold line p.setPen(QPen(colorBetween(colorGroup().background(), Qt::black, 0.3), 0)); y = toInt(dh2 - (highest * active->threshold()) * dh2); p.drawLine(0, y, width(), y); //draw a dot at the highest correlation period p.setPen(Qt::black); p.setBrush(Qt::black); //x = toInt(double(data->highestCorrelationIndex) * ratio); x = toInt(double(data->periodEstimates[data->highestCorrelationIndex]) * ratio); y = toInt(dh2 - highest * dh2); p.drawEllipse(x-2, y-2, 5, 5); } //draw a dot at the chosen correlation period if(data->chosenCorrelationIndex >= 0) { p.setPen(Qt::red); p.setBrush(Qt::red); //x = toInt(double(data->chosenCorrelationIndex) * ratio); //y = toInt(dh2 - chosen * dh2); x = toInt(double(data->periodEstimates[data->chosenCorrelationIndex]) * ratio); y = toInt(dh2 - data->periodEstimatesAmp[data->chosenCorrelationIndex] * dh2); p.drawEllipse(x-2, y-2, 5, 5); } //draw a line at the chosen correlation period if(data->chosenCorrelationIndex >= 0) { p.setPen(Qt::green); p.setBrush(Qt::green); //x = toInt(double(data->periodOctaveEstimate) * ratio); x = toInt(double(active->periodOctaveEstimate(chunk)) * ratio); p.drawLine(x, 0, x, height()); } } active->unlock(); } endDrawing(); }
//void AmplitudeWidget::drawChannelAmplitudeFilled(Channel *ch, QPainter &p) void AmplitudeWidget::drawChannelAmplitudeFilledGL(Channel *ch) { View *view = gdata->view; ChannelLocker channelLocker(ch); ZoomLookup *z = &ch->amplitudeZoomLookup; // baseX is the no. of chunks a pixel must represent. double baseX = view->zoomX() / ch->timePerChunk(); z->setZoomLevel(baseX); double currentChunk = ch->chunkFractionAtTime(view->currentTime()); double leftFrameTime = currentChunk - ((view->currentTime() - view->viewLeft()) / ch->timePerChunk()); int n = 0; int baseElement = int(floor(leftFrameTime / baseX)); if(baseElement < 0) { n -= baseElement; baseElement = 0; } int lastBaseElement = int(floor(double(ch->totalChunks()) / baseX)); //double heightRatio = double(height()) / dBRange(); double heightRatio = double(height()) / range(); //int firstN = n; //int lastN = firstN; //Q3PointArray bottomPoints(width()*2); Array1d<MyGLfloat2d> vertexArray(width()*2); int pointIndex = 0; //int topBottomPointIndex = 0; if (baseX > 1) { // More samples than pixels int theWidth = width(); //if(baseElement + theWidth > z->size()) z->setSize(baseElement + theWidth); if(lastBaseElement > z->size()) z->setSize(lastBaseElement); for(; n < theWidth && baseElement < lastBaseElement; n++, baseElement++) { myassert(baseElement >= 0); ZoomElement &ze = z->at(baseElement); //if(!z->hasValue(baseElement)) { if(!ze.isValid()) { if(!calcZoomElement(ze, ch, baseElement, baseX)) continue; } int y = height() - 1 - toInt((ze.high() - offsetInv()) * heightRatio); //bottomPoints.setPoint(topBottomPointIndex++, n, y); //bottomPoints.setPoint(topBottomPointIndex++, n, height()); vertexArray[pointIndex++] = MyGLfloat2d(n, y); vertexArray[pointIndex++] = MyGLfloat2d(n, height()); //lastN = n; } //p.setPen(Qt::NoPen); //p.setBrush(gdata->shading1Color()); //p.drawRect(firstN, 0, lastN, height()); //p.setPen(gdata->shading2Color()); //p.drawLineSegments(bottomPoints, 0, topBottomPointIndex/2); qglColor(gdata->shading2Color()); glVertexPointer(2, GL_FLOAT, 0, vertexArray.begin()); glDrawArrays(GL_QUAD_STRIP, 0, pointIndex); } else { //baseX <= 1 float err = 0.0; float val = 0.0; int intChunk = (int) floor(leftFrameTime); // Integer version of frame time double stepSize = 1.0 / baseX; // So we skip some pixels float x = 0.0f, y; //double start = 0 - stepSize; double start = (double(intChunk) - leftFrameTime) * stepSize; double stop = width() + (2 * stepSize); //int squareSize = (int(sqrt(stepSize)) / 2) * 2 + 1; //make it an odd number //int halfSquareSize = squareSize/2; double dn = start; int totalChunks = ch->totalChunks(); if(intChunk < 0) { dn += stepSize * -intChunk; intChunk = 0; } //bottomPoints.setPoint(topBottomPointIndex++, toInt(dn), height()); //vertexArray[pointIndex++] = MyGLfloat2d((GLfloat)dn, height()); //firstN = toInt(dn); for(; dn < stop && intChunk < totalChunks; dn += stepSize, intChunk++) { AnalysisData *data = ch->dataAtChunk(intChunk); myassert(data); if(!data) continue; err = data->correlation(); val = calculateElement(data); //p.setPen(QPen(colorBetween(colorGroup().background(), ch->color, val), 1)); x = dn; y = height() - 1 - ((val - offsetInv()) * heightRatio); //bottomPoints.setPoint(topBottomPointIndex++, x, y); vertexArray[pointIndex++] = MyGLfloat2d(x, y); vertexArray[pointIndex++] = MyGLfloat2d(x, height()); //lastN = x; } //bottomPoints.setPoint(topBottomPointIndex, bottomPoints.point(topBottomPointIndex-1).x(), height()); //if(pointIndex > 0) { // vertexArray[pointIndex] = MyGLfloat2d(vertexArray[pointIndex-1].x, height()); // pointIndex++; //} myassert(pointIndex <= width()*2); //p.setPen(Qt::NoPen); //p.setBrush(gdata->shading1Color()); //p.drawRect(firstN, 0, lastN, height()); //p.setPen(gdata->shading2Color()); //p.setBrush(gdata->shading2Color()); //p.drawPolygon(bottomPoints, false, 0, topBottomPointIndex); qglColor(gdata->shading2Color()); glVertexPointer(2, GL_FLOAT, 0, vertexArray.begin()); glDrawArrays(GL_QUAD_STRIP, 0, pointIndex); } }