Ejemplo n.º 1
0
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 = &currentNote->nsdfAggregateData;
        else if(aggregateMode == 2) input = &currentNote->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();
}
Ejemplo n.º 2
0
//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);
  }
}