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, | 
