Mercurial > hg > svgui
comparison layer/ColourScale.cpp @ 1324:13d9b422f7fe zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:31 +0100 |
parents | a34a2a25907c |
children | d79e21855aef |
comparison
equal
deleted
inserted
replaced
1183:57d192e26331 | 1324:13d9b422f7fe |
---|---|
28 ColourScale::ColourScale(Parameters parameters) : | 28 ColourScale::ColourScale(Parameters parameters) : |
29 m_params(parameters), | 29 m_params(parameters), |
30 m_mapper(m_params.colourMap, 1.f, double(m_maxPixel)) | 30 m_mapper(m_params.colourMap, 1.f, double(m_maxPixel)) |
31 { | 31 { |
32 if (m_params.minValue >= m_params.maxValue) { | 32 if (m_params.minValue >= m_params.maxValue) { |
33 cerr << "ERROR: ColourScale::ColourScale: minValue = " | 33 SVCERR << "ERROR: ColourScale::ColourScale: minValue = " |
34 << m_params.minValue << ", maxValue = " << m_params.maxValue << endl; | 34 << m_params.minValue << ", maxValue = " << m_params.maxValue << endl; |
35 throw std::logic_error("maxValue must be greater than minValue"); | 35 throw std::logic_error("maxValue must be greater than minValue"); |
36 } | 36 } |
37 | 37 |
38 m_mappedMin = m_params.minValue; | 38 m_mappedMin = m_params.minValue; |
39 m_mappedMax = m_params.maxValue; | 39 m_mappedMax = m_params.maxValue; |
40 | 40 |
42 m_mappedMin = m_params.threshold; | 42 m_mappedMin = m_params.threshold; |
43 } | 43 } |
44 | 44 |
45 if (m_params.scaleType == ColourScaleType::Log) { | 45 if (m_params.scaleType == ColourScaleType::Log) { |
46 | 46 |
47 LogRange::mapRange(m_mappedMin, m_mappedMax); | 47 // When used in e.g. spectrogram, we have a range with a min |
48 | 48 // value of zero. The LogRange converts that to a threshold |
49 // value of -10, so for a range of e.g. (0,1) we end up with | |
50 // (-10,0) as the mapped range. | |
51 // | |
52 // But in other contexts we could end up with a mapped range | |
53 // much larger than that if we have a small non-zero minimum | |
54 // value (less than 1e-10), or a particularly large | |
55 // maximum. That's unlikely to give us good results, so let's | |
56 // insist that the mapped log range has no more than 10 | |
57 // difference between min and max, to match the behaviour when | |
58 // min == 0 at the input. | |
59 // | |
60 double threshold = -10.0; | |
61 LogRange::mapRange(m_mappedMin, m_mappedMax, threshold); | |
62 if (m_mappedMin < m_mappedMax + threshold) { | |
63 m_mappedMin = m_mappedMax + threshold; | |
64 } | |
65 | |
49 } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { | 66 } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { |
50 | 67 |
51 m_mappedMin = -1.0; | 68 m_mappedMin = -1.0; |
52 m_mappedMax = 1.0; | 69 m_mappedMax = 1.0; |
53 | 70 |
54 } else if (m_params.scaleType == ColourScaleType::Absolute) { | 71 } else if (m_params.scaleType == ColourScaleType::Absolute) { |
55 | 72 |
56 m_mappedMin = fabs(m_mappedMin); | 73 m_mappedMin = fabs(m_mappedMin); |
57 m_mappedMax = fabs(m_mappedMax); | 74 m_mappedMax = fabs(m_mappedMax); |
58 if (m_mappedMin >= m_mappedMax) { | 75 if (m_mappedMin >= m_mappedMax) { |
59 std::swap(m_mappedMin, m_mappedMax); | 76 std::swap(m_mappedMin, m_mappedMax); |
60 } | 77 } |
61 } | 78 } |
62 | 79 |
63 if (m_mappedMin >= m_mappedMax) { | 80 if (m_mappedMin >= m_mappedMax) { |
64 cerr << "ERROR: ColourScale::ColourScale: minValue = " << m_params.minValue | 81 SVCERR << "ERROR: ColourScale::ColourScale: minValue = " << m_params.minValue |
65 << ", maxValue = " << m_params.maxValue | 82 << ", maxValue = " << m_params.maxValue |
66 << ", threshold = " << m_params.threshold | 83 << ", threshold = " << m_params.threshold |
67 << ", scale = " << int(m_params.scaleType) | 84 << ", scale = " << int(m_params.scaleType) |
68 << " resulting in mapped minValue = " << m_mappedMin | 85 << " resulting in mapped minValue = " << m_mappedMin |
69 << ", mapped maxValue = " << m_mappedMax << endl; | 86 << ", mapped maxValue = " << m_mappedMax << endl; |
70 throw std::logic_error("maxValue must be greater than minValue [after mapping]"); | 87 throw std::logic_error("maxValue must be greater than minValue [after mapping]"); |
71 } | 88 } |
72 } | 89 } |
73 | 90 |
74 ColourScale::~ColourScale() | 91 ColourScale::~ColourScale() |
75 { | 92 { |
85 ColourScale::getPixel(double value) const | 102 ColourScale::getPixel(double value) const |
86 { | 103 { |
87 double maxPixF = m_maxPixel; | 104 double maxPixF = m_maxPixel; |
88 | 105 |
89 if (m_params.scaleType == ColourScaleType::Phase) { | 106 if (m_params.scaleType == ColourScaleType::Phase) { |
90 double half = (maxPixF - 1.f) / 2.f; | 107 double half = (maxPixF - 1.f) / 2.f; |
91 int pixel = 1 + int((value * half) / M_PI + half); | 108 int pixel = 1 + int((value * half) / M_PI + half); |
92 // cerr << "phase = " << value << " pixel = " << pixel << endl; | 109 // SVCERR << "phase = " << value << " pixel = " << pixel << endl; |
93 return pixel; | 110 return pixel; |
94 } | 111 } |
95 | 112 |
96 value *= m_params.gain; | 113 value *= m_params.gain; |
97 | 114 |
98 if (value < m_params.threshold) return 0; | 115 if (value < m_params.threshold) return 0; |
99 | 116 |
100 double mapped = value; | 117 double mapped = value; |
101 | 118 |
102 if (m_params.scaleType == ColourScaleType::Log) { | 119 if (m_params.scaleType == ColourScaleType::Log) { |
103 mapped = LogRange::map(value); | 120 mapped = LogRange::map(value); |
104 } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { | 121 } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { |
105 if (mapped < -1.f) mapped = -1.f; | 122 if (mapped < -1.f) mapped = -1.f; |
106 if (mapped > 1.f) mapped = 1.f; | 123 if (mapped > 1.f) mapped = 1.f; |
107 } else if (m_params.scaleType == ColourScaleType::Absolute) { | 124 } else if (m_params.scaleType == ColourScaleType::Absolute) { |
108 if (mapped < 0.f) mapped = -mapped; | 125 if (mapped < 0.f) mapped = -mapped; |
109 } | 126 } |
110 | 127 |
111 mapped *= m_params.multiple; | 128 mapped *= m_params.multiple; |
112 | 129 |
113 if (mapped < m_mappedMin) { | 130 if (mapped < m_mappedMin) { |
114 mapped = m_mappedMin; | 131 mapped = m_mappedMin; |
115 } | 132 } |
116 if (mapped > m_mappedMax) { | 133 if (mapped > m_mappedMax) { |
117 mapped = m_mappedMax; | 134 mapped = m_mappedMax; |
118 } | 135 } |
119 | 136 |
120 double proportion = (mapped - m_mappedMin) / (m_mappedMax - m_mappedMin); | 137 double proportion = (mapped - m_mappedMin) / (m_mappedMax - m_mappedMin); |
121 | 138 |
122 int pixel = 0; | 139 int pixel = 0; |
123 | 140 |
124 if (m_params.scaleType == ColourScaleType::Meter) { | 141 if (m_params.scaleType == ColourScaleType::Meter) { |
125 pixel = AudioLevel::multiplier_to_preview(proportion, m_maxPixel-1) + 1; | 142 pixel = AudioLevel::multiplier_to_preview(proportion, m_maxPixel-1) + 1; |
126 } else { | 143 } else { |
127 pixel = int(proportion * maxPixF) + 1; | 144 pixel = int(proportion * maxPixF) + 1; |
128 } | 145 } |
129 | 146 |
130 if (pixel < 0) { | 147 if (pixel < 0) { |
131 pixel = 0; | 148 pixel = 0; |
132 } | 149 } |
133 if (pixel > m_maxPixel) { | 150 if (pixel > m_maxPixel) { |
134 pixel = m_maxPixel; | 151 pixel = m_maxPixel; |
135 } | 152 } |
136 return pixel; | 153 return pixel; |
137 } | 154 } |
138 | 155 |
139 QColor | 156 QColor |
140 ColourScale::getColourForPixel(int pixel, int rotation) const | 157 ColourScale::getColourForPixel(int pixel, int rotation) const |
141 { | 158 { |
142 if (pixel < 0) { | 159 if (pixel < 0) { |
143 pixel = 0; | 160 pixel = 0; |
144 } | 161 } |
145 if (pixel > m_maxPixel) { | 162 if (pixel > m_maxPixel) { |
146 pixel = m_maxPixel; | 163 pixel = m_maxPixel; |
147 } | 164 } |
148 if (pixel == 0) { | 165 if (pixel == 0) { |
149 if (m_mapper.hasLightBackground()) { | 166 if (m_mapper.hasLightBackground()) { |
150 return Qt::white; | 167 return Qt::white; |
151 } else { | 168 } else { |
152 return Qt::black; | 169 return Qt::black; |
153 } | 170 } |
154 } else { | 171 } else { |
155 int target = int(pixel) + rotation; | 172 int target = int(pixel) + rotation; |
156 while (target < 1) target += m_maxPixel; | 173 while (target < 1) target += m_maxPixel; |
157 while (target > m_maxPixel) target -= m_maxPixel; | 174 while (target > m_maxPixel) target -= m_maxPixel; |
158 return m_mapper.map(double(target)); | 175 return m_mapper.map(double(target)); |
159 } | 176 } |
160 } | 177 } |