bool TrajectoryAnalysisModuleData::Impl::isInitialized(
        const AnalysisData &data) const
{
    for (int i = 0; i < data.dataSetCount(); ++i)
    {
        if (data.columnCount(i) > 0)
        {
            // If not all of the column counts are set, startData() in the
            // constructor asserts, so that does not need to be checked here.
            return true;
        }
    }
    return false;
}
Exemple #2
0
int
AnalysisTemplate::initAnalysis(const TopologyInformation & /*top*/)
{
    _data.setColumns(_sel.size());
    registerAnalysisDataset(&_data, "avedist");

    _avem = new AnalysisDataAverageModule();
    _data.addModule(_avem);

    if (!_fnDist.empty())
    {
        AnalysisDataPlotModule *plotm = new AnalysisDataPlotModule(_options);
        plotm->setFileName(_fnDist);
        plotm->setTitle("Average distance");
        plotm->setXLabel("Time (ps)");
        plotm->setYLabel("Distance (nm)");
        _data.addModule(plotm);
    }
    return 0;
}
Exemple #3
0
void
AnalysisTemplate::initAnalysis(const TrajectoryAnalysisSettings &settings,
                               const TopologyInformation         & /*top*/)
{
    nb_.setCutoff(cutoff_);

    data_.setColumnCount(0, sel_.size());

    avem_.reset(new AnalysisDataAverageModule());
    data_.addModule(avem_);

    if (!fnDist_.empty())
    {
        AnalysisDataPlotModulePointer plotm(
                new AnalysisDataPlotModule(settings.plotSettings()));
        plotm->setFileName(fnDist_);
        plotm->setTitle("Average distance");
        plotm->setXAxisIsTime();
        plotm->setYLabel("Distance (nm)");
        data_.addModule(plotm);
    }
}
Exemple #4
0
void DrawWidget::setChannelVerticalView(Channel *ch, double leftTime, double currentTime, double zoomX, double viewBottom, double zoomY)
{
  ZoomLookup *z = &ch->normalZoomLookup;
    
  ChannelLocker channelLocker(ch);

  int viewBottomOffset = toInt(viewBottom / zoomY);
  viewBottom = double(viewBottomOffset) * zoomY;

  std::vector<float> ys;
  ys.reserve(width());
  std::vector<float> weightings;
  weightings.reserve(width());
  float maxY = 0.0f, minY = gdata->topPitch();
  float totalY = 0.0f;
  float numY = 0.0f;
  
  // 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 frameTime = leftFrameTime;
  int n = 0;
  int currentBaseElement = int(floor(currentChunk / baseX));
  int firstBaseElement = int(floor(frameTime / baseX));
  int baseElement = firstBaseElement;
  if(baseElement < 0) { n -= baseElement; baseElement = 0; }
  int lastBaseElement = int(floor(double(ch->totalChunks()) / baseX));
  double leftBaseWidth = MAX(1.0, double(currentBaseElement - firstBaseElement));
  double rightBaseWidth = MAX(1.0, double(lastBaseElement - currentBaseElement));
  
/*
  We calculate the auto follow and scale by averaging all the note elements in view.
  We weight the frequency averaging by a triangle weighting function centered on the current time.
  Also it is weighted by the corr value of each frame.
             /|\
            / | \
           /  |  \
          /   |   \
            ^   ^
 leftBaseWidth rightBaseWidth
*/

  
  //QPointArray bottomPoints(width()*2);
  //int pointIndex = 0;
      
  if (baseX > 1) { // More samples than pixels
    int theWidth = width();
    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;
      }
      if(ze.low() > 0.0f && ze.high() > 0.0f) {
        float weight = ze.corr();
        if(baseElement < currentBaseElement) weight *= double(currentBaseElement - baseElement) / leftBaseWidth;
        else if(baseElement > currentBaseElement) weight *= double(baseElement - currentBaseElement) / rightBaseWidth;
        if(ze.low() < minY) minY = ze.low();
        if(ze.high() > maxY) maxY = ze.high();
        totalY += (ze.low() + ze.high()) / 2.0f * weight;
        numY += weight;
        ys.push_back((ze.low() + ze.high()) / 2.0f);
        weightings.push_back(weight);
      }
/*
      int y = height() - 1 - toInt(ze.high / zoomY) + viewBottomOffset;
      bottomPoints.setPoint(pointIndex++, n, y);
      bottomPoints.setPoint(pointIndex++, n, height());
*/
    }
