Mercurial > hg > svgui
comparison layer/SliceLayer.cpp @ 197:6b023411087b
* Work on harmonising colour and scale ranges between types of layer
* Add normalize options to colour 3d plot layer
| author | Chris Cannam | 
|---|---|
| date | Thu, 01 Feb 2007 14:31:28 +0000 | 
| parents | 4a3bdde1ef13 | 
| children | c2ed5014d4ff | 
   comparison
  equal
  deleted
  inserted
  replaced
| 196:22c99c8aa1e0 | 197:6b023411087b | 
|---|---|
| 19 #include "view/View.h" | 19 #include "view/View.h" | 
| 20 #include "base/AudioLevel.h" | 20 #include "base/AudioLevel.h" | 
| 21 #include "base/RangeMapper.h" | 21 #include "base/RangeMapper.h" | 
| 22 #include "base/RealTime.h" | 22 #include "base/RealTime.h" | 
| 23 | 23 | 
| 24 #include "ColourMapper.h" | |
| 24 #include "PaintAssistant.h" | 25 #include "PaintAssistant.h" | 
| 25 | 26 | 
| 26 #include <QPainter> | 27 #include <QPainter> | 
| 27 #include <QPainterPath> | 28 #include <QPainterPath> | 
| 28 | 29 | 
| 29 SliceLayer::SliceLayer() : | 30 SliceLayer::SliceLayer() : | 
| 30 m_sliceableModel(0), | 31 m_sliceableModel(0), | 
| 31 m_colour(Qt::darkBlue), | 32 m_colour(Qt::darkBlue), | 
| 33 m_colourMap(0), | |
| 32 m_energyScale(dBScale), | 34 m_energyScale(dBScale), | 
| 33 m_samplingMode(SamplePeak), | 35 m_samplingMode(SamplePeak), | 
| 34 m_plotStyle(PlotSteps), | 36 m_plotStyle(PlotSteps), | 
| 35 m_binScale(LinearBins), | 37 m_binScale(LinearBins), | 
| 36 m_normalize(false), | 38 m_normalize(false), | 
| 173 } | 175 } | 
| 174 | 176 | 
| 175 float py = 0; | 177 float py = 0; | 
| 176 float nx = xorigin; | 178 float nx = xorigin; | 
| 177 | 179 | 
| 180 ColourMapper mapper(m_colourMap, 0, 1); | |
| 181 | |
| 178 for (size_t bin = 0; bin < mh; ++bin) { | 182 for (size_t bin = 0; bin < mh; ++bin) { | 
| 179 | 183 | 
| 180 float x; | 184 float x; | 
| 181 | 185 | 
| 182 switch (m_binScale) { | 186 switch (m_binScale) { | 
| 200 } | 204 } | 
| 201 | 205 | 
| 202 float value = values[bin]; | 206 float value = values[bin]; | 
| 203 | 207 | 
| 204 value *= m_gain; | 208 value *= m_gain; | 
| 209 float norm = 0.f; | |
| 205 float y = 0.f; | 210 float y = 0.f; | 
| 206 | 211 | 
| 207 switch (m_energyScale) { | 212 switch (m_energyScale) { | 
| 208 | 213 | 
| 209 case dBScale: | 214 case dBScale: | 
| 210 { | 215 { | 
| 211 float db = thresh; | 216 float db = thresh; | 
| 212 if (value > 0.f) db = 10.f * log10f(value); | 217 if (value > 0.f) db = 10.f * log10f(value); | 
| 213 if (db < thresh) db = thresh; | 218 if (db < thresh) db = thresh; | 
| 214 float val = (db - thresh) / -thresh; | 219 norm = (db - thresh) / -thresh; | 
| 215 y = yorigin - (float(h) * val); | 220 y = yorigin - (float(h) * norm); | 
| 216 break; | 221 break; | 
| 217 } | 222 } | 
| 218 | 223 | 
| 219 case MeterScale: | 224 case MeterScale: | 
| 220 y = yorigin - AudioLevel::multiplier_to_preview(value, h); | 225 y = AudioLevel::multiplier_to_preview(value, h); | 
| 226 norm = float(y) / float(h); | |
| 227 y = yorigin - y; | |
| 221 break; | 228 break; | 
| 222 | 229 | 
| 223 default: | 230 default: | 
| 231 norm = value; | |
| 224 y = yorigin - (float(h) * value); | 232 y = yorigin - (float(h) * value); | 
| 225 break; | 233 break; | 
| 226 } | 234 } | 
| 227 | 235 | 
| 228 if (m_plotStyle == PlotLines) { | 236 if (m_plotStyle == PlotLines) { | 
| 247 path.moveTo(x, yorigin); | 255 path.moveTo(x, yorigin); | 
| 248 path.lineTo(x, y); | 256 path.lineTo(x, y); | 
| 249 path.lineTo(nx, y); | 257 path.lineTo(nx, y); | 
| 250 path.lineTo(nx, yorigin); | 258 path.lineTo(nx, yorigin); | 
| 251 path.lineTo(x, yorigin); | 259 path.lineTo(x, yorigin); | 
| 260 | |
| 261 } else if (m_plotStyle == PlotFilledBlocks) { | |
| 262 | |
| 263 paint.fillRect(QRectF(x, y, nx - x, yorigin - y), mapper.map(norm)); | |
| 252 } | 264 } | 
| 253 | 265 | 
| 254 py = y; | 266 py = y; | 
| 255 } | 267 } | 
| 256 | 268 | 
| 257 paint.drawPath(path); | 269 if (m_plotStyle != PlotFilledBlocks) { | 
| 270 paint.drawPath(path); | |
| 271 } | |
| 258 paint.restore(); | 272 paint.restore(); | 
| 259 | 273 | 
| 260 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount()) { | 274 QPoint discard; | 
| 275 | |
| 276 if (v->getViewManager() && v->getViewManager()->shouldShowFrameCount() && | |
| 277 v->shouldIlluminateLocalFeatures(this, discard)) { | |
| 261 | 278 | 
| 262 int sampleRate = m_sliceableModel->getSampleRate(); | 279 int sampleRate = m_sliceableModel->getSampleRate(); | 
| 263 | 280 | 
| 264 QString startText = QString("%1 / %2") | 281 QString startText = QString("%1 / %2") | 
| 265 .arg(QString::fromStdString | 282 .arg(QString::fromStdString | 
| 433 | 450 | 
| 434 deft = (m_normalize ? 1 : 0); | 451 deft = (m_normalize ? 1 : 0); | 
| 435 | 452 | 
| 436 } else if (name == "Colour") { | 453 } else if (name == "Colour") { | 
| 437 | 454 | 
| 438 *min = 0; | 455 if (m_plotStyle == PlotFilledBlocks) { | 
| 439 *max = 5; | 456 | 
| 440 | 457 *min = 0; | 
| 441 if (m_colour == Qt::black) deft = 0; | 458 *max = ColourMapper::getColourMapCount() - 1; | 
| 442 else if (m_colour == Qt::darkRed) deft = 1; | 459 | 
| 443 else if (m_colour == Qt::darkBlue) deft = 2; | 460 deft = m_colourMap; | 
| 444 else if (m_colour == Qt::darkGreen) deft = 3; | 461 | 
| 445 else if (m_colour == QColor(200, 50, 255)) deft = 4; | 462 } else { | 
| 446 else if (m_colour == QColor(255, 150, 50)) deft = 5; | 463 | 
| 464 *min = 0; | |
| 465 *max = 5; | |
| 466 | |
| 467 if (m_colour == Qt::black) deft = 0; | |
| 468 else if (m_colour == Qt::darkRed) deft = 1; | |
| 469 else if (m_colour == Qt::darkBlue) deft = 2; | |
| 470 else if (m_colour == Qt::darkGreen) deft = 3; | |
| 471 else if (m_colour == QColor(200, 50, 255)) deft = 4; | |
| 472 else if (m_colour == QColor(255, 150, 50)) deft = 5; | |
| 473 } | |
| 447 | 474 | 
| 448 } else if (name == "Scale") { | 475 } else if (name == "Scale") { | 
| 449 | 476 | 
| 450 *min = 0; | 477 *min = 0; | 
| 451 *max = 2; | 478 *max = 2; | 
| 460 deft = (int)m_samplingMode; | 487 deft = (int)m_samplingMode; | 
| 461 | 488 | 
| 462 } else if (name == "Plot Type") { | 489 } else if (name == "Plot Type") { | 
| 463 | 490 | 
| 464 *min = 0; | 491 *min = 0; | 
| 465 *max = 2; | 492 *max = 3; | 
| 466 | 493 | 
| 467 deft = (int)m_plotStyle; | 494 deft = (int)m_plotStyle; | 
| 468 | 495 | 
| 469 } else if (name == "Bin Scale") { | 496 } else if (name == "Bin Scale") { | 
| 470 | 497 | 
| 471 *min = 0; | 498 *min = 0; | 
| 472 *max = 2; | 499 // *max = 2; | 
| 500 *max = 1; // I don't think we really do want to offer inverted log | |
| 473 | 501 | 
| 474 deft = (int)m_binScale; | 502 deft = (int)m_binScale; | 
| 475 | 503 | 
| 476 } else { | 504 } else { | 
| 477 deft = Layer::getPropertyRangeAndValue(name, min, max); | 505 deft = Layer::getPropertyRangeAndValue(name, min, max); | 
| 483 QString | 511 QString | 
| 484 SliceLayer::getPropertyValueLabel(const PropertyName &name, | 512 SliceLayer::getPropertyValueLabel(const PropertyName &name, | 
| 485 int value) const | 513 int value) const | 
| 486 { | 514 { | 
| 487 if (name == "Colour") { | 515 if (name == "Colour") { | 
| 488 switch (value) { | 516 if (m_plotStyle == PlotFilledBlocks) { | 
| 489 default: | 517 return ColourMapper::getColourMapName(value); | 
| 490 case 0: return tr("Black"); | 518 } else { | 
| 491 case 1: return tr("Red"); | 519 switch (value) { | 
| 492 case 2: return tr("Blue"); | 520 default: | 
| 493 case 3: return tr("Green"); | 521 case 0: return tr("Black"); | 
| 494 case 4: return tr("Purple"); | 522 case 1: return tr("Red"); | 
| 495 case 5: return tr("Orange"); | 523 case 2: return tr("Blue"); | 
| 524 case 3: return tr("Green"); | |
| 525 case 4: return tr("Purple"); | |
| 526 case 5: return tr("Orange"); | |
| 527 } | |
| 496 } | 528 } | 
| 497 } | 529 } | 
| 498 if (name == "Scale") { | 530 if (name == "Scale") { | 
| 499 switch (value) { | 531 switch (value) { | 
| 500 default: | 532 default: | 
| 515 switch (value) { | 547 switch (value) { | 
| 516 default: | 548 default: | 
| 517 case 0: return tr("Lines"); | 549 case 0: return tr("Lines"); | 
| 518 case 1: return tr("Steps"); | 550 case 1: return tr("Steps"); | 
| 519 case 2: return tr("Blocks"); | 551 case 2: return tr("Blocks"); | 
| 552 case 3: return tr("Colours"); | |
| 520 } | 553 } | 
| 521 } | 554 } | 
| 522 if (name == "Bin Scale") { | 555 if (name == "Bin Scale") { | 
| 523 switch (value) { | 556 switch (value) { | 
| 524 default: | 557 default: | 
| 543 SliceLayer::setProperty(const PropertyName &name, int value) | 576 SliceLayer::setProperty(const PropertyName &name, int value) | 
| 544 { | 577 { | 
| 545 if (name == "Gain") { | 578 if (name == "Gain") { | 
| 546 setGain(pow(10, float(value)/20.0)); | 579 setGain(pow(10, float(value)/20.0)); | 
| 547 } else if (name == "Colour") { | 580 } else if (name == "Colour") { | 
| 548 switch (value) { | 581 if (m_plotStyle == PlotFilledBlocks) { | 
| 549 default: | 582 setFillColourMap(value); | 
| 550 case 0: setBaseColour(Qt::black); break; | 583 } else { | 
| 551 case 1: setBaseColour(Qt::darkRed); break; | 584 switch (value) { | 
| 552 case 2: setBaseColour(Qt::darkBlue); break; | 585 default: | 
| 553 case 3: setBaseColour(Qt::darkGreen); break; | 586 case 0: setBaseColour(Qt::black); break; | 
| 554 case 4: setBaseColour(QColor(200, 50, 255)); break; | 587 case 1: setBaseColour(Qt::darkRed); break; | 
| 555 case 5: setBaseColour(QColor(255, 150, 50)); break; | 588 case 2: setBaseColour(Qt::darkBlue); break; | 
| 589 case 3: setBaseColour(Qt::darkGreen); break; | |
| 590 case 4: setBaseColour(QColor(200, 50, 255)); break; | |
| 591 case 5: setBaseColour(QColor(255, 150, 50)); break; | |
| 592 } | |
| 556 } | 593 } | 
| 557 } else if (name == "Scale") { | 594 } else if (name == "Scale") { | 
| 558 switch (value) { | 595 switch (value) { | 
| 559 default: | 596 default: | 
| 560 case 0: setEnergyScale(LinearScale); break; | 597 case 0: setEnergyScale(LinearScale); break; | 
| 589 m_colour = colour; | 626 m_colour = colour; | 
| 590 emit layerParametersChanged(); | 627 emit layerParametersChanged(); | 
| 591 } | 628 } | 
| 592 | 629 | 
| 593 void | 630 void | 
| 631 SliceLayer::setFillColourMap(int map) | |
| 632 { | |
| 633 if (m_colourMap == map) return; | |
| 634 m_colourMap = map; | |
| 635 emit layerParametersChanged(); | |
| 636 } | |
| 637 | |
| 638 void | |
| 594 SliceLayer::setEnergyScale(EnergyScale scale) | 639 SliceLayer::setEnergyScale(EnergyScale scale) | 
| 595 { | 640 { | 
| 596 if (m_energyScale == scale) return; | 641 if (m_energyScale == scale) return; | 
| 597 m_energyScale = scale; | 642 m_energyScale = scale; | 
| 598 emit layerParametersChanged(); | 643 emit layerParametersChanged(); | 
| 608 | 653 | 
| 609 void | 654 void | 
| 610 SliceLayer::setPlotStyle(PlotStyle style) | 655 SliceLayer::setPlotStyle(PlotStyle style) | 
| 611 { | 656 { | 
| 612 if (m_plotStyle == style) return; | 657 if (m_plotStyle == style) return; | 
| 658 bool colourTypeChanged = (style == PlotFilledBlocks || | |
| 659 m_plotStyle == PlotFilledBlocks); | |
| 613 m_plotStyle = style; | 660 m_plotStyle = style; | 
| 661 if (colourTypeChanged) { | |
| 662 emit layerParameterRangesChanged(); | |
| 663 } | |
| 614 emit layerParametersChanged(); | 664 emit layerParametersChanged(); | 
| 615 } | 665 } | 
| 616 | 666 | 
| 617 void | 667 void | 
| 618 SliceLayer::setBinScale(BinScale scale) | 668 SliceLayer::setBinScale(BinScale scale) | 
| 642 SliceLayer::toXmlString(QString indent, QString extraAttributes) const | 692 SliceLayer::toXmlString(QString indent, QString extraAttributes) const | 
| 643 { | 693 { | 
| 644 QString s; | 694 QString s; | 
| 645 | 695 | 
| 646 s += QString("colour=\"%1\" " | 696 s += QString("colour=\"%1\" " | 
| 647 "energyScale=\"%2\" " | 697 "colourScheme=\"%2\" " | 
| 648 "samplingMode=\"%3\" " | 698 "energyScale=\"%3\" " | 
| 649 "gain=\"%4\" " | 699 "samplingMode=\"%4\" " | 
| 650 "normalize=\"%5\"") | 700 "gain=\"%5\" " | 
| 701 "normalize=\"%6\"") | |
| 651 .arg(encodeColour(m_colour)) | 702 .arg(encodeColour(m_colour)) | 
| 703 .arg(m_colourMap) | |
| 652 .arg(m_energyScale) | 704 .arg(m_energyScale) | 
| 653 .arg(m_samplingMode) | 705 .arg(m_samplingMode) | 
| 654 .arg(m_gain) | 706 .arg(m_gain) | 
| 655 .arg(m_normalize ? "true" : "false"); | 707 .arg(m_normalize ? "true" : "false"); | 
| 656 | 708 | 
| 676 | 728 | 
| 677 SamplingMode mode = (SamplingMode) | 729 SamplingMode mode = (SamplingMode) | 
| 678 attributes.value("samplingMode").toInt(&ok); | 730 attributes.value("samplingMode").toInt(&ok); | 
| 679 if (ok) setSamplingMode(mode); | 731 if (ok) setSamplingMode(mode); | 
| 680 | 732 | 
| 733 int colourMap = attributes.value("colourScheme").toInt(&ok); | |
| 734 if (ok) setFillColourMap(colourMap); | |
| 735 | |
| 681 float gain = attributes.value("gain").toFloat(&ok); | 736 float gain = attributes.value("gain").toFloat(&ok); | 
| 682 if (ok) setGain(gain); | 737 if (ok) setGain(gain); | 
| 683 | 738 | 
| 684 bool normalize = (attributes.value("normalize").trimmed() == "true"); | 739 bool normalize = (attributes.value("normalize").trimmed() == "true"); | 
| 685 setNormalize(normalize); | 740 setNormalize(normalize); | 
