comparison layer/WaveformLayer.cpp @ 67:c4fff27cd651

* Add auto-normalize option to waveform layer * Various fixes to display of dB/metered levels in waveform layer. Still need to fix to ensure they don't waste half the display * Add mix channels option to waveform layer * Use multiple transforms menus, one per transform type -- not sure about this * Give centroid plugin two outputs, for log and linear frequency weightings * Show scale units from plugin in time-value display
author Chris Cannam
date Wed, 29 Mar 2006 12:35:17 +0000
parents 705f05ab42e3
children 193b569a975f
comparison
equal deleted inserted replaced
66:e9eac9368e29 67:c4fff27cd651
32 32
33 WaveformLayer::WaveformLayer() : 33 WaveformLayer::WaveformLayer() :
34 Layer(), 34 Layer(),
35 m_model(0), 35 m_model(0),
36 m_gain(1.0f), 36 m_gain(1.0f),
37 m_autoNormalize(false),
37 m_colour(Qt::black), 38 m_colour(Qt::black),
38 m_showMeans(true), 39 m_showMeans(true),
39 m_greyscale(true), 40 m_greyscale(true),
40 m_channelMode(SeparateChannels), 41 m_channelMode(SeparateChannels),
41 m_channel(-1), 42 m_channel(-1),
74 { 75 {
75 PropertyList list; 76 PropertyList list;
76 list.push_back(tr("Colour")); 77 list.push_back(tr("Colour"));
77 list.push_back(tr("Scale")); 78 list.push_back(tr("Scale"));
78 list.push_back(tr("Gain")); 79 list.push_back(tr("Gain"));
79 list.push_back(tr("Merge Channels")); 80 list.push_back(tr("Normalize Visible Area"));
81 list.push_back(tr("Channels"));
80 return list; 82 return list;
81 } 83 }
82 84
83 Layer::PropertyType 85 Layer::PropertyType
84 WaveformLayer::getPropertyType(const PropertyName &name) const 86 WaveformLayer::getPropertyType(const PropertyName &name) const
85 { 87 {
86 if (name == tr("Gain")) return RangeProperty; 88 if (name == tr("Gain")) return RangeProperty;
89 if (name == tr("Normalize Visible Area")) return ToggleProperty;
87 if (name == tr("Colour")) return ValueProperty; 90 if (name == tr("Colour")) return ValueProperty;
88 if (name == tr("Merge Channels")) return ToggleProperty; 91 if (name == tr("Channels")) return ValueProperty;
89 if (name == tr("Scale")) return ValueProperty; 92 if (name == tr("Scale")) return ValueProperty;
90 return InvalidProperty; 93 return InvalidProperty;
91 } 94 }
92 95
93 QString 96 QString
94 WaveformLayer::getPropertyGroupName(const PropertyName &name) const 97 WaveformLayer::getPropertyGroupName(const PropertyName &name) const
95 { 98 {
96 if (name == tr("Gain") || 99 if (name == tr("Gain") ||
100 name == tr("Normalize Visible Area") ||
97 name == tr("Scale")) return tr("Scale"); 101 name == tr("Scale")) return tr("Scale");
98 return QString(); 102 return QString();
99 } 103 }
100 104
101 int 105 int
102 WaveformLayer::getPropertyRangeAndValue(const PropertyName &name, 106 WaveformLayer::getPropertyRangeAndValue(const PropertyName &name,
103 int *min, int *max) const 107 int *min, int *max) const
104 { 108 {
105 int deft = 0; 109 int deft = 0;
106 110
107 int garbage0, garbage1; 111 int garbage0, garbage1;
108 if (!min) min = &garbage0; 112 if (!min) min = &garbage0;
114 *max = 50; 118 *max = 50;
115 119
116 deft = lrint(log10(m_gain) * 20.0); 120 deft = lrint(log10(m_gain) * 20.0);
117 if (deft < *min) deft = *min; 121 if (deft < *min) deft = *min;
118 if (deft > *max) deft = *max; 122 if (deft > *max) deft = *max;
123
124 } else if (name == tr("Normalize Visible Area")) {
125
126 deft = (m_autoNormalize ? 1 : 0);
119 127
120 } else if (name == tr("Colour")) { 128 } else if (name == tr("Colour")) {
121 129
122 *min = 0; 130 *min = 0;
123 *max = 5; 131 *max = 5;
127 else if (m_colour == Qt::darkBlue) deft = 2; 135 else if (m_colour == Qt::darkBlue) deft = 2;
128 else if (m_colour == Qt::darkGreen) deft = 3; 136 else if (m_colour == Qt::darkGreen) deft = 3;
129 else if (m_colour == QColor(200, 50, 255)) deft = 4; 137 else if (m_colour == QColor(200, 50, 255)) deft = 4;
130 else if (m_colour == QColor(255, 150, 50)) deft = 5; 138 else if (m_colour == QColor(255, 150, 50)) deft = 5;
131 139
132 } else if (name == tr("Merge Channels")) { 140 } else if (name == tr("Channels")) {
133 141
134 deft = ((m_channelMode == MergeChannels) ? 1 : 0); 142 *min = 0;
143 *max = 2;
144 if (m_channelMode == MixChannels) deft = 1;
145 else if (m_channelMode == MergeChannels) deft = 2;
146 else deft = 0;
135 147
136 } else if (name == tr("Scale")) { 148 } else if (name == tr("Scale")) {
137 149
138 *min = 0; 150 *min = 0;
139 *max = 2; 151 *max = 2;
168 case 0: return tr("Linear"); 180 case 0: return tr("Linear");
169 case 1: return tr("Meter"); 181 case 1: return tr("Meter");
170 case 2: return tr("dB"); 182 case 2: return tr("dB");
171 } 183 }
172 } 184 }
185 if (name == tr("Channels")) {
186 switch (value) {
187 default:
188 case 0: return tr("Separate");
189 case 1: return tr("Mean");
190 case 2: return tr("Butterfly");
191 }
192 }
173 return tr("<unknown>"); 193 return tr("<unknown>");
174 } 194 }
175 195
176 void 196 void
177 WaveformLayer::setProperty(const PropertyName &name, int value) 197 WaveformLayer::setProperty(const PropertyName &name, int value)
178 { 198 {
179 if (name == tr("Gain")) { 199 if (name == tr("Gain")) {
180 setGain(pow(10, float(value)/20.0)); 200 setGain(pow(10, float(value)/20.0));
201 } else if (name == tr("Normalize Visible Area")) {
202 setAutoNormalize(value ? true : false);
181 } else if (name == tr("Colour")) { 203 } else if (name == tr("Colour")) {
182 switch (value) { 204 switch (value) {
183 default: 205 default:
184 case 0: setBaseColour(Qt::black); break; 206 case 0: setBaseColour(Qt::black); break;
185 case 1: setBaseColour(Qt::darkRed); break; 207 case 1: setBaseColour(Qt::darkRed); break;
186 case 2: setBaseColour(Qt::darkBlue); break; 208 case 2: setBaseColour(Qt::darkBlue); break;
187 case 3: setBaseColour(Qt::darkGreen); break; 209 case 3: setBaseColour(Qt::darkGreen); break;
188 case 4: setBaseColour(QColor(200, 50, 255)); break; 210 case 4: setBaseColour(QColor(200, 50, 255)); break;
189 case 5: setBaseColour(QColor(255, 150, 50)); break; 211 case 5: setBaseColour(QColor(255, 150, 50)); break;
190 } 212 }
191 } else if (name == tr("Merge Channels")) { 213 } else if (name == tr("Channels")) {
192 setChannelMode(value ? MergeChannels : SeparateChannels); 214 if (value == 1) setChannelMode(MixChannels);
215 else if (value == 2) setChannelMode(MergeChannels);
216 else setChannelMode(SeparateChannels);
193 } else if (name == tr("Scale")) { 217 } else if (name == tr("Scale")) {
194 switch (value) { 218 switch (value) {
195 default: 219 default:
196 case 0: setScale(LinearScale); break; 220 case 0: setScale(LinearScale); break;
197 case 1: setScale(MeterScale); break; 221 case 1: setScale(MeterScale); break;
198 case 2: setScale(dBScale); break; 222 case 2: setScale(dBScale); break;
199 } 223 }
200 } 224 }
201 } 225 }
202 226
203 /* 227 void
204 228 WaveformLayer::setGain(float gain)
205 int
206 WaveformLayer::getProperty(const PropertyName &name)
207 {
208 if (name == "Gain") {
209 return int((getGain() - 1.0) * 10.0 + 0.01);
210 }
211 if (name == "Colour") {
212
213 */
214
215 void
216 WaveformLayer::setGain(float gain) //!!! inadequate for floats!
217 { 229 {
218 if (m_gain == gain) return; 230 if (m_gain == gain) return;
219 m_gain = gain; 231 m_gain = gain;
220 m_cacheValid = false; 232 m_cacheValid = false;
221 emit layerParametersChanged(); 233 emit layerParametersChanged();
222 } 234 }
223 235
224 void 236 void
237 WaveformLayer::setAutoNormalize(bool autoNormalize)
238 {
239 if (m_autoNormalize == autoNormalize) return;
240 m_autoNormalize = autoNormalize;
241 m_cacheValid = false;
242 emit layerParametersChanged();
243 }
244
245 void
225 WaveformLayer::setBaseColour(QColor colour) 246 WaveformLayer::setBaseColour(QColor colour)
226 { 247 {
227 if (m_colour == colour) return; 248 if (m_colour == colour) return;
228 m_colour = colour; 249 m_colour = colour;
229 m_cacheValid = false; 250 m_cacheValid = false;
296 } 317 }
297 318
298 int 319 int
299 WaveformLayer::dBscale(float sample, int m) const 320 WaveformLayer::dBscale(float sample, int m) const
300 { 321 {
301 if (sample < 0.0) return -dBscale(-sample, m); 322 //!!! if (sample < 0.0) return -dBscale(-sample, m);
323 if (sample < 0.0) return dBscale(-sample, m);
302 float dB = AudioLevel::multiplier_to_dB(sample); 324 float dB = AudioLevel::multiplier_to_dB(sample);
303 if (dB < -50.0) return 0; 325 if (dB < -50.0) return 0;
304 if (dB > 0.0) return m; 326 if (dB > 0.0) return m;
305 return int(((dB + 50.0) * m) / 50.0 + 0.1); 327 return int(((dB + 50.0) * m) / 50.0 + 0.1);
306 } 328 }
307 329
308 size_t 330 size_t
309 WaveformLayer::getChannelArrangement(size_t &min, size_t &max, bool &merging) 331 WaveformLayer::getChannelArrangement(size_t &min, size_t &max,
332 bool &merging, bool &mixing)
310 const 333 const
311 { 334 {
312 if (!m_model || !m_model->isOK()) return 0; 335 if (!m_model || !m_model->isOK()) return 0;
313 336
314 size_t channels = m_model->getChannelCount(); 337 size_t channels = m_model->getChannelCount();
316 339
317 size_t rawChannels = channels; 340 size_t rawChannels = channels;
318 341
319 if (m_channel == -1) { 342 if (m_channel == -1) {
320 min = 0; 343 min = 0;
321 if (m_channelMode == MergeChannels) { 344 if (m_channelMode == MergeChannels ||
345 m_channelMode == MixChannels) {
322 max = 0; 346 max = 0;
323 channels = 1; 347 channels = 1;
324 } else { 348 } else {
325 max = channels - 1; 349 max = channels - 1;
326 } 350 }
330 rawChannels = 1; 354 rawChannels = 1;
331 channels = 1; 355 channels = 1;
332 } 356 }
333 357
334 merging = (m_channelMode == MergeChannels && rawChannels > 1); 358 merging = (m_channelMode == MergeChannels && rawChannels > 1);
359 mixing = (m_channelMode == MixChannels && rawChannels > 1);
335 360
336 // std::cerr << "WaveformLayer::getChannelArrangement: min " << min << ", max " << max << ", merging " << merging << ", channels " << channels << std::endl; 361 // std::cerr << "WaveformLayer::getChannelArrangement: min " << min << ", max " << max << ", merging " << merging << ", channels " << channels << std::endl;
337 362
338 return channels; 363 return channels;
339 } 364 }
365
366 bool
367 WaveformLayer::isLayerScrollable(const View *) const
368 {
369 return !m_autoNormalize;
370 }
340 371
341 void 372 void
342 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const 373 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const
343 { 374 {
344 if (!m_model || !m_model->isOK()) { 375 if (!m_model || !m_model->isOK()) {
353 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() 384 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
354 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << ", start " << startFrame << std::endl; 385 << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << ", start " << startFrame << std::endl;
355 #endif 386 #endif
356 387
357 size_t channels = 0, minChannel = 0, maxChannel = 0; 388 size_t channels = 0, minChannel = 0, maxChannel = 0;
358 bool mergingChannels = false; 389 bool mergingChannels = false, mixingChannels = false;
359 390
360 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); 391 channels = getChannelArrangement(minChannel, maxChannel,
392 mergingChannels, mixingChannels);
361 if (channels == 0) return; 393 if (channels == 0) return;
362 394
363 int w = v->width(); 395 int w = v->width();
364 int h = v->height(); 396 int h = v->height();
365 397
444 midColour = midColour.light(150); 476 midColour = midColour.light(150);
445 } else { 477 } else {
446 midColour = midColour.light(50); 478 midColour = midColour.light(50);
447 } 479 }
448 480
481 while (m_effectiveGains.size() <= maxChannel) {
482 m_effectiveGains.push_back(m_gain);
483 }
484
449 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { 485 for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
450 486
451 int prevRangeBottom = -1, prevRangeTop = -1; 487 int prevRangeBottom = -1, prevRangeTop = -1;
452 QColor prevRangeBottomColour = m_colour, prevRangeTopColour = m_colour; 488 QColor prevRangeBottomColour = m_colour, prevRangeTopColour = m_colour;
453 489
466 size_t modelZoomLevel = zoomLevel; 502 size_t modelZoomLevel = zoomLevel;
467 503
468 ranges = m_model->getRanges 504 ranges = m_model->getRanges
469 (ch, frame0 < 0 ? 0 : frame0, frame1, modelZoomLevel); 505 (ch, frame0 < 0 ? 0 : frame0, frame1, modelZoomLevel);
470 506
471 if (mergingChannels) { 507 if (mergingChannels || mixingChannels) {
472 otherChannelRanges = m_model->getRanges 508 otherChannelRanges = m_model->getRanges
473 (1, frame0 < 0 ? 0 : frame0, frame1, modelZoomLevel); 509 (1, frame0 < 0 ? 0 : frame0, frame1, modelZoomLevel);
474 } 510 }
511
512 m_effectiveGains[ch] = m_gain;
513
514 if (m_autoNormalize) {
515 RangeSummarisableTimeValueModel::Range range =
516 m_model->getRange(ch, startFrame < 0 ? 0 : startFrame,
517 v->getEndFrame());
518 if (mergingChannels || mixingChannels) {
519 RangeSummarisableTimeValueModel::Range otherRange =
520 m_model->getRange(1, startFrame < 0 ? 0 : startFrame,
521 v->getEndFrame());
522 range.max = std::max(range.max, otherRange.max);
523 range.min = std::min(range.min, otherRange.min);
524 range.absmean = std::min(range.absmean, otherRange.absmean);
525 }
526 m_effectiveGains[ch] = 1.0 / std::max(fabsf(range.max),
527 fabsf(range.min));
528 }
529
530 float gain = m_effectiveGains[ch];
475 531
476 for (int x = x0; x <= x1; ++x) { 532 for (int x = x0; x <= x1; ++x) {
477 533
478 range = RangeSummarisableTimeValueModel::Range(); 534 range = RangeSummarisableTimeValueModel::Range();
479 size_t index = x - x0; 535 size_t index = x - x0;
534 range.min = std::min 590 range.min = std::min
535 (range.min, 591 (range.min,
536 -fabsf(otherChannelRanges[maxIndex].max)); 592 -fabsf(otherChannelRanges[maxIndex].max));
537 } 593 }
538 } 594 }
539 } 595
596 } else if (mixingChannels) {
597
598 if (index < otherChannelRanges.size()) {
599
600 range.max = (range.max + otherChannelRanges[index].max) / 2;
601 range.min = (range.min + otherChannelRanges[index].min) / 2;
602 range.absmean = (range.absmean + otherChannelRanges[index].absmean) / 2;
603 }
604 }
540 605
541 int greyLevels = 1; 606 int greyLevels = 1;
542 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4; 607 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;
543 608
544 switch (m_scale) { 609 switch (m_scale) {
545 610
546 case LinearScale: 611 case LinearScale:
547 rangeBottom = int( m * greyLevels * range.min * m_gain); 612 rangeBottom = int( m * greyLevels * range.min * gain);
548 rangeTop = int( m * greyLevels * range.max * m_gain); 613 rangeTop = int( m * greyLevels * range.max * gain);
549 meanBottom = int(-m * range.absmean * m_gain); 614 meanBottom = int(-m * range.absmean * gain);
550 meanTop = int( m * range.absmean * m_gain); 615 meanTop = int( m * range.absmean * gain);
551 break; 616 break;
552 617
553 case dBScale: 618 case dBScale:
554 rangeBottom = dBscale(range.min * m_gain, m * greyLevels); 619 if (!mergingChannels) {
555 rangeTop = dBscale(range.max * m_gain, m * greyLevels); 620 int db0 = dBscale(range.min * gain, m);
556 meanBottom = -dBscale(range.absmean * m_gain, m); 621 int db1 = dBscale(range.max * gain, m);
557 meanTop = dBscale(range.absmean * m_gain, m); 622 rangeTop = std::max(db0, db1);
623 meanTop = std::min(db0, db1);
624 if (mixingChannels) rangeBottom = meanTop;
625 else rangeBottom = dBscale(range.absmean * gain, m);
626 meanBottom = rangeBottom;
627 } else {
628 rangeBottom = -dBscale(range.min * gain, m * greyLevels);
629 rangeTop = dBscale(range.max * gain, m * greyLevels);
630 meanBottom = -dBscale(range.absmean * gain, m);
631 meanTop = dBscale(range.absmean * gain, m);
632 }
558 break; 633 break;
559 634
560 case MeterScale: 635 case MeterScale:
561 rangeBottom = AudioLevel::multiplier_to_preview(range.min * m_gain, m * greyLevels); 636 if (!mergingChannels) {
562 rangeTop = AudioLevel::multiplier_to_preview(range.max * m_gain, m * greyLevels); 637 int r0 = abs(AudioLevel::multiplier_to_preview(range.min * gain, m));
563 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean * m_gain, m); 638 int r1 = abs(AudioLevel::multiplier_to_preview(range.max * gain, m));
564 meanTop = AudioLevel::multiplier_to_preview(range.absmean * m_gain, m); 639 rangeTop = std::max(r0, r1);
640 meanTop = std::min(r0, r1);
641 if (mixingChannels) rangeBottom = meanTop;
642 else rangeBottom = AudioLevel::multiplier_to_preview(range.absmean * gain, m);
643 meanBottom = rangeBottom;
644 } else {
645 rangeBottom = AudioLevel::multiplier_to_preview(range.min * gain, m * greyLevels);
646 rangeTop = AudioLevel::multiplier_to_preview(range.max * gain, m * greyLevels);
647 meanBottom = -AudioLevel::multiplier_to_preview(range.absmean * gain, m);
648 meanTop = AudioLevel::multiplier_to_preview(range.absmean * gain, m);
649 }
650 break;
565 } 651 }
566 652
567 rangeBottom = my * greyLevels - rangeBottom; 653 rangeBottom = my * greyLevels - rangeBottom;
568 rangeTop = my * greyLevels - rangeTop; 654 rangeTop = my * greyLevels - rangeTop;
569 meanBottom = my - meanBottom; 655 meanBottom = my - meanBottom;
582 if (rangeTop < my - m) { rangeTop = my - m; } 668 if (rangeTop < my - m) { rangeTop = my - m; }
583 if (rangeTop > my + m) { rangeTop = my + m; } 669 if (rangeTop > my + m) { rangeTop = my + m; }
584 if (rangeBottom < my - m) { rangeBottom = my - m; } 670 if (rangeBottom < my - m) { rangeBottom = my - m; }
585 if (rangeBottom > my + m) { rangeBottom = my + m; } 671 if (rangeBottom > my + m) { rangeBottom = my + m; }
586 672
587 if (range.max * m_gain <= -1.0 || 673 if (range.max <= -1.0 ||
588 range.max * m_gain >= 1.0) clipped = true; 674 range.max >= 1.0) clipped = true;
589 675
590 if (meanBottom > rangeBottom) meanBottom = rangeBottom; 676 if (meanBottom > rangeBottom) meanBottom = rangeBottom;
591 if (meanTop < rangeTop) meanTop = rangeTop; 677 if (meanTop < rangeTop) meanTop = rangeTop;
592 678
593 bool drawMean = m_showMeans; 679 bool drawMean = m_showMeans;
594 if (meanTop == rangeTop) { 680 if (meanTop == rangeTop) {
595 if (meanTop < meanBottom) ++meanTop; 681 if (meanTop < meanBottom) ++meanTop;
596 else drawMean = false; 682 else drawMean = false;
597 } 683 }
598 if (meanBottom == rangeBottom) { 684 if (meanBottom == rangeBottom && m_scale == LinearScale) {
599 if (meanBottom > meanTop) --meanBottom; 685 if (meanBottom > meanTop) --meanBottom;
600 else drawMean = false; 686 else drawMean = false;
601 } 687 }
602 688
603 if (x != x0 && prevRangeBottom != -1) { 689 if (x != x0 && prevRangeBottom != -1) {
617 paint->drawPoint(x-1, prevRangeBottom); 703 paint->drawPoint(x-1, prevRangeBottom);
618 } 704 }
619 } 705 }
620 706
621 if (ready) { 707 if (ready) {
622 if (clipped || 708 if (clipped /*!!! ||
623 range.min * m_gain <= -1.0 || 709 range.min * gain <= -1.0 ||
624 range.max * m_gain >= 1.0) { 710 range.max * gain >= 1.0 */) {
625 paint->setPen(Qt::red); 711 paint->setPen(Qt::red);
626 } else { 712 } else {
627 paint->setPen(m_colour); 713 paint->setPen(m_colour);
628 } 714 }
629 } else { 715 } else {
702 text += tr("Time:\t%1") 788 text += tr("Time:\t%1")
703 .arg(rt0.toText(true).c_str()); 789 .arg(rt0.toText(true).c_str());
704 } 790 }
705 791
706 size_t channels = 0, minChannel = 0, maxChannel = 0; 792 size_t channels = 0, minChannel = 0, maxChannel = 0;
707 bool mergingChannels = false; 793 bool mergingChannels = false, mixingChannels = false;
708 794
709 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); 795 channels = getChannelArrangement(minChannel, maxChannel,
796 mergingChannels, mixingChannels);
710 if (channels == 0) return ""; 797 if (channels == 0) return "";
711 798
712 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { 799 for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
713 800
714 size_t blockSize = v->getZoomLevel(); 801 size_t blockSize = v->getZoomLevel();
761 if (!m_model || !m_model->isOK()) { 848 if (!m_model || !m_model->isOK()) {
762 return; 849 return;
763 } 850 }
764 851
765 size_t channels = 0, minChannel = 0, maxChannel = 0; 852 size_t channels = 0, minChannel = 0, maxChannel = 0;
766 bool mergingChannels = false; 853 bool mergingChannels = false, mixingChannels = false;
767 854
768 channels = getChannelArrangement(minChannel, maxChannel, mergingChannels); 855 channels = getChannelArrangement(minChannel, maxChannel,
856 mergingChannels, mixingChannels);
769 if (channels == 0) return; 857 if (channels == 0) return;
770 858
771 int h = rect.height(), w = rect.width(); 859 int h = rect.height(), w = rect.width();
772 int textHeight = paint.fontMetrics().height(); 860 int textHeight = paint.fontMetrics().height();
773 int toff = -textHeight/2 + paint.fontMetrics().ascent() + 1; 861 int toff = -textHeight/2 + paint.fontMetrics().ascent() + 1;
774 862
863 float gain = m_gain;
864
775 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { 865 for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
776 866
777 int m = (h / channels) / 2; 867 int m = (h / channels) / 2;
778 int my = m + (((ch - minChannel) * h) / channels); 868 int my = m + (((ch - minChannel) * h) / channels);
779 int py = -1; 869 int py = -1;
780 870
871 if (ch < m_effectiveGains.size()) gain = m_effectiveGains[ch];
872
781 for (int i = 0; i <= 10; ++i) { 873 for (int i = 0; i <= 10; ++i) {
782 874
783 int vy = 0; 875 int vy = 0;
784 QString text = ""; 876 QString text = "";
785 877
786 if (m_scale == LinearScale) { 878 if (m_scale == LinearScale) {
787 879
788 vy = int((m * i * m_gain) / 10); 880 vy = int((m * i * gain) / 10);
789 881
790 text = QString("%1").arg(float(i) / 10.0); 882 text = QString("%1").arg(float(i) / 10.0);
791 if (i == 0) text = "0.0"; 883 if (i == 0) text = "0.0";
792 if (i == 10) text = "1.0"; 884 if (i == 10) text = "1.0";
793 885
800 static int dbs[] = { -50, -40, -30, -20, -15, 892 static int dbs[] = { -50, -40, -30, -20, -15,
801 -10, -5, -3, -2, -1, 0 }; 893 -10, -5, -3, -2, -1, 0 };
802 db = dbs[i]; 894 db = dbs[i];
803 if (db == -50) minvalue = true; 895 if (db == -50) minvalue = true;
804 vy = AudioLevel::multiplier_to_preview 896 vy = AudioLevel::multiplier_to_preview
805 (AudioLevel::dB_to_multiplier(db) * m_gain, m); 897 (AudioLevel::dB_to_multiplier(db) * gain, m);
806 } else { 898 } else {
807 db = -100 + i * 10; 899 db = -100 + i * 10;
808 if (db == -100) minvalue = true; 900 if (db == -100) minvalue = true;
809 vy = dBscale 901 vy = dBscale
810 (AudioLevel::dB_to_multiplier(db) * m_gain, m); 902 (AudioLevel::dB_to_multiplier(db) * gain, m);
811 } 903 }
812 904
813 text = QString("%1").arg(db); 905 text = QString("%1").arg(db);
814 if (db == 0) text = tr("0dB"); 906 if (db == 0) text = tr("0dB");
815 if (minvalue) { 907 if (minvalue) {
817 vy = 0; 909 vy = 0;
818 } 910 }
819 } 911 }
820 912
821 if (vy < 0) vy = -vy; 913 if (vy < 0) vy = -vy;
822 if (vy >= m - 1) continue; 914 // if (vy >= m - 1) continue;
823 915
824 if (py >= 0 && (vy - py) < textHeight - 1) { 916 if (py >= 0 && (vy - py) < textHeight - 1) {
825 paint.drawLine(w - 4, my - vy, w, my - vy); 917 paint.drawLine(w - 4, my - vy, w, my - vy);
826 if (vy > 0) paint.drawLine(w - 4, my + vy, w, my + vy); 918 if (vy > 0) paint.drawLine(w - 4, my + vy, w, my + vy);
827 continue; 919 continue;
833 int tx = 3; 925 int tx = 3;
834 if (m_scale != LinearScale) { 926 if (m_scale != LinearScale) {
835 tx = w - 10 - paint.fontMetrics().width(text); 927 tx = w - 10 - paint.fontMetrics().width(text);
836 } 928 }
837 929
930 if (vy >= m - 1) continue;
931
838 paint.drawText(tx, my - vy + toff, text); 932 paint.drawText(tx, my - vy + toff, text);
839 if (vy > 0) paint.drawText(tx, my + vy + toff, text); 933 if (vy > 0) paint.drawText(tx, my + vy + toff, text);
840 934
841 py = vy; 935 py = vy;
842 } 936 }
853 "showMeans=\"%3\" " 947 "showMeans=\"%3\" "
854 "greyscale=\"%4\" " 948 "greyscale=\"%4\" "
855 "channelMode=\"%5\" " 949 "channelMode=\"%5\" "
856 "channel=\"%6\" " 950 "channel=\"%6\" "
857 "scale=\"%7\" " 951 "scale=\"%7\" "
858 "aggressive=\"%8\"") 952 "aggressive=\"%8\" "
953 "autoNormalize=\"%9\"")
859 .arg(m_gain) 954 .arg(m_gain)
860 .arg(encodeColour(m_colour)) 955 .arg(encodeColour(m_colour))
861 .arg(m_showMeans) 956 .arg(m_showMeans)
862 .arg(m_greyscale) 957 .arg(m_greyscale)
863 .arg(m_channelMode) 958 .arg(m_channelMode)
864 .arg(m_channel) 959 .arg(m_channel)
865 .arg(m_scale) 960 .arg(m_scale)
866 .arg(m_aggressive); 961 .arg(m_aggressive)
962 .arg(m_autoNormalize);
867 963
868 return Layer::toXmlString(indent, extraAttributes + " " + s); 964 return Layer::toXmlString(indent, extraAttributes + " " + s);
869 } 965 }
870 966
871 void 967 void
904 if (ok) setScale(scale); 1000 if (ok) setScale(scale);
905 1001
906 bool aggressive = (attributes.value("aggressive") == "1" || 1002 bool aggressive = (attributes.value("aggressive") == "1" ||
907 attributes.value("aggressive") == "true"); 1003 attributes.value("aggressive") == "true");
908 setUseGreyscale(aggressive); 1004 setUseGreyscale(aggressive);
1005
1006 bool autoNormalize = (attributes.value("autoNormalize") == "1" ||
1007 attributes.value("autoNormalize") == "true");
1008 setAutoNormalize(autoNormalize);
909 } 1009 }
910 1010
911 #ifdef INCLUDE_MOCFILES 1011 #ifdef INCLUDE_MOCFILES
912 #include "WaveformLayer.moc.cpp" 1012 #include "WaveformLayer.moc.cpp"
913 #endif 1013 #endif