comparison layer/SpectrogramLayer.cpp @ 210:748985c7e2c1

* Fix incorrect meter-scaling value for 0dB; some tidying
author Chris Cannam
date Wed, 28 Feb 2007 11:20:14 +0000
parents b6af2eb00780
children d2334a77db73
comparison
equal deleted inserted replaced
209:b6af2eb00780 210:748985c7e2c1
488 switch (value) { 488 switch (value) {
489 default: 489 default:
490 case 0: setColourScale(LinearColourScale); break; 490 case 0: setColourScale(LinearColourScale); break;
491 case 1: setColourScale(MeterColourScale); break; 491 case 1: setColourScale(MeterColourScale); break;
492 case 2: setColourScale(dBColourScale); break; 492 case 2: setColourScale(dBColourScale); break;
493 case 3: setColourScale(OtherColourScale); break; 493 case 3: setColourScale(dBSquaredColourScale); break;
494 case 4: setColourScale(PhaseColourScale); break; 494 case 4: setColourScale(PhaseColourScale); break;
495 } 495 }
496 } else if (name == "Frequency Scale") { 496 } else if (name == "Frequency Scale") {
497 switch (value) { 497 switch (value) {
498 default: 498 default:
1095 1095
1096 switch (m_colourScale) { 1096 switch (m_colourScale) {
1097 1097
1098 default: 1098 default:
1099 case LinearColourScale: 1099 case LinearColourScale:
1100 // value = int
1101 // (input * (m_normalizeColumns ? 1.0 : 50.0) * 255.0) + 1;
1102 value = int(((input - min) / (max - min)) * 255.f) + 1; 1100 value = int(((input - min) / (max - min)) * 255.f) + 1;
1103 break; 1101 break;
1104 1102
1105 case MeterColourScale: 1103 case MeterColourScale:
1106 // value = AudioLevel::multiplier_to_preview 1104 value = AudioLevel::multiplier_to_preview
1107 // (input * (m_normalizeColumns ? 1.0 : 50.0), 255) + 1; 1105 ((input - min) / (max - min), 254) + 1;
1108 value = AudioLevel::multiplier_to_preview((input - min) / (max - min), 255) + 1;
1109 break; 1106 break;
1110 1107
1111 case dBColourScale: 1108 case dBColourScale:
1112 //!!! experiment with normalizing the visible area this way. 1109 //!!! experiment with normalizing the visible area this way.
1113 //In any case, we need to have some indication of what the dB 1110 //In any case, we need to have some indication of what the dB
1126 if (input < 0.f) input = 0.f; 1123 if (input < 0.f) input = 0.f;
1127 if (input > 1.f) input = 1.f; 1124 if (input > 1.f) input = 1.f;
1128 value = int(input * 255.f) + 1; 1125 value = int(input * 255.f) + 1;
1129 break; 1126 break;
1130 1127
1131 case OtherColourScale: 1128 case dBSquaredColourScale:
1132 //!!! the "Other" scale is just where our current experiments go
1133 //!!! power rather than v
1134 input = (input * input) / (max * max); 1129 input = (input * input) / (max * max);
1135 if (input > 0.f) { 1130 if (input > 0.f) {
1136 input = 10.f * log10f(input); 1131 input = 10.f * log10f(input);
1137 } else { 1132 } else {
1138 input = thresh; 1133 input = thresh;
1144 input = (input - thresh) / (-thresh); 1139 input = (input - thresh) / (-thresh);
1145 if (input < 0.f) input = 0.f; 1140 if (input < 0.f) input = 0.f;
1146 if (input > 1.f) input = 1.f; 1141 if (input > 1.f) input = 1.f;
1147 value = int(input * 255.f) + 1; 1142 value = int(input * 255.f) + 1;
1148 break; 1143 break;
1149
1150 /*!!!
1151 input = 10.f * log10f(input * input);
1152 input = 1.f / (1.f + expf(- (input + 20.f) / 10.f));
1153
1154 if (input < 0.f) input = 0.f;
1155 if (input > 1.f) input = 1.f;
1156 value = int(input * 255.f) + 1;
1157 */
1158 break;
1159 1144
1160 case PhaseColourScale: 1145 case PhaseColourScale:
1161 value = int((input * 127.0 / M_PI) + 128); 1146 value = int((input * 127.0 / M_PI) + 128);
1162 break; 1147 break;
1163 } 1148 }
1164 1149
1165 if (value > UCHAR_MAX) value = UCHAR_MAX; 1150 if (value > UCHAR_MAX) value = UCHAR_MAX;
1166 if (value < 0) value = 0; 1151 if (value < 0) value = 0;
1167 return value; 1152 return value;
1168 } 1153 }
1169 1154
1194 input = (input * 80.0) - 80.0; 1179 input = (input * 80.0) - 80.0;
1195 input = powf(10.0, input) / 20.0; 1180 input = powf(10.0, input) / 20.0;
1196 value = int(input); 1181 value = int(input);
1197 break; 1182 break;
1198 1183
1199 case OtherColourScale: 1184 case dBSquaredColourScale:
1200 input = float(value - 1) / 255.0; 1185 input = float(value - 1) / 255.0;
1201 input = (input * 80.0) - 80.0; 1186 input = (input * 80.0) - 80.0;
1202 input = powf(10.0, input) / 20.0; 1187 input = powf(10.0, input) / 20.0;
1203 value = int(input); 1188 value = int(input);
1204 break; 1189 break;
2258 2243
2259 bool 2244 bool
2260 SpectrogramLayer::getValueExtents(float &min, float &max, 2245 SpectrogramLayer::getValueExtents(float &min, float &max,
2261 bool &logarithmic, QString &unit) const 2246 bool &logarithmic, QString &unit) const
2262 { 2247 {
2263 //!!!
2264 // min = getEffectiveMinFrequency();
2265 // max = getEffectiveMaxFrequency();
2266
2267 if (!m_model) return false; 2248 if (!m_model) return false;
2268 2249
2269 int sr = m_model->getSampleRate(); 2250 int sr = m_model->getSampleRate();
2270 min = float(sr) / m_fftSize; 2251 min = float(sr) / m_fftSize;
2271 max = float(sr) / 2; 2252 max = float(sr) / 2;
2509 { 2490 {
2510 int cw; 2491 int cw;
2511 2492
2512 cw = paint.fontMetrics().width("-80dB"); 2493 cw = paint.fontMetrics().width("-80dB");
2513 2494
2514 /*!!!
2515 switch (m_colourScale) {
2516 default:
2517 case LinearColourScale:
2518 cw = paint.fontMetrics().width(QString("0.00"));
2519 break;
2520
2521 case MeterColourScale:
2522 case dBColourScale:
2523 case OtherColourScale:
2524 cw = std::max(paint.fontMetrics().width(tr("-Inf")),
2525 paint.fontMetrics().width(tr("-90")));
2526 break;
2527
2528 case PhaseColourScale:
2529 cw = paint.fontMetrics().width(QString("-") + QChar(0x3c0));
2530 break;
2531 }
2532 */
2533
2534
2535 return cw; 2495 return cw;
2536 } 2496 }
2537 2497
2538 int 2498 int
2539 SpectrogramLayer::getVerticalScaleWidth(View *v, QPainter &paint) const 2499 SpectrogramLayer::getVerticalScaleWidth(View *v, QPainter &paint) const
2594 int ch = h - textHeight * (topLines + 1) - 8; 2554 int ch = h - textHeight * (topLines + 1) - 8;
2595 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1); 2555 // paint.drawRect(4, textHeight + 4, cw - 1, ch + 1);
2596 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1); 2556 paint.drawRect(4 + cw - cbw, textHeight * topLines + 4, cbw - 1, ch + 1);
2597 2557
2598 QString top, bottom; 2558 QString top, bottom;
2599 /*!!!
2600 switch (m_colourScale) {
2601 default:
2602 case LinearColourScale:
2603 top = (m_normalizeColumns ? "1.0" : "0.02");
2604 bottom = (m_normalizeColumns ? "0.0" : "0.00");
2605 break;
2606
2607 case MeterColourScale:
2608 top = (m_normalizeColumns ? QString("0") :
2609 QString("%1").arg(int(AudioLevel::multiplier_to_dB(0.02))));
2610 bottom = QString("%1").
2611 arg(int(AudioLevel::multiplier_to_dB
2612 (AudioLevel::preview_to_multiplier(0, 255))));
2613 break;
2614
2615 case dBColourScale:
2616 case OtherColourScale:
2617 top = "0";
2618 bottom = "-80";
2619 break;
2620
2621 case PhaseColourScale:
2622 top = QChar(0x3c0);
2623 bottom = "-" + top;
2624 break;
2625 }
2626 */
2627 float min = m_viewMags[v].getMin(); 2559 float min = m_viewMags[v].getMin();
2628 float max = m_viewMags[v].getMax(); 2560 float max = m_viewMags[v].getMax();
2629 2561
2630 float dBmin = AudioLevel::multiplier_to_dB(min); 2562 float dBmin = AudioLevel::multiplier_to_dB(min);
2631 float dBmax = AudioLevel::multiplier_to_dB(max); 2563 float dBmax = AudioLevel::multiplier_to_dB(max);
2661 float dBval = dBmin + (((dBmax - dBmin) * i) / (ch - 1)); 2593 float dBval = dBmin + (((dBmax - dBmin) * i) / (ch - 1));
2662 int idb = int(dBval); 2594 int idb = int(dBval);
2663 2595
2664 float value = AudioLevel::dB_to_multiplier(dBval); 2596 float value = AudioLevel::dB_to_multiplier(dBval);
2665 int colour = getDisplayValue(v, value * m_gain); 2597 int colour = getDisplayValue(v, value * m_gain);
2666 /* 2598
2667 float value = min + (((max - min) * i) / (ch - 1));
2668 if (value < m_threshold) value = 0.f;
2669 int colour = getDisplayValue(v, value * m_gain);
2670 */
2671 /*
2672 int colour = (i * 255) / ch + 1;
2673 */
2674 paint.setPen(m_palette.getColour(colour)); 2599 paint.setPen(m_palette.getColour(colour));
2675 2600
2676 int y = textHeight * topLines + 4 + ch - i; 2601 int y = textHeight * topLines + 4 + ch - i;
2677 2602
2678 paint.drawLine(5 + cw - cbw, y, cw + 2, y); 2603 paint.drawLine(5 + cw - cbw, y, cw + 2, y);
2679
2680 // paint.drawLine(5, 4 + textHeight + ch - i,
2681 // cw + 2, 4 + textHeight + ch - i);
2682
2683 2604
2684 if (i == 0) { 2605 if (i == 0) {
2685 lasty = y; 2606 lasty = y;
2686 lastdb = idb; 2607 lastdb = idb;
2687 } else if (i < ch - paint.fontMetrics().ascent() && 2608 } else if (i < ch - paint.fontMetrics().ascent() &&
2799 2720
2800 class SpectrogramRangeMapper : public RangeMapper 2721 class SpectrogramRangeMapper : public RangeMapper
2801 { 2722 {
2802 public: 2723 public:
2803 SpectrogramRangeMapper(int sr, int fftsize) : 2724 SpectrogramRangeMapper(int sr, int fftsize) :
2804 // m_dist((float(sr) / 2) - (float(sr) / fftsize)),
2805 m_dist(float(sr) / 2), 2725 m_dist(float(sr) / 2),
2806 m_s2(sqrtf(sqrtf(2))) { } 2726 m_s2(sqrtf(sqrtf(2))) { }
2807 ~SpectrogramRangeMapper() { } 2727 ~SpectrogramRangeMapper() { }
2808 2728
2809 virtual int getPositionForValue(float value) const { 2729 virtual int getPositionForValue(float value) const {