comparison layer/WaveformLayer.cpp @ 1266:a34a2a25907c

Untabify
author Chris Cannam
date Thu, 01 Mar 2018 18:02:22 +0000
parents 1badacff7ab2
children bc2cb82050a0
comparison
equal deleted inserted replaced
1265:6e724c81f18f 1266:a34a2a25907c
133 QString 133 QString
134 WaveformLayer::getPropertyGroupName(const PropertyName &name) const 134 WaveformLayer::getPropertyGroupName(const PropertyName &name) const
135 { 135 {
136 if (name == "Gain" || 136 if (name == "Gain" ||
137 name == "Normalize Visible Area" || 137 name == "Normalize Visible Area" ||
138 name == "Scale") return tr("Scale"); 138 name == "Scale") return tr("Scale");
139 return QString(); 139 return QString();
140 } 140 }
141 141
142 int 142 int
143 WaveformLayer::getPropertyRangeAndValue(const PropertyName &name, 143 WaveformLayer::getPropertyRangeAndValue(const PropertyName &name,
150 if (!max) max = &garbage1; 150 if (!max) max = &garbage1;
151 if (!deflt) deflt = &garbage2; 151 if (!deflt) deflt = &garbage2;
152 152
153 if (name == "Gain") { 153 if (name == "Gain") {
154 154
155 *min = -50; 155 *min = -50;
156 *max = 50; 156 *max = 50;
157 *deflt = 0; 157 *deflt = 0;
158 158
159 val = int(lrint(log10(m_gain) * 20.0)); 159 val = int(lrint(log10(m_gain) * 20.0));
160 if (val < *min) val = *min; 160 if (val < *min) val = *min;
161 if (val > *max) val = *max; 161 if (val > *max) val = *max;
162 162
163 } else if (name == "Normalize Visible Area") { 163 } else if (name == "Normalize Visible Area") {
164 164
165 val = (m_autoNormalize ? 1 : 0); 165 val = (m_autoNormalize ? 1 : 0);
166 *deflt = 0; 166 *deflt = 0;
174 else if (m_channelMode == MergeChannels) val = 2; 174 else if (m_channelMode == MergeChannels) val = 2;
175 else val = 0; 175 else val = 0;
176 176
177 } else if (name == "Scale") { 177 } else if (name == "Scale") {
178 178
179 *min = 0; 179 *min = 0;
180 *max = 2; 180 *max = 2;
181 *deflt = 0; 181 *deflt = 0;
182 182
183 val = (int)m_scale; 183 val = (int)m_scale;
184 184
185 } else { 185 } else {
186 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); 186 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt);
187 } 187 }
188 188
189 return val; 189 return val;
190 } 190 }
191 191
192 QString 192 QString
193 WaveformLayer::getPropertyValueLabel(const PropertyName &name, 193 WaveformLayer::getPropertyValueLabel(const PropertyName &name,
194 int value) const 194 int value) const
195 { 195 {
196 if (name == "Scale") { 196 if (name == "Scale") {
197 switch (value) { 197 switch (value) {
198 default: 198 default:
199 case 0: return tr("Linear"); 199 case 0: return tr("Linear");
200 case 1: return tr("Meter"); 200 case 1: return tr("Meter");
201 case 2: return tr("dB"); 201 case 2: return tr("dB");
202 } 202 }
203 } 203 }
204 if (name == "Channels") { 204 if (name == "Channels") {
205 switch (value) { 205 switch (value) {
206 default: 206 default:
207 case 0: return tr("Separate"); 207 case 0: return tr("Separate");
223 223
224 void 224 void
225 WaveformLayer::setProperty(const PropertyName &name, int value) 225 WaveformLayer::setProperty(const PropertyName &name, int value)
226 { 226 {
227 if (name == "Gain") { 227 if (name == "Gain") {
228 setGain(float(pow(10, float(value)/20.0))); 228 setGain(float(pow(10, float(value)/20.0)));
229 } else if (name == "Normalize Visible Area") { 229 } else if (name == "Normalize Visible Area") {
230 setAutoNormalize(value ? true : false); 230 setAutoNormalize(value ? true : false);
231 } else if (name == "Channels") { 231 } else if (name == "Channels") {
232 if (value == 1) setChannelMode(MixChannels); 232 if (value == 1) setChannelMode(MixChannels);
233 else if (value == 2) setChannelMode(MergeChannels); 233 else if (value == 2) setChannelMode(MergeChannels);
234 else setChannelMode(SeparateChannels); 234 else setChannelMode(SeparateChannels);
235 } else if (name == "Scale") { 235 } else if (name == "Scale") {
236 switch (value) { 236 switch (value) {
237 default: 237 default:
238 case 0: setScale(LinearScale); break; 238 case 0: setScale(LinearScale); break;
239 case 1: setScale(MeterScale); break; 239 case 1: setScale(MeterScale); break;
240 case 2: setScale(dBScale); break; 240 case 2: setScale(dBScale); break;
241 } 241 }
242 } else { 242 } else {
243 SingleColourLayer::setProperty(name, value); 243 SingleColourLayer::setProperty(name, value);
244 } 244 }
245 } 245 }
246 246
376 if (channels == 0) return 0; 376 if (channels == 0) return 0;
377 377
378 int rawChannels = channels; 378 int rawChannels = channels;
379 379
380 if (m_channel == -1) { 380 if (m_channel == -1) {
381 min = 0; 381 min = 0;
382 if (m_channelMode == MergeChannels || 382 if (m_channelMode == MergeChannels ||
383 m_channelMode == MixChannels) { 383 m_channelMode == MixChannels) {
384 max = 0; 384 max = 0;
385 channels = 1; 385 channels = 1;
386 } else { 386 } else {
387 max = channels - 1; 387 max = channels - 1;
388 } 388 }
389 } else { 389 } else {
390 min = m_channel; 390 min = m_channel;
391 max = m_channel; 391 max = m_channel;
392 rawChannels = 1; 392 rawChannels = 1;
393 channels = 1; 393 channels = 1;
394 } 394 }
395 395
396 merging = (m_channelMode == MergeChannels && rawChannels > 1); 396 merging = (m_channelMode == MergeChannels && rawChannels > 1);
397 mixing = (m_channelMode == MixChannels && rawChannels > 1); 397 mixing = (m_channelMode == MixChannels && rawChannels > 1);
398 398
477 477
478 void 478 void
479 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const 479 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const
480 { 480 {
481 if (!m_model || !m_model->isOK()) { 481 if (!m_model || !m_model->isOK()) {
482 return; 482 return;
483 } 483 }
484 484
485 int zoomLevel = v->getZoomLevel(); 485 int zoomLevel = v->getZoomLevel();
486 486
487 #ifdef DEBUG_WAVEFORM_PAINT 487 #ifdef DEBUG_WAVEFORM_PAINT
488 Profiler profiler("WaveformLayer::paint", true); 488 Profiler profiler("WaveformLayer::paint", true);
489 cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() 489 cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
490 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << endl; 490 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << endl;
491 #endif 491 #endif
492 492
493 int channels = 0, minChannel = 0, maxChannel = 0; 493 int channels = 0, minChannel = 0, maxChannel = 0;
494 bool mergingChannels = false, mixingChannels = false; 494 bool mergingChannels = false, mixingChannels = false;
495 495
507 507
508 #ifdef DEBUG_WAVEFORM_PAINT 508 #ifdef DEBUG_WAVEFORM_PAINT
509 cerr << "WaveformLayer::paint: aggressive is true" << endl; 509 cerr << "WaveformLayer::paint: aggressive is true" << endl;
510 #endif 510 #endif
511 511
512 if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) { 512 if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) {
513 m_cacheValid = false; 513 m_cacheValid = false;
514 } 514 }
515 515
516 if (!m_cache || m_cache->width() != w || m_cache->height() != h) { 516 if (!m_cache || m_cache->width() != w || m_cache->height() != h) {
517 #ifdef DEBUG_WAVEFORM_PAINT 517 #ifdef DEBUG_WAVEFORM_PAINT
518 if (m_cache) { 518 if (m_cache) {
519 cerr << "WaveformLayer::paint: cache size " << m_cache->width() << "x" << m_cache->height() << " differs from view size " << w << "x" << h << ": regenerating aggressive cache" << endl; 519 cerr << "WaveformLayer::paint: cache size " << m_cache->width() << "x" << m_cache->height() << " differs from view size " << w << "x" << h << ": regenerating aggressive cache" << endl;
520 } 520 }
521 #endif 521 #endif
522 delete m_cache; 522 delete m_cache;
523 m_cache = new QPixmap(w, h); 523 m_cache = new QPixmap(w, h);
524 m_cacheValid = false; 524 m_cacheValid = false;
525 } 525 }
526 526
527 if (m_cacheValid) { 527 if (m_cacheValid) {
528 viewPainter.drawPixmap(rect, *m_cache, rect); 528 viewPainter.drawPixmap(rect, *m_cache, rect);
529 return; 529 return;
530 } 530 }
531 531
532 paint = new QPainter(m_cache); 532 paint = new QPainter(m_cache);
533 533
534 paint->setPen(Qt::NoPen); 534 paint->setPen(Qt::NoPen);
535 paint->setBrush(getBackgroundQColor(v)); 535 paint->setBrush(getBackgroundQColor(v));
536 paint->drawRect(rect); 536 paint->drawRect(rect);
537 537
538 paint->setPen(getForegroundQColor(v)); 538 paint->setPen(getForegroundQColor(v));
539 paint->setBrush(Qt::NoBrush); 539 paint->setBrush(Qt::NoBrush);
540 540
541 } else { 541 } else {
542 paint = &viewPainter; 542 paint = &viewPainter;
543 } 543 }
544 544
545 paint->setRenderHint(QPainter::Antialiasing, false); 545 paint->setRenderHint(QPainter::Antialiasing, false);
546 546
547 if (m_middleLineHeight != 0.5) { 547 if (m_middleLineHeight != 0.5) {
595 QColor baseColour = getBaseQColor(); 595 QColor baseColour = getBaseQColor();
596 std::vector<QColor> greys = getPartialShades(v); 596 std::vector<QColor> greys = getPartialShades(v);
597 597
598 QColor midColour = baseColour; 598 QColor midColour = baseColour;
599 if (midColour == Qt::black) { 599 if (midColour == Qt::black) {
600 midColour = Qt::gray; 600 midColour = Qt::gray;
601 } else if (v->hasLightBackground()) { 601 } else if (v->hasLightBackground()) {
602 midColour = midColour.light(150); 602 midColour = midColour.light(150);
603 } else { 603 } else {
604 midColour = midColour.light(50); 604 midColour = midColour.light(50);
605 } 605 }
606 606
607 while ((int)m_effectiveGains.size() <= maxChannel) { 607 while ((int)m_effectiveGains.size() <= maxChannel) {
608 m_effectiveGains.push_back(m_gain); 608 m_effectiveGains.push_back(m_gain);
609 } 609 }
610 610
611 for (int ch = minChannel; ch <= maxChannel; ++ch) { 611 for (int ch = minChannel; ch <= maxChannel; ++ch) {
612 612
613 int prevRangeBottom = -1, prevRangeTop = -1; 613 int prevRangeBottom = -1, prevRangeTop = -1;
614 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour; 614 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
615 615
616 m_effectiveGains[ch] = m_gain; 616 m_effectiveGains[ch] = m_gain;
617 617
618 if (m_autoNormalize) { 618 if (m_autoNormalize) {
619 m_effectiveGains[ch] = getNormalizeGain(v, ch); 619 m_effectiveGains[ch] = getNormalizeGain(v, ch);
620 } 620 }
621 621
622 double gain = m_effectiveGains[ch]; 622 double gain = m_effectiveGains[ch];
623 623
624 int m = (h / channels) / 2; 624 int m = (h / channels) / 2;
625 int my = m + (((ch - minChannel) * h) / channels); 625 int my = m + (((ch - minChannel) * h) / channels);
626 626
627 #ifdef DEBUG_WAVEFORM_PAINT 627 #ifdef DEBUG_WAVEFORM_PAINT
628 cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl; 628 cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl;
629 #endif 629 #endif
630 630
631 if (my - m > y1 || my + m < y0) continue; 631 if (my - m > y1 || my + m < y0) continue;
632 632
633 if ((m_scale == dBScale || m_scale == MeterScale) && 633 if ((m_scale == dBScale || m_scale == MeterScale) &&
634 m_channelMode != MergeChannels) { 634 m_channelMode != MergeChannels) {
635 m = (h / channels); 635 m = (h / channels);
636 my = m + (((ch - minChannel) * h) / channels); 636 my = m + (((ch - minChannel) * h) / channels);
637 } 637 }
638 638
639 paint->setPen(greys[1]); 639 paint->setPen(greys[1]);
640 paint->drawLine(x0, my, x1, my); 640 paint->drawLine(x0, my, x1, my);
641 641
642 int n = 10; 642 int n = 10;
643 int py = -1; 643 int py = -1;
644 644
645 if (v->hasLightBackground() && 645 if (v->hasLightBackground() &&
692 692
693 #ifdef DEBUG_WAVEFORM_PAINT 693 #ifdef DEBUG_WAVEFORM_PAINT
694 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << endl; 694 cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << endl;
695 #endif 695 #endif
696 696
697 if (mergingChannels || mixingChannels) { 697 if (mergingChannels || mixingChannels) {
698 if (m_model->getChannelCount() > 1) { 698 if (m_model->getChannelCount() > 1) {
699 if (!otherChannelRanges) { 699 if (!otherChannelRanges) {
700 otherChannelRanges = 700 otherChannelRanges =
701 new RangeSummarisableTimeValueModel::RangeBlock; 701 new RangeSummarisableTimeValueModel::RangeBlock;
702 } 702 }
705 modelZoomLevel); 705 modelZoomLevel);
706 } else { 706 } else {
707 if (otherChannelRanges != ranges) delete otherChannelRanges; 707 if (otherChannelRanges != ranges) delete otherChannelRanges;
708 otherChannelRanges = ranges; 708 otherChannelRanges = ranges;
709 } 709 }
710 } 710 }
711 711
712 for (int x = x0; x <= x1; ++x) { 712 for (int x = x0; x <= x1; ++x) {
713 713
714 range = RangeSummarisableTimeValueModel::Range(); 714 range = RangeSummarisableTimeValueModel::Range();
715 715
716 sv_frame_t f0, f1; 716 sv_frame_t f0, f1;
717 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue; 717 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue;
718 f1 = f1 - 1; 718 f1 = f1 - 1;
719 719
731 731
732 if (i1 > i0 + 1) { 732 if (i1 > i0 + 1) {
733 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << endl; 733 cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << endl;
734 } 734 }
735 735
736 if (ranges && i0 < (sv_frame_t)ranges->size()) { 736 if (ranges && i0 < (sv_frame_t)ranges->size()) {
737 737
738 range = (*ranges)[size_t(i0)]; 738 range = (*ranges)[size_t(i0)];
739 739
740 if (i1 > i0 && i1 < (int)ranges->size()) { 740 if (i1 > i0 && i1 < (int)ranges->size()) {
741 range.setMax(std::max(range.max(), 741 range.setMax(std::max(range.max(),
742 (*ranges)[size_t(i1)].max())); 742 (*ranges)[size_t(i1)].max()));
743 range.setMin(std::min(range.min(), 743 range.setMin(std::min(range.min(),
744 (*ranges)[size_t(i1)].min())); 744 (*ranges)[size_t(i1)].min()));
745 range.setAbsmean((range.absmean() 745 range.setAbsmean((range.absmean()
746 + (*ranges)[size_t(i1)].absmean()) / 2); 746 + (*ranges)[size_t(i1)].absmean()) / 2);
747 } 747 }
748 748
749 } else { 749 } else {
750 #ifdef DEBUG_WAVEFORM_PAINT 750 #ifdef DEBUG_WAVEFORM_PAINT
751 cerr << "No (or not enough) ranges for i0 = " << i0 << endl; 751 cerr << "No (or not enough) ranges for i0 = " << i0 << endl;
752 #endif 752 #endif
753 continue; 753 continue;
754 } 754 }
755 755
756 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0; 756 int rangeBottom = 0, rangeTop = 0, meanBottom = 0, meanTop = 0;
757 757
758 if (mergingChannels) { 758 if (mergingChannels) {
759 759
760 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) { 760 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
761 761
762 range.setMax(fabsf(range.max())); 762 range.setMax(fabsf(range.max()));
763 range.setMin(-fabsf((*otherChannelRanges)[size_t(i0)].max())); 763 range.setMin(-fabsf((*otherChannelRanges)[size_t(i0)].max()));
764 range.setAbsmean 764 range.setAbsmean
765 ((range.absmean() + 765 ((range.absmean() +
766 (*otherChannelRanges)[size_t(i0)].absmean()) / 2); 766 (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
767 767
768 if (i1 > i0 && i1 < (sv_frame_t)otherChannelRanges->size()) { 768 if (i1 > i0 && i1 < (sv_frame_t)otherChannelRanges->size()) {
769 // let's not concern ourselves about the mean 769 // let's not concern ourselves about the mean
770 range.setMin 770 range.setMin
771 (std::min 771 (std::min
772 (range.min(), 772 (range.min(),
773 -fabsf((*otherChannelRanges)[size_t(i1)].max()))); 773 -fabsf((*otherChannelRanges)[size_t(i1)].max())));
774 } 774 }
775 } 775 }
776 776
777 } else if (mixingChannels) { 777 } else if (mixingChannels) {
778 778
779 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) { 779 if (otherChannelRanges && i0 < (sv_frame_t)otherChannelRanges->size()) {
780 780
781 range.setMax((range.max() 781 range.setMax((range.max()
782 + (*otherChannelRanges)[size_t(i0)].max()) / 2); 782 + (*otherChannelRanges)[size_t(i0)].max()) / 2);
783 range.setMin((range.min() 783 range.setMin((range.min()
784 + (*otherChannelRanges)[size_t(i0)].min()) / 2); 784 + (*otherChannelRanges)[size_t(i0)].min()) / 2);
785 range.setAbsmean((range.absmean() 785 range.setAbsmean((range.absmean()
786 + (*otherChannelRanges)[size_t(i0)].absmean()) / 2); 786 + (*otherChannelRanges)[size_t(i0)].absmean()) / 2);
787 } 787 }
788 } 788 }
789 789
790 int greyLevels = 1; 790 int greyLevels = 1;
791 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4; 791 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;
792 792
793 switch (m_scale) { 793 switch (m_scale) {
794 794
795 case LinearScale: 795 case LinearScale:
796 rangeBottom = int(double(m * greyLevels) * range.min() * gain); 796 rangeBottom = int(double(m * greyLevels) * range.min() * gain);
797 rangeTop = int(double(m * greyLevels) * range.max() * gain); 797 rangeTop = int(double(m * greyLevels) * range.max() * gain);
798 meanBottom = int(double(-m) * range.absmean() * gain); 798 meanBottom = int(double(-m) * range.absmean() * gain);
799 meanTop = int(double(m) * range.absmean() * gain); 799 meanTop = int(double(m) * range.absmean() * gain);
800 break; 800 break;
801 801
802 case dBScale: 802 case dBScale:
803 if (!mergingChannels) { 803 if (!mergingChannels) {
804 int db0 = dBscale(range.min() * gain, m); 804 int db0 = dBscale(range.min() * gain, m);
805 int db1 = dBscale(range.max() * gain, m); 805 int db1 = dBscale(range.max() * gain, m);
806 rangeTop = std::max(db0, db1); 806 rangeTop = std::max(db0, db1);
807 meanTop = std::min(db0, db1); 807 meanTop = std::min(db0, db1);
812 rangeBottom = -dBscale(range.min() * gain, m * greyLevels); 812 rangeBottom = -dBscale(range.min() * gain, m * greyLevels);
813 rangeTop = dBscale(range.max() * gain, m * greyLevels); 813 rangeTop = dBscale(range.max() * gain, m * greyLevels);
814 meanBottom = -dBscale(range.absmean() * gain, m); 814 meanBottom = -dBscale(range.absmean() * gain, m);
815 meanTop = dBscale(range.absmean() * gain, m); 815 meanTop = dBscale(range.absmean() * gain, m);
816 } 816 }
817 break; 817 break;
818 818
819 case MeterScale: 819 case MeterScale:
820 if (!mergingChannels) { 820 if (!mergingChannels) {
821 int r0 = abs(AudioLevel::multiplier_to_preview(range.min() * gain, m)); 821 int r0 = abs(AudioLevel::multiplier_to_preview(range.min() * gain, m));
822 int r1 = abs(AudioLevel::multiplier_to_preview(range.max() * gain, m)); 822 int r1 = abs(AudioLevel::multiplier_to_preview(range.max() * gain, m));
823 rangeTop = std::max(r0, r1); 823 rangeTop = std::max(r0, r1);
824 meanTop = std::min(r0, r1); 824 meanTop = std::min(r0, r1);
830 rangeTop = AudioLevel::multiplier_to_preview(range.max() * gain, m * greyLevels); 830 rangeTop = AudioLevel::multiplier_to_preview(range.max() * gain, m * greyLevels);
831 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean() * gain, m); 831 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
832 meanTop = AudioLevel::multiplier_to_preview(range.absmean() * gain, m); 832 meanTop = AudioLevel::multiplier_to_preview(range.absmean() * gain, m);
833 } 833 }
834 break; 834 break;
835 } 835 }
836 836
837 rangeBottom = my * greyLevels - rangeBottom; 837 rangeBottom = my * greyLevels - rangeBottom;
838 rangeTop = my * greyLevels - rangeTop; 838 rangeTop = my * greyLevels - rangeTop;
839 meanBottom = my - meanBottom; 839 meanBottom = my - meanBottom;
840 meanTop = my - meanTop; 840 meanTop = my - meanTop;
841 841
842 int topFill = (rangeTop % greyLevels); 842 int topFill = (rangeTop % greyLevels);
843 if (topFill > 0) topFill = greyLevels - topFill; 843 if (topFill > 0) topFill = greyLevels - topFill;
844 844
845 int bottomFill = (rangeBottom % greyLevels); 845 int bottomFill = (rangeBottom % greyLevels);
846 846
847 rangeTop = rangeTop / greyLevels; 847 rangeTop = rangeTop / greyLevels;
848 rangeBottom = rangeBottom / greyLevels; 848 rangeBottom = rangeBottom / greyLevels;
849 849
850 bool clipped = false; 850 bool clipped = false;
851 851
852 if (rangeTop < my - m) { rangeTop = my - m; } 852 if (rangeTop < my - m) { rangeTop = my - m; }
853 if (rangeTop > my + m) { rangeTop = my + m; } 853 if (rangeTop > my + m) { rangeTop = my + m; }
854 if (rangeBottom < my - m) { rangeBottom = my - m; } 854 if (rangeBottom < my - m) { rangeBottom = my - m; }
855 if (rangeBottom > my + m) { rangeBottom = my + m; } 855 if (rangeBottom > my + m) { rangeBottom = my + m; }
856 856
857 if (range.max() <= -1.0 || 857 if (range.max() <= -1.0 ||
858 range.max() >= 1.0) clipped = true; 858 range.max() >= 1.0) clipped = true;
859 859
860 if (meanBottom > rangeBottom) meanBottom = rangeBottom; 860 if (meanBottom > rangeBottom) meanBottom = rangeBottom;
861 if (meanTop < rangeTop) meanTop = rangeTop; 861 if (meanTop < rangeTop) meanTop = rangeTop;
862 862
863 bool drawMean = m_showMeans; 863 bool drawMean = m_showMeans;
864 if (meanTop == rangeTop) { 864 if (meanTop == rangeTop) {
865 if (meanTop < meanBottom) ++meanTop; 865 if (meanTop < meanBottom) ++meanTop;
866 else drawMean = false; 866 else drawMean = false;
867 } 867 }
868 if (meanBottom == rangeBottom && m_scale == LinearScale) { 868 if (meanBottom == rangeBottom && m_scale == LinearScale) {
869 if (meanBottom > meanTop) --meanBottom; 869 if (meanBottom > meanTop) --meanBottom;
870 else drawMean = false; 870 else drawMean = false;
871 } 871 }
872 872
873 if (x != x0 && prevRangeBottom != -1) { 873 if (x != x0 && prevRangeBottom != -1) {
874 if (prevRangeBottom > rangeBottom + 1 && 874 if (prevRangeBottom > rangeBottom + 1 &&
875 prevRangeTop > rangeBottom + 1) { 875 prevRangeTop > rangeBottom + 1) {
876 // paint->setPen(midColour); 876 // paint->setPen(midColour);
877 paint->setPen(baseColour); 877 paint->setPen(baseColour);
878 paint->drawLine(x-1, prevRangeTop, x, rangeBottom + 1); 878 paint->drawLine(x-1, prevRangeTop, x, rangeBottom + 1);
879 paint->setPen(prevRangeTopColour); 879 paint->setPen(prevRangeTopColour);
880 paint->drawPoint(x-1, prevRangeTop); 880 paint->drawPoint(x-1, prevRangeTop);
881 } else if (prevRangeBottom < rangeTop - 1 && 881 } else if (prevRangeBottom < rangeTop - 1 &&
882 prevRangeTop < rangeTop - 1) { 882 prevRangeTop < rangeTop - 1) {
883 // paint->setPen(midColour); 883 // paint->setPen(midColour);
884 paint->setPen(baseColour); 884 paint->setPen(baseColour);
885 paint->drawLine(x-1, prevRangeBottom, x, rangeTop - 1); 885 paint->drawLine(x-1, prevRangeBottom, x, rangeTop - 1);
886 paint->setPen(prevRangeBottomColour); 886 paint->setPen(prevRangeBottomColour);
887 paint->drawPoint(x-1, prevRangeBottom); 887 paint->drawPoint(x-1, prevRangeBottom);
888 } 888 }
889 } 889 }
890 890
891 if (ready) { 891 if (ready) {
892 if (clipped /*!!! || 892 if (clipped /*!!! ||
893 range.min() * gain <= -1.0 || 893 range.min() * gain <= -1.0 ||
894 range.max() * gain >= 1.0 */) { 894 range.max() * gain >= 1.0 */) {
895 paint->setPen(Qt::red); //!!! getContrastingColour 895 paint->setPen(Qt::red); //!!! getContrastingColour
896 } else { 896 } else {
897 paint->setPen(baseColour); 897 paint->setPen(baseColour);
898 } 898 }
899 } else { 899 } else {
900 paint->setPen(midColour); 900 paint->setPen(midColour);
901 } 901 }
902 902
903 #ifdef DEBUG_WAVEFORM_PAINT 903 #ifdef DEBUG_WAVEFORM_PAINT
904 cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl; 904 cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl;
905 #endif 905 #endif
906 906
908 paint->drawPoint(x, rangeTop); 908 paint->drawPoint(x, rangeTop);
909 } else { 909 } else {
910 paint->drawLine(x, rangeBottom, x, rangeTop); 910 paint->drawLine(x, rangeBottom, x, rangeTop);
911 } 911 }
912 912
913 prevRangeTopColour = baseColour; 913 prevRangeTopColour = baseColour;
914 prevRangeBottomColour = baseColour; 914 prevRangeBottomColour = baseColour;
915 915
916 if (m_greyscale && (m_scale == LinearScale) && ready) { 916 if (m_greyscale && (m_scale == LinearScale) && ready) {
917 if (!clipped) { 917 if (!clipped) {
918 if (rangeTop < rangeBottom) { 918 if (rangeTop < rangeBottom) {
919 if (topFill > 0 && 919 if (topFill > 0 &&
920 (!drawMean || (rangeTop < meanTop - 1))) { 920 (!drawMean || (rangeTop < meanTop - 1))) {
921 paint->setPen(greys[topFill - 1]); 921 paint->setPen(greys[topFill - 1]);
922 paint->drawPoint(x, rangeTop); 922 paint->drawPoint(x, rangeTop);
923 prevRangeTopColour = greys[topFill - 1]; 923 prevRangeTopColour = greys[topFill - 1];
924 } 924 }
925 if (bottomFill > 0 && 925 if (bottomFill > 0 &&
926 (!drawMean || (rangeBottom > meanBottom + 1))) { 926 (!drawMean || (rangeBottom > meanBottom + 1))) {
927 paint->setPen(greys[bottomFill - 1]); 927 paint->setPen(greys[bottomFill - 1]);
928 paint->drawPoint(x, rangeBottom); 928 paint->drawPoint(x, rangeBottom);
929 prevRangeBottomColour = greys[bottomFill - 1]; 929 prevRangeBottomColour = greys[bottomFill - 1];
930 } 930 }
931 } 931 }
932 } 932 }
933 } 933 }
934 934
935 if (drawMean) { 935 if (drawMean) {
936 paint->setPen(midColour); 936 paint->setPen(midColour);
937 paint->drawLine(x, meanBottom, x, meanTop); 937 paint->drawLine(x, meanBottom, x, meanTop);
938 } 938 }
939 939
940 prevRangeBottom = rangeBottom; 940 prevRangeBottom = rangeBottom;
941 prevRangeTop = rangeTop; 941 prevRangeTop = rangeTop;
942 } 942 }
943 } 943 }
944 944
945 if (m_middleLineHeight != 0.5) { 945 if (m_middleLineHeight != 0.5) {
946 paint->restore(); 946 paint->restore();
947 } 947 }
948 948
949 if (m_aggressive) { 949 if (m_aggressive) {
950 950
951 if (ready && rect == v->getPaintRect()) { 951 if (ready && rect == v->getPaintRect()) {
952 m_cacheValid = true; 952 m_cacheValid = true;
953 m_cacheZoomLevel = zoomLevel; 953 m_cacheZoomLevel = zoomLevel;
954 } 954 }
955 paint->end(); 955 paint->end();
956 delete paint; 956 delete paint;
957 viewPainter.drawPixmap(rect, *m_cache, rect); 957 viewPainter.drawPixmap(rect, *m_cache, rect);
958 } 958 }
959 959
960 if (otherChannelRanges != ranges) delete otherChannelRanges; 960 if (otherChannelRanges != ranges) delete otherChannelRanges;
961 delete ranges; 961 delete ranges;
962 } 962 }
979 979
980 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate()); 980 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate());
981 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate()); 981 RealTime rt1 = RealTime::frame2RealTime(f1, m_model->getSampleRate());
982 982
983 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) { 983 if (f1 != f0 + 1 && (rt0.sec != rt1.sec || rt0.msec() != rt1.msec())) {
984 text += tr("Time:\t%1 - %2") 984 text += tr("Time:\t%1 - %2")
985 .arg(rt0.toText(true).c_str()) 985 .arg(rt0.toText(true).c_str())
986 .arg(rt1.toText(true).c_str()); 986 .arg(rt1.toText(true).c_str());
987 } else { 987 } else {
988 text += tr("Time:\t%1") 988 text += tr("Time:\t%1")
989 .arg(rt0.toText(true).c_str()); 989 .arg(rt0.toText(true).c_str());
990 } 990 }
991 991
992 int channels = 0, minChannel = 0, maxChannel = 0; 992 int channels = 0, minChannel = 0, maxChannel = 0;
993 bool mergingChannels = false, mixingChannels = false; 993 bool mergingChannels = false, mixingChannels = false;
994 994
996 mergingChannels, mixingChannels); 996 mergingChannels, mixingChannels);
997 if (channels == 0) return ""; 997 if (channels == 0) return "";
998 998
999 for (int ch = minChannel; ch <= maxChannel; ++ch) { 999 for (int ch = minChannel; ch <= maxChannel; ++ch) {
1000 1000
1001 int blockSize = v->getZoomLevel(); 1001 int blockSize = v->getZoomLevel();
1002 RangeSummarisableTimeValueModel::RangeBlock ranges; 1002 RangeSummarisableTimeValueModel::RangeBlock ranges;
1003 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize); 1003 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
1004 1004
1005 if (ranges.empty()) continue; 1005 if (ranges.empty()) continue;
1006 1006
1007 RangeSummarisableTimeValueModel::Range range = ranges[0]; 1007 RangeSummarisableTimeValueModel::Range range = ranges[0];
1008 1008
1009 QString label = tr("Level:"); 1009 QString label = tr("Level:");
1010 if (minChannel != maxChannel) { 1010 if (minChannel != maxChannel) {
1011 if (ch == 0) label = tr("Left:"); 1011 if (ch == 0) label = tr("Left:");
1012 else if (ch == 1) label = tr("Right:"); 1012 else if (ch == 1) label = tr("Right:");
1013 else label = tr("Channel %1").arg(ch + 1); 1013 else label = tr("Channel %1").arg(ch + 1);
1014 } 1014 }
1015 1015
1016 bool singleValue = false; 1016 bool singleValue = false;
1017 double min, max; 1017 double min, max;
1018 1018
1019 if (fabs(range.min()) < 0.01) { 1019 if (fabs(range.min()) < 0.01) {
1026 singleValue = (imin == imax); 1026 singleValue = (imin == imax);
1027 min = double(imin)/10000; 1027 min = double(imin)/10000;
1028 max = double(imax)/10000; 1028 max = double(imax)/10000;
1029 } 1029 }
1030 1030
1031 int db = int(AudioLevel::multiplier_to_dB(std::max(fabsf(range.min()), 1031 int db = int(AudioLevel::multiplier_to_dB(std::max(fabsf(range.min()),
1032 fabsf(range.max()))) 1032 fabsf(range.max())))
1033 * 100); 1033 * 100);
1034 1034
1035 if (!singleValue) { 1035 if (!singleValue) {
1036 text += tr("\n%1\t%2 - %3 (%4 dB peak)") 1036 text += tr("\n%1\t%2 - %3 (%4 dB peak)")
1037 .arg(label).arg(min).arg(max).arg(double(db)/100); 1037 .arg(label).arg(min).arg(max).arg(double(db)/100);
1038 } else { 1038 } else {
1039 text += tr("\n%1\t%2 (%3 dB peak)") 1039 text += tr("\n%1\t%2 (%3 dB peak)")
1040 .arg(label).arg(min).arg(double(db)/100); 1040 .arg(label).arg(min).arg(double(db)/100);
1041 } 1041 }
1042 } 1042 }
1043 1043
1044 return text; 1044 return text;
1045 } 1045 }
1046 1046
1055 if (channels == 0) return 0; 1055 if (channels == 0) return 0;
1056 if (maxChannel < minChannel || channel < minChannel) return 0; 1056 if (maxChannel < minChannel || channel < minChannel) return 0;
1057 1057
1058 int h = v->getPaintHeight(); 1058 int h = v->getPaintHeight();
1059 int m = (h / channels) / 2; 1059 int m = (h / channels) / 2;
1060 1060
1061 if ((m_scale == dBScale || m_scale == MeterScale) && 1061 if ((m_scale == dBScale || m_scale == MeterScale) &&
1062 m_channelMode != MergeChannels) { 1062 m_channelMode != MergeChannels) {
1063 m = (h / channels); 1063 m = (h / channels);
1064 } 1064 }
1065 1065
1199 1199
1200 int 1200 int
1201 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const 1201 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const
1202 { 1202 {
1203 if (m_scale == LinearScale) { 1203 if (m_scale == LinearScale) {
1204 return paint.fontMetrics().width("0.0") + 13; 1204 return paint.fontMetrics().width("0.0") + 13;
1205 } else { 1205 } else {
1206 return std::max(paint.fontMetrics().width(tr("0dB")), 1206 return std::max(paint.fontMetrics().width(tr("0dB")),
1207 paint.fontMetrics().width(Strings::minus_infinity)) + 13; 1207 paint.fontMetrics().width(Strings::minus_infinity)) + 13;
1208 } 1208 }
1209 } 1209 }
1210 1210
1211 void 1211 void
1212 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const 1212 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const
1213 { 1213 {
1214 if (!m_model || !m_model->isOK()) { 1214 if (!m_model || !m_model->isOK()) {
1215 return; 1215 return;
1216 } 1216 }
1217 1217
1218 int channels = 0, minChannel = 0, maxChannel = 0; 1218 int channels = 0, minChannel = 0, maxChannel = 0;
1219 bool mergingChannels = false, mixingChannels = false; 1219 bool mergingChannels = false, mixingChannels = false;
1220 1220
1228 1228
1229 double gain = m_gain; 1229 double gain = m_gain;
1230 1230
1231 for (int ch = minChannel; ch <= maxChannel; ++ch) { 1231 for (int ch = minChannel; ch <= maxChannel; ++ch) {
1232 1232
1233 int lastLabelledY = -1; 1233 int lastLabelledY = -1;
1234 1234
1235 if (ch < (int)m_effectiveGains.size()) gain = m_effectiveGains[ch]; 1235 if (ch < (int)m_effectiveGains.size()) gain = m_effectiveGains[ch];
1236 1236
1237 int n = 10; 1237 int n = 10;
1238 1238
1239 for (int i = 0; i <= n; ++i) { 1239 for (int i = 0; i <= n; ++i) {
1240 1240
1241 double val = 0.0, nval = 0.0; 1241 double val = 0.0, nval = 0.0;
1242 QString text = ""; 1242 QString text = "";
1243 1243
1244 switch (m_scale) { 1244 switch (m_scale) {
1245 1245
1246 case LinearScale: 1246 case LinearScale:
1247 val = (i * gain) / n; 1247 val = (i * gain) / n;
1248 text = QString("%1").arg(double(i) / n); 1248 text = QString("%1").arg(double(i) / n);
1249 if (i == 0) text = "0.0"; 1249 if (i == 0) text = "0.0";
1250 else { 1250 else {
1251 nval = -val; 1251 nval = -val;
1252 if (i == n) text = "1.0"; 1252 if (i == n) text = "1.0";
1253 } 1253 }
1254 break; 1254 break;
1255 1255
1256 case MeterScale: 1256 case MeterScale:
1257 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain; 1257 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain;
1258 text = QString("%1").arg(meterdbs[i]); 1258 text = QString("%1").arg(meterdbs[i]);
1259 if (i == n) text = tr("0dB"); 1259 if (i == n) text = tr("0dB");
1260 if (i == 0) { 1260 if (i == 0) {
1261 text = Strings::minus_infinity; 1261 text = Strings::minus_infinity;
1262 val = 0.0; 1262 val = 0.0;
1263 } 1263 }
1264 break; 1264 break;
1265 1265
1266 case dBScale: 1266 case dBScale:
1267 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain; 1267 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain;
1268 text = QString("%1").arg(-(10*n) + i * 10); 1268 text = QString("%1").arg(-(10*n) + i * 10);
1269 if (i == n) text = tr("0dB"); 1269 if (i == n) text = tr("0dB");
1270 if (i == 0) { 1270 if (i == 0) {
1271 text = Strings::minus_infinity; 1271 text = Strings::minus_infinity;
1272 val = 0.0; 1272 val = 0.0;
1273 } 1273 }
1274 break; 1274 break;
1275 } 1275 }
1276 1276
1277 if (val < -1.0 || val > 1.0) continue; 1277 if (val < -1.0 || val > 1.0) continue;
1278 1278
1323 } else { 1323 } else {
1324 1324
1325 paint.drawLine(w - 4, y, w, y); 1325 paint.drawLine(w - 4, y, w, y);
1326 if (ny != y) paint.drawLine(w - 4, ny, w, ny); 1326 if (ny != y) paint.drawLine(w - 4, ny, w, ny);
1327 } 1327 }
1328 } 1328 }
1329 } 1329 }
1330 } 1330 }
1331 1331
1332 void 1332 void
1333 WaveformLayer::toXml(QTextStream &stream, 1333 WaveformLayer::toXml(QTextStream &stream,
1338 QString colourName, colourSpec, darkbg; 1338 QString colourName, colourSpec, darkbg;
1339 ColourDatabase::getInstance()->getStringValues 1339 ColourDatabase::getInstance()->getStringValues
1340 (m_colour, colourName, colourSpec, darkbg); 1340 (m_colour, colourName, colourSpec, darkbg);
1341 1341
1342 s += QString("gain=\"%1\" " 1342 s += QString("gain=\"%1\" "
1343 "showMeans=\"%2\" " 1343 "showMeans=\"%2\" "
1344 "greyscale=\"%3\" " 1344 "greyscale=\"%3\" "
1345 "channelMode=\"%4\" " 1345 "channelMode=\"%4\" "
1346 "channel=\"%5\" " 1346 "channel=\"%5\" "
1347 "scale=\"%6\" " 1347 "scale=\"%6\" "
1348 "middleLineHeight=\"%7\" " 1348 "middleLineHeight=\"%7\" "
1349 "aggressive=\"%8\" " 1349 "aggressive=\"%8\" "
1350 "autoNormalize=\"%9\"") 1350 "autoNormalize=\"%9\"")
1351 .arg(m_gain) 1351 .arg(m_gain)
1352 .arg(m_showMeans) 1352 .arg(m_showMeans)
1353 .arg(m_greyscale) 1353 .arg(m_greyscale)
1354 .arg(m_channelMode) 1354 .arg(m_channelMode)
1355 .arg(m_channel) 1355 .arg(m_channel)
1356 .arg(m_scale) 1356 .arg(m_scale)
1357 .arg(m_middleLineHeight) 1357 .arg(m_middleLineHeight)
1358 .arg(m_aggressive) 1358 .arg(m_aggressive)
1359 .arg(m_autoNormalize); 1359 .arg(m_autoNormalize);
1360 1360
1361 SingleColourLayer::toXml(stream, indent, extraAttributes + " " + s); 1361 SingleColourLayer::toXml(stream, indent, extraAttributes + " " + s);
1362 } 1362 }
1363 1363
1370 1370
1371 float gain = attributes.value("gain").toFloat(&ok); 1371 float gain = attributes.value("gain").toFloat(&ok);
1372 if (ok) setGain(gain); 1372 if (ok) setGain(gain);
1373 1373
1374 bool showMeans = (attributes.value("showMeans") == "1" || 1374 bool showMeans = (attributes.value("showMeans") == "1" ||
1375 attributes.value("showMeans") == "true"); 1375 attributes.value("showMeans") == "true");
1376 setShowMeans(showMeans); 1376 setShowMeans(showMeans);
1377 1377
1378 bool greyscale = (attributes.value("greyscale") == "1" || 1378 bool greyscale = (attributes.value("greyscale") == "1" ||
1379 attributes.value("greyscale") == "true"); 1379 attributes.value("greyscale") == "true");
1380 setUseGreyscale(greyscale); 1380 setUseGreyscale(greyscale);
1381 1381
1382 ChannelMode channelMode = (ChannelMode) 1382 ChannelMode channelMode = (ChannelMode)
1383 attributes.value("channelMode").toInt(&ok); 1383 attributes.value("channelMode").toInt(&ok);
1384 if (ok) setChannelMode(channelMode); 1384 if (ok) setChannelMode(channelMode);
1385 1385
1386 int channel = attributes.value("channel").toInt(&ok); 1386 int channel = attributes.value("channel").toInt(&ok);
1387 if (ok) setChannel(channel); 1387 if (ok) setChannel(channel);
1388 1388
1391 1391
1392 float middleLineHeight = attributes.value("middleLineHeight").toFloat(&ok); 1392 float middleLineHeight = attributes.value("middleLineHeight").toFloat(&ok);
1393 if (ok) setMiddleLineHeight(middleLineHeight); 1393 if (ok) setMiddleLineHeight(middleLineHeight);
1394 1394
1395 bool aggressive = (attributes.value("aggressive") == "1" || 1395 bool aggressive = (attributes.value("aggressive") == "1" ||
1396 attributes.value("aggressive") == "true"); 1396 attributes.value("aggressive") == "true");
1397 setUseGreyscale(aggressive); 1397 setUseGreyscale(aggressive);
1398 1398
1399 bool autoNormalize = (attributes.value("autoNormalize") == "1" || 1399 bool autoNormalize = (attributes.value("autoNormalize") == "1" ||
1400 attributes.value("autoNormalize") == "true"); 1400 attributes.value("autoNormalize") == "true");
1401 setAutoNormalize(autoNormalize); 1401 setAutoNormalize(autoNormalize);