void DrawWidget::drawChannelFilled(Channel *ch, QPainter &p, double leftTime, double currentTime, double zoomX, double viewBottom, double zoomY, int viewType) { ZoomLookup *z; if(viewType == DRAW_VIEW_SUMMARY) z = &ch->summaryZoomLookup; else z = &ch->normalZoomLookup; ChannelLocker channelLocker(ch); QColor current = ch->color; QColor invert(255 - current.red(), 255 - current.green(), 255 - current.blue()); p.setPen(current); int viewBottomOffset = toInt(viewBottom / zoomY); viewBottom = double(viewBottomOffset) * zoomY; // baseX is the no. of chunks a pixel must represent. double baseX = zoomX / ch->timePerChunk(); z->setZoomLevel(baseX); double currentChunk = ch->chunkFractionAtTime(currentTime); double leftFrameTime = currentChunk - ((currentTime - leftTime) / ch->timePerChunk()); //double leftFrameTime = leftTime / ch->timePerChunk(); double frameTime = leftFrameTime; //if(frameTime < 0.0) frameTime = 0.0; int n = 0; int baseElement = int(floor(frameTime / baseX)); if(baseElement < 0) { n -= baseElement; baseElement = 0; } int lastBaseElement = int(floor(double(ch->totalChunks()) / baseX)); int firstN = n; int lastN = firstN; //QPointArray pointArray(width()*2); //QPointArray topPoints(width()*2); /* Q3PointArray bottomPoints(width()*2); Q3PointArray evenMidPoints(width()*2); Q3PointArray oddMidPoints(width()*2); Q3PointArray evenMidPoints2(width()*2); Q3PointArray oddMidPoints2(width()*2);*/ QPolygon bottomPoints(width()*2); QPolygon evenMidPoints(width()*2); QPolygon oddMidPoints(width()*2); QPolygon evenMidPoints2(width()*2); QPolygon oddMidPoints2(width()*2); std::vector<QRect> noteRect(width()*2); std::vector<QRect> noteRect2(width()*2); std::vector<bool> isNoteRectEven(width()*2); //int pointIndex = 0; int pointIndex = 0; int evenMidPointIndex = 0; int oddMidPointIndex = 0; int evenMidPointIndex2 = 0; int oddMidPointIndex2 = 0; int rectIndex = 0; int rectIndex2 = 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(ch, ze, baseElement, baseX)) continue; } /*p.setPen(gdata->shading1Color()); p.moveTo(n, 0); p.lineTo(n, height() - 1 - toInt(ze.high / zoomY) + viewBottomOffset); p.setPen(gdata->shading2Color()); p.lineTo(n, height());*/ int y = height() - 1 - toInt(ze.high() / zoomY) + viewBottomOffset; int y2, y3; //if(ze.noteIndex >= 0) { if(ze.noteIndex() != -1 && ch->dataAtChunk(ze.midChunk())->getNoteIndex() != -1) { myassert(ze.noteIndex() >= 0); myassert(ze.noteIndex() < int(ch->noteData.size())); myassert(ch->isValidChunk(ze.midChunk())); AnalysisData *data = ch->dataAtChunk(ze.midChunk()); //double avgNote = ch->noteData[ze.noteIndex()].avgNote(); //printf("avgFreq = %f, ", ch->noteData[ze.noteIndex].avgFreq()); //printf("numPeriods = %f, ", ch->noteData[ze.noteIndex].numPeriods()); //printf("noteLength = %f\n", ch->noteData[ze.noteIndex].noteLength()); //y2 = height() - 1 - toInt((avgNote+0.5) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((avgNote-0.5) / zoomY) + viewBottomOffset; //y2 = height() - 1 - toInt((data->shortTermMean + data->shortTermDeviation) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((data->shortTermMean - data->shortTermDeviation) / zoomY) + viewBottomOffset; if(gdata->showMeanVarianceBars()) { //longTermMean bars y2 = height() - 1 - toInt((data->getLongTermMean() + data->getLongTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getLongTermMean() - data->getLongTermDeviation()) / zoomY) + viewBottomOffset; if(ze.noteIndex() % 2 == 0) { evenMidPoints.setPoint(evenMidPointIndex++, n, y2); evenMidPoints.setPoint(evenMidPointIndex++, n, y3); } else { oddMidPoints.setPoint(oddMidPointIndex++, n, y2); oddMidPoints.setPoint(oddMidPointIndex++, n, y3); } //shortTermMean bars y2 = height() - 1 - toInt((data->getShortTermMean() + data->getShortTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getShortTermMean() - data->getShortTermDeviation()) / zoomY) + viewBottomOffset; if(ze.noteIndex() % 2 == 0) { evenMidPoints2.setPoint(evenMidPointIndex2++, n, y2); evenMidPoints2.setPoint(evenMidPointIndex2++, n, y3); } else { oddMidPoints2.setPoint(oddMidPointIndex2++, n, y2); oddMidPoints2.setPoint(oddMidPointIndex2++, n, y3); } } //} else { // y2 = y3 = 0; } //topPoints.setPoint(pointIndex, n, 0); //topPoints.setPoint(pointIndex, n, y); bottomPoints.setPoint(pointIndex++, n, y); bottomPoints.setPoint(pointIndex++, n, height()); lastN = n; } //p.setPen(gdata->shading1Color()); //p.drawLineSegments(topPoints, 0, pointIndex/2); p.setPen(Qt::NoPen); p.setBrush(gdata->shading1Color()); p.drawRect(firstN, 0, lastN, height()); p.setPen(gdata->shading2Color()); //p.drawLineSegments(bottomPoints, 0, pointIndex/2); if(pointIndex > 1) p.drawLines(bottomPoints.constData(), pointIndex/2); if(gdata->showMeanVarianceBars()) { //shortTermMean bars p.setPen(Qt::green); //p.drawLineSegments(evenMidPoints2, 0, evenMidPointIndex2/2); if(evenMidPointIndex2 > 1) p.drawLines(evenMidPoints2.constData(), evenMidPointIndex2/2); p.setPen(Qt::yellow); //p.drawLineSegments(oddMidPoints2, 0, oddMidPointIndex2/2); if(oddMidPointIndex2 > 1) p.drawLines(oddMidPoints2.constData(), oddMidPointIndex2/2); //longTermMean bars p.setPen(Qt::yellow); //p.drawLineSegments(evenMidPoints, 0, evenMidPointIndex/2); if(evenMidPointIndex > 1) p.drawLines(evenMidPoints.constData(), evenMidPointIndex/2); p.setPen(Qt::green); //p.drawLineSegments(oddMidPoints, 0, oddMidPointIndex/2); if(oddMidPointIndex > 1) p.drawLines(oddMidPoints.constData(), oddMidPointIndex/2); } } else { // More pixels than samples float err = 0.0; float pitch = 0.0; int intChunk = (int) floor(frameTime); // Integer version of frame time if(intChunk < 0) intChunk = 0; double stepSize = 1.0 / baseX; // So we skip some pixels int x = 0, y, y2, y3; //double start = 0 - stepSize; double start = (double(intChunk) - frameTime) * stepSize; double stop = width() + (2 * stepSize); //int squareSize = (int(sqrt(stepSize)) / 2) * 2 + 1; //make it an odd number //int halfSquareSize = squareSize/2; //QPointArray topPoints(0); //QPointArray bottomPoints(0); //int pointIndex = 0; //topPoints.putPoints(pointIndex, 1, toInt(start), 0); //bottomPoints.putPoints(pointIndex, 1, toInt(start), height()); //pointIndex++; //topPoints.setPoint(pointIndex, toInt(start), 0); bottomPoints.setPoint(pointIndex++, toInt(start), height()); lastN = firstN = toInt(start); for (double n = start; n < stop && intChunk < (int)ch->totalChunks(); n += stepSize, intChunk++) { myassert(intChunk >= 0); //if (intChunk < 0) continue; // So we don't go off the beginning of the array AnalysisData *data = ch->dataAtChunk(intChunk); err = data->getCorrelation(); //if (err >= CERTAIN_THRESHOLD) { //float val = MIN(ch->dataAtChunk(intChunk)->volumeValue, 1.0); if(gdata->pitchContourMode() == 0) //p.setPen(QPen(colorBetween(colorGroup().background(), ch->color, err*2.0-1.0), lineWidth)); //p.setPen(QPen(colorBetween(gdata->backgroundColor(), ch->color, err*sqrt(data->rms)*10.0), lineWidth)); p.setPen(QPen(colorBetween(QColor(255, 255, 255), ch->color, err * dB2ViewVal(data->getLogRms())), lineWidth)); else p.setPen(QPen(ch->color, lineWidth)); x = toInt(n); lastN = x; //note = (data->isValid()) ? data->note : 0.0f; //note = (ch->isVisibleNote(data->noteIndex)) ? data->note : 0.0f; pitch = (ch->isVisibleChunk(data)) ? data->getPitch() : 0.0f; //if(ch->isVisibleChunk(data)) { if(data->getNoteIndex() >= 0) { isNoteRectEven[rectIndex] = (data->getNoteIndex() % 2) == 0; //note = data->note; //double avgNote = ch->noteData[data->noteIndex].avgNote(); //y2 = height() - 1 - toInt((avgNote+0.5) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((avgNote-0.5) / zoomY) + viewBottomOffset; //y2 = height() - 1 - toInt((data->shortTermMean + data->shortTermDeviation) / zoomY) + viewBottomOffset; //y3 = height() - 1 - toInt((data->shortTermMean - data->shortTermDeviation) / zoomY) + viewBottomOffset; if(gdata->showMeanVarianceBars()) { //longTermMean bars y2 = height() - 1 - toInt((data->getLongTermMean() + data->getLongTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getLongTermMean() - data->getLongTermDeviation()) / zoomY) + viewBottomOffset; noteRect[rectIndex].setLeft(x); noteRect[rectIndex].setRight(toInt(n+stepSize)); noteRect[rectIndex].setTop(y2); noteRect[rectIndex++].setBottom(y3); //shortTermMean bars y2 = height() - 1 - toInt((data->getShortTermMean() + data->getShortTermDeviation()) / zoomY) + viewBottomOffset; y3 = height() - 1 - toInt((data->getShortTermMean() - data->getShortTermDeviation()) / zoomY) + viewBottomOffset; noteRect2[rectIndex2].setLeft(x); noteRect2[rectIndex2].setRight(toInt(n+stepSize)); noteRect2[rectIndex2].setTop(y2); noteRect2[rectIndex2++].setBottom(y3); } //} else { // note = 0.0f; } myassert(pitch >= 0.0 && pitch <= gdata->topPitch()); //note = bound(note, 0, gdata->topNote()); y = height() - 1 - toInt(pitch / zoomY) + viewBottomOffset; //y = height() - 1 - int((note / zoomY) - (viewBottom / zoomY)); //topPoints.putPoints(pointIndex, 1, x, y); //bottomPoints.putPoints(pointIndex, 1, x, y); //pointIndex++; //topPoints.setPoint(pointIndex, x, y); bottomPoints.setPoint(pointIndex++, x, y); } //topPoints.putPoints(pointIndex, 1, topPoints.point(pointIndex-1).x(), 0); //bottomPoints.putPoints(pointIndex, 1, bottomPoints.point(pointIndex-1).x(), height()); //pointIndex++; //topPoints.setPoint(pointIndex, topPoints.point(pointIndex-1).x(), 0); bottomPoints.setPoint(pointIndex, bottomPoints.point(pointIndex-1).x(), height()); pointIndex++; //p.setPen(gdata->shading1Color()); //p.setBrush(gdata->shading1Color()); //p.drawPolygon(topPoints); //p.setPen(gdata->shading2Color()); //p.setBrush(gdata->shading2Color()); //p.drawPolygon(bottomPoints); myassert(pointIndex <= width()*2); //p.setPen(gdata->shading1Color()); p.setPen(Qt::NoPen); p.setBrush(gdata->shading1Color()); //p.drawPolygon(topPoints, false, 0, pointIndex); p.drawRect(firstN, 0, lastN, height()); //p.setPen(gdata->shading2Color()); p.setBrush(gdata->shading2Color()); //p.drawPolygon(bottomPoints, false, 0, pointIndex); p.drawPolygon(bottomPoints.constData(), pointIndex, Qt::OddEvenFill); if(gdata->showMeanVarianceBars()) { //shortTermMean bars for(int j=0; j<rectIndex2; j++) { if(isNoteRectEven[j]) p.setBrush(Qt::green); else p.setBrush(Qt::yellow); p.drawRect(noteRect2[j]); } //longTermMean bars QColor seeThroughYellow = Qt::yellow; seeThroughYellow.setAlpha(255); QColor seeThroughGreen = Qt::green; seeThroughGreen.setAlpha(255); for(int j=0; j<rectIndex; j++) { //if(isNoteRectEven[j]) p.setBrush(QBrush(Qt::yellow, Qt::Dense3Pattern)); //else p.setBrush(QBrush(Qt::green, Qt::Dense3Pattern)); if(isNoteRectEven[j]) p.setBrush(seeThroughYellow); else p.setBrush(seeThroughGreen); p.drawRect(noteRect[j]); } } } }
void VibratoTimeAxis::doUpdate() { Channel *active = gdata->getActiveChannel(); int myStartChunk = -1; int myCurrentChunk = -1; int myEndChunk = -1; double myNoteLength = 0.0; int myWindowOffset = -999999; if (active) { AnalysisData *data = active->dataAtCurrentChunk(); if(data && active->isVisibleNote(data->getNoteIndex()) && active->isLabelNote(data->getNoteIndex())) { NoteData *note = new NoteData(); note = &active->noteData[data->getNoteIndex()]; myStartChunk = note->startChunk(); myCurrentChunk = active->chunkAtCurrentTime(); myEndChunk = note->endChunk(); myNoteLength = note->noteLength(); // Calculate windowoffset if ((myEndChunk - myStartChunk) * zoomFactorX > width() - 2 * noteLabelOffset) { // The vibrato-polyline doesn't fit in the window if ((myCurrentChunk - myStartChunk) * zoomFactorX < (width() - 2 * noteLabelOffset)/2) { // We're at the left side of the vibrato-polyline myWindowOffset = 0 - noteLabelOffset; } else if ((myEndChunk - myCurrentChunk) * zoomFactorX < (width() - 2 * noteLabelOffset)/2) { // We're at the right side of the vibrato-polyline myWindowOffset = toInt((myEndChunk - myStartChunk) * zoomFactorX - width() + noteLabelOffset + 1); } else { // We're somewhere in the middle of the vibrato-polyline myWindowOffset = toInt((myCurrentChunk - myStartChunk) * zoomFactorX - width()/2); } } else { // The vibrato-polyline does fit in the window myWindowOffset = 0 - noteLabelOffset; } } } if (myCurrentChunk == -1) { // No note if (prevCurrentChunk == myCurrentChunk) { // Still no timeaxis needed, no update needed } else { // Timeaxis should be erased, update widget prevCurrentChunk = -1; prevWindowOffset = -999999; currentChunkToUse = -1; } } else { // Note if (prevWindowOffset == myWindowOffset) { // No movement, don't redraw timeaxis } else { // Position in note to draw has changed, so draw the timeaxis prevCurrentChunk = myCurrentChunk; prevWindowOffset = myWindowOffset; startChunkToUse = myStartChunk; currentChunkToUse = myCurrentChunk; endChunkToUse = myEndChunk; noteLengthToUse = myNoteLength; windowOffsetToUse = myWindowOffset; } } }