Mercurial > hg > svgui
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, |