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