comparison layer/WaveformLayer.cpp @ 1325:bc2cb82050a0 zoom

Gradual ZoomLevel updates
author Chris Cannam
date Wed, 19 Sep 2018 15:42:22 +0100
parents a34a2a25907c
children 6dac67c3ed82
comparison
equal deleted inserted replaced
1324:13d9b422f7fe 1325:bc2cb82050a0
47 m_channel(-1), 47 m_channel(-1),
48 m_scale(LinearScale), 48 m_scale(LinearScale),
49 m_middleLineHeight(0.5), 49 m_middleLineHeight(0.5),
50 m_aggressive(false), 50 m_aggressive(false),
51 m_cache(0), 51 m_cache(0),
52 m_cacheValid(false), 52 m_cacheValid(false)
53 m_cacheZoomLevel(0)
54 { 53 {
55 54
56 } 55 }
57 56
58 WaveformLayer::~WaveformLayer() 57 WaveformLayer::~WaveformLayer()
480 { 479 {
481 if (!m_model || !m_model->isOK()) { 480 if (!m_model || !m_model->isOK()) {
482 return; 481 return;
483 } 482 }
484 483
485 int zoomLevel = v->getZoomLevel(); 484 ZoomLevel zoomLevel = v->getZoomLevel();
486 485
487 #ifdef DEBUG_WAVEFORM_PAINT 486 #ifdef DEBUG_WAVEFORM_PAINT
488 Profiler profiler("WaveformLayer::paint", true); 487 Profiler profiler("WaveformLayer::paint", true);
489 cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() 488 cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
490 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << endl; 489 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << endl;
507 506
508 #ifdef DEBUG_WAVEFORM_PAINT 507 #ifdef DEBUG_WAVEFORM_PAINT
509 cerr << "WaveformLayer::paint: aggressive is true" << endl; 508 cerr << "WaveformLayer::paint: aggressive is true" << endl;
510 #endif 509 #endif
511 510
511 using namespace std::rel_ops;
512
512 if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) { 513 if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) {
513 m_cacheValid = false; 514 m_cacheValid = false;
514 } 515 }
515 516
516 if (!m_cache || m_cache->width() != w || m_cache->height() != h) { 517 if (!m_cache || m_cache->width() != w || m_cache->height() != h) {
570 // Each pixel within our visible range must always draw from 571 // Each pixel within our visible range must always draw from
571 // exactly the same set of underlying audio frames, no matter what 572 // exactly the same set of underlying audio frames, no matter what
572 // the range being drawn is. And that set of underlying frames 573 // the range being drawn is. And that set of underlying frames
573 // must remain the same when we scroll one or more pixels left or 574 // must remain the same when we scroll one or more pixels left or
574 // right. 575 // right.
575 576
576 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel); 577 int desiredBlockSize = 1;
578 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
579 desiredBlockSize = zoomLevel.level;
580 }
581 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
577 582
578 sv_frame_t frame0; 583 sv_frame_t frame0;
579 sv_frame_t frame1; 584 sv_frame_t frame1;
580 sv_frame_t spare; 585 sv_frame_t spare;
581 586
582 getSourceFramesForX(v, x0, modelZoomLevel, frame0, spare); 587 getSourceFramesForX(v, x0, blockSize, frame0, spare);
583 getSourceFramesForX(v, x1, modelZoomLevel, spare, frame1); 588 getSourceFramesForX(v, x1, blockSize, spare, frame1);
584 589
585 #ifdef DEBUG_WAVEFORM_PAINT 590 #ifdef DEBUG_WAVEFORM_PAINT
586 cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << modelZoomLevel << ")" << endl; 591 cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << blockSize << ")" << endl;
587 #endif 592 #endif
588 593
589 RangeSummarisableTimeValueModel::RangeBlock *ranges = 594 RangeSummarisableTimeValueModel::RangeBlock *ranges =
590 new RangeSummarisableTimeValueModel::RangeBlock; 595 new RangeSummarisableTimeValueModel::RangeBlock;
591 596
686 } 691 }
687 } 692 }
688 } 693 }
689 694
690 m_model->getSummaries(ch, frame0, frame1 - frame0, 695 m_model->getSummaries(ch, frame0, frame1 - frame0,
691 *ranges, modelZoomLevel); 696 *ranges, blockSize);
692 697
693 #ifdef DEBUG_WAVEFORM_PAINT 698 #ifdef DEBUG_WAVEFORM_PAINT
694 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << endl; 699 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
695 #endif 700 #endif
696 701
697 if (mergingChannels || mixingChannels) { 702 if (mergingChannels || mixingChannels) {
698 if (m_model->getChannelCount() > 1) { 703 if (m_model->getChannelCount() > 1) {
699 if (!otherChannelRanges) { 704 if (!otherChannelRanges) {
700 otherChannelRanges = 705 otherChannelRanges =
701 new RangeSummarisableTimeValueModel::RangeBlock; 706 new RangeSummarisableTimeValueModel::RangeBlock;
702 } 707 }
703 m_model->getSummaries 708 m_model->getSummaries
704 (1, frame0, frame1 - frame0, *otherChannelRanges, 709 (1, frame0, frame1 - frame0, *otherChannelRanges,
705 modelZoomLevel); 710 blockSize);
706 } else { 711 } else {
707 if (otherChannelRanges != ranges) delete otherChannelRanges; 712 if (otherChannelRanges != ranges) delete otherChannelRanges;
708 otherChannelRanges = ranges; 713 otherChannelRanges = ranges;
709 } 714 }
710 } 715 }
712 for (int x = x0; x <= x1; ++x) { 717 for (int x = x0; x <= x1; ++x) {
713 718
714 range = RangeSummarisableTimeValueModel::Range(); 719 range = RangeSummarisableTimeValueModel::Range();
715 720
716 sv_frame_t f0, f1; 721 sv_frame_t f0, f1;
717 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue; 722 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) continue;
718 f1 = f1 - 1; 723 f1 = f1 - 1;
719 724
720 if (f0 < frame0) { 725 if (f0 < frame0) {
721 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl; 726 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl;
722 continue; 727 continue;
723 } 728 }
724 729
725 sv_frame_t i0 = (f0 - frame0) / modelZoomLevel; 730 sv_frame_t i0 = (f0 - frame0) / blockSize;
726 sv_frame_t i1 = (f1 - frame0) / modelZoomLevel; 731 sv_frame_t i1 = (f1 - frame0) / blockSize;
727 732
728 #ifdef DEBUG_WAVEFORM_PAINT 733 #ifdef DEBUG_WAVEFORM_PAINT
729 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl; 734 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
730 #endif 735 #endif
731 736
732 if (i1 > i0 + 1) { 737 if (i1 > i0 + 1) {
733 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << endl; 738 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << blockSize << ")" << endl;
734 } 739 }
735 740
736 if (ranges && i0 < (sv_frame_t)ranges->size()) { 741 if (ranges && i0 < (sv_frame_t)ranges->size()) {
737 742
738 range = (*ranges)[size_t(i0)]; 743 range = (*ranges)[size_t(i0)];
966 { 971 {
967 int x = pos.x(); 972 int x = pos.x();
968 973
969 if (!m_model || !m_model->isOK()) return ""; 974 if (!m_model || !m_model->isOK()) return "";
970 975
971 int zoomLevel = v->getZoomLevel(); 976 ZoomLevel zoomLevel = v->getZoomLevel();
972 977
973 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel); 978 int desiredBlockSize = 1;
979 if (zoomLevel.zone == ZoomLevel::FramesPerPixel) {
980 desiredBlockSize = zoomLevel.level;
981 }
982
983 int blockSize = m_model->getSummaryBlockSize(desiredBlockSize);
974 984
975 sv_frame_t f0, f1; 985 sv_frame_t f0, f1;
976 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) return ""; 986 if (!getSourceFramesForX(v, x, blockSize, f0, f1)) return "";
977 987
978 QString text; 988 QString text;
979 989
980 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate()); 990 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate());
981 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate()); 991 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate());
996 mergingChannels, mixingChannels); 1006 mergingChannels, mixingChannels);
997 if (channels == 0) return ""; 1007 if (channels == 0) return "";
998 1008
999 for (int ch = minChannel; ch <= maxChannel; ++ch) { 1009 for (int ch = minChannel; ch <= maxChannel; ++ch) {
1000 1010
1001 int blockSize = v->getZoomLevel();
1002 RangeSummarisableTimeValueModel::RangeBlock ranges; 1011 RangeSummarisableTimeValueModel::RangeBlock ranges;
1003 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize); 1012 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
1004 1013
1005 if (ranges.empty()) continue; 1014 if (ranges.empty()) continue;
1006 1015