f@0: #pragma once f@0: #include "IControl.h" f@0: f@0: #include f@0: f@0: class FreqView : public IControl f@0: { f@0: f@0: int mNumBins; f@0: std::vector mBins; f@0: std::vector mPeaks; f@0: double mSampleRate; f@0: double mHalfSampleRate; f@0: double mDecayAmount; f@0: double mSelectionStart; f@0: double mSelectionSize; f@0: double mThreshold; f@0: f@0: IRECT mPad; f@0: f@0: public: f@0: f@0: static const double kPeakDecayRate; f@0: static const double kMaxPeakDB; f@0: static const double kZeroDbY; f@0: static const IColor kGridColor; f@0: static const IColor kBgColor; f@0: static const IColor kPadColor; f@0: static const IChannelBlend kSelectionBlend; f@0: f@0: FreqView(IPlugBase *pPlug, IRECT pR, int numBins) : f@0: IControl(pPlug, pR), f@0: mGrid(*this), f@0: mNumBins(numBins), f@0: mBins(numBins, 0.0f), f@0: mPeaks(numBins, 0.0f), f@0: mSelectionStart(0), f@0: mSelectionSize(1), f@0: mSampleRate(44100), f@0: mHalfSampleRate(44100/2), f@0: mPad(pR.GetPadded(4)) f@0: f@0: { } f@0: f@0: ~FreqView(){} f@0: f@0: bool Draw(IGraphics* pGraphics) override f@0: { f@0: f@0: pGraphics->FillIRect(&kPadColor, &mPad); f@0: pGraphics->FillIRect(&kBgColor, &mRECT); f@0: f@0: /* draw grid */ f@0: mGrid.Draw(pGraphics); f@0: f@0: /* draw the frequency scope */ f@0: for (int i = 1; i < mNumBins; i++){ f@0: //DrawBin(pGraphics, i); f@0: f@0: int x1 = mRECT.L + (float(i-1) / mNumBins * mRECT.W()); f@0: int x2 = mRECT.L + (float(i) / mNumBins * mRECT.W()); f@0: f@0: /* max between new peak and old peak decay wins */ f@0: mPeaks[i] = IPMAX(AmpToMeter(mBins[i], kMaxPeakDB) , mPeaks[i] - mDecayAmount); f@0: f@0: int y1 = mRECT.T + (mRECT.H() * (1 - mPeaks[i-1])); f@0: int y2 = mRECT.T + (mRECT.H() * (1 - mPeaks[i])); f@0: f@0: f@0: pGraphics->DrawLine(&COLOR_WHITE, x1, y1, x2, y2 ); f@0: } f@0: f@0: /* draw the selection */ f@0: //pGraphics->DrawVerticalLine(&COLOR_GREEN, mRECT.L + (mRECT.W() * (mSelectionStart/mHalfSampleRate)) , mRECT.B, mRECT.T); f@0: int left = mRECT.L + (mRECT.W() * (mSelectionStart/mHalfSampleRate)); f@0: int right = left + (mRECT.W() * (mSelectionSize/mHalfSampleRate)); f@0: int top = mRECT.T + (mRECT.H() * (1 - DbToMeter(mThreshold, kMaxPeakDB))); f@0: f@0: IRECT selRect(left , top, right, mRECT.B); f@0: IRECT peakRect(left, mRECT.T, right, top); f@0: f@0: pGraphics->FillIRect(&COLOR_GREEN, &selRect, &kSelectionBlend); f@0: pGraphics->FillIRect(&COLOR_RED, &peakRect, &kSelectionBlend); f@0: f@0: return true; f@0: } f@0: f@0: f@0: f@0: bool IsDirty() override f@0: { f@0: return true; f@0: } f@0: f@0: static double AmpToMeter(double amplitudeVal, double maxDB) f@0: { f@0: double db; f@0: if (amplitudeVal > 0) f@0: db = ::AmpToDB(amplitudeVal); f@0: else f@0: db = -999; f@0: return BOUNDED((db + 60) / maxDB, 0, 1); f@0: } f@0: f@0: static double DbToMeter(double dbVal, double maxDB) f@0: { f@0: return BOUNDED((dbVal + 60) / maxDB, 0, 1); f@0: } f@0: f@0: void setBins(float * compBins) f@0: { f@0: for (int i = 0; i < mNumBins; i++){ f@0: mBins[i] = compBins[i]; f@0: } f@0: SetDirty(false); f@0: Redraw(); f@0: } f@0: f@0: inline void setSelectionStart(double startHz) f@0: { f@0: mSelectionStart = startHz; f@0: } f@0: f@0: inline double getSelectionStart() const f@0: { f@0: return mSelectionStart; f@0: } f@0: f@0: inline void setSelectionSize(double sizeHz) f@0: { f@0: mSelectionSize = sizeHz; f@0: } f@0: f@0: inline double getSelectionSize() const f@0: { f@0: return mSelectionSize; f@0: } f@0: f@0: inline void setThreshold(double thresDb) f@0: { f@0: mThreshold = thresDb; f@0: } f@0: f@0: inline void setSampleRate(double sampleRate) f@0: { f@0: mSampleRate = sampleRate; f@0: mHalfSampleRate = sampleRate/2; f@0: const double deltaT = mNumBins / sampleRate; f@0: mDecayAmount = deltaT * kPeakDecayRate; f@0: f@0: /* reset selection with the new sampling rate */ f@0: setSelectionStart(mSelectionStart); f@0: setSelectionSize(mSelectionSize); f@0: } f@0: f@0: f@0: class Grid f@0: { f@0: /* const reference to enclosing class */ f@0: const FreqView & mView; f@0: std::vector mHlines; f@0: public: f@0: f@0: static const IColor kZeroDbLineColor; f@0: f@0: Grid(const FreqView &v ): mView(v) f@0: { f@0: for (int db=-60; dbDrawHorizontalLine(&FreqView::kGridColor, l, r.L, r.R); f@0: } f@0: f@0: /* draw vertical lines */ f@0: for(int i=1000; iDrawVerticalLine(&kGridColor, x , r.T, r.B); f@0: } f@0: f@0: /* draw the 0 dB horiz line */ f@0: pGraphics->DrawHorizontalLine(&kZeroDbLineColor, r.B - (r.H() * FreqView::kZeroDbY), r.L, r.R ); f@0: f@0: } f@0: f@0: } mGrid; f@0: }; f@0: