comparison layer/WaveformLayer.cpp @ 1336:43296804c473 zoom

Toward oversampling rendering
author Chris Cannam
date Mon, 24 Sep 2018 14:40:48 +0100
parents bc44b520405f
children 4f9a3c84be60
comparison
equal deleted inserted replaced
1335:bc44b520405f 1336:43296804c473
29 #include <QTextStream> 29 #include <QTextStream>
30 30
31 #include <iostream> 31 #include <iostream>
32 #include <cmath> 32 #include <cmath>
33 33
34 #include <bqresample/Resampler.h>
35
34 //#define DEBUG_WAVEFORM_PAINT 1 36 //#define DEBUG_WAVEFORM_PAINT 1
35 37
36 using std::vector; 38 using std::vector;
37 39
38 40
46 m_channelMode(SeparateChannels), 48 m_channelMode(SeparateChannels),
47 m_channel(-1), 49 m_channel(-1),
48 m_scale(LinearScale), 50 m_scale(LinearScale),
49 m_middleLineHeight(0.5), 51 m_middleLineHeight(0.5),
50 m_aggressive(false), 52 m_aggressive(false),
53 m_oversampleRate(8),
54 m_oversampleTail(200),
55 m_oversampler(0),
51 m_cache(0), 56 m_cache(0),
52 m_cacheValid(false) 57 m_cacheValid(false)
53 { 58 {
54
55 } 59 }
56 60
57 WaveformLayer::~WaveformLayer() 61 WaveformLayer::~WaveformLayer()
58 { 62 {
59 delete m_cache; 63 delete m_cache;
64 delete m_oversampler;
60 } 65 }
61 66
62 void 67 void
63 WaveformLayer::setModel(const RangeSummarisableTimeValueModel *model) 68 WaveformLayer::setModel(const RangeSummarisableTimeValueModel *model)
64 { 69 {
78 83
79 m_model = model; 84 m_model = model;
80 m_cacheValid = false; 85 m_cacheValid = false;
81 if (!m_model || !m_model->isOK()) return; 86 if (!m_model || !m_model->isOK()) return;
82 87
88 delete m_oversampler;
89 breakfastquay::Resampler::Parameters params;
90 params.initialSampleRate = m_model->getSampleRate();
91 m_oversampler = new breakfastquay::Resampler
92 (params, m_model->getChannelCount());
93
83 connectSignals(m_model); 94 connectSignals(m_model);
84 95
85 emit modelReplaced(); 96 emit modelReplaced();
86 97
87 if (channelsChanged) emit layerParametersChanged(); 98 if (channelsChanged) emit layerParametersChanged();
408 419
409 static float meterdbs[] = { -40, -30, -20, -15, -10, 420 static float meterdbs[] = { -40, -30, -20, -15, -10,
410 -5, -3, -2, -1, -0.5, 0 }; 421 -5, -3, -2, -1, -0.5, 0 };
411 422
412 bool 423 bool
413 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v, int x, int modelZoomLevel, 424 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v,
425 int x, int modelZoomLevel,
414 sv_frame_t &f0, sv_frame_t &f1) const 426 sv_frame_t &f0, sv_frame_t &f1) const
415 { 427 {
416 sv_frame_t viewFrame = v->getFrameForX(x); 428 sv_frame_t viewFrame = v->getFrameForX(x);
417 if (viewFrame < 0) { 429 if (viewFrame < 0) {
418 f0 = 0; 430 f0 = 0;
595 #endif 607 #endif
596 608
597 while ((int)m_effectiveGains.size() <= maxChannel) { 609 while ((int)m_effectiveGains.size() <= maxChannel) {
598 m_effectiveGains.push_back(m_gain); 610 m_effectiveGains.push_back(m_gain);
599 } 611 }
600
601 vector<RangeSummarisableTimeValueModel::RangeBlock> ranges;
602
603 for (int ch = minChannel; ch <= maxChannel; ++ch) { 612 for (int ch = minChannel; ch <= maxChannel; ++ch) {
604 ranges.push_back({}); 613 m_effectiveGains[ch] = getNormalizeGain(v, ch);
605 m_model->getSummaries(ch, frame0, frame1 - frame0, 614 }
606 ranges[ch - minChannel], blockSize); 615
616 if (v->getZoomLevel().zone == ZoomLevel::FramesPerPixel) {
617
618 vector<RangeSummarisableTimeValueModel::RangeBlock> ranges;
619
620 for (int ch = minChannel; ch <= maxChannel; ++ch) {
621 ranges.push_back({});
622 m_model->getSummaries(ch, frame0, frame1 - frame0,
623 ranges[ch - minChannel], blockSize);
607 #ifdef DEBUG_WAVEFORM_PAINT 624 #ifdef DEBUG_WAVEFORM_PAINT
608 cerr << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl; 625 cerr << "channel " << ch << ": " << ranges[ch - minChannel].size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << blockSize << endl;
609 #endif 626 #endif
610 } 627 }
611 628
612 if (mergingChannels || mixingChannels) { 629 if (mergingChannels || mixingChannels) {
613 if (minChannel != 0 || maxChannel != 0) { 630 if (minChannel != 0 || maxChannel != 0) {
614 SVCERR << "Internal error: min & max channels should be 0 when merging or mixing all channels" << endl; 631 SVCERR << "Internal error: min & max channels should be 0 when merging or mixing all channels" << endl;
615 } else if (m_model->getChannelCount() > 1) { 632 } else if (m_model->getChannelCount() > 1) {
616 ranges.push_back({}); 633 ranges.push_back({});
617 m_model->getSummaries 634 m_model->getSummaries
618 (1, frame0, frame1 - frame0, ranges[1], blockSize); 635 (1, frame0, frame1 - frame0, ranges[1], blockSize);
619 } 636 }
620 } 637 }
621 638
622 for (int ch = minChannel; ch <= maxChannel; ++ch) { 639 for (int ch = minChannel; ch <= maxChannel; ++ch) {
623 paintChannel(v, paint, rect, ch, ranges, blockSize, frame0, frame1); 640 paintChannelSummarised(v, paint, rect, ch,
624 } 641 ranges, blockSize, frame0, frame1);
625 642 }
643 } else {
644
645 for (int ch = minChannel; ch <= maxChannel; ++ch) {
646 paintChannelOversampled(v, paint, rect, ch, frame0, frame1);
647 }
648 }
649
626 if (m_middleLineHeight != 0.5) { 650 if (m_middleLineHeight != 0.5) {
627 paint->restore(); 651 paint->restore();
628 } 652 }
629 653
630 if (m_aggressive) { 654 if (m_aggressive) {
637 viewPainter.drawPixmap(rect, *m_cache, rect); 661 viewPainter.drawPixmap(rect, *m_cache, rect);
638 } 662 }
639 } 663 }
640 664
641 void 665 void
642 WaveformLayer::paintChannel(LayerGeometryProvider *v, QPainter *paint, 666 WaveformLayer::paintChannelSummarised(LayerGeometryProvider *v,
643 QRect rect, int ch, 667 QPainter *paint,
644 const vector<RangeSummarisableTimeValueModel::RangeBlock> &ranges, 668 QRect rect, int ch,
645 int blockSize, sv_frame_t frame0, sv_frame_t frame1) 669 const vector<RangeSummarisableTimeValueModel::RangeBlock> &ranges,
670 int blockSize,
671 sv_frame_t frame0, sv_frame_t frame1)
646 const 672 const
647 { 673 {
648 int x0 = rect.left(); 674 int x0 = rect.left();
649 int y0 = rect.top(); 675 int y0 = rect.top();
650 676
672 midColour = midColour.light(50); 698 midColour = midColour.light(50);
673 } 699 }
674 700
675 int prevRangeBottom = -1, prevRangeTop = -1; 701 int prevRangeBottom = -1, prevRangeTop = -1;
676 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour; 702 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
677
678 m_effectiveGains[ch] = m_gain;
679
680 if (m_autoNormalize) {
681 m_effectiveGains[ch] = getNormalizeGain(v, ch);
682 }
683 703
684 double gain = m_effectiveGains[ch]; 704 double gain = m_effectiveGains[ch];
685 705
686 int m = (h / channels) / 2; 706 int m = (h / channels) / 2;
687 int my = m + (((ch - minChannel) * h) / channels); 707 int my = m + (((ch - minChannel) * h) / channels);
929 paint->drawLine(x, meanBottom, x, meanTop); 949 paint->drawLine(x, meanBottom, x, meanTop);
930 } 950 }
931 951
932 prevRangeBottom = rangeBottom; 952 prevRangeBottom = rangeBottom;
933 prevRangeTop = rangeTop; 953 prevRangeTop = rangeTop;
954 }
955 }
956
957 void
958 WaveformLayer::paintChannelOversampled(LayerGeometryProvider *v,
959 QPainter *paint,
960 QRect rect,
961 int ch,
962 sv_frame_t frame0, sv_frame_t frame1)
963 const
964 {
965 int x0 = rect.left();
966 int y0 = rect.top();
967
968 int x1 = rect.right();
969 int y1 = rect.bottom();
970
971 int h = v->getPaintHeight();
972
973 int channels = 0, minChannel = 0, maxChannel = 0;
974 bool mergingChannels = false, mixingChannels = false;
975
976 channels = getChannelArrangement(minChannel, maxChannel,
977 mergingChannels, mixingChannels);
978 if (channels == 0) return;
979
980 QColor baseColour = getBaseQColor();
981 vector<QColor> greys = getPartialShades(v);
982
983 QColor midColour = baseColour;
984 if (midColour == Qt::black) {
985 midColour = Qt::gray;
986 } else if (v->hasLightBackground()) {
987 midColour = midColour.light(150);
988 } else {
989 midColour = midColour.light(50);
990 }
991
992 double gain = m_effectiveGains[ch];
993
994 int m = (h / channels) / 2;
995 int my = m + (((ch - minChannel) * h) / channels);
996
997 #ifdef DEBUG_WAVEFORM_PAINT
998 cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl;
999 #endif
1000
1001 if (my - m > y1 || my + m < y0) return;
1002
1003 if ((m_scale == dBScale || m_scale == MeterScale) &&
1004 m_channelMode != MergeChannels) {
1005 m = (h / channels);
1006 my = m + (((ch - minChannel) * h) / channels);
1007 }
1008
1009 paint->setPen(greys[1]);
1010 paint->drawLine(x0, my, x1, my);
1011
1012 paintChannelScaleGuides(v, paint, rect, ch);
1013
1014 for (sv_frame_t f = frame0; f <= frame1; ++f) {
1015
934 } 1016 }
935 } 1017 }
936 1018
937 void 1019 void
938 WaveformLayer::paintChannelScaleGuides(LayerGeometryProvider *v, 1020 WaveformLayer::paintChannelScaleGuides(LayerGeometryProvider *v,