comparison layer/WaveformLayer.cpp @ 1474:36ad3cdabf55 by-id

Further layer updates for ModelById
author Chris Cannam
date Tue, 02 Jul 2019 14:08:44 +0100
parents f2525e6cbdf1
children 1ccb64bfb22b
comparison
equal deleted inserted replaced
1473:886c1cd48f9d 1474:36ad3cdabf55
39 using std::vector; 39 using std::vector;
40 40
41 41
42 WaveformLayer::WaveformLayer() : 42 WaveformLayer::WaveformLayer() :
43 SingleColourLayer(), 43 SingleColourLayer(),
44 m_model(nullptr),
45 m_gain(1.0f), 44 m_gain(1.0f),
46 m_autoNormalize(false), 45 m_autoNormalize(false),
47 m_showMeans(true), 46 m_showMeans(true),
48 m_channelMode(SeparateChannels), 47 m_channelMode(SeparateChannels),
49 m_channel(-1), 48 m_channel(-1),
62 61
63 const ZoomConstraint * 62 const ZoomConstraint *
64 WaveformLayer::getZoomConstraint() const 63 WaveformLayer::getZoomConstraint() const
65 { 64 {
66 auto model = ModelById::get(m_model); 65 auto model = ModelById::get(m_model);
67 if (model) return m_model->getZoomConstraint(); 66 if (model) return model->getZoomConstraint();
68 else return nullptr; 67 else return nullptr;
69 } 68 }
70 69
71 void 70 void
72 WaveformLayer::setModel(ModelId modelId) 71 WaveformLayer::setModel(ModelId modelId)
112 PropertyList list = SingleColourLayer::getProperties(); 111 PropertyList list = SingleColourLayer::getProperties();
113 list.push_back("Scale"); 112 list.push_back("Scale");
114 list.push_back("Gain"); 113 list.push_back("Gain");
115 list.push_back("Normalize Visible Area"); 114 list.push_back("Normalize Visible Area");
116 115
117 if (m_model && m_model->getChannelCount() > 1 && m_channel == -1) { 116 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
117 if (model && model->getChannelCount() > 1 && m_channel == -1) {
118 list.push_back("Channels"); 118 list.push_back("Channels");
119 } 119 }
120 120
121 return list; 121 return list;
122 } 122 }
339 339
340 int 340 int
341 WaveformLayer::getCompletion(LayerGeometryProvider *) const 341 WaveformLayer::getCompletion(LayerGeometryProvider *) const
342 { 342 {
343 int completion = 100; 343 int completion = 100;
344 if (!m_model || !m_model->isOK()) return completion; 344 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
345 if (m_model->isReady(&completion)) return 100; 345 if (!model || !model->isOK()) return completion;
346 if (model->isReady(&completion)) return 100;
346 return completion; 347 return completion;
347 } 348 }
348 349
349 bool 350 bool
350 WaveformLayer::getValueExtents(double &min, double &max, 351 WaveformLayer::getValueExtents(double &min, double &max,
377 int 378 int
378 WaveformLayer::getChannelArrangement(int &min, int &max, 379 WaveformLayer::getChannelArrangement(int &min, int &max,
379 bool &merging, bool &mixing) 380 bool &merging, bool &mixing)
380 const 381 const
381 { 382 {
382 if (!m_model || !m_model->isOK()) return 0; 383 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
383 384 if (!model || !model->isOK()) return 0;
384 int channels = m_model->getChannelCount(); 385
386 int channels = model->getChannelCount();
385 if (channels == 0) return 0; 387 if (channels == 0) return 0;
386 388
387 int rawChannels = channels; 389 int rawChannels = channels;
388 390
389 if (m_channel == -1) { 391 if (m_channel == -1) {
422 bool 424 bool
423 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v, 425 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v,
424 int x, int modelZoomLevel, 426 int x, int modelZoomLevel,
425 sv_frame_t &f0, sv_frame_t &f1) const 427 sv_frame_t &f0, sv_frame_t &f1) const
426 { 428 {
429 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
430 if (!model) return false;
431
427 sv_frame_t viewFrame = v->getFrameForX(x); 432 sv_frame_t viewFrame = v->getFrameForX(x);
428 if (viewFrame < 0) { 433 if (viewFrame < 0) {
429 f0 = 0; 434 f0 = 0;
430 f1 = 0; 435 f1 = 0;
431 return false; 436 return false;
442 f1 = viewFrame; 447 f1 = viewFrame;
443 f1 = f1 / modelZoomLevel; 448 f1 = f1 / modelZoomLevel;
444 f1 = f1 * modelZoomLevel; 449 f1 = f1 * modelZoomLevel;
445 } 450 }
446 451
447 return (f0 < m_model->getEndFrame()); 452 return (f0 < model->getEndFrame());
448 } 453 }
449 454
450 float 455 float
451 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const 456 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const
452 { 457 {
458 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
459 if (!model) return 0.f;
460
453 sv_frame_t startFrame = v->getStartFrame(); 461 sv_frame_t startFrame = v->getStartFrame();
454 sv_frame_t endFrame = v->getEndFrame(); 462 sv_frame_t endFrame = v->getEndFrame();
455 463
456 sv_frame_t modelStart = m_model->getStartFrame(); 464 sv_frame_t modelStart = model->getStartFrame();
457 sv_frame_t modelEnd = m_model->getEndFrame(); 465 sv_frame_t modelEnd = model->getEndFrame();
458 466
459 sv_frame_t rangeStart, rangeEnd; 467 sv_frame_t rangeStart, rangeEnd;
460 468
461 if (startFrame < modelStart) rangeStart = modelStart; 469 if (startFrame < modelStart) rangeStart = modelStart;
462 else rangeStart = startFrame; 470 else rangeStart = startFrame;
466 else rangeEnd = endFrame; 474 else rangeEnd = endFrame;
467 475
468 if (rangeEnd < rangeStart) rangeEnd = rangeStart; 476 if (rangeEnd < rangeStart) rangeEnd = rangeStart;
469 477
470 RangeSummarisableTimeValueModel::Range range = 478 RangeSummarisableTimeValueModel::Range range =
471 m_model->getSummary(channel, rangeStart, rangeEnd - rangeStart); 479 model->getSummary(channel, rangeStart, rangeEnd - rangeStart);
472 480
473 int minChannel = 0, maxChannel = 0; 481 int minChannel = 0, maxChannel = 0;
474 bool mergingChannels = false, mixingChannels = false; 482 bool mergingChannels = false, mixingChannels = false;
475 483
476 (void)getChannelArrangement(minChannel, maxChannel, 484 (void)getChannelArrangement(minChannel, maxChannel,
477 mergingChannels, mixingChannels); 485 mergingChannels, mixingChannels);
478 486
479 if (mergingChannels || mixingChannels) { 487 if (mergingChannels || mixingChannels) {
480 RangeSummarisableTimeValueModel::Range otherRange = 488 RangeSummarisableTimeValueModel::Range otherRange =
481 m_model->getSummary(1, rangeStart, rangeEnd - rangeStart); 489 model->getSummary(1, rangeStart, rangeEnd - rangeStart);
482 range.setMax(std::max(range.max(), otherRange.max())); 490 range.setMax(std::max(range.max(), otherRange.max()));
483 range.setMin(std::min(range.min(), otherRange.min())); 491 range.setMin(std::min(range.min(), otherRange.min()));
484 range.setAbsmean(std::min(range.absmean(), otherRange.absmean())); 492 range.setAbsmean(std::min(range.absmean(), otherRange.absmean()));
485 } 493 }
486 494
488 } 496 }
489 497
490 void 498 void
491 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const 499 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const
492 { 500 {
493 if (!m_model || !m_model->isOK()) { 501 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
502 if (!model || !model->isOK()) {
494 return; 503 return;
495 } 504 }
496 505
497 ZoomLevel zoomLevel = v->getZoomLevel(); 506 ZoomLevel zoomLevel = v->getZoomLevel();
498 507
592 601
593 int desiredBlockSize = 1; 602 int desiredBlockSize = 1;
594 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { 603 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
595 desiredBlockSize = zoomLevel.level; 604 desiredBlockSize = zoomLevel.level;
596 } 605 }
597 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize); 606 int blockSize = model->getSummaryBlockSize(desiredBlockSize);
598 607
599 sv_frame_t frame0; 608 sv_frame_t frame0;
600 sv_frame_t frame1; 609 sv_frame_t frame1;
601 sv_frame_t spare; 610 sv_frame_t spare;
602 611
641 if (m_middleLineHeight != 0.5) { 650 if (m_middleLineHeight != 0.5) {
642 paint->restore(); 651 paint->restore();
643 } 652 }
644 653
645 if (m_aggressive) { 654 if (m_aggressive) {
646 if (m_model->isReady() && rect == v->getPaintRect()) { 655 if (model->isReady() && rect == v->getPaintRect()) {
647 m_cacheValid = true; 656 m_cacheValid = true;
648 m_cacheZoomLevel = zoomLevel; 657 m_cacheZoomLevel = zoomLevel;
649 } 658 }
650 paint->end(); 659 paint->end();
651 delete paint; 660 delete paint;
658 bool mixingOrMerging, 667 bool mixingOrMerging,
659 sv_frame_t frame0, sv_frame_t frame1, 668 sv_frame_t frame0, sv_frame_t frame1,
660 int blockSize, RangeVec &ranges) 669 int blockSize, RangeVec &ranges)
661 const 670 const
662 { 671 {
672 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
673 if (!model) return;
674
663 for (int ch = minChannel; ch <= maxChannel; ++ch) { 675 for (int ch = minChannel; ch <= maxChannel; ++ch) {
664 ranges.push_back({}); 676 ranges.push_back({});
665 m_model->getSummaries(ch, frame0, frame1 - frame0, 677 model->getSummaries(ch, frame0, frame1 - frame0,
666 ranges[ch - minChannel], blockSize); 678 ranges[ch - minChannel], blockSize);
667 #ifdef DEBUG_WAVEFORM_PAINT 679 #ifdef DEBUG_WAVEFORM_PAINT
668 SVCERR << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; 680 SVCERR << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
669 #endif 681 #endif
670 } 682 }
671 683
672 if (mixingOrMerging) { 684 if (mixingOrMerging) {
673 if (minChannel != 0 || maxChannel != 0) { 685 if (minChannel != 0 || maxChannel != 0) {
674 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); 686 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels");
675 } else if (m_model->getChannelCount() > 1) { 687 } else if (model->getChannelCount() > 1) {
676 ranges.push_back({}); 688 ranges.push_back({});
677 m_model->getSummaries 689 model->getSummaries
678 (1, frame0, frame1 - frame0, ranges[1], blockSize); 690 (1, frame0, frame1 - frame0, ranges[1], blockSize);
679 } 691 }
680 } 692 }
681 } 693 }
682 694
685 bool mixingOrMerging, 697 bool mixingOrMerging,
686 sv_frame_t frame0, sv_frame_t frame1, 698 sv_frame_t frame0, sv_frame_t frame1,
687 int oversampleBy, RangeVec &ranges) 699 int oversampleBy, RangeVec &ranges)
688 const 700 const
689 { 701 {
702 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
703 if (!model) return;
704
690 if (mixingOrMerging) { 705 if (mixingOrMerging) {
691 if (minChannel != 0 || maxChannel != 0) { 706 if (minChannel != 0 || maxChannel != 0) {
692 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels"); 707 throw std::logic_error("Internal error: min & max channels should be 0 when merging or mixing all channels");
693 } 708 }
694 if (m_model->getChannelCount() > 1) { 709 if (model->getChannelCount() > 1) {
695 // call back on self for the individual channels with 710 // call back on self for the individual channels with
696 // mixingOrMerging false 711 // mixingOrMerging false
697 getOversampledRanges 712 getOversampledRanges
698 (0, 1, false, frame0, frame1, oversampleBy, ranges); 713 (0, 1, false, frame0, frame1, oversampleBy, ranges);
699 return; 714 return;
702 717
703 // These frame values, tail length, etc variables are at the model 718 // These frame values, tail length, etc variables are at the model
704 // sample rate, not the oversampled rate 719 // sample rate, not the oversampled rate
705 720
706 sv_frame_t tail = 16; 721 sv_frame_t tail = 16;
707 sv_frame_t startFrame = m_model->getStartFrame(); 722 sv_frame_t startFrame = model->getStartFrame();
708 sv_frame_t endFrame = m_model->getEndFrame(); 723 sv_frame_t endFrame = model->getEndFrame();
709 724
710 sv_frame_t rf0 = frame0 - tail; 725 sv_frame_t rf0 = frame0 - tail;
711 if (rf0 < startFrame) { 726 if (rf0 < startFrame) {
712 rf0 = 0; 727 rf0 = 0;
713 } 728 }
722 return; 737 return;
723 } 738 }
724 739
725 for (int ch = minChannel; ch <= maxChannel; ++ch) { 740 for (int ch = minChannel; ch <= maxChannel; ++ch) {
726 floatvec_t oversampled = WaveformOversampler::getOversampledData 741 floatvec_t oversampled = WaveformOversampler::getOversampledData
727 (m_model, ch, frame0, frame1 - frame0, oversampleBy); 742 (*model, ch, frame0, frame1 - frame0, oversampleBy);
728 RangeSummarisableTimeValueModel::RangeBlock rr; 743 RangeSummarisableTimeValueModel::RangeBlock rr;
729 for (float v: oversampled) { 744 for (float v: oversampled) {
730 RangeSummarisableTimeValueModel::Range r; 745 RangeSummarisableTimeValueModel::Range r;
731 r.sample(v); 746 r.sample(v);
732 rr.push_back(r); 747 rr.push_back(r);
754 int blockSize, 769 int blockSize,
755 sv_frame_t frame0, 770 sv_frame_t frame0,
756 sv_frame_t frame1) 771 sv_frame_t frame1)
757 const 772 const
758 { 773 {
774 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
775 if (!model) return;
776
759 int x0 = rect.left(); 777 int x0 = rect.left();
760 int y0 = rect.top(); 778 int y0 = rect.top();
761 779
762 int x1 = rect.right(); 780 int x1 = rect.right();
763 int y1 = rect.bottom(); 781 int y1 = rect.bottom();
775 QColor midColour = baseColour; 793 QColor midColour = baseColour;
776 794
777 if (midColour == Qt::black) { 795 if (midColour == Qt::black) {
778 midColour = Qt::gray; 796 midColour = Qt::gray;
779 } else if (v->hasLightBackground()) { 797 } else if (v->hasLightBackground()) {
780 midColour = midColour.light(150); 798 midColour = midColour.lighter(150);
781 } else { 799 } else {
782 midColour = midColour.light(50); 800 midColour = midColour.lighter(50);
783 } 801 }
784 802
785 double gain = m_effectiveGains[ch]; 803 double gain = m_effectiveGains[ch];
786 804
787 int m = (h / channels) / 2; 805 int m = (h / channels) / 2;
1049 double penWidth = 1.0; 1067 double penWidth = 1.0;
1050 if (v->getZoomLevel().zone == ZoomLevel::FramesPerPixel) { 1068 if (v->getZoomLevel().zone == ZoomLevel::FramesPerPixel) {
1051 penWidth = 0.0; 1069 penWidth = 0.0;
1052 } 1070 }
1053 1071
1054 if (m_model->isReady()) { 1072 if (model->isReady()) {
1055 paint->setPen(QPen(baseColour, penWidth)); 1073 paint->setPen(QPen(baseColour, penWidth));
1056 } else { 1074 } else {
1057 paint->setPen(QPen(midColour, penWidth)); 1075 paint->setPen(QPen(midColour, penWidth));
1058 } 1076 }
1059 paint->drawPath(waveformPath); 1077 paint->drawPath(waveformPath);
1152 QString 1170 QString
1153 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 1171 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
1154 { 1172 {
1155 int x = pos.x(); 1173 int x = pos.x();
1156 1174
1157 if (!m_model || !m_model->isOK()) return ""; 1175 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
1176 if (!model || !model->isOK()) return "";
1158 1177
1159 ZoomLevel zoomLevel = v->getZoomLevel(); 1178 ZoomLevel zoomLevel = v->getZoomLevel();
1160 1179
1161 int desiredBlockSize = 1; 1180 int desiredBlockSize = 1;
1162 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) { 1181 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
1163 desiredBlockSize = zoomLevel.level; 1182 desiredBlockSize = zoomLevel.level;
1164 } 1183 }
1165 1184
1166 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize); 1185 int blockSize = model->getSummaryBlockSize(desiredBlockSize);
1167 1186
1168 sv_frame_t f0, f1; 1187 sv_frame_t f0, f1;
1169 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return ""; 1188 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return "";
1170 1189
1171 QString text; 1190 QString text;
1172 1191
1173 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate()); 1192 RealTime rt0 = RealTime::frame2RealTime(f0, model->getSampleRate());
1174 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate()); 1193 RealTime rt1 = RealTime::frame2RealTime(f1, model->getSampleRate());
1175 1194
1176 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) { 1195 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) {
1177 text += tr("Time:\t%1 - %2") 1196 text += tr("Time:\t%1 - %2")
1178 .arg(rt0.toText(true).c_str()) 1197 .arg(rt0.toText(true).c_str())
1179 .arg(rt1.toText(true).c_str()); 1198 .arg(rt1.toText(true).c_str());
1190 if (channels == 0) return ""; 1209 if (channels == 0) return "";
1191 1210
1192 for (int ch = minChannel; ch <= maxChannel; ++ch) { 1211 for (int ch = minChannel; ch <= maxChannel; ++ch) {
1193 1212
1194 RangeSummarisableTimeValueModel::RangeBlock ranges; 1213 RangeSummarisableTimeValueModel::RangeBlock ranges;
1195 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize); 1214 model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
1196 1215
1197 if (ranges.empty()) continue; 1216 if (ranges.empty()) continue;
1198 1217
1199 RangeSummarisableTimeValueModel::Range range = ranges[0]; 1218 RangeSummarisableTimeValueModel::Range range = ranges[0];
1200 1219
1390 } 1409 }
1391 1410
1392 int 1411 int
1393 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const 1412 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const
1394 { 1413 {
1414 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested
1415 // replacement (horizontalAdvance) was only added in Qt 5.11
1416 // which is too new for us
1417 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1418
1395 if (m_scale == LinearScale) { 1419 if (m_scale == LinearScale) {
1396 return paint.fontMetrics().width("0.0") + 13; 1420 return paint.fontMetrics().width("0.0") + 13;
1397 } else { 1421 } else {
1398 return std::max(paint.fontMetrics().width(tr("0dB")), 1422 return std::max(paint.fontMetrics().width(tr("0dB")),
1399 paint.fontMetrics().width(Strings::minus_infinity)) + 13; 1423 paint.fontMetrics().width(Strings::minus_infinity)) + 13;
1401 } 1425 }
1402 1426
1403 void 1427 void
1404 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const 1428 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const
1405 { 1429 {
1406 if (!m_model || !m_model->isOK()) { 1430 auto model = ModelById::getAs<RangeSummarisableTimeValueModel>(m_model);
1431 if (!model || !model->isOK()) {
1407 return; 1432 return;
1408 } 1433 }
1409 1434
1410 int channels = 0, minChannel = 0, maxChannel = 0; 1435 int channels = 0, minChannel = 0, maxChannel = 0;
1411 bool mergingChannels = false, mixingChannels = false; 1436 bool mergingChannels = false, mixingChannels = false;