comparison layer/SliceLayer.cpp @ 1281:fc9d9f1103fa horizontal-scale

Provide linear horizontal scale in spectrum as well as log; fix bin positioning and colour scale property box updating; ensure proper background colour and visibility of peak lines
author Chris Cannam
date Thu, 03 May 2018 15:15:15 +0100
parents a34a2a25907c
children 51e6125627fa
comparison
equal deleted inserted replaced
1280:34394e8c2942 1281:fc9d9f1103fa
29 #include <QTextStream> 29 #include <QTextStream>
30 30
31 31
32 SliceLayer::SliceLayer() : 32 SliceLayer::SliceLayer() :
33 m_sliceableModel(0), 33 m_sliceableModel(0),
34 m_colourMap(0), 34 m_colourMap(int(ColourMapper::Ice)),
35 m_energyScale(dBScale), 35 m_energyScale(dBScale),
36 m_samplingMode(SampleMean), 36 m_samplingMode(SampleMean),
37 m_plotStyle(PlotLines), 37 m_plotStyle(PlotLines),
38 m_binScale(LinearBins), 38 m_binScale(LinearBins),
39 m_normalize(false), 39 m_normalize(false),
208 case LinearBins: 208 case LinearBins:
209 x = (w * bin) / count; 209 x = (w * bin) / count;
210 break; 210 break;
211 211
212 case LogBins: 212 case LogBins:
213 x = (w * log10(bin + 1)) / log10(count + 1); 213 // The 0.8 here is an awkward compromise. Our x-coord is
214 // proportional to log of bin number, with the x-coord "of a
215 // bin" being that of the left edge of the bin range. We can't
216 // start counting bins from 0, as that would give us x = -Inf
217 // and hide the first bin entirely. But if we start from 1, we
218 // are giving a lot of space to the first bin, which in most
219 // display modes won't be used because the "point" location
220 // for that bin is in the middle of it. Yet in some modes
221 // we'll still want it. A compromise is to count our first bin
222 // as "a bit less than 1", so that most of it is visible but a
223 // bit is tactfully cropped at the left edge so it doesn't
224 // take up so much space.
225 x = (w * log10(bin + 0.8)) / log10(count + 0.8);
214 break; 226 break;
215 227
216 case InvertedLogBins: 228 case InvertedLogBins:
217 x = w - (w * log10(count - bin - 1)) / log10(count); 229 x = w - (w * log10(count - bin - 1)) / log10(count);
218 break; 230 break;
245 case LinearBins: 257 case LinearBins:
246 bin = (x * count) / w + eps; 258 bin = (x * count) / w + eps;
247 break; 259 break;
248 260
249 case LogBins: 261 case LogBins:
250 bin = pow(10.0, (x * log10(count + 1)) / w) - 1.0 + eps; 262 // See comment in getXForBin
263 bin = pow(10.0, (x * log10(count + 0.8)) / w) - 0.8 + eps;
251 break; 264 break;
252 265
253 case InvertedLogBins: 266 case InvertedLogBins:
254 bin = count + 1 - pow(10.0, (log10(count) * (w - x)) / double(w)) + eps; 267 bin = count + 1 - pow(10.0, (log10(count) * (w - x)) / double(w)) + eps;
255 break; 268 break;
549 paint.drawText(3 + paint.fontMetrics().width(a), 562 paint.drawText(3 + paint.fontMetrics().width(a),
550 3 + paint.fontMetrics().ascent(), b); 563 3 + paint.fontMetrics().ascent(), b);
551 } 564 }
552 } 565 }
553 566
567 bool
568 SliceLayer::hasLightBackground() const
569 {
570 if (usesSolidColour()) {
571 ColourMapper mapper(m_colourMap, 0, 1);
572 return mapper.hasLightBackground();
573 } else {
574 return SingleColourLayer::hasLightBackground();
575 }
576 }
577
554 Layer::PropertyList 578 Layer::PropertyList
555 SliceLayer::getProperties() const 579 SliceLayer::getProperties() const
556 { 580 {
557 PropertyList list = SingleColourLayer::getProperties(); 581 PropertyList list = SingleColourLayer::getProperties();
558 list.push_back("Bin Scale"); 582 list.push_back("Bin Scale");
593 if (name == "Threshold") return RangeProperty; 617 if (name == "Threshold") return RangeProperty;
594 if (name == "Plot Type") return ValueProperty; 618 if (name == "Plot Type") return ValueProperty;
595 if (name == "Scale") return ValueProperty; 619 if (name == "Scale") return ValueProperty;
596 if (name == "Sampling Mode") return ValueProperty; 620 if (name == "Sampling Mode") return ValueProperty;
597 if (name == "Bin Scale") return ValueProperty; 621 if (name == "Bin Scale") return ValueProperty;
598 if (name == "Colour" && m_plotStyle == PlotFilledBlocks) return ValueProperty; 622 if (name == "Colour" && usesSolidColour()) return ColourMapProperty;
599 return SingleColourLayer::getPropertyType(name); 623 return SingleColourLayer::getPropertyType(name);
600 } 624 }
601 625
602 QString 626 QString
603 SliceLayer::getPropertyGroupName(const PropertyName &name) const 627 SliceLayer::getPropertyGroupName(const PropertyName &name) const
651 } else if (name == "Normalize") { 675 } else if (name == "Normalize") {
652 676
653 val = (m_normalize ? 1 : 0); 677 val = (m_normalize ? 1 : 0);
654 *deflt = 0; 678 *deflt = 0;
655 679
656 } else if (name == "Colour" && m_plotStyle == PlotFilledBlocks) { 680 } else if (name == "Colour" && usesSolidColour()) {
657 681
658 *min = 0; 682 *min = 0;
659 *max = ColourMapper::getColourMapCount() - 1; 683 *max = ColourMapper::getColourMapCount() - 1;
660 *deflt = 0; 684 *deflt = int(ColourMapper::Ice);
661 685
662 val = m_colourMap; 686 val = m_colourMap;
663 687
664 } else if (name == "Scale") { 688 } else if (name == "Scale") {
665 689
701 return val; 725 return val;
702 } 726 }
703 727
704 QString 728 QString
705 SliceLayer::getPropertyValueLabel(const PropertyName &name, 729 SliceLayer::getPropertyValueLabel(const PropertyName &name,
706 int value) const 730 int value) const
707 { 731 {
708 if (name == "Colour" && m_plotStyle == PlotFilledBlocks) { 732 if (name == "Colour" && usesSolidColour()) {
709 return ColourMapper::getColourMapName(value); 733 return ColourMapper::getColourMapName(value);
710 } 734 }
711 if (name == "Scale") { 735 if (name == "Scale") {
712 switch (value) { 736 switch (value) {
713 default: 737 default:
763 if (name == "Gain") { 787 if (name == "Gain") {
764 setGain(powf(10, float(value)/20.0f)); 788 setGain(powf(10, float(value)/20.0f));
765 } else if (name == "Threshold") { 789 } else if (name == "Threshold") {
766 if (value == -80) setThreshold(0.0f); 790 if (value == -80) setThreshold(0.0f);
767 else setThreshold(float(AudioLevel::dB_to_multiplier(value))); 791 else setThreshold(float(AudioLevel::dB_to_multiplier(value)));
768 } else if (name == "Colour" && m_plotStyle == PlotFilledBlocks) { 792 } else if (name == "Colour" && usesSolidColour()) {
769 setFillColourMap(value); 793 setFillColourMap(value);
770 } else if (name == "Scale") { 794 } else if (name == "Scale") {
771 switch (value) { 795 switch (value) {
772 default: 796 default:
773 case 0: setEnergyScale(LinearScale); break; 797 case 0: setEnergyScale(LinearScale); break;