/*
    p.setPen(Qt::NoPen);
    p.setBrush(gdata->shading1Color());
    p.drawRect(firstN, 0, lastN, height());
    p.setPen(gdata->shading2Color());
    p.drawLineSegments(bottomPoints, 0, pointIndex/2);
*/
  } else { // More pixels than samples
    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
    float corr;
    
    double start = (double(intChunk) - frameTime) * stepSize;
    double stop = width() + (2 * stepSize);
    //bottomPoints.setPoint(pointIndex++, toInt(start), height());
    for (double n = start; n < stop && intChunk < (int)ch->totalChunks(); n += stepSize, intChunk++) {
      myassert(intChunk >= 0);
      AnalysisData *data = ch->dataAtChunk(intChunk);
      
/*
      if(gdata->pitchContourMode() == 0)
        p.setPen(QPen(colorBetween(gdata->backgroundColor(),  ch->color, err*sqrt(data->rms)*10.0), lineWidth));
      else
        p.setPen(QPen(ch->color, lineWidth));
*/
      pitch = (ch->isVisibleChunk(data)) ? data->getPitch() : 0.0f;
      myassert(pitch >= 0.0 && pitch <= gdata->topPitch());
      //corr = data->correlation*sqrt(data->rms)*10.0;
      corr = data->getCorrelation() * dB2ViewVal(data->getLogRms());
      if(pitch > 0.0f) {
        float weight = corr;
        if(minY < pitch) minY = pitch;
        if(maxY > pitch) maxY = pitch;
        totalY += pitch * weight;
        numY += weight;
        ys.push_back(pitch);
        weightings.push_back(weight);
      }
      //bottomPoints.setPoint(pointIndex++, x, y);
    }
    //bottomPoints.setPoint(pointIndex, bottomPoints.point(pointIndex-1).x(), height());
    //pointIndex++;

/*
    myassert(pointIndex <= width()*2);
    p.setPen(Qt::NoPen);
    p.setBrush(gdata->shading1Color());
    p.drawRect(firstN, 0, lastN, height());
    p.setBrush(gdata->shading2Color());
    p.drawPolygon(bottomPoints, false, 0, pointIndex);
*/
  }
  
  if(!ys.empty() > 0) {
    float meanY = totalY / numY;
    double spred = 0.0;
    myassert(ys.size() == weightings.size());
    //use a linear spred function. not a squared one like standard deviation
    for(uint j=0; j<ys.size(); j++) {
      spred += sq(ys[j] - meanY) * weightings[j];
    }
    spred = sqrt(spred / numY) * 4.0;
    //printf("spred = %f\n", spred);
    if(spred < 12.0) spred = 12.0; //show a minimum of 12 semi-tones
    gdata->view->setViewBottomRaw(meanY - gdata->view->viewHeight() / 2.0);
    //gdata->view->setLogZoomYRaw(log(height()/spred));
  }
}
Exemple #5
0
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]);
      }
    }
  }
}
Exemple #6
0
void DrawWidget::drawChannel(QPaintDevice &pd, 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);
  printf("viewBottomOffset=%d, %f, %f\n", viewBottomOffset, 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));
  
  Q3PointArray pointArray(pd.width()*2);
  //QPointArray topPoints(width()*2);
  //QPointArray bottomPoints(width()*2);
  //int pointIndex = 0;
  //int pointIndex = 0;
      
 	if (baseX > 1) { // More samples than pixels
    int theWidth = pd.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(!ze.isValid()) {
        if(calcZoomElement(ch, ze, baseElement, baseX)) continue;
      }
     
      if(ze.high() != 0.0f && ze.high() - ze.low() < 1.0) { //if range is closer than one semi-tone then draw a line between them
      //if(ze.noteLow > 0) {
        p.setPen(ze.color());
        //p.setPen(QPen(ze.color(), lineWidth));
        //Note: lineTo doen't draw a pixel on the last point of the line
        p.drawLine(n, pd.height() - lineTopHalfWidth - toInt(ze.high() / zoomY) + viewBottomOffset, n, pd.height() + lineBottomHalfWidth - toInt(ze.low() / zoomY) + viewBottomOffset);
        //pointArray.setPoint(pointIndex++, n, height() - lineTopHalfWidth    - toInt(ze.high / zoomY) + viewBottomOffset);
        //pointArray.setPoint(pointIndex++, n, height() + lineBottomHalfWidth - toInt(ze.low  / zoomY) + viewBottomOffset);
      }
    }
    //myassert(pointIndex <= width()*2);
    //p.setPen(ch->color);
    //p.drawLineSegments(pointArray, 0, pointIndex/2);

 	} else { // More pixels than samples
    float err = 0.0, pitch = 0.0, prevPitch = 0.0, vol;
    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;
  
    //double start = 0 - stepSize;
    double start = (double(intChunk) - frameTime) * stepSize;
    double stop = pd.width() + (2 * stepSize);
    int squareSize = (int(sqrt(stepSize)) / 2) * 2 + 1; //make it an odd number
    int halfSquareSize = squareSize/2;
    int penX=0, penY=0;
    //topPoints.setPoint(pointIndex, toInt(start), 0);
    //bottomPoints.setPoint(pointIndex++, toInt(start), height());
    
    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();
      //vol = dB2ViewVal(data->logrms(), ch->rmsCeiling, ch->rmsFloor);
      vol = dB2Normalised(data->getLogRms(), ch->rmsCeiling, ch->rmsFloor);
      //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));
        if(viewType == DRAW_VIEW_PRINT)
          p.setPen(QPen(colorBetween(QColor(255, 255, 255), ch->color, err*vol), lineWidth));
        else
          p.setPen(QPen(colorBetween(gdata->backgroundColor(), ch->color, err*vol), lineWidth));
      else
        p.setPen(QPen(ch->color, lineWidth));
      
      x = toInt(n);
      //note = (data->isValid()) ? data->note : 0.0f;
      //note = (ch->isVisibleNote(data->noteIndex)) ? data->note : 0.0f;
      pitch = (ch->isVisibleChunk(data)) ? data->getPitch() : 0.0f;
      myassert(pitch >= 0.0 && pitch <= gdata->topPitch());
      //pitch = bound(pitch, 0, gdata->topPitch());
      y = pd.height() - 1 - toInt(pitch / zoomY) + viewBottomOffset;
      //y = height() - 1 - int((note / zoomY) - (viewBottom / zoomY));
      if(pitch > 0.0f) {
        if(fabs(prevPitch - pitch) < 1.0 && n != start) { //if closer than one semi-tone from previous then draw a line between them
          //p.lineTo(x, y);
          p.drawLine(penX, penY, x, y);
          penX = x; penY = y;
        } else {
          p.drawPoint(x, y);
          //p.moveTo(x, y);
          penX = x; penY = y;
        }
        if(stepSize > 10) { //draw squares on the data points
          //p.setPen(invert);
          p.setBrush(Qt::NoBrush);
          p.drawRect(x - halfSquareSize, y - halfSquareSize, squareSize, squareSize);
          //p.setPen(QPen(current, 2));
        }
        //} else {
        //  p.moveTo(x, height()-1-int(((note-viewBottom) / zoomY)));
        //}
      }
      prevPitch = pitch;
    }
  }
}
void CorrelationWidget::paintEvent( QPaintEvent * )
{
  Channel *active = gdata->getActiveChannel();

  AnalysisData *data = NULL;
  int chunk=0;
  double dh2 = double(height()-1) / 2.0;
  int j, x, y;
    
  beginDrawing(false);
    
  if(active) {
    
    active->lock();
    chunk = active->currentChunk();
    data = active->dataAtChunk(chunk);

    //int centerX = width() / 2;
    if(data) {
      double freq = data->getFundamentalFreq();
      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->getCorrelation());
        QColor color2 = colorBetween(gdata->backgroundColor(), gdata->shading2Color(), data->getCorrelation());
        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->getCorrelation()));
        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->getPeriodEstimatesSize()); j++) {
        x = toInt(double(data->getPeriodEstimatesAt(j)) * ratio);
        y = toInt(dh2 - data->getPeriodEstimatesAmpAt(j) * dh2);
        p.drawEllipse(x-2, y-2, 5, 5);
      }
      
      if(data->getHighestCorrelationIndex() >= 0) {
        float highest = data->getPeriodEstimatesAmpAt(data->getHighestCorrelationIndex());
        //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->getPeriodEstimatesAt(data->getHighestCorrelationIndex())) * ratio);
        y = toInt(dh2 - highest * dh2);
        p.drawEllipse(x-2, y-2, 5, 5);
      }
      
      //draw a dot at the chosen correlation period
      if(data->getChosenCorrelationIndex() >= 0) {
        p.setPen(Qt::red);
        p.setBrush(Qt::red);
        //x = toInt(double(data->chosenCorrelationIndex) * ratio);
        //y = toInt(dh2 - chosen * dh2);
        x = toInt(double(data->getPeriodEstimatesAt(data->getChosenCorrelationIndex())) * ratio);
        y = toInt(dh2 - data->getPeriodEstimatesAmpAt(data->getChosenCorrelationIndex()) * dh2);
        p.drawEllipse(x-2, y-2, 5, 5);
      }

      //draw a line at the chosen correlation period
      if(data->getChosenCorrelationIndex() >= 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 MyTransforms::calculateAnalysisData(float *input, AnalysisData &analysisData, Channel *ch, float threshold)
void MyTransforms::calculateAnalysisData(/*float *input, */int chunk, Channel *ch/*, float threshold*/)
{
  myassert(ch);
  myassert(ch->dataAtChunk(chunk));
  AnalysisData &analysisData = *ch->dataAtChunk(chunk);
  AnalysisData *prevAnalysisData = ch->dataAtChunk(chunk-1);
  //Array1d<float> output(k);
  float *output = ch->nsdfData.begin();
  float *curInput = (equalLoudness) ? ch->filteredInput.begin() : ch->directInput.begin();

  std::vector<int> nsdfMaxPositions;
  //int pos = 0;
  //int curMaxPos = 0;
  //float corrError = 0.0f;
  //freqPerBin = rate / 2.0 / double(size);

  //analysisData.maxIntensity = fabs(*std::max_element(input, input+n, absoluteLess()));
  analysisData.maxIntensityDB() = linear2dB(fabs(*std::max_element(curInput, curInput+n, absoluteLess<float>())));
  
  //if(gdata->doingActiveFFT()) {
    //std::copy(curInput, curInput+n, dataTime);
  doChannelDataFFT(ch, curInput, chunk);
    //std::copy(dataTemp, dataTemp+n, dataTime);
  //}
  std::copy(curInput, curInput+n, dataTime);
  
  //if(!gdata->doingActiveAnalysis()) return;
  //if(gdata->doingFreqAnalysis()) {
  if(gdata->doingFreqAnalysis() && (ch->firstTimeThrough() || gdata->doingActiveAnalysis())) {
    //calculate the Normalised Square Difference Function
    //analysisData.rms = nsdf(dataTime, output.begin()) / double(n/*size*/);
    //analysisData.rms = nsdf(dataTime, output) / double(n/*size*/);
    double logrms = linear2dB(nsdf(dataTime, ch->nsdfData.begin()) / double(n)); /**< Do the NSDF calculation */
    analysisData.logrms() = logrms;
    if(gdata->doingAutoNoiseFloor() && !analysisData.done) {
      //do it for gdata. this is only here for old code. remove some stage
      if(chunk == 0) { gdata->rmsFloor() = 0.0; gdata->rmsCeiling() = gdata->dBFloor(); }
      if(logrms+15 < gdata->rmsFloor()) gdata->rmsFloor() = logrms+15;
      if(logrms > gdata->rmsCeiling()) gdata->rmsCeiling() = logrms;

      //do it for the channel
      if(chunk == 0) { ch->rmsFloor = 0.0; ch->rmsCeiling = gdata->dBFloor(); }
      if(logrms+15 < ch->rmsFloor) ch->rmsFloor = logrms+15;
      if(logrms > ch->rmsCeiling) ch->rmsCeiling = logrms;
    }
    //if(!analysisData.done) {
      //analysisData.notePlaying = ch->isNotePlaying();
      //if(ch->isNotePlaying()) 
      //  addTo(ch->nsdfData.begin(), ch->nsdfData.end(), ch->nsdfAggregateData.begin());
    //}

    //analysisData.freqCentroid() = calcFreqCentroid(storeFFT, size);
    analysisData.freqCentroid() = calcFreqCentroidFromLogMagnitudes(ch->fftData1.begin(), ch->fftData1.size());
    if(prevAnalysisData)
      analysisData.deltaFreqCentroid() = bound(fabs(analysisData.freqCentroid() - prevAnalysisData->freqCentroid())*20.0, 0.0, 1.0);
    else 
      analysisData.deltaFreqCentroid() = 0.0;
    
    findNSDFMaxima(ch->nsdfData.begin(), k, nsdfMaxPositions);
    if(!analysisData.done) {
      //if(ch->isNotePlaying()) {
        //analysisData.periodOctaveEstimate = ch->calcOctaveEstimate(chunk, threshold);
/*
        findNSDFMaxima(ch->nsdfAggregateData.begin(), k, nsdfAggregateMaxPositions);
        myassert(!nsdfAggregateMaxPositions.empty());
  
        //get the highest nsdfAggregateMaxPosition
        uint j;
        int nsdfAggregateMaxIndex = 0;
        int nsdfAggregateChoosenIndex = 0;
        for(j=1; j<nsdfAggregateMaxPositions.size(); j++) {
          if(ch->nsdfAggregateData[nsdfAggregateMaxPositions[j]] > ch->nsdfAggregateData[nsdfAggregateMaxPositions[nsdfAggregateMaxIndex]]) nsdfAggregateMaxIndex = j;
        }
        //get the choosen nsdfAggregateMaxPosition
        float nsdfAggregateCutoff = ch->nsdfAggregateData[nsdfAggregateMaxPositions[nsdfAggregateMaxIndex]] * threshold;
        for(j=0; j<nsdfAggregateMaxPositions.size(); j++) {
          if(ch->nsdfAggregateData[nsdfAggregateMaxPositions[j]] >= nsdfAggregateCutoff) { nsdfAggregateChoosenIndex = j; break; }
        }
        analysisData.periodOctaveEstimate = float(nsdfAggregateMaxPositions[nsdfAggregateChoosenIndex]+1); //add 1 for index offset, ie position 0 = 1 period
*/
    }

    //store some of the best period estimates
    analysisData.periodEstimates.clear();
    analysisData.periodEstimatesAmp.clear();
    //float smallThreshold = 0.7f;
    //float smallCutoff = output[overallMaxIndex] * smallThreshold;
    float smallCutoff = 0.4f;
    for(std::vector<int>::iterator iter = nsdfMaxPositions.begin(); iter < nsdfMaxPositions.end(); iter++) {
      if(output[*iter] >= smallCutoff) {
        //analysisData.periodEstimates.push_back(double(*iter + 1) + parabolaTurningPoint(output[*iter-1], output[*iter], output[*iter+1]));
        //analysisData.periodEstimatesAmp.push_back(output[*iter]); //TODO: These should be calculated more accurately
        float x, y;
        //do a parabola fit to find the maximum
        parabolaTurningPoint2(output[*iter-1], output[*iter], output[*iter+1], float(*iter + 1), &x, &y);
        y = bound(y, -1.0f, 1.0f);
        analysisData.periodEstimates.push_back(x);
        analysisData.periodEstimatesAmp.push_back(y);
      }
    }
    
    float periodDiff = 0.0f;
    //if(maxPositions.empty()) { //no period found
    if(analysisData.periodEstimates.empty()) { //no period found
      //analysisData.correlation() = 0.0f;
      analysisData.calcScores();
      analysisData.done = true;
      //goto finished; //return;
    } else {
      //calc the periodDiff
      if(chunk > 0 && prevAnalysisData->highestCorrelationIndex!=-1) {
        float prevPeriod = prevAnalysisData->periodEstimates[prevAnalysisData->highestCorrelationIndex];
        std::vector<float>::iterator closestIter = binary_search_closest(analysisData.periodEstimates.begin(), analysisData.periodEstimates.end(), prevPeriod);
        //print_elements(analysisData.periodEstimates.begin(), analysisData.periodEstimates.end());
        //printf("closestIter = %f, %f\n", *closestIter, prevPeriod);
        periodDiff = *closestIter - prevPeriod;
        if(absolute(periodDiff) > 8.0f) periodDiff = 0.0f;
      }

      int nsdfMaxIndex = int(std::max_element(analysisData.periodEstimatesAmp.begin(), analysisData.periodEstimatesAmp.end()) - analysisData.periodEstimatesAmp.begin());
      analysisData.highestCorrelationIndex = nsdfMaxIndex;

      if(!analysisData.done) {
        //if(gdata->doingActiveCepstrum()) {
        if(gdata->analysisType() == MPM_MODIFIED_CEPSTRUM) {
            ch->chooseCorrelationIndex(chunk, float(analysisData.cepstrumIndex)); //calculate pitch
        } else {
          if(ch->isNotePlaying() && chunk > 0) {
            //ch->chooseCorrelationIndex(chunk, ch->getLastNote()->periodOctaveEstimate()); //calculate pitch
            //ch->chooseCorrelationIndex(chunk, ch->periodOctaveEstimate(std::max(0, chunk-1))); //calculate pitch
            ch->chooseCorrelationIndex(chunk, ch->periodOctaveEstimate(chunk-1)); //calculate pitch
          } else {
            ch->chooseCorrelationIndex1(chunk); //calculate pitch
          }
          //ch->chooseCorrelationIndex(chunk, (float)ch->rate() / 440.0f); //calculate pitch
        }
        ch->calcDeviation(chunk);

        ch->doPronyFit(chunk); //calculate vibratoPitch, vibratoWidth, vibratoSpeed
      }

      analysisData.changeness() = 0.0f;
      //analysisData.changeness() = get_max_note_change(dataTime, analysisData.period);

      if(gdata->doingHarmonicAnalysis()) {
        std::copy(dataTime, dataTime+n, dataTemp);
        if(analysisData.chosenCorrelationIndex >= 0)
          doHarmonicAnalysis(dataTemp, analysisData, analysisData.periodEstimates[analysisData.chosenCorrelationIndex]/*period*/);
        //doHarmonicAnalysis(input, analysisData, period);
      }

      //analysisData.volumeValue = (dB2Normalised(analysisData.logrms) + (analysisData.correlation-1.0f)) * 0.2;
    }

    //float periodDiff = 0.0f;
    if(gdata->doingFreqAnalysis() && ch->doingDetailedPitch() && ch->firstTimeThrough()) {
      //periodDiff = ch->calcDetailedPitch(curInput, analysisData.period, chunk);
      float periodDiff2 = ch->calcDetailedPitch(curInput, analysisData.period, chunk);
      //printf("chunk=%d, %f, %f\n", chunk, periodDiff, periodDiff2);
      periodDiff = periodDiff2;

      ch->pitchLookup.push_back(ch->detailedPitchData.begin(), ch->detailedPitchData.size());
      ch->pitchLookupSmoothed.push_back(ch->detailedPitchDataSmoothed.begin(), ch->detailedPitchDataSmoothed.size());
/*      float periodDiff1 = (rate / pitch2freq(ch->detailedPitchData.back()));
      float periodDiff2 = (rate / pitch2freq(ch->detailedPitchData.front()));
      periodDiff = periodDiff1 - periodDiff2;
      printf("%f, %f, %f\n", periodDiff1, periodDiff2, periodDiff);
*/
    }

    if(!analysisData.done) {
      analysisData.calcScores();
      ch->processNoteDecisions(chunk, periodDiff);
      analysisData.done = true;
    }

    if(gdata->doingFreqAnalysis() && ch->doingDetailedPitch() && ch->firstTimeThrough()) {
      ch->calcVibratoData(chunk);
    }
  }

  if(gdata->doingFreqAnalysis() && ch->doingDetailedPitch() && (!ch->firstTimeThrough())) {
    ch->pitchLookup.copyTo(ch->detailedPitchData.begin(), chunk*ch->detailedPitchData.size(), ch->detailedPitchData.size());
    ch->pitchLookupSmoothed.copyTo(ch->detailedPitchDataSmoothed.begin(), chunk*ch->detailedPitchDataSmoothed.size(), ch->detailedPitchDataSmoothed.size());
  }

  if(!analysisData.done) {
    int j;
    //calc rms by hand
    double rms = 0.0;
    for(j=0; j<n; j++) {
      rms += sq(dataTime[j]);
    }
    //analysisData.rms = sqrt(analysisData.rms);
    analysisData.logrms() = linear2dB(rms / float(n));
    analysisData.calcScores();
    analysisData.done = true;
  }

}
Exemple #9
0
//------------------------------------------------------------------------------
bool lessFundametalFreq::operator()(const AnalysisData & x, const AnalysisData & y)
{
  return x.getFundamentalFreq() < y.getFundamentalFreq();
}
Exemple #10
0
void HBlockWidget::paintEvent( QPaintEvent * )
{
  Channel *active = gdata->getActiveChannel();
  
  beginDrawing();
    
  if(active) {
    AnalysisData *theData = active->dataAtCurrentChunk();
    if(theData) {
  
      //get a copy of theData so we don't hold the mutex for too long
      active->lock();
      AnalysisData data = *theData;
      active->unlock();
  
      // We have harmonicFreq - the actual frequencies of the harmonies - and harmonicAmp, their amplitude
      //std::vector<float> harmonicFreq = active->lookup[frame].harmonicFreq;
      std::vector<float> harmonicFreq = data.harmonicFreq;
      // harmonicAmp values range between 0-1
      //std::vector<float> harmonicAmp = active->lookup[frame].harmonicAmp;
      std::vector<float> harmonicAmp = data.harmonicAmp;
  
      // Get the frame's fundamental frequency
      //float fund = active->lookup[frame].fundamentalFreq;
      float fund = data.fundamentalFreq;
  
      // Work out the bar height for each harmonic
      double barHeight = double(height()) / double(harmonicFreq.size());
      QColor fillColor = colorBetween(colorGroup().background(), active->color, data.volumeValue());
      QColor outlineColor = colorBetween(colorGroup().background(), Qt::black, data.volumeValue());
      p.setBrush(fillColor);
  
      int barStart = 0;
      float barWidth = 0;
      int diff = 0;
      /*
      * Each note has a fundamental frequency f, which comes from the lookup table.
      * The harmonic frequencies are defined as f, 2f, 3f, 4f, 5f...
      * harmonicFreq stores what the harmonics have been calculated to be.
      */
      for (uint i = 0; i < harmonicFreq.size(); i++) {
        p.setPen(outlineColor);
        p.setBrush(colorBetween(fillColor, Qt::black, data.harmonicNoise[i]));
        // Work out how many pixels wide the harmonic should be
        barWidth = (harmonicAmp.at(i)) * width();
        /* Work out how many pixels the harmonic should be offset from where it would be
        * if it were exactly (i+1)f   */
        //diff = toInt( (harmonicFreq.at(i) - (i+1) * fund) / fund * width() / 10.0 );
        diff = toInt( (harmonicFreq.at(i) - (i+1) * fund) / fund * barWidth );
        // Work out the starting position, and draw the bar
        barStart = toInt( ((width() / 2) + diff) - barWidth / 2);
	     int barBottom = height() - toInt(barHeight * i);
        p.drawRect(barStart, barBottom, toInt(barWidth), -toInt(barHeight));
        // Draw the centre line on the bar
        p.setPen(Qt::white);
        p.drawLine((width() / 2) + diff, barBottom, (width() / 2) + diff, barBottom - toInt(barHeight));
      }
      // Draw the exact line (f, 2f, 3f...)
      p.setPen(Qt::white);
      p.drawLine(width() / 2, 0, width() /2, height());
    }
  }
  endDrawing();
}
Exemple #11
0
//------------------------------------------------------------------------------
bool greaterValue::operator()(const AnalysisData &x, const AnalysisData &y)
{
  return x.getValue(v) > y.getValue(v);
}
Exemple #12
0
//------------------------------------------------------------------------------
bool lessValue::operator()(const AnalysisData &x, const AnalysisData &y)
{
  return x.getValue(v) < y.getValue(v);
}
Exemple #13
0
//------------------------------------------------------------------------------
bool greaterPitch::operator()(const AnalysisData &x, const AnalysisData &y)
{
  return x.getPitch() > y.getPitch();
}
Exemple #14
0
//------------------------------------------------------------------------------
bool lessPitch::operator()(const AnalysisData &x, const AnalysisData &y)
{
  return x.getPitch() < y.getPitch();
}
Exemple #15
0
//------------------------------------------------------------------------------
bool greaterFundametalFreq::operator()(const AnalysisData &x, const AnalysisData &y)
{
  return x.getFundamentalFreq() > y.getFundamentalFreq();
}
Exemple #16
0
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;
    }
  }
}
//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);
  }
}