Mercurial > hg > svgui
comparison layer/WaveformLayer.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
| author | Chris Cannam |
|---|---|
| date | Fri, 13 Jan 2017 10:29:50 +0000 |
| parents | 1badacff7ab2 |
| children | a34a2a25907c |
comparison
equal
deleted
inserted
replaced
| 1048:e8102ff5573b | 1216:dc2af6616c83 |
|---|---|
| 17 | 17 |
| 18 #include "base/AudioLevel.h" | 18 #include "base/AudioLevel.h" |
| 19 #include "view/View.h" | 19 #include "view/View.h" |
| 20 #include "base/Profiler.h" | 20 #include "base/Profiler.h" |
| 21 #include "base/RangeMapper.h" | 21 #include "base/RangeMapper.h" |
| 22 #include "base/Strings.h" | |
| 23 | |
| 22 #include "ColourDatabase.h" | 24 #include "ColourDatabase.h" |
| 25 #include "PaintAssistant.h" | |
| 23 | 26 |
| 24 #include <QPainter> | 27 #include <QPainter> |
| 25 #include <QPixmap> | 28 #include <QPixmap> |
| 26 #include <QTextStream> | 29 #include <QTextStream> |
| 27 | 30 |
| 324 m_cacheValid = false; | 327 m_cacheValid = false; |
| 325 emit layerParametersChanged(); | 328 emit layerParametersChanged(); |
| 326 } | 329 } |
| 327 | 330 |
| 328 int | 331 int |
| 329 WaveformLayer::getCompletion(View *) const | 332 WaveformLayer::getCompletion(LayerGeometryProvider *) const |
| 330 { | 333 { |
| 331 int completion = 100; | 334 int completion = 100; |
| 332 if (!m_model || !m_model->isOK()) return completion; | 335 if (!m_model || !m_model->isOK()) return completion; |
| 333 if (m_model->isReady(&completion)) return 100; | 336 if (m_model->isReady(&completion)) return 100; |
| 334 return completion; | 337 return completion; |
| 397 | 400 |
| 398 return channels; | 401 return channels; |
| 399 } | 402 } |
| 400 | 403 |
| 401 bool | 404 bool |
| 402 WaveformLayer::isLayerScrollable(const View *) const | 405 WaveformLayer::isLayerScrollable(const LayerGeometryProvider *) const |
| 403 { | 406 { |
| 404 return !m_autoNormalize; | 407 return !m_autoNormalize; |
| 405 } | 408 } |
| 406 | 409 |
| 407 static float meterdbs[] = { -40, -30, -20, -15, -10, | 410 static float meterdbs[] = { -40, -30, -20, -15, -10, |
| 408 -5, -3, -2, -1, -0.5, 0 }; | 411 -5, -3, -2, -1, -0.5, 0 }; |
| 409 | 412 |
| 410 bool | 413 bool |
| 411 WaveformLayer::getSourceFramesForX(View *v, int x, int modelZoomLevel, | 414 WaveformLayer::getSourceFramesForX(LayerGeometryProvider *v, int x, int modelZoomLevel, |
| 412 sv_frame_t &f0, sv_frame_t &f1) const | 415 sv_frame_t &f0, sv_frame_t &f1) const |
| 413 { | 416 { |
| 414 sv_frame_t viewFrame = v->getFrameForX(x); | 417 sv_frame_t viewFrame = v->getFrameForX(x); |
| 415 if (viewFrame < 0) { | 418 if (viewFrame < 0) { |
| 416 f0 = 0; | 419 f0 = 0; |
| 431 | 434 |
| 432 return (f0 < m_model->getEndFrame()); | 435 return (f0 < m_model->getEndFrame()); |
| 433 } | 436 } |
| 434 | 437 |
| 435 float | 438 float |
| 436 WaveformLayer::getNormalizeGain(View *v, int channel) const | 439 WaveformLayer::getNormalizeGain(LayerGeometryProvider *v, int channel) const |
| 437 { | 440 { |
| 438 sv_frame_t startFrame = v->getStartFrame(); | 441 sv_frame_t startFrame = v->getStartFrame(); |
| 439 sv_frame_t endFrame = v->getEndFrame(); | 442 sv_frame_t endFrame = v->getEndFrame(); |
| 440 | 443 |
| 441 sv_frame_t modelStart = m_model->getStartFrame(); | 444 sv_frame_t modelStart = m_model->getStartFrame(); |
| 471 | 474 |
| 472 return float(1.0 / std::max(fabs(range.max()), fabs(range.min()))); | 475 return float(1.0 / std::max(fabs(range.max()), fabs(range.min()))); |
| 473 } | 476 } |
| 474 | 477 |
| 475 void | 478 void |
| 476 WaveformLayer::paint(View *v, QPainter &viewPainter, QRect rect) const | 479 WaveformLayer::paint(LayerGeometryProvider *v, QPainter &viewPainter, QRect rect) const |
| 477 { | 480 { |
| 478 if (!m_model || !m_model->isOK()) { | 481 if (!m_model || !m_model->isOK()) { |
| 479 return; | 482 return; |
| 480 } | 483 } |
| 481 | 484 |
| 492 | 495 |
| 493 channels = getChannelArrangement(minChannel, maxChannel, | 496 channels = getChannelArrangement(minChannel, maxChannel, |
| 494 mergingChannels, mixingChannels); | 497 mergingChannels, mixingChannels); |
| 495 if (channels == 0) return; | 498 if (channels == 0) return; |
| 496 | 499 |
| 497 int w = v->width(); | 500 int w = v->getPaintWidth(); |
| 498 int h = v->height(); | 501 int h = v->getPaintHeight(); |
| 499 | 502 |
| 500 bool ready = m_model->isReady(); | 503 bool ready = m_model->isReady(); |
| 501 QPainter *paint; | 504 QPainter *paint; |
| 502 | 505 |
| 503 if (m_aggressive) { | 506 if (m_aggressive) { |
| 557 x1 = rect.right(); | 560 x1 = rect.right(); |
| 558 y0 = rect.top(); | 561 y0 = rect.top(); |
| 559 y1 = rect.bottom(); | 562 y1 = rect.bottom(); |
| 560 | 563 |
| 561 if (x0 > 0) --x0; | 564 if (x0 > 0) --x0; |
| 562 if (x1 < v->width()) ++x1; | 565 if (x1 < w) ++x1; |
| 563 | 566 |
| 564 // Our zoom level may differ from that at which the underlying | 567 // Our zoom level may differ from that at which the underlying |
| 565 // model has its blocks. | 568 // model has its blocks. |
| 566 | 569 |
| 567 // Each pixel within our visible range must always draw from | 570 // Each pixel within our visible range must always draw from |
| 943 paint->restore(); | 946 paint->restore(); |
| 944 } | 947 } |
| 945 | 948 |
| 946 if (m_aggressive) { | 949 if (m_aggressive) { |
| 947 | 950 |
| 948 if (ready && rect == v->rect()) { | 951 if (ready && rect == v->getPaintRect()) { |
| 949 m_cacheValid = true; | 952 m_cacheValid = true; |
| 950 m_cacheZoomLevel = zoomLevel; | 953 m_cacheZoomLevel = zoomLevel; |
| 951 } | 954 } |
| 952 paint->end(); | 955 paint->end(); |
| 953 delete paint; | 956 delete paint; |
| 957 if (otherChannelRanges != ranges) delete otherChannelRanges; | 960 if (otherChannelRanges != ranges) delete otherChannelRanges; |
| 958 delete ranges; | 961 delete ranges; |
| 959 } | 962 } |
| 960 | 963 |
| 961 QString | 964 QString |
| 962 WaveformLayer::getFeatureDescription(View *v, QPoint &pos) const | 965 WaveformLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
| 963 { | 966 { |
| 964 int x = pos.x(); | 967 int x = pos.x(); |
| 965 | 968 |
| 966 if (!m_model || !m_model->isOK()) return ""; | 969 if (!m_model || !m_model->isOK()) return ""; |
| 967 | 970 |
| 1040 | 1043 |
| 1041 return text; | 1044 return text; |
| 1042 } | 1045 } |
| 1043 | 1046 |
| 1044 int | 1047 int |
| 1045 WaveformLayer::getYForValue(const View *v, double value, int channel) const | 1048 WaveformLayer::getYForValue(const LayerGeometryProvider *v, double value, int channel) const |
| 1046 { | 1049 { |
| 1047 int channels = 0, minChannel = 0, maxChannel = 0; | 1050 int channels = 0, minChannel = 0, maxChannel = 0; |
| 1048 bool mergingChannels = false, mixingChannels = false; | 1051 bool mergingChannels = false, mixingChannels = false; |
| 1049 | 1052 |
| 1050 channels = getChannelArrangement(minChannel, maxChannel, | 1053 channels = getChannelArrangement(minChannel, maxChannel, |
| 1051 mergingChannels, mixingChannels); | 1054 mergingChannels, mixingChannels); |
| 1052 if (channels == 0) return 0; | 1055 if (channels == 0) return 0; |
| 1053 if (maxChannel < minChannel || channel < minChannel) return 0; | 1056 if (maxChannel < minChannel || channel < minChannel) return 0; |
| 1054 | 1057 |
| 1055 int h = v->height(); | 1058 int h = v->getPaintHeight(); |
| 1056 int m = (h / channels) / 2; | 1059 int m = (h / channels) / 2; |
| 1057 | 1060 |
| 1058 if ((m_scale == dBScale || m_scale == MeterScale) && | 1061 if ((m_scale == dBScale || m_scale == MeterScale) && |
| 1059 m_channelMode != MergeChannels) { | 1062 m_channelMode != MergeChannels) { |
| 1060 m = (h / channels); | 1063 m = (h / channels); |
| 1083 | 1086 |
| 1084 return my - vy; | 1087 return my - vy; |
| 1085 } | 1088 } |
| 1086 | 1089 |
| 1087 double | 1090 double |
| 1088 WaveformLayer::getValueForY(const View *v, int y, int &channel) const | 1091 WaveformLayer::getValueForY(const LayerGeometryProvider *v, int y, int &channel) const |
| 1089 { | 1092 { |
| 1090 int channels = 0, minChannel = 0, maxChannel = 0; | 1093 int channels = 0, minChannel = 0, maxChannel = 0; |
| 1091 bool mergingChannels = false, mixingChannels = false; | 1094 bool mergingChannels = false, mixingChannels = false; |
| 1092 | 1095 |
| 1093 channels = getChannelArrangement(minChannel, maxChannel, | 1096 channels = getChannelArrangement(minChannel, maxChannel, |
| 1094 mergingChannels, mixingChannels); | 1097 mergingChannels, mixingChannels); |
| 1095 if (channels == 0) return 0; | 1098 if (channels == 0) return 0; |
| 1096 if (maxChannel < minChannel) return 0; | 1099 if (maxChannel < minChannel) return 0; |
| 1097 | 1100 |
| 1098 int h = v->height(); | 1101 int h = v->getPaintHeight(); |
| 1099 int m = (h / channels) / 2; | 1102 int m = (h / channels) / 2; |
| 1100 | 1103 |
| 1101 if ((m_scale == dBScale || m_scale == MeterScale) && | 1104 if ((m_scale == dBScale || m_scale == MeterScale) && |
| 1102 m_channelMode != MergeChannels) { | 1105 m_channelMode != MergeChannels) { |
| 1103 m = (h / channels); | 1106 m = (h / channels); |
| 1129 | 1132 |
| 1130 return value / m_gain; | 1133 return value / m_gain; |
| 1131 } | 1134 } |
| 1132 | 1135 |
| 1133 bool | 1136 bool |
| 1134 WaveformLayer::getYScaleValue(const View *v, int y, | 1137 WaveformLayer::getYScaleValue(const LayerGeometryProvider *v, int y, |
| 1135 double &value, QString &unit) const | 1138 double &value, QString &unit) const |
| 1136 { | 1139 { |
| 1137 int channel; | 1140 int channel; |
| 1138 | 1141 |
| 1139 value = getValueForY(v, y, channel); | 1142 value = getValueForY(v, y, channel); |
| 1155 | 1158 |
| 1156 return true; | 1159 return true; |
| 1157 } | 1160 } |
| 1158 | 1161 |
| 1159 bool | 1162 bool |
| 1160 WaveformLayer::getYScaleDifference(const View *v, int y0, int y1, | 1163 WaveformLayer::getYScaleDifference(const LayerGeometryProvider *v, int y0, int y1, |
| 1161 double &diff, QString &unit) const | 1164 double &diff, QString &unit) const |
| 1162 { | 1165 { |
| 1163 int c0, c1; | 1166 int c0, c1; |
| 1164 double v0 = getValueForY(v, y0, c0); | 1167 double v0 = getValueForY(v, y0, c0); |
| 1165 double v1 = getValueForY(v, y1, c1); | 1168 double v1 = getValueForY(v, y1, c1); |
| 1193 | 1196 |
| 1194 return true; | 1197 return true; |
| 1195 } | 1198 } |
| 1196 | 1199 |
| 1197 int | 1200 int |
| 1198 WaveformLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const | 1201 WaveformLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const |
| 1199 { | 1202 { |
| 1200 if (m_scale == LinearScale) { | 1203 if (m_scale == LinearScale) { |
| 1201 return paint.fontMetrics().width("0.0") + 13; | 1204 return paint.fontMetrics().width("0.0") + 13; |
| 1202 } else { | 1205 } else { |
| 1203 return std::max(paint.fontMetrics().width(tr("0dB")), | 1206 return std::max(paint.fontMetrics().width(tr("0dB")), |
| 1204 paint.fontMetrics().width(tr("-Inf"))) + 13; | 1207 paint.fontMetrics().width(Strings::minus_infinity)) + 13; |
| 1205 } | 1208 } |
| 1206 } | 1209 } |
| 1207 | 1210 |
| 1208 void | 1211 void |
| 1209 WaveformLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const | 1212 WaveformLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const |
| 1210 { | 1213 { |
| 1211 if (!m_model || !m_model->isOK()) { | 1214 if (!m_model || !m_model->isOK()) { |
| 1212 return; | 1215 return; |
| 1213 } | 1216 } |
| 1214 | 1217 |
| 1253 case MeterScale: | 1256 case MeterScale: |
| 1254 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain; | 1257 val = AudioLevel::dB_to_multiplier(meterdbs[i]) * gain; |
| 1255 text = QString("%1").arg(meterdbs[i]); | 1258 text = QString("%1").arg(meterdbs[i]); |
| 1256 if (i == n) text = tr("0dB"); | 1259 if (i == n) text = tr("0dB"); |
| 1257 if (i == 0) { | 1260 if (i == 0) { |
| 1258 text = tr("-Inf"); | 1261 text = Strings::minus_infinity; |
| 1259 val = 0.0; | 1262 val = 0.0; |
| 1260 } | 1263 } |
| 1261 break; | 1264 break; |
| 1262 | 1265 |
| 1263 case dBScale: | 1266 case dBScale: |
| 1264 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain; | 1267 val = AudioLevel::dB_to_multiplier(-(10*n) + i * 10) * gain; |
| 1265 text = QString("%1").arg(-(10*n) + i * 10); | 1268 text = QString("%1").arg(-(10*n) + i * 10); |
| 1266 if (i == n) text = tr("0dB"); | 1269 if (i == n) text = tr("0dB"); |
| 1267 if (i == 0) { | 1270 if (i == 0) { |
| 1268 text = tr("-Inf"); | 1271 text = Strings::minus_infinity; |
| 1269 val = 0.0; | 1272 val = 0.0; |
| 1270 } | 1273 } |
| 1271 break; | 1274 break; |
| 1272 } | 1275 } |
| 1273 | 1276 |
