comparison layer/SpectrogramLayer.cpp @ 1104:46cc4644206d spectrogram-minor-refactor

Convert ColumnNormalization to an enum class, and separate out normalize-visible
author Chris Cannam
date Thu, 14 Jul 2016 16:12:05 +0100
parents d84a0033b305
children ea5ae9dd10ba
comparison
equal deleted inserted replaced
1103:d84a0033b305 1104:46cc4644206d
74 m_initialMaxFrequency(8000), 74 m_initialMaxFrequency(8000),
75 m_colourScale(ColourScale::LogColourScale), 75 m_colourScale(ColourScale::LogColourScale),
76 m_colourMap(0), 76 m_colourMap(0),
77 m_binScale(BinScale::Linear), 77 m_binScale(BinScale::Linear),
78 m_binDisplay(BinDisplay::AllBins), 78 m_binDisplay(BinDisplay::AllBins),
79 m_normalization(ColumnOp::NoNormalization), 79 m_normalization(ColumnNormalization::None),
80 m_normalizeVisibleArea(false),
80 m_lastEmittedZoomStep(-1), 81 m_lastEmittedZoomStep(-1),
81 m_synchronous(false), 82 m_synchronous(false),
82 m_haveDetailedScale(false), 83 m_haveDetailedScale(false),
83 m_exiting(false), 84 m_exiting(false),
84 m_fftModel(0), 85 m_fftModel(0),
110 setMaxFrequency(2000); 111 setMaxFrequency(2000);
111 setMinFrequency(40); 112 setMinFrequency(40);
112 setBinScale(BinScale::Log); 113 setBinScale(BinScale::Log);
113 setColourScale(ColourScale::LinearColourScale); 114 setColourScale(ColourScale::LinearColourScale);
114 setBinDisplay(BinDisplay::PeakFrequencies); 115 setBinDisplay(BinDisplay::PeakFrequencies);
115 setNormalization(ColumnOp::NormalizeColumns); 116 setNormalization(ColumnNormalization::Max1);
116 colourConfigName = "spectrogram-melodic-colour"; 117 colourConfigName = "spectrogram-melodic-colour";
117 colourConfigDefault = int(ColourMapper::Sunset); 118 colourConfigDefault = int(ColourMapper::Sunset);
118 } 119 }
119 120
120 QSettings settings; 121 QSettings settings;
132 133
133 SpectrogramLayer::~SpectrogramLayer() 134 SpectrogramLayer::~SpectrogramLayer()
134 { 135 {
135 invalidateImageCaches(); 136 invalidateImageCaches();
136 invalidateFFTModel(); 137 invalidateFFTModel();
138 }
139
140 ColourScale::Scale
141 SpectrogramLayer::convertToColourScale(int value)
142 {
143 switch (value) {
144 case 0: return ColourScale::LinearColourScale;
145 case 1: return ColourScale::MeterColourScale;
146 case 2: return ColourScale::LogColourScale; //!!! db^2
147 case 3: return ColourScale::LogColourScale;
148 case 4: return ColourScale::PhaseColourScale;
149 default: return ColourScale::LinearColourScale;
150 }
151 }
152
153 int
154 SpectrogramLayer::convertFromColourScale(ColourScale::Scale scale)
155 {
156 switch (scale) {
157 case ColourScale::LinearColourScale: return 0;
158 case ColourScale::MeterColourScale: return 1;
159 case ColourScale::LogColourScale: return 3; //!!! + db^2
160 case ColourScale::PhaseColourScale: return 4;
161
162 case ColourScale::PlusMinusOneScale:
163 case ColourScale::AbsoluteScale:
164 default: return 0;
165 }
166 }
167
168 std::pair<ColumnNormalization, bool>
169 SpectrogramLayer::convertToColumnNorm(int value)
170 {
171 switch (value) {
172 default:
173 case 0: return { ColumnNormalization::None, false };
174 case 1: return { ColumnNormalization::Max1, false };
175 case 2: return { ColumnNormalization::None, true }; // visible area
176 case 3: return { ColumnNormalization::Hybrid, false };
177 }
178 }
179
180 int
181 SpectrogramLayer::convertFromColumnNorm(ColumnNormalization norm, bool visible)
182 {
183 if (visible) return 2;
184 switch (norm) {
185 case ColumnNormalization::None: return 0;
186 case ColumnNormalization::Max1: return 1;
187 case ColumnNormalization::Hybrid: return 3;
188
189 case ColumnNormalization::Sum1:
190 default: return 0;
191 }
137 } 192 }
138 193
139 void 194 void
140 SpectrogramLayer::setModel(const DenseTimeValueModel *model) 195 SpectrogramLayer::setModel(const DenseTimeValueModel *model)
141 { 196 {
275 // linear, meter, db^2, db, phase 330 // linear, meter, db^2, db, phase
276 *min = 0; 331 *min = 0;
277 *max = 4; 332 *max = 4;
278 *deflt = 2; 333 *deflt = 2;
279 334
280 val = (int)m_colourScale; 335 val = convertFromColourScale(m_colourScale);
281 336
282 } else if (name == "Colour") { 337 } else if (name == "Colour") {
283 338
284 *min = 0; 339 *min = 0;
285 *max = ColourMapper::getColourMapCount() - 1; 340 *max = ColourMapper::getColourMapCount() - 1;
359 414
360 } else if (name == "Normalization") { 415 } else if (name == "Normalization") {
361 416
362 *min = 0; 417 *min = 0;
363 *max = 3; 418 *max = 3;
364 *deflt = int(ColumnOp::NoNormalization); 419 *deflt = 0;
365 val = (int)m_normalization; 420
421 val = convertFromColumnNorm(m_normalization, m_normalizeVisibleArea);
366 422
367 } else { 423 } else {
368 val = Layer::getPropertyRangeAndValue(name, min, max, deflt); 424 val = Layer::getPropertyRangeAndValue(name, min, max, deflt);
369 } 425 }
370 426
556 case 0: setBinDisplay(BinDisplay::AllBins); break; 612 case 0: setBinDisplay(BinDisplay::AllBins); break;
557 case 1: setBinDisplay(BinDisplay::PeakBins); break; 613 case 1: setBinDisplay(BinDisplay::PeakBins); break;
558 case 2: setBinDisplay(BinDisplay::PeakFrequencies); break; 614 case 2: setBinDisplay(BinDisplay::PeakFrequencies); break;
559 } 615 }
560 } else if (name == "Normalization") { 616 } else if (name == "Normalization") {
561 switch (value) { 617 auto n = convertToColumnNorm(value);
562 default: 618 setNormalization(n.first);
563 case 0: setNormalization(ColumnOp::NoNormalization); break; 619 setNormalizeVisibleArea(n.second);
564 case 1: setNormalization(ColumnOp::NormalizeColumns); break;
565 case 2: setNormalization(ColumnOp::NormalizeVisibleArea); break;
566 case 3: setNormalization(ColumnOp::NormalizeHybrid); break;
567 }
568 } 620 }
569 } 621 }
570 622
571 void 623 void
572 SpectrogramLayer::invalidateImageCaches() 624 SpectrogramLayer::invalidateImageCaches()
884 { 936 {
885 return m_binDisplay; 937 return m_binDisplay;
886 } 938 }
887 939
888 void 940 void
889 SpectrogramLayer::setNormalization(ColumnOp::Normalization n) 941 SpectrogramLayer::setNormalization(ColumnNormalization n)
890 { 942 {
891 if (m_normalization == n) return; 943 if (m_normalization == n) return;
892 944
893 invalidateImageCaches(); 945 invalidateImageCaches();
894 invalidateMagnitudes(); 946 invalidateMagnitudes();
895 m_normalization = n; 947 m_normalization = n;
896 948
897 emit layerParametersChanged(); 949 emit layerParametersChanged();
898 } 950 }
899 951
900 ColumnOp::Normalization 952 ColumnNormalization
901 SpectrogramLayer::getNormalization() const 953 SpectrogramLayer::getNormalization() const
902 { 954 {
903 return m_normalization; 955 return m_normalization;
956 }
957
958 void
959 SpectrogramLayer::setNormalizeVisibleArea(bool n)
960 {
961 if (m_normalizeVisibleArea == n) return;
962
963 invalidateImageCaches();
964 invalidateMagnitudes();
965 m_normalizeVisibleArea = n;
966
967 emit layerParametersChanged();
968 }
969
970 bool
971 SpectrogramLayer::getNormalizeVisibleArea() const
972 {
973 return m_normalizeVisibleArea;
904 } 974 }
905 975
906 void 976 void
907 SpectrogramLayer::setLayerDormant(const LayerGeometryProvider *v, bool dormant) 977 SpectrogramLayer::setLayerDormant(const LayerGeometryProvider *v, bool dormant)
908 { 978 {
1028 int value = 0; 1098 int value = 0;
1029 1099
1030 double min = 0.0; 1100 double min = 0.0;
1031 double max = 1.0; 1101 double max = 1.0;
1032 1102
1033 if (m_normalization == ColumnOp::NormalizeVisibleArea) { 1103 if (m_normalizeVisibleArea) {
1034 min = m_viewMags[v->getId()].getMin(); 1104 min = m_viewMags[v->getId()].getMin();
1035 max = m_viewMags[v->getId()].getMax(); 1105 max = m_viewMags[v->getId()].getMax();
1036 } else if (m_normalization != ColumnOp::NormalizeColumns) { 1106 } else if (m_normalization != ColumnNormalization::Max1) {
1037 if (m_colourScale == ColourScale::LinearColourScale //|| 1107 if (m_colourScale == ColourScale::LinearColourScale //||
1038 // m_colourScale == MeterColourScale) { 1108 // m_colourScale == MeterColourScale) {
1039 ) { 1109 ) {
1040 max = 0.1; 1110 max = 0.1;
1041 } 1111 }
1585 cparams.scale = m_colourScale; 1655 cparams.scale = m_colourScale;
1586 cparams.threshold = m_threshold; 1656 cparams.threshold = m_threshold;
1587 cparams.gain = m_gain; 1657 cparams.gain = m_gain;
1588 1658
1589 if (m_colourScale != ColourScale::PhaseColourScale && 1659 if (m_colourScale != ColourScale::PhaseColourScale &&
1590 m_normalization == ColumnOp::NoNormalization) { 1660 m_normalization == ColumnNormalization::None) {
1591 cparams.gain *= 2.f / float(getFFTSize()); 1661 cparams.gain *= 2.f / float(getFFTSize());
1592 } 1662 }
1593 1663
1594 Colour3DPlotRenderer::Parameters params; 1664 Colour3DPlotRenderer::Parameters params;
1595 params.colourScale = ColourScale(cparams); 1665 params.colourScale = ColourScale(cparams);
1666 1736
1667 if (updateViewMagnitudes(v)) { 1737 if (updateViewMagnitudes(v)) {
1668 #ifdef DEBUG_SPECTROGRAM_REPAINT 1738 #ifdef DEBUG_SPECTROGRAM_REPAINT
1669 cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v->getId()].getMin() << "->" << m_viewMags[v->getId()].getMax() << "]" << endl; 1739 cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v->getId()].getMin() << "->" << m_viewMags[v->getId()].getMax() << "]" << endl;
1670 #endif 1740 #endif
1671 if (m_normalization == ColumnOp::NormalizeVisibleArea) { 1741 if (m_normalizeVisibleArea) {
1672 cache.invalidate(); 1742 cache.invalidate();
1673 } 1743 }
1674 } 1744 }
1675 1745
1676 if (cache.getZoomLevel() != zoomLevel || 1746 if (cache.getZoomLevel() != zoomLevel ||
2107 paint.drawImage(pr.x(), pr.y(), cache.getImage(), 2177 paint.drawImage(pr.x(), pr.y(), cache.getImage(),
2108 pr.x(), pr.y(), pr.width(), pr.height()); 2178 pr.x(), pr.y(), pr.width(), pr.height());
2109 2179
2110 if (!m_synchronous) { 2180 if (!m_synchronous) {
2111 2181
2112 if ((m_normalization != ColumnOp::NormalizeVisibleArea) || !overallMagChanged) { 2182 if (!m_normalizeVisibleArea || !overallMagChanged) {
2113 2183
2114 QRect areaLeft(0, 0, cache.getValidLeft(), h); 2184 QRect areaLeft(0, 0, cache.getValidLeft(), h);
2115 QRect areaRight(cache.getValidRight(), 0, 2185 QRect areaRight(cache.getValidRight(), 0,
2116 cache.getSize().width() - cache.getValidRight(), h); 2186 cache.getSize().width() - cache.getValidRight(), h);
2117 2187
3388 } 3458 }
3389 // SVDEBUG << "SpectrogramLayer::setMeasureRectYCoord: start " << r.startY << " <- " << y << ", end " << r.endY << " <- " << y << endl; 3459 // SVDEBUG << "SpectrogramLayer::setMeasureRectYCoord: start " << r.startY << " <- " << y << ", end " << r.endY << " <- " << y << endl;
3390 3460
3391 } 3461 }
3392 3462
3393 static ColourScale::Scale
3394 convertInColourScale(int fileScale)
3395 {
3396 switch (fileScale) {
3397 case 0: return ColourScale::LinearColourScale;
3398 case 1: return ColourScale::MeterColourScale;
3399 case 2: return ColourScale::LogColourScale; //!!!
3400 case 3: return ColourScale::LogColourScale;
3401 case 4: return ColourScale::PhaseColourScale;
3402 default: return ColourScale::LinearColourScale;
3403 }
3404 }
3405
3406 static int
3407 convertOutColourScale(ColourScale::Scale scale)
3408 {
3409 switch (scale) {
3410 case ColourScale::LinearColourScale: return 0;
3411 case ColourScale::MeterColourScale: return 1;
3412 case ColourScale::LogColourScale: return 3; //!!!
3413 case ColourScale::PhaseColourScale: return 4;
3414 case ColourScale::PlusMinusOneScale:
3415 case ColourScale::AbsoluteScale:
3416 default: return 0;
3417 }
3418 }
3419
3420 void 3463 void
3421 SpectrogramLayer::toXml(QTextStream &stream, 3464 SpectrogramLayer::toXml(QTextStream &stream,
3422 QString indent, QString extraAttributes) const 3465 QString indent, QString extraAttributes) const
3423 { 3466 {
3424 QString s; 3467 QString s;
3441 "colourRotation=\"%5\" " 3484 "colourRotation=\"%5\" "
3442 "frequencyScale=\"%6\" " 3485 "frequencyScale=\"%6\" "
3443 "binDisplay=\"%7\" ") 3486 "binDisplay=\"%7\" ")
3444 .arg(m_minFrequency) 3487 .arg(m_minFrequency)
3445 .arg(m_maxFrequency) 3488 .arg(m_maxFrequency)
3446 .arg(convertOutColourScale(m_colourScale)) 3489 .arg(convertFromColourScale(m_colourScale))
3447 .arg(m_colourMap) 3490 .arg(m_colourMap)
3448 .arg(m_colourRotation) 3491 .arg(m_colourRotation)
3449 .arg(int(m_binScale)) 3492 .arg(int(m_binScale))
3450 .arg(int(m_binDisplay)); 3493 .arg(int(m_binDisplay));
3451 3494
3453 // normalization in future: write out the column normalization 3496 // normalization in future: write out the column normalization
3454 // type separately, and then whether we are normalizing visible 3497 // type separately, and then whether we are normalizing visible
3455 // area as well afterwards 3498 // area as well afterwards
3456 3499
3457 s += QString("columnNormalization=\"%1\" ") 3500 s += QString("columnNormalization=\"%1\" ")
3458 .arg(m_normalization == ColumnOp::NormalizeColumns ? "peak" : 3501 .arg(m_normalization == ColumnNormalization::Max1 ? "peak" :
3459 m_normalization == ColumnOp::NormalizeHybrid ? "hybrid" : "none"); 3502 m_normalization == ColumnNormalization::Hybrid ? "hybrid" : "none");
3460 3503
3461 // Old-style normalization attribute. We *don't* write out 3504 // Old-style normalization attribute. We *don't* write out
3462 // normalizeHybrid here because the only release that would accept 3505 // normalizeHybrid here because the only release that would accept
3463 // it (Tony v1.0) has a totally different scale factor for 3506 // it (Tony v1.0) has a totally different scale factor for
3464 // it. We'll just have to accept that session files from Tony 3507 // it. We'll just have to accept that session files from Tony
3465 // v2.0+ will look odd in Tony v1.0 3508 // v2.0+ will look odd in Tony v1.0
3466 3509
3467 s += QString("normalizeColumns=\"%1\" ") 3510 s += QString("normalizeColumns=\"%1\" ")
3468 .arg(m_normalization == ColumnOp::NormalizeColumns ? "true" : "false"); 3511 .arg(m_normalization == ColumnNormalization::Max1 ? "true" : "false");
3469 3512
3470 // And this applies to both old- and new-style attributes 3513 // And this applies to both old- and new-style attributes
3471 3514
3472 s += QString("normalizeVisibleArea=\"%1\" ") 3515 s += QString("normalizeVisibleArea=\"%1\" ")
3473 .arg(m_normalization == ColumnOp::NormalizeVisibleArea ? "true" : "false"); 3516 .arg(m_normalizeVisibleArea ? "true" : "false");
3474 3517
3475 Layer::toXml(stream, indent, extraAttributes + " " + s); 3518 Layer::toXml(stream, indent, extraAttributes + " " + s);
3476 } 3519 }
3477 3520
3478 void 3521 void
3516 if (ok) { 3559 if (ok) {
3517 SVDEBUG << "SpectrogramLayer::setProperties: setting max freq to " << maxFrequency << endl; 3560 SVDEBUG << "SpectrogramLayer::setProperties: setting max freq to " << maxFrequency << endl;
3518 setMaxFrequency(maxFrequency); 3561 setMaxFrequency(maxFrequency);
3519 } 3562 }
3520 3563
3521 ColourScale::Scale colourScale = convertInColourScale 3564 ColourScale::Scale colourScale = convertToColourScale
3522 (attributes.value("colourScale").toInt(&ok)); 3565 (attributes.value("colourScale").toInt(&ok));
3523 if (ok) setColourScale(colourScale); 3566 if (ok) setColourScale(colourScale);
3524 3567
3525 int colourMap = attributes.value("colourScheme").toInt(&ok); 3568 int colourMap = attributes.value("colourScheme").toInt(&ok);
3526 if (ok) setColourMap(colourMap); 3569 if (ok) setColourMap(colourMap);
3543 if (columnNormalization != "") { 3586 if (columnNormalization != "") {
3544 3587
3545 haveNewStyleNormalization = true; 3588 haveNewStyleNormalization = true;
3546 3589
3547 if (columnNormalization == "peak") { 3590 if (columnNormalization == "peak") {
3548 setNormalization(ColumnOp::NormalizeColumns); 3591 setNormalization(ColumnNormalization::Max1);
3549 } else if (columnNormalization == "hybrid") { 3592 } else if (columnNormalization == "hybrid") {
3550 setNormalization(ColumnOp::NormalizeHybrid); 3593 setNormalization(ColumnNormalization::Hybrid);
3551 } else if (columnNormalization == "none") { 3594 } else if (columnNormalization == "none") {
3552 // do nothing 3595 setNormalization(ColumnNormalization::None);
3553 } else { 3596 } else {
3554 cerr << "NOTE: Unknown or unsupported columnNormalization attribute \"" 3597 cerr << "NOTE: Unknown or unsupported columnNormalization attribute \""
3555 << columnNormalization << "\"" << endl; 3598 << columnNormalization << "\"" << endl;
3556 } 3599 }
3557 } 3600 }
3559 if (!haveNewStyleNormalization) { 3602 if (!haveNewStyleNormalization) {
3560 3603
3561 bool normalizeColumns = 3604 bool normalizeColumns =
3562 (attributes.value("normalizeColumns").trimmed() == "true"); 3605 (attributes.value("normalizeColumns").trimmed() == "true");
3563 if (normalizeColumns) { 3606 if (normalizeColumns) {
3564 setNormalization(ColumnOp::NormalizeColumns); 3607 setNormalization(ColumnNormalization::Max1);
3565 } 3608 }
3566 3609
3567 bool normalizeHybrid = 3610 bool normalizeHybrid =
3568 (attributes.value("normalizeHybrid").trimmed() == "true"); 3611 (attributes.value("normalizeHybrid").trimmed() == "true");
3569 if (normalizeHybrid) { 3612 if (normalizeHybrid) {
3570 setNormalization(ColumnOp::NormalizeHybrid); 3613 setNormalization(ColumnNormalization::Hybrid);
3571 } 3614 }
3572 } 3615 }
3573 3616
3574 bool normalizeVisibleArea = 3617 bool normalizeVisibleArea =
3575 (attributes.value("normalizeVisibleArea").trimmed() == "true"); 3618 (attributes.value("normalizeVisibleArea").trimmed() == "true");
3576 if (normalizeVisibleArea) { 3619 setNormalizeVisibleArea(normalizeVisibleArea);
3577 setNormalization(ColumnOp::NormalizeVisibleArea); 3620
3578 } 3621 if (!haveNewStyleNormalization && m_normalization == ColumnNormalization::Hybrid) {
3579
3580 if (!haveNewStyleNormalization && m_normalization == ColumnOp::NormalizeHybrid) {
3581 // Tony v1.0 is (and hopefully will remain!) the only released 3622 // Tony v1.0 is (and hopefully will remain!) the only released
3582 // SV-a-like to use old-style attributes when saving sessions 3623 // SV-a-like to use old-style attributes when saving sessions
3583 // that ask for hybrid normalization. It saves them with the 3624 // that ask for hybrid normalization. It saves them with the
3584 // wrong gain factor, so hack in a fix for that here -- this 3625 // wrong gain factor, so hack in a fix for that here -- this
3585 // gives us backward but not forward compatibility. 3626 // gives us backward but not forward compatibility.