Mercurial > hg > svgui
comparison layer/SpectrogramLayer.cpp @ 1105:ea5ae9dd10ba spectrogram-minor-refactor
Convert ColourScaleType into an enum class
author | Chris Cannam |
---|---|
date | Thu, 14 Jul 2016 16:52:16 +0100 |
parents | 46cc4644206d |
children | 8abdefce36a6 |
comparison
equal
deleted
inserted
replaced
1104:46cc4644206d | 1105:ea5ae9dd10ba |
---|---|
70 m_colourRotation(0), | 70 m_colourRotation(0), |
71 m_initialRotation(0), | 71 m_initialRotation(0), |
72 m_minFrequency(10), | 72 m_minFrequency(10), |
73 m_maxFrequency(8000), | 73 m_maxFrequency(8000), |
74 m_initialMaxFrequency(8000), | 74 m_initialMaxFrequency(8000), |
75 m_colourScale(ColourScale::LogColourScale), | 75 m_colourScale(ColourScaleType::Log), |
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(ColumnNormalization::None), | 79 m_normalization(ColumnNormalization::None), |
80 m_normalizeVisibleArea(false), | 80 m_normalizeVisibleArea(false), |
96 setWindowSize(8192); | 96 setWindowSize(8192); |
97 setWindowHopLevel(4); | 97 setWindowHopLevel(4); |
98 m_initialMaxFrequency = 1500; | 98 m_initialMaxFrequency = 1500; |
99 setMaxFrequency(1500); | 99 setMaxFrequency(1500); |
100 setMinFrequency(40); | 100 setMinFrequency(40); |
101 setColourScale(ColourScale::LinearColourScale); | 101 setColourScale(ColourScaleType::Linear); |
102 setColourMap(ColourMapper::Sunset); | 102 setColourMap(ColourMapper::Sunset); |
103 setBinScale(BinScale::Log); | 103 setBinScale(BinScale::Log); |
104 colourConfigName = "spectrogram-melodic-colour"; | 104 colourConfigName = "spectrogram-melodic-colour"; |
105 colourConfigDefault = int(ColourMapper::Sunset); | 105 colourConfigDefault = int(ColourMapper::Sunset); |
106 // setGain(20); | 106 // setGain(20); |
109 setWindowHopLevel(5); | 109 setWindowHopLevel(5); |
110 m_initialMaxFrequency = 2000; | 110 m_initialMaxFrequency = 2000; |
111 setMaxFrequency(2000); | 111 setMaxFrequency(2000); |
112 setMinFrequency(40); | 112 setMinFrequency(40); |
113 setBinScale(BinScale::Log); | 113 setBinScale(BinScale::Log); |
114 setColourScale(ColourScale::LinearColourScale); | 114 setColourScale(ColourScaleType::Linear); |
115 setBinDisplay(BinDisplay::PeakFrequencies); | 115 setBinDisplay(BinDisplay::PeakFrequencies); |
116 setNormalization(ColumnNormalization::Max1); | 116 setNormalization(ColumnNormalization::Max1); |
117 colourConfigName = "spectrogram-melodic-colour"; | 117 colourConfigName = "spectrogram-melodic-colour"; |
118 colourConfigDefault = int(ColourMapper::Sunset); | 118 colourConfigDefault = int(ColourMapper::Sunset); |
119 } | 119 } |
135 { | 135 { |
136 invalidateImageCaches(); | 136 invalidateImageCaches(); |
137 invalidateFFTModel(); | 137 invalidateFFTModel(); |
138 } | 138 } |
139 | 139 |
140 ColourScale::Scale | 140 ColourScaleType |
141 SpectrogramLayer::convertToColourScale(int value) | 141 SpectrogramLayer::convertToColourScale(int value) |
142 { | 142 { |
143 switch (value) { | 143 switch (value) { |
144 case 0: return ColourScale::LinearColourScale; | 144 case 0: return ColourScaleType::Linear; |
145 case 1: return ColourScale::MeterColourScale; | 145 case 1: return ColourScaleType::Meter; |
146 case 2: return ColourScale::LogColourScale; //!!! db^2 | 146 case 2: return ColourScaleType::Log; //!!! db^2 |
147 case 3: return ColourScale::LogColourScale; | 147 case 3: return ColourScaleType::Log; |
148 case 4: return ColourScale::PhaseColourScale; | 148 case 4: return ColourScaleType::Phase; |
149 default: return ColourScale::LinearColourScale; | 149 default: return ColourScaleType::Linear; |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 int | 153 int |
154 SpectrogramLayer::convertFromColourScale(ColourScale::Scale scale) | 154 SpectrogramLayer::convertFromColourScale(ColourScaleType scale) |
155 { | 155 { |
156 switch (scale) { | 156 switch (scale) { |
157 case ColourScale::LinearColourScale: return 0; | 157 case ColourScaleType::Linear: return 0; |
158 case ColourScale::MeterColourScale: return 1; | 158 case ColourScaleType::Meter: return 1; |
159 case ColourScale::LogColourScale: return 3; //!!! + db^2 | 159 case ColourScaleType::Log: return 3; //!!! + db^2 |
160 case ColourScale::PhaseColourScale: return 4; | 160 case ColourScaleType::Phase: return 4; |
161 | 161 |
162 case ColourScale::PlusMinusOneScale: | 162 case ColourScaleType::PlusMinusOne: |
163 case ColourScale::AbsoluteScale: | 163 case ColourScaleType::Absolute: |
164 default: return 0; | 164 default: return 0; |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 std::pair<ColumnNormalization, bool> | 168 std::pair<ColumnNormalization, bool> |
592 m_lastEmittedZoomStep = vs; | 592 m_lastEmittedZoomStep = vs; |
593 } | 593 } |
594 } else if (name == "Colour Scale") { | 594 } else if (name == "Colour Scale") { |
595 switch (value) { | 595 switch (value) { |
596 default: | 596 default: |
597 case 0: setColourScale(ColourScale::LinearColourScale); break; | 597 case 0: setColourScale(ColourScaleType::Linear); break; |
598 case 1: setColourScale(ColourScale::MeterColourScale); break; | 598 case 1: setColourScale(ColourScaleType::Meter); break; |
599 case 2: setColourScale(ColourScale::LogColourScale); break; //!!! dB^2 | 599 case 2: setColourScale(ColourScaleType::Log); break; //!!! dB^2 |
600 case 3: setColourScale(ColourScale::LogColourScale); break; | 600 case 3: setColourScale(ColourScaleType::Log); break; |
601 case 4: setColourScale(ColourScale::PhaseColourScale); break; | 601 case 4: setColourScale(ColourScaleType::Phase); break; |
602 } | 602 } |
603 } else if (name == "Frequency Scale") { | 603 } else if (name == "Frequency Scale") { |
604 switch (value) { | 604 switch (value) { |
605 default: | 605 default: |
606 case 0: setBinScale(BinScale::Linear); break; | 606 case 0: setBinScale(BinScale::Linear); break; |
865 | 865 |
866 emit layerParametersChanged(); | 866 emit layerParametersChanged(); |
867 } | 867 } |
868 | 868 |
869 void | 869 void |
870 SpectrogramLayer::setColourScale(ColourScale::Scale colourScale) | 870 SpectrogramLayer::setColourScale(ColourScaleType colourScale) |
871 { | 871 { |
872 if (m_colourScale == colourScale) return; | 872 if (m_colourScale == colourScale) return; |
873 | 873 |
874 invalidateImageCaches(); | 874 invalidateImageCaches(); |
875 | 875 |
876 m_colourScale = colourScale; | 876 m_colourScale = colourScale; |
877 | 877 |
878 emit layerParametersChanged(); | 878 emit layerParametersChanged(); |
879 } | 879 } |
880 | 880 |
881 ColourScale::Scale | 881 ColourScaleType |
882 SpectrogramLayer::getColourScale() const | 882 SpectrogramLayer::getColourScale() const |
883 { | 883 { |
884 return m_colourScale; | 884 return m_colourScale; |
885 } | 885 } |
886 | 886 |
1102 | 1102 |
1103 if (m_normalizeVisibleArea) { | 1103 if (m_normalizeVisibleArea) { |
1104 min = m_viewMags[v->getId()].getMin(); | 1104 min = m_viewMags[v->getId()].getMin(); |
1105 max = m_viewMags[v->getId()].getMax(); | 1105 max = m_viewMags[v->getId()].getMax(); |
1106 } else if (m_normalization != ColumnNormalization::Max1) { | 1106 } else if (m_normalization != ColumnNormalization::Max1) { |
1107 if (m_colourScale == ColourScale::LinearColourScale //|| | 1107 if (m_colourScale == ColourScaleType::Linear //|| |
1108 // m_colourScale == MeterColourScale) { | 1108 // m_colourScale == ColourScaleType::Meter) { |
1109 ) { | 1109 ) { |
1110 max = 0.1; | 1110 max = 0.1; |
1111 } | 1111 } |
1112 } | 1112 } |
1113 | 1113 |
1116 if (max == 0.0) max = 1.0; | 1116 if (max == 0.0) max = 1.0; |
1117 if (max == min) min = max - 0.0001; | 1117 if (max == min) min = max - 0.0001; |
1118 | 1118 |
1119 switch (m_colourScale) { | 1119 switch (m_colourScale) { |
1120 | 1120 |
1121 case ColourScale::LinearColourScale: | 1121 case ColourScaleType::Linear: |
1122 value = int(((input - min) / (max - min)) * 255.0) + 1; | 1122 value = int(((input - min) / (max - min)) * 255.0) + 1; |
1123 break; | 1123 break; |
1124 | 1124 |
1125 case ColourScale::MeterColourScale: | 1125 case ColourScaleType::Meter: |
1126 value = AudioLevel::multiplier_to_preview | 1126 value = AudioLevel::multiplier_to_preview |
1127 ((input - min) / (max - min), 254) + 1; | 1127 ((input - min) / (max - min), 254) + 1; |
1128 break; | 1128 break; |
1129 | 1129 |
1130 //!!! check this | 1130 //!!! check this |
1143 if (input < 0.0) input = 0.0; | 1143 if (input < 0.0) input = 0.0; |
1144 if (input > 1.0) input = 1.0; | 1144 if (input > 1.0) input = 1.0; |
1145 value = int(input * 255.0) + 1; | 1145 value = int(input * 255.0) + 1; |
1146 break; | 1146 break; |
1147 */ | 1147 */ |
1148 case ColourScale::LogColourScale: | 1148 case ColourScaleType::Log: |
1149 //!!! experiment with normalizing the visible area this way. | 1149 //!!! experiment with normalizing the visible area this way. |
1150 //In any case, we need to have some indication of what the dB | 1150 //In any case, we need to have some indication of what the dB |
1151 //scale is relative to. | 1151 //scale is relative to. |
1152 input = (input - min) / (max - min); | 1152 input = (input - min) / (max - min); |
1153 if (input > 0.0) { | 1153 if (input > 0.0) { |
1163 if (input < 0.0) input = 0.0; | 1163 if (input < 0.0) input = 0.0; |
1164 if (input > 1.0) input = 1.0; | 1164 if (input > 1.0) input = 1.0; |
1165 value = int(input * 255.0) + 1; | 1165 value = int(input * 255.0) + 1; |
1166 break; | 1166 break; |
1167 | 1167 |
1168 case ColourScale::PhaseColourScale: | 1168 case ColourScaleType::Phase: |
1169 value = int((input * 127.0 / M_PI) + 128); | 1169 value = int((input * 127.0 / M_PI) + 128); |
1170 break; | 1170 break; |
1171 | 1171 |
1172 case ColourScale::PlusMinusOneScale: | 1172 case ColourScaleType::PlusMinusOne: |
1173 case ColourScale::AbsoluteScale: | 1173 case ColourScaleType::Absolute: |
1174 default: | 1174 default: |
1175 ; | 1175 ; |
1176 } | 1176 } |
1177 | 1177 |
1178 if (value > UCHAR_MAX) value = UCHAR_MAX; | 1178 if (value > UCHAR_MAX) value = UCHAR_MAX; |
1654 cparams.colourMap = m_colourMap; | 1654 cparams.colourMap = m_colourMap; |
1655 cparams.scale = m_colourScale; | 1655 cparams.scale = m_colourScale; |
1656 cparams.threshold = m_threshold; | 1656 cparams.threshold = m_threshold; |
1657 cparams.gain = m_gain; | 1657 cparams.gain = m_gain; |
1658 | 1658 |
1659 if (m_colourScale != ColourScale::PhaseColourScale && | 1659 if (m_colourScale != ColourScaleType::Phase && |
1660 m_normalization == ColumnNormalization::None) { | 1660 m_normalization == ColumnNormalization::None) { |
1661 cparams.gain *= 2.f / float(getFFTSize()); | 1661 cparams.gain *= 2.f / float(getFFTSize()); |
1662 } | 1662 } |
1663 | 1663 |
1664 Colour3DPlotRenderer::Parameters params; | 1664 Colour3DPlotRenderer::Parameters params; |
1981 } | 1981 } |
1982 if (m_drawBuffer.width() < bufwid || m_drawBuffer.height() != h) { | 1982 if (m_drawBuffer.width() < bufwid || m_drawBuffer.height() != h) { |
1983 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); | 1983 m_drawBuffer = QImage(bufwid, h, QImage::Format_Indexed8); |
1984 } | 1984 } |
1985 usePeaksCache = (increment * m_peakCacheDivisor) < zoomLevel; | 1985 usePeaksCache = (increment * m_peakCacheDivisor) < zoomLevel; |
1986 if (m_colourScale == ColourScale::PhaseColourScale) usePeaksCache = false; | 1986 if (m_colourScale == ColourScaleType::Phase) usePeaksCache = false; |
1987 } | 1987 } |
1988 | 1988 |
1989 for (int pixel = 0; pixel < 256; ++pixel) { | 1989 for (int pixel = 0; pixel < 256; ++pixel) { |
1990 m_drawBuffer.setColor((unsigned char)pixel, | 1990 m_drawBuffer.setColor((unsigned char)pixel, |
1991 m_palette.getColour((unsigned char)pixel).rgb()); | 1991 m_palette.getColour((unsigned char)pixel).rgb()); |
2311 column = getColumnFromFFTModel(fft, | 2311 column = getColumnFromFFTModel(fft, |
2312 sx, | 2312 sx, |
2313 minbin, | 2313 minbin, |
2314 maxbin - minbin + 1); | 2314 maxbin - minbin + 1); |
2315 | 2315 |
2316 if (m_colourScale != ColourScale::PhaseColourScale) { | 2316 if (m_colourScale != ColourScaleType::Phase) { |
2317 column = ColumnOp::fftScale(column, getFFTSize()); | 2317 column = ColumnOp::fftScale(column, getFFTSize()); |
2318 } | 2318 } |
2319 | 2319 |
2320 recordColumnExtents(column, | 2320 recordColumnExtents(column, |
2321 sx, | 2321 sx, |
2322 overallMag, | 2322 overallMag, |
2323 overallMagChanged); | 2323 overallMagChanged); |
2324 | 2324 |
2325 if (m_colourScale != ColourScale::PhaseColourScale) { | 2325 if (m_colourScale != ColourScaleType::Phase) { |
2326 column = ColumnOp::normalize(column, m_normalization); | 2326 column = ColumnOp::normalize(column, m_normalization); |
2327 } | 2327 } |
2328 | 2328 |
2329 preparedColumn = ColumnOp::applyGain(column, m_gain); | 2329 preparedColumn = ColumnOp::applyGain(column, m_gain); |
2330 | 2330 |
2403 int minbin, | 2403 int minbin, |
2404 int bincount) const | 2404 int bincount) const |
2405 { | 2405 { |
2406 vector<float> values(bincount, 0.f); | 2406 vector<float> values(bincount, 0.f); |
2407 | 2407 |
2408 if (m_colourScale == ColourScale::PhaseColourScale) { | 2408 if (m_colourScale == ColourScaleType::Phase) { |
2409 fft->getPhasesAt(sx, values.data(), minbin, bincount); | 2409 fft->getPhasesAt(sx, values.data(), minbin, bincount); |
2410 } else { | 2410 } else { |
2411 fft->getMagnitudesAt(sx, values.data(), minbin, bincount); | 2411 fft->getMagnitudesAt(sx, values.data(), minbin, bincount); |
2412 } | 2412 } |
2413 | 2413 |
2418 SpectrogramLayer::getColumnFromGenericModel(DenseThreeDimensionalModel *model, | 2418 SpectrogramLayer::getColumnFromGenericModel(DenseThreeDimensionalModel *model, |
2419 int sx, // column number in model | 2419 int sx, // column number in model |
2420 int minbin, | 2420 int minbin, |
2421 int bincount) const | 2421 int bincount) const |
2422 { | 2422 { |
2423 if (m_colourScale == ColourScale::PhaseColourScale) { | 2423 if (m_colourScale == ColourScaleType::Phase) { |
2424 throw std::logic_error("can't use phase scale with generic 3d model"); | 2424 throw std::logic_error("can't use phase scale with generic 3d model"); |
2425 } | 2425 } |
2426 | 2426 |
2427 auto col = model->getColumn(sx); | 2427 auto col = model->getColumn(sx); |
2428 | 2428 |
2572 sx, | 2572 sx, |
2573 minbin, | 2573 minbin, |
2574 maxbin - minbin + 1); | 2574 maxbin - minbin + 1); |
2575 } | 2575 } |
2576 | 2576 |
2577 if (m_colourScale != ColourScale::PhaseColourScale) { | 2577 if (m_colourScale != ColourScaleType::Phase) { |
2578 column = ColumnOp::fftScale(column, getFFTSize()); | 2578 column = ColumnOp::fftScale(column, getFFTSize()); |
2579 } | 2579 } |
2580 | 2580 |
2581 recordColumnExtents(column, | 2581 recordColumnExtents(column, |
2582 sx, | 2582 sx, |
2583 overallMag, | 2583 overallMag, |
2584 overallMagChanged); | 2584 overallMagChanged); |
2585 | 2585 |
2586 if (m_colourScale != ColourScale::PhaseColourScale) { | 2586 if (m_colourScale != ColourScaleType::Phase) { |
2587 column = ColumnOp::normalize(column, m_normalization); | 2587 column = ColumnOp::normalize(column, m_normalization); |
2588 } | 2588 } |
2589 | 2589 |
2590 if (m_binDisplay == BinDisplay::PeakBins) { | 2590 if (m_binDisplay == BinDisplay::PeakBins) { |
2591 column = ColumnOp::peakPick(column); | 2591 column = ColumnOp::peakPick(column); |
3130 int toff = -textHeight + paint.fontMetrics().ascent() + 2; | 3130 int toff = -textHeight + paint.fontMetrics().ascent() + 2; |
3131 | 3131 |
3132 if (detailed && (h > textHeight * 3 + 10)) { | 3132 if (detailed && (h > textHeight * 3 + 10)) { |
3133 | 3133 |
3134 int topLines = 2; | 3134 int topLines = 2; |
3135 if (m_colourScale == ColourScale::PhaseColourScale) topLines = 1; | 3135 if (m_colourScale == ColourScaleType::Phase) topLines = 1; |
3136 | 3136 |
3137 int ch = h - textHeight * (topLines + 1) - 8; | 3137 int ch = h - textHeight * (topLines + 1) - 8; |
3138 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); | 3138 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); |
3139 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); | 3139 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); |
3140 | 3140 |
3157 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; | 3157 if (dBmin < dBmax - 60.f) dBmin = dBmax - 60.f; |
3158 bottom = QString("%1").arg(lrint(dBmin)); | 3158 bottom = QString("%1").arg(lrint(dBmin)); |
3159 | 3159 |
3160 //!!! & phase etc | 3160 //!!! & phase etc |
3161 | 3161 |
3162 if (m_colourScale != ColourScale::PhaseColourScale) { | 3162 if (m_colourScale != ColourScaleType::Phase) { |
3163 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, | 3163 paint.drawText((cw + 6 - paint.fontMetrics().width("dBFS")) / 2, |
3164 2 + textHeight + toff, "dBFS"); | 3164 2 + textHeight + toff, "dBFS"); |
3165 } | 3165 } |
3166 | 3166 |
3167 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, | 3167 // paint.drawText((cw + 6 - paint.fontMetrics().width(top)) / 2, |
3559 if (ok) { | 3559 if (ok) { |
3560 SVDEBUG << "SpectrogramLayer::setProperties: setting max freq to " << maxFrequency << endl; | 3560 SVDEBUG << "SpectrogramLayer::setProperties: setting max freq to " << maxFrequency << endl; |
3561 setMaxFrequency(maxFrequency); | 3561 setMaxFrequency(maxFrequency); |
3562 } | 3562 } |
3563 | 3563 |
3564 ColourScale::Scale colourScale = convertToColourScale | 3564 ColourScaleType colourScale = convertToColourScale |
3565 (attributes.value("colourScale").toInt(&ok)); | 3565 (attributes.value("colourScale").toInt(&ok)); |
3566 if (ok) setColourScale(colourScale); | 3566 if (ok) setColourScale(colourScale); |
3567 | 3567 |
3568 int colourMap = attributes.value("colourScheme").toInt(&ok); | 3568 int colourMap = attributes.value("colourScheme").toInt(&ok); |
3569 if (ok) setColourMap(colourMap); | 3569 if (ok) setColourMap(colourMap); |