Mercurial > hg > svgui
comparison layer/SpectrumLayer.cpp @ 1282:f90a3c2f2930
Merge from branch horizontal-scale
author | Chris Cannam |
---|---|
date | Thu, 03 May 2018 15:24:14 +0100 |
parents | fc9d9f1103fa |
children | d79e21855aef |
comparison
equal
deleted
inserted
replaced
1279:a04f1012fca2 | 1282:f90a3c2f2930 |
---|---|
23 #include "base/Pitch.h" | 23 #include "base/Pitch.h" |
24 #include "base/Strings.h" | 24 #include "base/Strings.h" |
25 | 25 |
26 #include "ColourMapper.h" | 26 #include "ColourMapper.h" |
27 #include "PaintAssistant.h" | 27 #include "PaintAssistant.h" |
28 #include "PianoScale.h" | |
29 #include "HorizontalFrequencyScale.h" | |
28 | 30 |
29 #include <QPainter> | 31 #include <QPainter> |
30 #include <QTextStream> | 32 #include <QTextStream> |
31 | 33 |
32 | 34 |
300 double | 302 double |
301 SpectrumLayer::getFrequencyForX(const LayerGeometryProvider *v, double x) const | 303 SpectrumLayer::getFrequencyForX(const LayerGeometryProvider *v, double x) const |
302 { | 304 { |
303 if (!m_sliceableModel) return 0; | 305 if (!m_sliceableModel) return 0; |
304 double bin = getBinForX(v, x); | 306 double bin = getBinForX(v, x); |
307 // we assume the frequency of a bin corresponds to the centre of | |
308 // its visual range | |
309 bin -= 0.5; | |
305 return (m_sliceableModel->getSampleRate() * bin) / | 310 return (m_sliceableModel->getSampleRate() * bin) / |
306 (m_sliceableModel->getHeight() * 2); | 311 (m_sliceableModel->getHeight() * 2); |
307 } | 312 } |
308 | 313 |
309 double | 314 double |
310 SpectrumLayer::getXForFrequency(const LayerGeometryProvider *v, double freq) const | 315 SpectrumLayer::getXForFrequency(const LayerGeometryProvider *v, double freq) const |
311 { | 316 { |
312 if (!m_sliceableModel) return 0; | 317 if (!m_sliceableModel) return 0; |
313 double bin = (freq * m_sliceableModel->getHeight() * 2) / | 318 double bin = (freq * m_sliceableModel->getHeight() * 2) / |
314 m_sliceableModel->getSampleRate(); | 319 m_sliceableModel->getSampleRate(); |
320 // we want the centre of the bin range | |
321 bin += 0.5; | |
315 return getXForBin(v, bin); | 322 return getXForBin(v, bin); |
316 } | 323 } |
317 | 324 |
318 bool | 325 bool |
319 SpectrumLayer::getXScaleValue(const LayerGeometryProvider *v, int x, | 326 SpectrumLayer::getXScaleValue(const LayerGeometryProvider *v, int x, |
596 (const_cast<DenseThreeDimensionalModel *>(m_sliceableModel)); | 603 (const_cast<DenseThreeDimensionalModel *>(m_sliceableModel)); |
597 | 604 |
598 double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj | 605 double thresh = (pow(10, -6) / m_gain) * (m_windowSize / 2.0); // -60dB adj |
599 | 606 |
600 int xorigin = getVerticalScaleWidth(v, false, paint) + 1; | 607 int xorigin = getVerticalScaleWidth(v, false, paint) + 1; |
601 int w = v->getPaintWidth() - xorigin - 1; | 608 int scaleHeight = getHorizontalScaleHeight(v, paint); |
602 | |
603 int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5); | |
604 if (pkh < 10) pkh = 10; | |
605 | |
606 paint.save(); | |
607 | 609 |
608 if (fft && m_showPeaks) { | 610 if (fft && m_showPeaks) { |
609 | 611 |
610 // draw peak lines | 612 // draw peak lines |
611 | |
612 // SVDEBUG << "Showing peaks..." << endl; | |
613 | 613 |
614 int col = int(v->getCentreFrame() / fft->getResolution()); | 614 int col = int(v->getCentreFrame() / fft->getResolution()); |
615 | 615 |
616 paint.save(); | 616 paint.save(); |
617 paint.setRenderHint(QPainter::Antialiasing, false); | 617 paint.setRenderHint(QPainter::Antialiasing, false); |
618 paint.setPen(QColor(160, 160, 160)); //!!! | 618 |
619 | 619 ColourMapper mapper = |
620 hasLightBackground() ? | |
621 ColourMapper(ColourMapper::BlackOnWhite, 0, 1) : | |
622 ColourMapper(ColourMapper::WhiteOnBlack, 0, 1); | |
623 | |
620 int peakminbin = 0; | 624 int peakminbin = 0; |
621 int peakmaxbin = fft->getHeight() - 1; | 625 int peakmaxbin = fft->getHeight() - 1; |
622 double peakmaxfreq = Pitch::getFrequencyForPitch(128); | 626 double peakmaxfreq = Pitch::getFrequencyForPitch(128); |
623 peakmaxbin = int(((peakmaxfreq * fft->getHeight() * 2) / fft->getSampleRate())); | 627 peakmaxbin = int(((peakmaxfreq * fft->getHeight() * 2) / fft->getSampleRate())); |
624 | 628 |
625 FFTModel::PeakSet peaks = fft->getPeakFrequencies | 629 FFTModel::PeakSet peaks = fft->getPeakFrequencies |
626 (FFTModel::MajorPitchAdaptivePeaks, col, peakminbin, peakmaxbin); | 630 (FFTModel::MajorPitchAdaptivePeaks, col, peakminbin, peakmaxbin); |
627 | 631 |
628 ColourMapper mapper(ColourMapper::BlackOnWhite, 0, 1); | |
629 | |
630 BiasCurve curve; | 632 BiasCurve curve; |
631 getBiasCurve(curve); | 633 getBiasCurve(curve); |
632 int cs = int(curve.size()); | 634 int cs = int(curve.size()); |
633 | 635 |
634 std::vector<double> values; | 636 std::vector<double> values; |
654 | 656 |
655 double norm = 0.f; | 657 double norm = 0.f; |
656 (void)getYForValue(v, values[bin], norm); // don't need return value, need norm | 658 (void)getYForValue(v, values[bin], norm); // don't need return value, need norm |
657 | 659 |
658 paint.setPen(mapper.map(norm)); | 660 paint.setPen(mapper.map(norm)); |
659 paint.drawLine(x, 0, x, v->getPaintHeight() - scaleh - pkh - 1); | 661 paint.drawLine(x, 0, x, v->getPaintHeight() - scaleHeight - 1); |
660 } | 662 } |
661 | 663 |
662 paint.restore(); | 664 paint.restore(); |
663 } | 665 } |
664 | 666 |
667 paint.save(); | |
668 | |
665 SliceLayer::paint(v, paint, rect); | 669 SliceLayer::paint(v, paint, rect); |
666 | 670 |
671 paintHorizontalScale(v, paint, xorigin); | |
672 | |
673 paint.restore(); | |
674 } | |
675 | |
676 int | |
677 SpectrumLayer::getHorizontalScaleHeight(LayerGeometryProvider *v, | |
678 QPainter &paint) const | |
679 { | |
680 int pkh = int(paint.fontMetrics().height() * 0.7 + 0.5); | |
681 if (pkh < 10) pkh = 10; | |
682 | |
683 int scaleh = HorizontalFrequencyScale().getHeight(v, paint); | |
684 | |
685 return pkh + scaleh; | |
686 } | |
687 | |
688 void | |
689 SpectrumLayer::paintHorizontalScale(LayerGeometryProvider *v, | |
690 QPainter &paint, | |
691 int xorigin) const | |
692 { | |
667 //!!! All of this stuff relating to depicting frequencies | 693 //!!! All of this stuff relating to depicting frequencies |
668 // (keyboard, crosshairs etc) should be applicable to any slice | 694 // (keyboard, crosshairs etc) should be applicable to any slice |
669 // layer whose model has a vertical scale unit of Hz. However, | 695 // layer whose model has a vertical scale unit of Hz. However, |
670 // the dense 3d model at the moment doesn't record its vertical | 696 // the dense 3d model at the moment doesn't record its vertical |
671 // scale unit -- we need to fix that and hoist this code as | 697 // scale unit -- we need to fix that and hoist this code as |
672 // appropriate. Same really goes for any code in SpectrogramLayer | 698 // appropriate. Same really goes for any code in SpectrogramLayer |
673 // that could be relevant to Colour3DPlotLayer with unit Hz, but | 699 // that could be relevant to Colour3DPlotLayer with unit Hz, but |
674 // that's a bigger proposition. | 700 // that's a bigger proposition. |
675 | 701 |
676 int h = v->getPaintHeight(); | 702 if (!v->getViewManager()->shouldShowHorizontalValueScale()) { |
703 return; | |
704 } | |
705 | |
706 int totalScaleHeight = getHorizontalScaleHeight(v, paint); // inc piano | |
707 int freqScaleHeight = HorizontalFrequencyScale().getHeight(v, paint); | |
708 int paintHeight = v->getPaintHeight(); | |
709 int paintWidth = v->getPaintWidth(); | |
677 | 710 |
678 PianoScale().paintPianoHorizontal | 711 PianoScale().paintPianoHorizontal |
679 (v, this, paint, QRect(xorigin, h - pkh - 1, w + xorigin, pkh)); | 712 (v, this, paint, |
680 | 713 QRect(xorigin, paintHeight - totalScaleHeight - 1, |
681 paint.restore(); | 714 paintWidth - 1, totalScaleHeight - freqScaleHeight)); |
715 | |
716 int scaleLeft = int(getXForBin(v, 1)); | |
717 | |
718 paint.drawLine(int(getXForBin(v, 0)), paintHeight - freqScaleHeight, | |
719 scaleLeft, paintHeight - freqScaleHeight); | |
720 | |
721 QString hz = tr("Hz"); | |
722 int hzw = paint.fontMetrics().width(hz); | |
723 if (scaleLeft > hzw + 5) { | |
724 paint.drawText | |
725 (scaleLeft - hzw - 5, | |
726 paintHeight - freqScaleHeight + paint.fontMetrics().ascent() + 5, | |
727 hz); | |
728 } | |
729 | |
730 HorizontalFrequencyScale().paintScale | |
731 (v, this, paint, | |
732 QRect(scaleLeft, paintHeight - freqScaleHeight, | |
733 paintWidth, totalScaleHeight), | |
734 m_binScale == LogBins); | |
682 } | 735 } |
683 | 736 |
684 void | 737 void |
685 SpectrumLayer::getBiasCurve(BiasCurve &curve) const | 738 SpectrumLayer::getBiasCurve(BiasCurve &curve) const |
686 { | 739 { |