comparison layer/WaveformLayer.cpp @ 944:78c152e4db95

Merge from branch tonioni
author Chris Cannam
date Mon, 20 Apr 2015 09:12:17 +0100
parents 4a578a360011
children f6d9f28f37cb 3871dffc31bd
comparison
equal deleted inserted replaced
896:78e041e45ff0 944:78c152e4db95
151 151
152 *min = -50; 152 *min = -50;
153 *max = 50; 153 *max = 50;
154 *deflt = 0; 154 *deflt = 0;
155 155
156 val = lrint(log10(m_gain) * 20.0); 156 val = int(lrint(log10(m_gain) * 20.0));
157 if (val < *min) val = *min; 157 if (val < *min) val = *min;
158 if (val > *max) val = *max; 158 if (val > *max) val = *max;
159 159
160 } else if (name == "Normalize Visible Area") { 160 } else if (name == "Normalize Visible Area") {
161 161
220 220
221 void 221 void
222 WaveformLayer::setProperty(const PropertyName &name, int value) 222 WaveformLayer::setProperty(const PropertyName &name, int value)
223 { 223 {
224 if (name == "Gain") { 224 if (name == "Gain") {
225 setGain(pow(10, float(value)/20.0)); 225 setGain(float(pow(10, float(value)/20.0)));
226 } else if (name == "Normalize Visible Area") { 226 } else if (name == "Normalize Visible Area") {
227 setAutoNormalize(value ? true : false); 227 setAutoNormalize(value ? true : false);
228 } else if (name == "Channels") { 228 } else if (name == "Channels") {
229 if (value == 1) setChannelMode(MixChannels); 229 if (value == 1) setChannelMode(MixChannels);
230 else if (value == 2) setChannelMode(MergeChannels); 230 else if (value == 2) setChannelMode(MergeChannels);
306 m_cacheValid = false; 306 m_cacheValid = false;
307 emit layerParametersChanged(); 307 emit layerParametersChanged();
308 } 308 }
309 309
310 void 310 void
311 WaveformLayer::setMiddleLineHeight(float height) 311 WaveformLayer::setMiddleLineHeight(double height)
312 { 312 {
313 if (m_middleLineHeight == height) return; 313 if (m_middleLineHeight == height) return;
314 m_middleLineHeight = height; 314 m_middleLineHeight = height;
315 m_cacheValid = false; 315 m_cacheValid = false;
316 emit layerParametersChanged(); 316 emit layerParametersChanged();
333 if (m_model->isReady(&completion)) return 100; 333 if (m_model->isReady(&completion)) return 100;
334 return completion; 334 return completion;
335 } 335 }
336 336
337 bool 337 bool
338 WaveformLayer::getValueExtents(float &min, float &max, 338 WaveformLayer::getValueExtents(double &min, double &max,
339 bool &, QString &unit) const 339 bool &, QString &unit) const
340 { 340 {
341 if (m_scale == LinearScale) { 341 if (m_scale == LinearScale) {
342 min = 0.0; 342 min = 0.0;
343 max = 1.0; 343 max = 1.0;
351 } 351 }
352 return true; 352 return true;
353 } 353 }
354 354
355 int 355 int
356 WaveformLayer::dBscale(float sample, int m) const 356 WaveformLayer::dBscale(double sample, int m) const
357 { 357 {
358 if (sample < 0.0) return dBscale(-sample, m); 358 if (sample < 0.0) return dBscale(-sample, m);
359 float dB = AudioLevel::multiplier_to_dB(sample); 359 double dB = AudioLevel::multiplier_to_dB(sample);
360 if (dB < -50.0) return 0; 360 if (dB < -50.0) return 0;
361 if (dB > 0.0) return m; 361 if (dB > 0.0) return m;
362 return int(((dB + 50.0) * m) / 50.0 + 0.1); 362 return int(((dB + 50.0) * m) / 50.0 + 0.1);
363 } 363 }
364 364
407 static float meterdbs[] = { -40, -30, -20, -15, -10, 407 static float meterdbs[] = { -40, -30, -20, -15, -10,
408 -5, -3, -2, -1, -0.5, 0 }; 408 -5, -3, -2, -1, -0.5, 0 };
409 409
410 bool 410 bool
411 WaveformLayer::getSourceFramesForX(View *v, int x, int modelZoomLevel, 411 WaveformLayer::getSourceFramesForX(View *v, int x, int modelZoomLevel,
412 int &f0, int &f1) const 412 sv_frame_t &f0, sv_frame_t &f1) const
413 { 413 {
414 int viewFrame = v->getFrameForX(x); 414 sv_frame_t viewFrame = v->getFrameForX(x);
415 if (viewFrame < 0) { 415 if (viewFrame < 0) {
416 f0 = 0; 416 f0 = 0;
417 f1 = 0; 417 f1 = 0;
418 return false; 418 return false;
419 } 419 }
433 } 433 }
434 434
435 float 435 float
436 WaveformLayer::getNormalizeGain(View *v, int channel) const 436 WaveformLayer::getNormalizeGain(View *v, int channel) const
437 { 437 {
438 int startFrame = v->getStartFrame(); 438 sv_frame_t startFrame = v->getStartFrame();
439 int endFrame = v->getEndFrame(); 439 sv_frame_t endFrame = v->getEndFrame();
440 440
441 int modelStart = m_model->getStartFrame(); 441 sv_frame_t modelStart = m_model->getStartFrame();
442 int modelEnd = m_model->getEndFrame(); 442 sv_frame_t modelEnd = m_model->getEndFrame();
443 443
444 int rangeStart, rangeEnd; 444 sv_frame_t rangeStart, rangeEnd;
445 445
446 if (startFrame < modelStart) rangeStart = modelStart; 446 if (startFrame < modelStart) rangeStart = modelStart;
447 else rangeStart = startFrame; 447 else rangeStart = startFrame;
448 448
449 if (endFrame < 0) rangeEnd = 0; 449 if (endFrame < 0) rangeEnd = 0;
467 range.setMax(std::max(range.max(), otherRange.max())); 467 range.setMax(std::max(range.max(), otherRange.max()));
468 range.setMin(std::min(range.min(), otherRange.min())); 468 range.setMin(std::min(range.min(), otherRange.min()));
469 range.setAbsmean(std::min(range.absmean(), otherRange.absmean())); 469 range.setAbsmean(std::min(range.absmean(), otherRange.absmean()));
470 } 470 }
471 471
472 return 1.0 / std::max(fabsf(range.max()), fabsf(range.min())); 472 return float(1.0 / std::max(fabs(range.max()), fabs(range.min())));
473 } 473 }
474 474
475 void 475 void
476 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const 476 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const
477 { 477 {
541 541
542 paint->setRenderHint(QPainter::Antialiasing, false); 542 paint->setRenderHint(QPainter::Antialiasing, false);
543 543
544 if (m_middleLineHeight != 0.5) { 544 if (m_middleLineHeight != 0.5) {
545 paint->save(); 545 paint->save();
546 float space = m_middleLineHeight * 2; 546 double space = m_middleLineHeight * 2;
547 if (space > 1.0) space = 2.0 - space; 547 if (space > 1.0) space = 2.0 - space;
548 float yt = h * (m_middleLineHeight - space/2); 548 double yt = h * (m_middleLineHeight - space/2);
549 paint->translate(QPointF(0, yt)); 549 paint->translate(QPointF(0, yt));
550 paint->scale(1.0, space); 550 paint->scale(1.0, space);
551 } 551 }
552 552
553 int x0 = 0, x1 = w - 1; 553 int x0 = 0, x1 = w - 1;
570 // must remain the same when we scroll one or more pixels left or 570 // must remain the same when we scroll one or more pixels left or
571 // right. 571 // right.
572 572
573 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel); 573 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel);
574 574
575 int frame0; 575 sv_frame_t frame0;
576 int frame1; 576 sv_frame_t frame1;
577 int spare; 577 sv_frame_t spare;
578 578
579 getSourceFramesForX(v, x0, modelZoomLevel, frame0, spare); 579 getSourceFramesForX(v, x0, modelZoomLevel, frame0, spare);
580 getSourceFramesForX(v, x1, modelZoomLevel, spare, frame1); 580 getSourceFramesForX(v, x1, modelZoomLevel, spare, frame1);
581 581
582 #ifdef DEBUG_WAVEFORM_PAINT 582 #ifdef DEBUG_WAVEFORM_PAINT
614 614
615 if (m_autoNormalize) { 615 if (m_autoNormalize) {
616 m_effectiveGains[ch] = getNormalizeGain(v, ch); 616 m_effectiveGains[ch] = getNormalizeGain(v, ch);
617 } 617 }
618 618
619 float gain = m_effectiveGains[ch]; 619 double gain = m_effectiveGains[ch];
620 620
621 int m = (h / channels) / 2; 621 int m = (h / channels) / 2;
622 int my = m + (((ch - minChannel) * h) / channels); 622 int my = m + (((ch - minChannel) * h) / channels);
623 623
624 #ifdef DEBUG_WAVEFORM_PAINT 624 #ifdef DEBUG_WAVEFORM_PAINT
645 645
646 paint->setPen(QColor(240, 240, 240)); 646 paint->setPen(QColor(240, 240, 240));
647 647
648 for (int i = 1; i < n; ++i) { 648 for (int i = 1; i < n; ++i) {
649 649
650 float val = 0.0, nval = 0.0; 650 double val = 0.0, nval = 0.0;
651 651
652 switch (m_scale) { 652 switch (m_scale) {
653 653
654 case LinearScale: 654 case LinearScale:
655 val = (i * gain) / n; 655 val = (i * gain) / n;
708 708
709 for (int x = x0; x <= x1; ++x) { 709 for (int x = x0; x <= x1; ++x) {
710 710
711 range = RangeSummarisableTimeValueModel::Range(); 711 range = RangeSummarisableTimeValueModel::Range();
712 712
713 int f0, f1; 713 sv_frame_t f0, f1;
714 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue; 714 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) continue;
715 f1 = f1 - 1; 715 f1 = f1 - 1;
716 716
717 if (f0 < frame0) { 717 if (f0 < frame0) {
718 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl; 718 cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl;
719 continue; 719 continue;
720 } 720 }
721 721
722 int i0 = (f0 - frame0) / modelZoomLevel; 722 sv_frame_t i0 = (f0 - frame0) / modelZoomLevel;
723 int i1 = (f1 - frame0) / modelZoomLevel; 723 sv_frame_t i1 = (f1 - frame0) / modelZoomLevel;
724 724
725 #ifdef DEBUG_WAVEFORM_PAINT 725 #ifdef DEBUG_WAVEFORM_PAINT
726 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl; 726 cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
727 #endif 727 #endif
728 728
782 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4; 782 if (m_greyscale && (m_scale == LinearScale)) greyLevels = 4;
783 783
784 switch (m_scale) { 784 switch (m_scale) {
785 785
786 case LinearScale: 786 case LinearScale:
787 rangeBottom = int( m * greyLevels * range.min() * gain); 787 rangeBottom = int(double(m * greyLevels) * range.min() * gain);
788 rangeTop = int( m * greyLevels * range.max() * gain); 788 rangeTop = int(double(m * greyLevels) * range.max() * gain);
789 meanBottom = int(-m * range.absmean() * gain); 789 meanBottom = int(double(-m) * range.absmean() * gain);
790 meanTop = int( m * range.absmean() * gain); 790 meanTop = int(double(m) * range.absmean() * gain);
791 break; 791 break;
792 792
793 case dBScale: 793 case dBScale:
794 if (!mergingChannels) { 794 if (!mergingChannels) {
795 int db0 = dBscale(range.min() * gain, m); 795 int db0 = dBscale(range.min() * gain, m);
961 961
962 int zoomLevel = v->getZoomLevel(); 962 int zoomLevel = v->getZoomLevel();
963 963
964 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel); 964 int modelZoomLevel = m_model->getSummaryBlockSize(zoomLevel);
965 965
966 int f0, f1; 966 sv_frame_t f0, f1;
967 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) return ""; 967 if (!getSourceFramesForX(v, x, modelZoomLevel, f0, f1)) return "";
968 968
969 QString text; 969 QString text;
970 970
971 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate()); 971 RealTime rt0 = RealTime::frame2RealTime(f0, m_model->getSampleRate());
1003 else if (ch == 1) label = tr("Right:"); 1003 else if (ch == 1) label = tr("Right:");
1004 else label = tr("Channel %1").arg(ch + 1); 1004 else label = tr("Channel %1").arg(ch + 1);
1005 } 1005 }
1006 1006
1007 bool singleValue = false; 1007 bool singleValue = false;
1008 float min, max; 1008 double min, max;
1009 1009
1010 if (fabs(range.min()) < 0.01) { 1010 if (fabs(range.min()) < 0.01) {
1011 min = range.min(); 1011 min = range.min();
1012 max = range.max(); 1012 max = range.max();
1013 singleValue = (min == max); 1013 singleValue = (min == max);
1014 } else { 1014 } else {
1015 int imin = lrint(range.min() * 10000); 1015 int imin = int(lrint(range.min() * 10000));
1016 int imax = lrint(range.max() * 10000); 1016 int imax = int(lrint(range.max() * 10000));
1017 singleValue = (imin == imax); 1017 singleValue = (imin == imax);
1018 min = float(imin)/10000; 1018 min = double(imin)/10000;
1019 max = float(imax)/10000; 1019 max = double(imax)/10000;
1020 } 1020 }
1021 1021
1022 int db = int(AudioLevel::multiplier_to_dB(std::max(fabsf(range.min()), 1022 int db = int(AudioLevel::multiplier_to_dB(std::max(fabsf(range.min()),
1023 fabsf(range.max()))) 1023 fabsf(range.max())))
1024 * 100); 1024 * 100);
1025 1025
1026 if (!singleValue) { 1026 if (!singleValue) {
1027 text += tr("\n%1\t%2 - %3 (%4 dB peak)") 1027 text += tr("\n%1\t%2 - %3 (%4 dB peak)")
1028 .arg(label).arg(min).arg(max).arg(float(db)/100); 1028 .arg(label).arg(min).arg(max).arg(double(db)/100);
1029 } else { 1029 } else {
1030 text += tr("\n%1\t%2 (%3 dB peak)") 1030 text += tr("\n%1\t%2 (%3 dB peak)")
1031 .arg(label).arg(min).arg(float(db)/100); 1031 .arg(label).arg(min).arg(double(db)/100);
1032 } 1032 }
1033 } 1033 }
1034 1034
1035 return text; 1035 return text;
1036 } 1036 }
1037 1037
1038 int 1038 int
1039 WaveformLayer::getYForValue(const View *v, float value, int channel) const 1039 WaveformLayer::getYForValue(const View *v, double value, int channel) const
1040 { 1040 {
1041 int channels = 0, minChannel = 0, maxChannel = 0; 1041 int channels = 0, minChannel = 0, maxChannel = 0;
1042 bool mergingChannels = false, mixingChannels = false; 1042 bool mergingChannels = false, mixingChannels = false;
1043 1043
1044 channels = getChannelArrangement(minChannel, maxChannel, 1044 channels = getChannelArrangement(minChannel, maxChannel,
1076 // cerr << "mergingChannels= " << mergingChannels << ", channel = " << channel << ", value = " << value << ", vy = " << vy << endl; 1076 // cerr << "mergingChannels= " << mergingChannels << ", channel = " << channel << ", value = " << value << ", vy = " << vy << endl;
1077 1077
1078 return my - vy; 1078 return my - vy;
1079 } 1079 }
1080 1080
1081 float 1081 double
1082 WaveformLayer::getValueForY(const View *v, int y, int &channel) const 1082 WaveformLayer::getValueForY(const View *v, int y, int &channel) const
1083 { 1083 {
1084 int channels = 0, minChannel = 0, maxChannel = 0; 1084 int channels = 0, minChannel = 0, maxChannel = 0;
1085 bool mergingChannels = false, mixingChannels = false; 1085 bool mergingChannels = false, mixingChannels = false;
1086 1086
1100 channel = (y * channels) / h + minChannel; 1100 channel = (y * channels) / h + minChannel;
1101 1101
1102 int my = m + (((channel - minChannel) * h) / channels); 1102 int my = m + (((channel - minChannel) * h) / channels);
1103 1103
1104 int vy = my - y; 1104 int vy = my - y;
1105 float value = 0; 1105 double value = 0;
1106 float thresh = -50.f; 1106 double thresh = -50.f;
1107 1107
1108 switch (m_scale) { 1108 switch (m_scale) {
1109 1109
1110 case LinearScale: 1110 case LinearScale:
1111 value = float(vy) / m; 1111 value = double(vy) / m;
1112 break; 1112 break;
1113 1113
1114 case MeterScale: 1114 case MeterScale:
1115 value = AudioLevel::preview_to_multiplier(vy, m); 1115 value = AudioLevel::preview_to_multiplier(vy, m);
1116 break; 1116 break;
1117 1117
1118 case dBScale: 1118 case dBScale:
1119 value = (-thresh * float(vy)) / m + thresh; 1119 value = (-thresh * double(vy)) / m + thresh;
1120 value = AudioLevel::dB_to_multiplier(value); 1120 value = AudioLevel::dB_to_multiplier(value);
1121 break; 1121 break;
1122 } 1122 }
1123 1123
1124 return value / m_gain; 1124 return value / m_gain;
1125 } 1125 }
1126 1126
1127 bool 1127 bool
1128 WaveformLayer::getYScaleValue(const View *v, int y, 1128 WaveformLayer::getYScaleValue(const View *v, int y,
1129 float &value, QString &unit) const 1129 double &value, QString &unit) const
1130 { 1130 {
1131 int channel; 1131 int channel;
1132 1132
1133 value = getValueForY(v, y, channel); 1133 value = getValueForY(v, y, channel);
1134 1134
1135 if (m_scale == dBScale || m_scale == MeterScale) { 1135 if (m_scale == dBScale || m_scale == MeterScale) {
1136 1136
1137 float thresh = -50.f; 1137 double thresh = -50.f;
1138 1138
1139 if (value > 0.f) { 1139 if (value > 0.0) {
1140 value = 10.f * log10f(value); 1140 value = 10.0 * log10(value);
1141 if (value < thresh) value = thresh; 1141 if (value < thresh) value = thresh;
1142 } else value = thresh; 1142 } else value = thresh;
1143 1143
1144 unit = "dBV"; 1144 unit = "dBV";
1145 1145
1150 return true; 1150 return true;
1151 } 1151 }
1152 1152
1153 bool 1153 bool
1154 WaveformLayer::getYScaleDifference(const View *v, int y0, int y1, 1154 WaveformLayer::getYScaleDifference(const View *v, int y0, int y1,
1155 float &diff, QString &unit) const 1155 double &diff, QString &unit) const
1156 { 1156 {
1157 int c0, c1; 1157 int c0, c1;
1158 float v0 = getValueForY(v, y0, c0); 1158 double v0 = getValueForY(v, y0, c0);
1159 float v1 = getValueForY(v, y1, c1); 1159 double v1 = getValueForY(v, y1, c1);
1160 1160
1161 if (c0 != c1) { 1161 if (c0 != c1) {
1162 // different channels, not comparable 1162 // different channels, not comparable
1163 diff = 0.f; 1163 diff = 0.0;
1164 unit = ""; 1164 unit = "";
1165 return false; 1165 return false;
1166 } 1166 }
1167 1167
1168 if (m_scale == dBScale || m_scale == MeterScale) { 1168 if (m_scale == dBScale || m_scale == MeterScale) {
1169 1169
1170 float thresh = -50.f; 1170 double thresh = -50.0;
1171 1171
1172 if (v1 == v0) diff = thresh; 1172 if (v1 == v0) diff = thresh;
1173 else { 1173 else {
1174 if (v1 > v0) diff = v0 / v1; 1174 if (v1 > v0) diff = v0 / v1;
1175 else diff = v1 / v0; 1175 else diff = v1 / v0;
1176 1176
1177 diff = 10.f * log10f(diff); 1177 diff = 10.0 * log10(diff);
1178 if (diff < thresh) diff = thresh; 1178 if (diff < thresh) diff = thresh;
1179 } 1179 }
1180 1180
1181 unit = "dBV"; 1181 unit = "dBV";
1182 1182
1183 } else { 1183 } else {
1184 diff = fabsf(v1 - v0); 1184 diff = fabs(v1 - v0);
1185 unit = "V"; 1185 unit = "V";
1186 } 1186 }
1187 1187
1188 return true; 1188 return true;
1189 } 1189 }
1215 1215
1216 int h = rect.height(), w = rect.width(); 1216 int h = rect.height(), w = rect.width();
1217 int textHeight = paint.fontMetrics().height(); 1217 int textHeight = paint.fontMetrics().height();
1218 int toff = -textHeight/2 + paint.fontMetrics().ascent() + 1; 1218 int toff = -textHeight/2 + paint.fontMetrics().ascent() + 1;
1219 1219
1220 float gain = m_gain; 1220 double gain = m_gain;
1221 1221
1222 for (int ch = minChannel; ch <= maxChannel; ++ch) { 1222 for (int ch = minChannel; ch <= maxChannel; ++ch) {
1223 1223
1224 int lastLabelledY = -1; 1224 int lastLabelledY = -1;
1225 1225
1227 1227
1228 int n = 10; 1228 int n = 10;
1229 1229
1230 for (int i = 0; i <= n; ++i) { 1230 for (int i = 0; i <= n; ++i) {
1231 1231
1232 float val = 0.0, nval = 0.0; 1232 double val = 0.0, nval = 0.0;
1233 QString text = ""; 1233 QString text = "";
1234 1234
1235 switch (m_scale) { 1235 switch (m_scale) {
1236 1236
1237 case LinearScale: 1237 case LinearScale:
1238 val = (i * gain) / n; 1238 val = (i * gain) / n;
1239 text = QString("%1").arg(float(i) / n); 1239 text = QString("%1").arg(double(i) / n);
1240 if (i == 0) text = "0.0"; 1240 if (i == 0) text = "0.0";
1241 else { 1241 else {
1242 nval = -val; 1242 nval = -val;
1243 if (i == n) text = "1.0"; 1243 if (i == n) text = "1.0";
1244 } 1244 }
1400 } 1400 }
1401 1401
1402 int 1402 int
1403 WaveformLayer::getCurrentVerticalZoomStep() const 1403 WaveformLayer::getCurrentVerticalZoomStep() const
1404 { 1404 {
1405 int val = lrint(log10(m_gain) * 20.0) + 50; 1405 int val = int(lrint(log10(m_gain) * 20.0) + 50);
1406 if (val < 0) val = 0; 1406 if (val < 0) val = 0;
1407 if (val > 100) val = 100; 1407 if (val > 100) val = 100;
1408 return val; 1408 return val;
1409 } 1409 }
1410 1410
1411 void 1411 void
1412 WaveformLayer::setVerticalZoomStep(int step) 1412 WaveformLayer::setVerticalZoomStep(int step)
1413 { 1413 {
1414 setGain(pow(10, float(step - 50) / 20.0)); 1414 setGain(powf(10, float(step - 50) / 20.f));
1415 } 1415 }
1416 1416