Audacity 3.2.0
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
MeterPanel Class Referencefinal

MeterPanel is a panel that paints the meter used for monitoring or playback. More...

#include <MeterPanel.h>

Inheritance diagram for MeterPanel:
[legend]
Collaboration diagram for MeterPanel:
[legend]

Classes

struct  State
 

Public Types

enum  Style {
  AutomaticStereo , HorizontalStereo , VerticalStereo , MixerTrackCluster ,
  HorizontalStereoCompact , VerticalStereoCompact
}
 

Public Member Functions

 MeterPanel (AudacityProject *, wxWindow *parent, wxWindowID id, bool isInput, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, Style style=HorizontalStereo, float fDecayRate=60.0f)
 
void SetFocusFromKbd () override
 
void Clear () override
 
Style GetStyle () const
 
Style GetDesiredStyle () const
 
void SetStyle (Style newStyle)
 
void Reset (double sampleRate, bool resetClipping) override
 This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callback). More...
 
void UpdateDisplay (unsigned numChannels, int numFrames, const float *sampleData) override
 Update the meters with a block of audio data. More...
 
bool IsMeterDisabled () const override
 Find out if the level meter is disabled or not. More...
 
float GetMaxPeak () const override
 
float GetPeakHold () const
 
bool IsMonitoring () const
 
bool IsActive () const
 
bool IsClipping () const override
 
void StartMonitoring ()
 
void StopMonitoring ()
 
State SaveState ()
 
void RestoreState (const State &state)
 
void SetMixer (wxCommandEvent &event)
 
int GetDBRange () const override
 
bool ShowDialog ()
 
void Increase (float steps)
 
void Decrease (float steps)
 
void UpdateSliderControl ()
 
void ShowMenu (const wxPoint &pos)
 
void SetName (const TranslatableString &name)
 
- Public Member Functions inherited from MeterPanelBase
 ~MeterPanelBase () override
 
template<typename ... Args>
 MeterPanelBase (Args &&...args)
 
std::shared_ptr< MeterGetMeter () const
 
virtual void Clear ()=0
 
virtual void Reset (double sampleRate, bool resetClipping)=0
 
virtual void UpdateDisplay (unsigned numChannels, int numFrames, const float *sampleData)=0
 
virtual bool IsMeterDisabled () const =0
 
virtual float GetMaxPeak () const =0
 
virtual bool IsClipping () const =0
 
virtual int GetDBRange () const =0
 
 wxPanelWrapper ()
 
 wxPanelWrapper (wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL|wxNO_BORDER, const TranslatableString &name=XO("Panel"))
 
- Public Member Functions inherited from wxPanelWrapper
 wxPanelWrapper ()
 
 wxPanelWrapper (wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL|wxNO_BORDER, const TranslatableString &name=XO("Panel"))
 
bool Create (wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL|wxNO_BORDER, const TranslatableString &name=XO("Panel"))
 
void SetLabel (const TranslatableString &label)
 
void SetName (const TranslatableString &name)
 
void SetToolTip (const TranslatableString &toolTip)
 
void SetName ()
 
- Public Member Functions inherited from wxTabTraversalWrapper< wxPanel >
 wxTabTraversalWrapper (Args &&... args)
 
 wxTabTraversalWrapper (const wxTabTraversalWrapper &)=delete
 
 wxTabTraversalWrapper (wxTabTraversalWrapper &&)=delete
 
wxTabTraversalWrapperoperator= (const wxTabTraversalWrapper &)=delete
 
wxTabTraversalWrapperoperator= (wxTabTraversalWrapper &&)=delete
 

Private Member Functions

void UpdatePrefs () override
 
void UpdateSelectedPrefs (int) override
 
void OnErase (wxEraseEvent &evt)
 
void OnPaint (wxPaintEvent &evt)
 
void OnSize (wxSizeEvent &evt)
 
void OnMouse (wxMouseEvent &evt)
 
void OnKeyDown (wxKeyEvent &evt)
 
void OnCharHook (wxKeyEvent &evt)
 
void OnContext (wxContextMenuEvent &evt)
 
void OnSetFocus (wxFocusEvent &evt)
 
void OnKillFocus (wxFocusEvent &evt)
 
void OnAudioIOStatus (AudioIOEvent)
 
void OnAudioCapture (AudioIOEvent)
 
void OnMeterUpdate (wxTimerEvent &evt)
 
void OnTipTimeout (wxTimerEvent &evt)
 
void HandleLayout (wxDC &dc)
 
void SetActiveStyle (Style style)
 
void SetBarAndClip (int iBar, bool vert)
 
void DrawMeterBar (wxDC &dc, MeterBar *meterBar)
 
void ResetBar (MeterBar *bar, bool resetClipping)
 
void RepaintBarsNow ()
 
wxFont GetFont () const
 
void OnMonitor (wxCommandEvent &evt)
 
void OnPreferences (wxCommandEvent &evt)
 
wxString Key (const wxString &key) const
 
- Private Member Functions inherited from PrefsListener
 PrefsListener ()
 
virtual ~PrefsListener ()
 
virtual void UpdatePrefs ()=0
 
virtual void UpdateSelectedPrefs (int id)
 

Private Attributes

Observer::Subscription mAudioIOStatusSubscription
 
Observer::Subscription mAudioCaptureSubscription
 
AudacityProjectmProject
 
MeterUpdateQueue mQueue
 
wxTimer mTimer
 
wxTimer mTipTimer
 
int mWidth
 
int mHeight
 
int mRulerWidth
 
int mRulerHeight
 
bool mIsInput
 
Style mStyle
 
Style mDesiredStyle
 
bool mGradient
 
bool mDB
 
int mDBRange
 
bool mDecay
 
float mDecayRate
 
bool mClip
 
int mNumPeakSamplesToClip
 
double mPeakHoldDuration
 
double mT
 
double mRate
 
long mMeterRefreshRate
 
long mMeterDisabled
 
bool mMonitoring
 
bool mActive
 
unsigned mNumBars
 
MeterBar mBar [kMaxMeterBars]
 
bool mLayoutValid
 
std::unique_ptr< wxBitmap > mBitmap
 
wxPoint mLeftTextPos
 
wxPoint mRightTextPos
 
wxSize mLeftSize
 
wxSize mRightSize
 
wxPen mPen
 
wxPen mDisabledPen
 
wxPen mPeakPeakPen
 
wxBrush mBrush
 
wxBrush mRMSBrush
 
wxBrush mClipBrush
 
wxBrush mBkgndBrush
 
wxBrush mDisabledBkgndBrush
 
Ruler mRuler
 
wxString mLeftText
 
wxString mRightText
 
std::unique_ptr< LWSlidermSlider
 
wxPoint mSliderPos
 
wxSize mSliderSize
 
bool mEnabled { true }
 
bool mIsFocused
 
wxRect mFocusRect
 

Friends

class MeterAx
 

Additional Inherited Members

- Static Public Member Functions inherited from MeterPanelBase
static TempAllowFocus TemporarilyAllowFocus ()
 
- Static Private Member Functions inherited from PrefsListener
static void Broadcast (int id=0)
 Call this static function to notify all PrefsListener objects. More...
 

Detailed Description

MeterPanel is a panel that paints the meter used for monitoring or playback.

VU Meter, for displaying recording/playback level.

This is a bunch of common code that can display many different forms of VU meters and other displays.

But note that a lot of later code here assumes these are MeterToolBar meters, e.g., MeterPanel::StartMonitoring, so these are not as generic/common as originally intended.

Definition at line 101 of file MeterPanel.h.

Member Enumeration Documentation

◆ Style

Enumerator
AutomaticStereo 
HorizontalStereo 
VerticalStereo 
MixerTrackCluster 
HorizontalStereoCompact 
VerticalStereoCompact 

Definition at line 110 of file MeterPanel.h.

110 {
114 MixerTrackCluster, // Doesn't show menu, icon, or L/R labels, but otherwise like VerticalStereo.
115 HorizontalStereoCompact, // Thinner.
116 VerticalStereoCompact, // Narrower.
117 };
@ HorizontalStereoCompact
Definition: MeterPanel.h:115
@ AutomaticStereo
Definition: MeterPanel.h:111
@ HorizontalStereo
Definition: MeterPanel.h:112
@ VerticalStereo
Definition: MeterPanel.h:113
@ VerticalStereoCompact
Definition: MeterPanel.h:116
@ MixerTrackCluster
Definition: MeterPanel.h:114

Constructor & Destructor Documentation

◆ MeterPanel()

MeterPanel::MeterPanel ( AudacityProject project,
wxWindow *  parent,
wxWindowID  id,
bool  isInput,
const wxPoint &  pos = wxDefaultPosition,
const wxSize &  size = wxDefaultSize,
Style  style = HorizontalStereo,
float  fDecayRate = 60.0f 
)

Definition at line 288 of file MeterPanel.cpp.

295: MeterPanelBase(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER | wxWANTS_CHARS),
296 mProject(project),
297 mQueue{ 1024 },
298 mWidth(size.x),
299 mHeight(size.y),
300 mIsInput(isInput),
301 mDesiredStyle(style),
302 mGradient(true),
303 mDB(true),
305 mDecay(true),
306 mDecayRate(fDecayRate),
307 mClip(true),
310 mT(0),
311 mRate(0),
312 mMonitoring(false),
313 mActive(false),
314 mNumBars(0),
315 mLayoutValid(false),
316 mBitmap{}
317{
318 // i18n-hint: Noun (the meter is used for playback or record level monitoring)
319 SetName( XO("Meter") );
320 // Suppress warnings about the header file
321 wxUnusedVar(SpeakerMenu_xpm);
322 wxUnusedVar(MicMenu_xpm);
323 wxUnusedVar(PrefStyles);
324
326
327 mIsFocused = false;
328
329#if wxUSE_ACCESSIBILITY
330 SetAccessible(safenew MeterAx(this));
331#endif
332
333 // Do this BEFORE UpdatePrefs()!
336 mRuler.SetLabelEdges(true);
337 //mRuler.SetTickColour( wxColour( 0,0,255 ) );
338
340 {
341 mSlider = std::make_unique<LWSlider>(this, XO(""),
342 pos,
343 size,
345 false, /* showlabels */
346 false, /* drawticks */
347 false, /* drawtrack */
348 false /* alwayshidetip */
349 );
350 mSlider->SetScroll(0.1f, 2.0f);
351 }
352
354 UpdatePrefs();
355
356 wxColour backgroundColour = theTheme.Colour( clrMedium);
357 mBkgndBrush = wxBrush(backgroundColour, wxBRUSHSTYLE_SOLID);
358 SetBackgroundColour( backgroundColour );
359
360 mPeakPeakPen = wxPen(theTheme.Colour( clrMeterPeak), 1, wxPENSTYLE_SOLID);
361 mDisabledPen = wxPen(theTheme.Colour( clrMeterDisabledPen), 1, wxPENSTYLE_SOLID);
362
365
368
369 if (mIsInput) {
370 mPen = wxPen( theTheme.Colour( clrMeterInputPen ), 1, wxPENSTYLE_SOLID);
371 mBrush = wxBrush( theTheme.Colour( clrMeterInputBrush ), wxBRUSHSTYLE_SOLID);
372 mRMSBrush = wxBrush( theTheme.Colour( clrMeterInputRMSBrush ), wxBRUSHSTYLE_SOLID);
373 mClipBrush = wxBrush( theTheme.Colour( clrMeterInputClipBrush ), wxBRUSHSTYLE_SOLID);
374// mLightPen = wxPen( theTheme.Colour( clrMeterInputLightPen ), 1, wxSOLID);
375// mDarkPen = wxPen( theTheme.Colour( clrMeterInputDarkPen ), 1, wxSOLID);
376 }
377 else {
378 mPen = wxPen( theTheme.Colour( clrMeterOutputPen ), 1, wxPENSTYLE_SOLID);
379 mBrush = wxBrush( theTheme.Colour( clrMeterOutputBrush ), wxBRUSHSTYLE_SOLID);
380 mRMSBrush = wxBrush( theTheme.Colour( clrMeterOutputRMSBrush ), wxBRUSHSTYLE_SOLID);
381 mClipBrush = wxBrush( theTheme.Colour( clrMeterOutputClipBrush ), wxBRUSHSTYLE_SOLID);
382// mLightPen = wxPen( theTheme.Colour( clrMeterOutputLightPen ), 1, wxSOLID);
383// mDarkPen = wxPen( theTheme.Colour( clrMeterOutputDarkPen ), 1, wxSOLID);
384 }
385
386// mDisabledBkgndBrush = wxBrush(theTheme.Colour( clrMeterDisabledBrush), wxSOLID);
387 // No longer show a difference in the background colour when not monitoring.
388 // We have the tip instead.
390
391 mTipTimer.SetOwner(this, OnTipTimeoutID);
392 mTimer.SetOwner(this, OnMeterUpdateID);
393 // TODO: Yikes. Hard coded sample rate.
394 // JKC: I've looked at this, and it's benignish. It just means that the meter
395 // balistics are right for 44KHz and a bit more frisky than they should be
396 // for higher sample rates.
397 Reset(44100.0, true);
398}
#define PERCENT_SLIDER
Definition: ASlider.h:39
IntSetting DecibelScaleCutoff
Negation of this value is the lowest dB level that should be shown in dB scales.
Definition: Decibels.cpp:12
XO("Cut/Copy/Paste")
#define safenew
Definition: MemoryX.h:10
static const wxChar * PrefStyles[]
Definition: MeterPanel.cpp:255
@ OnMeterUpdateID
Definition: MeterPanel.cpp:263
@ OnTipTimeoutID
Definition: MeterPanel.cpp:266
THEME_API Theme theTheme
Definition: Theme.cpp:82
static AudioIO * Get()
Definition: AudioIO.cpp:147
MeterPanelBase(Args &&...args)
bool mLayoutValid
Definition: MeterPanel.h:288
void UpdatePrefs() override
Definition: MeterPanel.cpp:405
Style mStyle
Definition: MeterPanel.h:266
wxFont GetFont() const
double mRate
Definition: MeterPanel.h:277
Style mDesiredStyle
Definition: MeterPanel.h:267
bool mClip
Definition: MeterPanel.h:273
int mDBRange
Definition: MeterPanel.h:270
bool mIsInput
Definition: MeterPanel.h:264
Ruler mRuler
Definition: MeterPanel.h:303
Observer::Subscription mAudioCaptureSubscription
Definition: MeterPanel.h:251
wxTimer mTimer
Definition: MeterPanel.h:255
float mDecayRate
Definition: MeterPanel.h:272
wxBrush mDisabledBkgndBrush
Definition: MeterPanel.h:302
bool mDecay
Definition: MeterPanel.h:271
double mPeakHoldDuration
Definition: MeterPanel.h:275
std::unique_ptr< LWSlider > mSlider
Definition: MeterPanel.h:307
double mT
Definition: MeterPanel.h:276
AudacityProject * mProject
Definition: MeterPanel.h:253
unsigned mNumBars
Definition: MeterPanel.h:285
wxBrush mBkgndBrush
Definition: MeterPanel.h:301
friend class MeterAx
Definition: MeterPanel.h:316
void OnAudioIOStatus(AudioIOEvent)
bool mMonitoring
Definition: MeterPanel.h:281
bool mGradient
Definition: MeterPanel.h:268
bool mActive
Definition: MeterPanel.h:283
void UpdateSliderControl()
Definition: MeterPanel.cpp:473
wxBrush mBrush
Definition: MeterPanel.h:298
Observer::Subscription mAudioIOStatusSubscription
Definition: MeterPanel.h:250
std::unique_ptr< wxBitmap > mBitmap
Definition: MeterPanel.h:290
wxTimer mTipTimer
Definition: MeterPanel.h:256
wxPen mPeakPeakPen
Definition: MeterPanel.h:297
int mNumPeakSamplesToClip
Definition: MeterPanel.h:274
wxBrush mClipBrush
Definition: MeterPanel.h:300
void Reset(double sampleRate, bool resetClipping) override
This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callbac...
Definition: MeterPanel.cpp:898
void OnAudioCapture(AudioIOEvent)
wxPen mPen
Definition: MeterPanel.h:295
bool mIsFocused
Definition: MeterPanel.h:313
MeterUpdateQueue mQueue
Definition: MeterPanel.h:254
wxBrush mRMSBrush
Definition: MeterPanel.h:299
wxPen mDisabledPen
Definition: MeterPanel.h:296
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
void SetFlip(bool flip)
Definition: Ruler.cpp:239
void SetFonts(const wxFont &minorFont, const wxFont &majorFont, const wxFont &minorMinorFont)
Definition: Ruler.cpp:278
void SetLabelEdges(bool labelEdges)
Definition: Ruler.cpp:226
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
wxColour & Colour(int iIndex)

Member Function Documentation

◆ Clear()

void MeterPanel::Clear ( )
overridevirtual

Implements MeterPanelBase.

Definition at line 400 of file MeterPanel.cpp.

401{
402 mQueue.Clear();
403}

References MeterUpdateQueue::Clear(), and mQueue.

Here is the call graph for this function:

◆ Decrease()

void MeterPanel::Decrease ( float  steps)

Definition at line 887 of file MeterPanel.cpp.

888{
889 if (mSlider)
890 {
891 wxCommandEvent e;
892
893 mSlider->Decrease(steps);
894 SetMixer(e);
895 }
896}
void SetMixer(wxCommandEvent &event)
Definition: MeterPanel.cpp:829

References mSlider, and SetMixer().

Referenced by MeterToolBar::AdjustInputGain(), and MeterToolBar::AdjustOutputGain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DrawMeterBar()

void MeterPanel::DrawMeterBar ( wxDC &  dc,
MeterBar meterBar 
)
private

Definition at line 1593 of file MeterPanel.cpp.

1594{
1595 // Cache some metrics
1596 wxCoord x = bar->r.GetLeft();
1597 wxCoord y = bar->r.GetTop();
1598 wxCoord w = bar->r.GetWidth();
1599 wxCoord h = bar->r.GetHeight();
1600 wxCoord ht;
1601 wxCoord wd;
1602
1603 // Setup for erasing the background
1604 dc.SetPen(*wxTRANSPARENT_PEN);
1606
1607 if (mGradient)
1608 {
1609 // Map the predrawn bitmap into the source DC
1610 wxMemoryDC srcDC;
1611 srcDC.SelectObject(*mBitmap);
1612
1613 if (bar->vert)
1614 {
1615 // Copy as much of the predrawn meter bar as is required for the
1616 // current peak.
1617 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1618 ht = (int)(bar->peak * (h - 1) + 0.5);
1619
1620 // Blank out the rest
1621 if (h - ht)
1622 {
1623 // ht includes peak value...not really needed but doesn't hurt
1624 dc.DrawRectangle(x, y, w, h - ht);
1625 }
1626
1627 // Copy as much of the predrawn meter bar as is required for the
1628 // current peak.
1629 // +/-1 to include the peak position
1630 if (ht)
1631 {
1632 dc.Blit(x, y + h - ht - 1, w, ht + 1, &srcDC, x, y + h - ht - 1);
1633 }
1634
1635 // Draw the "recent" peak hold line using the predrawn meter bar so that
1636 // it will be the same color as the original level.
1637 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1638 ht = (int)(bar->peakHold * (h - 1) + 0.5);
1639 if (ht > 1)
1640 {
1641 dc.Blit(x, y + h - ht - 1, w, 2, &srcDC, x, y + h - ht - 1);
1642 }
1643
1644 // Draw the "maximum" peak hold line
1645 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1646 dc.SetPen(mPeakPeakPen);
1647 ht = (int)(bar->peakPeakHold * (h - 1) + 0.5);
1648 if (ht > 0)
1649 {
1650 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1651 if (ht > 1)
1652 {
1653 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1654 }
1655 }
1656 }
1657 else
1658 {
1659 // Calculate the peak position
1660 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1661 wd = (int)(bar->peak * (w - 1) + 0.5);
1662
1663 // Blank out the rest
1664 if (w - wd)
1665 {
1666 // wd includes peak value...not really needed but doesn't hurt
1667 dc.DrawRectangle(x + wd, y, w - wd, h);
1668 }
1669
1670 // Copy as much of the predrawn meter bar as is required for the
1671 // current peak. But, only blit() if there's something to copy
1672 // to prevent display corruption.
1673 // +1 to include peak position
1674 if (wd)
1675 {
1676 dc.Blit(x, y, wd + 1, h, &srcDC, x, y);
1677 }
1678
1679 // Draw the "recent" peak hold line using the predrawn meter bar so that
1680 // it will be the same color as the original level.
1681 // -1 to give a 2 pixel width
1682 wd = (int)(bar->peakHold * (w - 1) + 0.5);
1683 if (wd > 1)
1684 {
1685 dc.Blit(x + wd - 1, y, 2, h, &srcDC, x + wd, y);
1686 }
1687
1688 // Draw the "maximum" peak hold line using a themed color
1689 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1690 dc.SetPen(mPeakPeakPen);
1691 wd = (int)(bar->peakPeakHold * (w - 1) + 0.5);
1692 if (wd > 0)
1693 {
1694 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1695 if (wd > 1)
1696 {
1697 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1698 }
1699 }
1700 }
1701
1702 // No longer need the source DC, so unselect the predrawn bitmap
1703 srcDC.SelectObject(wxNullBitmap);
1704 }
1705 else
1706 {
1707 if (bar->vert)
1708 {
1709 // Calculate the peak position
1710 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1711 ht = (int)(bar->peak * (h - 1) + 0.5);
1712
1713 // Blank out the rest
1714 if (h - ht)
1715 {
1716 // ht includes peak value...not really needed but doesn't hurt
1717 dc.DrawRectangle(x, y, w, h - ht);
1718 }
1719
1720 // Draw the peak level
1721 // +/-1 to include the peak position
1722 dc.SetPen(*wxTRANSPARENT_PEN);
1723 dc.SetBrush(mMeterDisabled ? mDisabledBkgndBrush : mBrush);
1724 if (ht)
1725 {
1726 dc.DrawRectangle(x, y + h - ht - 1, w, ht + 1);
1727 }
1728
1729 // Draw the "recent" peak hold line
1730 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1731 dc.SetPen(mPen);
1732 ht = (int)(bar->peakHold * (h - 1) + 0.5);
1733 if (ht > 0)
1734 {
1735 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1736 if (ht > 1)
1737 {
1738 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1739 }
1740 }
1741
1742 // Calculate the rms position
1743 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1744 // +1 to include the rms position
1745 ht = (int)(bar->rms * (h - 1) + 0.5);
1746
1747 // Draw the RMS level
1748 dc.SetPen(*wxTRANSPARENT_PEN);
1750 if (ht)
1751 {
1752 dc.DrawRectangle(x, y + h - ht - 1, w, ht + 1);
1753 }
1754
1755 // Draw the "maximum" peak hold line
1756 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1757 dc.SetPen(mPeakPeakPen);
1758 ht = (int)(bar->peakPeakHold * (h - 1) + 0.5);
1759 if (ht > 0)
1760 {
1761 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1762 if (ht > 1)
1763 {
1764 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1765 }
1766 }
1767 }
1768 else
1769 {
1770 // Calculate the peak position
1771 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1772 wd = (int)(bar->peak * (w - 1) + 0.5);
1773
1774 // Blank out the rest
1775 if (w - wd)
1776 {
1777 // wd includes peak value...not really needed but doesn't hurt
1778 dc.DrawRectangle(x + wd, y, w - wd, h);
1779 }
1780
1781 // Draw the peak level
1782 // +1 to include peak position
1783 dc.SetPen(*wxTRANSPARENT_PEN);
1784 dc.SetBrush(mMeterDisabled ? mDisabledBkgndBrush : mBrush);
1785 if (wd)
1786 {
1787 dc.DrawRectangle(x, y, wd + 1, h);
1788 }
1789
1790 // Draw the "recent" peak hold line
1791 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1792 dc.SetPen(mPen);
1793 wd = (int)(bar->peakHold * (w - 1) + 0.5);
1794 if (wd > 0)
1795 {
1796 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1797 if (wd > 1)
1798 {
1799 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1800 }
1801 }
1802
1803 // Calculate the rms position
1804 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1805 wd = (int)(bar->rms * (w - 1) + 0.5);
1806
1807 // Draw the rms level
1808 // +1 to include the rms position
1809 dc.SetPen(*wxTRANSPARENT_PEN);
1811 if (wd)
1812 {
1813 dc.DrawRectangle(x, y, wd + 1, h);
1814 }
1815
1816 // Draw the "maximum" peak hold line using a themed color
1817 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1818 dc.SetPen(mPeakPeakPen);
1819 wd = (int)(bar->peakPeakHold * (w - 1) + 0.5);
1820 if (wd > 0)
1821 {
1822 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1823 if (wd > 1)
1824 {
1825 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1826 }
1827 }
1828 }
1829 }
1830
1831 // If meter had a clipping indicator, draw or erase it
1832 // LLL: At least I assume that's what "mClip" is supposed to be for as
1833 // it is always "true".
1834 if (mClip)
1835 {
1836 if (bar->clipping)
1837 {
1838 dc.SetBrush(mClipBrush);
1839 }
1840 else
1841 {
1843 }
1844 dc.SetPen(*wxTRANSPARENT_PEN);
1845 wxRect r(bar->rClip.GetX() + 1,
1846 bar->rClip.GetY() + 1,
1847 bar->rClip.GetWidth() - 1,
1848 bar->rClip.GetHeight() - 1);
1849 dc.DrawRectangle(r);
1850 }
1851}
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:187
long mMeterDisabled
Definition: MeterPanel.h:279

References MeterBar::clipping, AColor::Line(), mBitmap, mBkgndBrush, mBrush, mClip, mClipBrush, mDisabledBkgndBrush, mGradient, mMeterDisabled, mPeakPeakPen, mPen, mRMSBrush, MeterBar::peak, MeterBar::peakHold, MeterBar::peakPeakHold, MeterBar::r, MeterBar::rClip, MeterBar::rms, and MeterBar::vert.

Referenced by OnPaint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDBRange()

int MeterPanel::GetDBRange ( ) const
inlineoverridevirtual

Implements MeterPanelBase.

Definition at line 199 of file MeterPanel.h.

199{ return mDB ? mDBRange : -1; }

◆ GetDesiredStyle()

Style MeterPanel::GetDesiredStyle ( ) const
inline

Definition at line 133 of file MeterPanel.h.

133{ return mDesiredStyle; }

◆ GetFont()

wxFont MeterPanel::GetFont ( ) const
private

Definition at line 1162 of file MeterPanel.cpp.

1163{
1164 int fontSize = 10;
1165#if defined __WXMSW__
1166 fontSize = 8;
1167#endif
1168
1169 return wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
1170}

Referenced by HandleLayout(), and OnPaint().

Here is the caller graph for this function:

◆ GetMaxPeak()

float MeterPanel::GetMaxPeak ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1144 of file MeterPanel.cpp.

1145{
1146 float maxPeak = 0.;
1147
1148 for(unsigned int j=0; j<mNumBars; j++)
1149 maxPeak = mBar[j].peak > maxPeak ? mBar[j].peak : maxPeak;
1150
1151 return(maxPeak);
1152}
MeterBar mBar[kMaxMeterBars]
Definition: MeterPanel.h:286

References mBar, and mNumBars.

◆ GetPeakHold()

float MeterPanel::GetPeakHold ( ) const

Definition at line 1154 of file MeterPanel.cpp.

1155{
1156 auto peakHold = .0f;
1157 for (unsigned int i = 0; i < mNumBars; i++)
1158 peakHold = std::max(peakHold, mBar[i].peakPeakHold);
1159 return peakHold;
1160}

References mBar, and mNumBars.

◆ GetStyle()

Style MeterPanel::GetStyle ( ) const
inline

Definition at line 132 of file MeterPanel.h.

132{ return mStyle; }

◆ HandleLayout()

void MeterPanel::HandleLayout ( wxDC &  dc)
private

Definition at line 1289 of file MeterPanel.cpp.

1290{
1291 // Refresh to reflect any language changes
1292 /* i18n-hint: One-letter abbreviation for Left, in VU Meter */
1293 mLeftText = _("L");
1294 /* i18n-hint: One-letter abbreviation for Right, in VU Meter */
1295 mRightText = _("R");
1296
1297 dc.SetFont(GetFont());
1298 int width = mWidth;
1299 int height = mHeight;
1300 int left = 0;
1301 int top = 0;
1302 int barw;
1303 int barh;
1304 int lside;
1305 int rside;
1306
1307 // MixerTrackCluster has no L/R labels or icon
1309 {
1311 {
1313 }
1314
1316 {
1318 }
1320 {
1322 }
1323
1324 if (mLeftSize.GetWidth() == 0) // Not yet initialized to dc.
1325 {
1326 dc.GetTextExtent(mLeftText, &mLeftSize.x, &mLeftSize.y);
1327 dc.GetTextExtent(mRightText, &mRightSize.x, &mRightSize.y);
1328 }
1329 }
1330
1331 int ltxtWidth = mLeftSize.GetWidth();
1332 int ltxtHeight = mLeftSize.GetHeight();
1333 int rtxtWidth = mRightSize.GetWidth();
1334 int rtxtHeight = mRightSize.GetHeight();
1335
1336 switch (mStyle)
1337 {
1338 default:
1339 wxPrintf(wxT("Style not handled yet!\n"));
1340 break;
1341 case MixerTrackCluster:
1342 // width is now the entire width of the meter canvas
1343 width -= mRulerWidth + left;
1344
1345 // height is now the entire height of the meter canvas
1346 height -= top + gap;
1347
1348 // barw is half of the canvas while allowing for a gap between meters
1349 barw = (width - gap) / 2;
1350
1351 // barh is now the height of the canvas
1352 barh = height;
1353
1354 // We always have 2 bars
1355 mNumBars = 2;
1356
1357 // Save dimensions of the left bevel
1358 mBar[0].b = wxRect(left, top, barw, barh);
1359
1360 // Save dimensions of the right bevel
1361 mBar[1].b = mBar[0].b;
1362 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1363
1364 // Set bar and clipping indicator dimensions
1365 SetBarAndClip(0, true);
1366 SetBarAndClip(1, true);
1367
1368 mRuler.SetBounds(mBar[1].r.GetRight() + 1, // +1 for the bevel
1369 mBar[1].r.GetTop(),
1370 mWidth,
1371 mBar[1].r.GetBottom());
1372 mRuler.OfflimitsPixels(0, 0);
1373 break;
1374 case VerticalStereo:
1375 // Determine required width of each side;
1376 lside = ltxtWidth + gap;
1377 rside = intmax(mRulerWidth, rtxtWidth);
1378
1379 // left is now the right edge of the icon or L label
1380 left = lside;
1381
1382 // Ensure there's a margin between top edge of window and the meters
1383 top = gap;
1384
1385 // Position the L/R labels
1386 mLeftTextPos = wxPoint(left - ltxtWidth - gap, height - gap - ltxtHeight);
1387 mRightTextPos = wxPoint(width - rside - gap, height - gap - rtxtHeight);
1388
1389 // left is now left edge of left bar
1390 left += gap;
1391
1392 // width is now the entire width of the meter canvas
1393 width -= gap + rside + gap + left;
1394
1395 // height is now the entire height of the meter canvas
1396 height -= top + gap;
1397
1398 mSliderPos = wxPoint{ 0, top - gap };
1399 mSliderSize = wxSize{ width, height + 2 * gap };
1400
1401 // barw is half of the canvas while allowing for a gap between meters
1402 barw = (width - gap) / 2;
1403
1404 // barh is now the height of the canvas
1405 barh = height;
1406
1407 // We always have 2 bars
1408 mNumBars = 2;
1409
1410 // Save dimensions of the left bevel
1411 mBar[0].b = wxRect(left, top, barw, barh);
1412
1413 // Save dimensions of the right bevel
1414 mBar[1].b = mBar[0].b;
1415 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1416
1417 // Set bar and clipping indicator dimensions
1418 SetBarAndClip(0, true);
1419 SetBarAndClip(1, true);
1420
1421 mRuler.SetBounds(mBar[1].r.GetRight() + 1, // +1 for the bevel
1422 mBar[1].r.GetTop(),
1423 mWidth,
1424 mBar[1].r.GetBottom());
1425 mRuler.OfflimitsPixels(mRightTextPos.y - gap, mBar[1].r.GetBottom());
1426 break;
1428 // Ensure there's a margin between top edge of window and the meters
1429 top = gap;
1430
1431 // height is now the entire height of the meter canvas
1432 height -= top + gap + ltxtHeight + gap;
1433
1434 mSliderPos = wxPoint{ 0, top - gap };
1435 mSliderSize = wxSize{ width, height + 2 * gap };
1436
1437 // barw is half of the canvas while allowing for a gap between meters
1438 barw = (width / 2) - gap;
1439
1440 // barh is now the height of the canvas
1441 barh = height;
1442
1443 // We always have 2 bars
1444 mNumBars = 2;
1445
1446 // Save dimensions of the left bevel
1447 mBar[0].b = wxRect(left, top, barw, barh);
1448
1449 // Save dimensions of the right bevel
1450 mBar[1].b = mBar[0].b;
1451 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1452
1453 // Set bar and clipping indicator dimensions
1454 SetBarAndClip(0, true);
1455 SetBarAndClip(1, true);
1456
1457 // L/R is centered horizontally under each bar
1458 mLeftTextPos = wxPoint(mBar[0].b.GetLeft() + ((mBar[0].b.GetWidth() - ltxtWidth) / 2), top + barh + gap);
1459 mRightTextPos = wxPoint(mBar[1].b.GetLeft() + ((mBar[1].b.GetWidth() - rtxtWidth) / 2), top + barh + gap);
1460
1462 mBar[1].r.GetTop(),
1463 (mWidth - mRulerWidth) / 2,
1464 mBar[1].r.GetBottom());
1465 mRuler.OfflimitsPixels(0, 0);
1466 break;
1467 case HorizontalStereo:
1468 // Button right next to dragger.
1469 left = 0;
1470
1471 // Add a gap between bottom of icon and bottom of window
1472 height -= gap;
1473
1474 left = gap;
1475
1476 // Make sure there's room for icon and gap between the bottom of the meter and icon
1477 height -= rtxtHeight + gap;
1478
1479 // L/R is centered vertically and to the left of a each bar
1480 mLeftTextPos = wxPoint(left, (height / 4) - ltxtHeight / 2);
1481 mRightTextPos = wxPoint(left, (height * 3 / 4) - rtxtHeight / 2);
1482
1483 // Add width of widest of the L/R characters
1484 left += intmax(ltxtWidth, rtxtWidth); //, iconWidth);
1485
1486 mSliderPos = wxPoint{ left - gap, 0 };
1487
1488 // Add gap between L/R and meter bevel
1489 left += gap;
1490
1491 // width is now the entire width of the meter canvas
1492 width -= left;
1493
1494 mSliderSize = wxSize{ width + 2 * gap, height };
1495
1496 // barw is now the width of the canvas minus gap between canvas and right window edge
1497 barw = width - gap;
1498
1499 // barh is half of the canvas while allowing for a gap between meters
1500 barh = (height - gap) / 2;
1501
1502 // We always have 2 bars
1503 mNumBars = 2;
1504
1505 // Save dimensions of the top bevel
1506 mBar[0].b = wxRect(left, top, barw, barh);
1507
1508 // Save dimensions of the bottom bevel
1509 mBar[1].b = mBar[0].b;
1510 mBar[1].b.SetTop(mBar[0].b.GetBottom() + 1 + gap); // +1 for bottom edge
1511
1512 // Set bar and clipping indicator dimensions
1513 SetBarAndClip(0, false);
1514 SetBarAndClip(1, false);
1515
1516 mRuler.SetBounds(mBar[1].r.GetLeft(),
1517 mBar[1].r.GetBottom() + 1, // +1 to fit below bevel
1518 mBar[1].r.GetRight(),
1519 mHeight - mBar[1].r.GetBottom() + 1);
1520 break;
1522 left = gap;
1523
1524 // L/R is centered vertically and to the left of a each bar
1525 mLeftTextPos = wxPoint(left, (height / 4) - (ltxtHeight / 2));
1526 mRightTextPos = wxPoint(left, (height * 3 / 4) - (ltxtHeight / 2));
1527
1528 // Add width of widest of the L/R characters
1529 left += intmax(ltxtWidth, rtxtWidth);
1530
1531 mSliderPos = wxPoint{ left - gap, 0 };
1532
1533 // Add gap between L/R and meter bevel
1534 left += gap;
1535
1536 // width is now the entire width of the meter canvas
1537 width -= left;
1538
1539 mSliderSize = wxSize{ width + 2 * gap, height };
1540
1541 // barw is now the width of the canvas minus gap between canvas and window edge
1542 barw = width - gap;
1543
1544 // barh is half of the canvas while allowing for a gap between meters
1545 barh = (height - gap) / 2;
1546
1547 // We always have 2 bars
1548 mNumBars = 2;
1549
1550 // Save dimensions of the top bevel
1551 mBar[0].b = wxRect(left, top, barw, barh);
1552
1553 // Save dimensions of the bottom bevel
1554 // Since the bars butt up against the window's top and bottom edges, we need
1555 // to include an extra pixel in the bottom bar when the window height and
1556 // meter height do not exactly match.
1557 mBar[1].b = mBar[0].b;
1558 mBar[1].b.SetTop(mBar[0].b.GetBottom() + 1 + gap); // +1 for bottom bevel
1559 mBar[1].b.SetHeight(mHeight - mBar[1].b.GetTop() - 1); // +1 for bottom bevel
1560
1561 // Add clipping indicators - do after setting bar/bevel dimensions above
1562 SetBarAndClip(0, false);
1563 SetBarAndClip(1, false);
1564
1565 mRuler.SetBounds(mBar[1].r.GetLeft(),
1566 mBar[1].b.GetTop() - (mRulerHeight / 2),
1567 mBar[1].r.GetRight(),
1568 mBar[1].b.GetTop() - (mRulerHeight / 2));
1569 mRuler.OfflimitsPixels(0, 0);
1570 break;
1571 }
1572
1573 mLayoutValid = true;
1574}
wxT("CloseDown"))
#define _(s)
Definition: Internat.h:75
static int intmax(int a, int b)
Definition: MeterPanel.cpp:933
static const int gap
Definition: MeterPanel.cpp:253
wxString mRightText
Definition: MeterPanel.h:305
wxSize mRightSize
Definition: MeterPanel.h:294
wxPoint mSliderPos
Definition: MeterPanel.h:308
int mRulerHeight
Definition: MeterPanel.h:262
int mRulerWidth
Definition: MeterPanel.h:261
wxString mLeftText
Definition: MeterPanel.h:304
void SetBarAndClip(int iBar, bool vert)
wxPoint mLeftTextPos
Definition: MeterPanel.h:291
wxSize mLeftSize
Definition: MeterPanel.h:293
wxPoint mRightTextPos
Definition: MeterPanel.h:292
wxSize mSliderSize
Definition: MeterPanel.h:309
void SetActiveStyle(Style style)
void OfflimitsPixels(int start, int end)
Definition: Ruler.cpp:302
void SetBounds(int left, int top, int right, int bottom)
Definition: Ruler.cpp:332
wxRect b
Definition: MeterPanel.h:41
wxRect r
Definition: MeterPanel.h:42

References _, AutomaticStereo, MeterBar::b, gap, GetFont(), HorizontalStereo, HorizontalStereoCompact, intmax(), mBar, mDesiredStyle, mHeight, MixerTrackCluster, mLayoutValid, mLeftSize, mLeftText, mLeftTextPos, mNumBars, mRightSize, mRightText, mRightTextPos, mRuler, mRulerHeight, mRulerWidth, mSliderPos, mSliderSize, mStyle, mWidth, Ruler::OfflimitsPixels(), MeterBar::r, SetActiveStyle(), SetBarAndClip(), Ruler::SetBounds(), VerticalStereo, VerticalStereoCompact, and wxT().

Referenced by OnPaint().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Increase()

void MeterPanel::Increase ( float  steps)

Definition at line 876 of file MeterPanel.cpp.

877{
878 if (mSlider)
879 {
880 wxCommandEvent e;
881
882 mSlider->Increase(steps);
883 SetMixer(e);
884 }
885}

References mSlider, and SetMixer().

Referenced by MeterToolBar::AdjustInputGain(), and MeterToolBar::AdjustOutputGain().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsActive()

bool MeterPanel::IsActive ( ) const

Definition at line 1187 of file MeterPanel.cpp.

1188{
1189 return mActive;
1190}

References mActive.

◆ IsClipping()

bool MeterPanel::IsClipping ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1197 of file MeterPanel.cpp.

1198{
1199 for (int c = 0; c < mNumBars; c++)
1200 if (mBar[c].clipping)
1201 return true;
1202 return false;
1203}

References mBar, and mNumBars.

◆ IsMeterDisabled()

bool MeterPanel::IsMeterDisabled ( ) const
overridevirtual

Find out if the level meter is disabled or not.

This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callback).

Implements MeterPanelBase.

Definition at line 1853 of file MeterPanel.cpp.

1854{
1855 return mMeterDisabled != 0;
1856}

References mMeterDisabled.

◆ IsMonitoring()

bool MeterPanel::IsMonitoring ( ) const

Definition at line 1192 of file MeterPanel.cpp.

1193{
1194 return mMonitoring;
1195}

References mMonitoring.

◆ Key()

wxString MeterPanel::Key ( const wxString &  key) const
private

Definition at line 2092 of file MeterPanel.cpp.

2093{
2095 {
2096 return wxT("/Meter/Mixerboard/") + key;
2097 }
2098
2099 if (mIsInput)
2100 {
2101 return wxT("/Meter/Input/") + key;
2102 }
2103
2104 return wxT("/Meter/Output/") + key;
2105}
static const AudacityProject::AttachedObjects::RegisteredFactory key

References key, mIsInput, mStyle, and wxT().

Referenced by OnPreferences(), and UpdatePrefs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnAudioCapture()

void MeterPanel::OnAudioCapture ( AudioIOEvent  event)
private

Definition at line 1907 of file MeterPanel.cpp.

1908{
1909 if (event.type == AudioIOEvent::CAPTURE && event.pProject != mProject)
1910 {
1911 mEnabled = !event.on;
1912
1913 if (mSlider)
1914 mSlider->SetEnabled(mEnabled);
1915 }
1916}
bool mEnabled
Definition: MeterPanel.h:311
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:71

References AudioIOEvent::CAPTURE, mEnabled, mProject, mSlider, AudioIOEvent::pProject, and AudioIOEvent::type.

◆ OnAudioIOStatus()

void MeterPanel::OnAudioIOStatus ( AudioIOEvent  evt)
private

Definition at line 1886 of file MeterPanel.cpp.

1887{
1888 if (!mIsInput != (evt.type == AudioIOEvent::PLAYBACK))
1889 return;
1890
1891 AudacityProject *p = evt.pProject;
1892 mActive = evt.on && (p == mProject);
1893 if( mActive ){
1894 mTimer.Start(1000 / mMeterRefreshRate);
1895 if (evt.type == AudioIOEvent::MONITOR)
1897 } else {
1898 mTimer.Stop();
1899 mMonitoring = false;
1900 }
1901
1902 // Only refresh is we're the active meter
1903 if (IsShownOnScreen())
1904 Refresh(false);
1905}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
long mMeterRefreshRate
Definition: MeterPanel.h:278
bool on
Definition: AudioIO.h:77

References mActive, mIsInput, mMeterRefreshRate, mMonitoring, AudioIOEvent::MONITOR, mProject, mTimer, AudioIOEvent::on, AudioIOEvent::PLAYBACK, AudioIOEvent::pProject, and AudioIOEvent::type.

◆ OnCharHook()

void MeterPanel::OnCharHook ( wxKeyEvent &  evt)
private

Definition at line 751 of file MeterPanel.cpp.

752{
753 switch(evt.GetKeyCode())
754 {
755 // These are handled in the OnCharHook handler because, on Windows at least, the
756 // key up event will be passed on to the menu if we show it here. This causes
757 // the default sound to be heard if assigned.
758 case WXK_RETURN:
759 case WXK_NUMPAD_ENTER:
760 case WXK_WINDOWS_MENU:
761 case WXK_MENU:
763 ShowMenu(GetClientRect().GetBottomLeft());
764 else
765 evt.Skip();
766 break;
767 default:
768 evt.Skip();
769 break;
770 }
771}
void ShowMenu(const wxPoint &pos)

References mStyle, and ShowMenu().

Here is the call graph for this function:

◆ OnContext()

void MeterPanel::OnContext ( wxContextMenuEvent &  evt)
private

Definition at line 773 of file MeterPanel.cpp.

774{
775 if (mStyle != MixerTrackCluster) // MixerTrackCluster style has no menu.
776 {
777 ShowMenu(GetClientRect().GetBottomLeft());
778 }
779 else
780 {
781 evt.Skip();
782 }
783}

References mStyle, and ShowMenu().

Here is the call graph for this function:

◆ OnErase()

void MeterPanel::OnErase ( wxEraseEvent &  evt)
private

Definition at line 495 of file MeterPanel.cpp.

496{
497 // Ignore it to prevent flashing
498}

◆ OnKeyDown()

void MeterPanel::OnKeyDown ( wxKeyEvent &  evt)
private

Definition at line 785 of file MeterPanel.cpp.

786{
787 switch (evt.GetKeyCode())
788 {
789 case WXK_TAB:
790 if (evt.ShiftDown())
791 Navigate(wxNavigationKeyEvent::IsBackward);
792 else
793 Navigate(wxNavigationKeyEvent::IsForward);
794 break;
795 default:
796 mSlider->OnKeyDown(evt);
797 break;
798 }
799}

References mSlider.

◆ OnKillFocus()

void MeterPanel::OnKillFocus ( wxFocusEvent &  evt)
private

Definition at line 807 of file MeterPanel.cpp.

808{
809 if(mSlider)
810 mSlider->OnKillFocus();
811 mTipTimer.Stop();
812
813 mIsFocused = false;
814 Refresh(false);
815}

References mIsFocused, mSlider, and mTipTimer.

◆ OnMeterUpdate()

void MeterPanel::OnMeterUpdate ( wxTimerEvent &  evt)
private

Definition at line 1040 of file MeterPanel.cpp.

1041{
1042 MeterUpdateMsg msg;
1043 int numChanges = 0;
1044#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1045 double maxPeak = 0.0;
1046 bool discarded = false;
1047#endif
1048
1049 // We shouldn't receive any events if the meter is disabled, but clear it to be safe
1050 if (mMeterDisabled) {
1051 mQueue.Clear();
1052 return;
1053 }
1054
1055
1056 // There may have been several update messages since the last
1057 // time we got to this function. Catch up to real-time by
1058 // popping them off until there are none left. It is necessary
1059 // to process all of them, otherwise we won't handle peaks and
1060 // peak-hold bars correctly.
1061 while(mQueue.Get(msg)) {
1062 numChanges++;
1063 double deltaT = msg.numFrames / mRate;
1064
1065 mT += deltaT;
1066 for(unsigned int j=0; j<mNumBars; j++) {
1067 mBar[j].isclipping = false;
1068
1069 //
1070 if (mDB) {
1071 msg.peak[j] = ToDB(msg.peak[j], mDBRange);
1072 msg.rms[j] = ToDB(msg.rms[j], mDBRange);
1073 }
1074
1075 if (mDecay) {
1076 if (mDB) {
1077 float decayAmount = mDecayRate * deltaT / mDBRange;
1078 mBar[j].peak = floatMax(msg.peak[j],
1079 mBar[j].peak - decayAmount);
1080 }
1081 else {
1082 double decayAmount = mDecayRate * deltaT;
1083 double decayFactor = DB_TO_LINEAR(-decayAmount);
1084 mBar[j].peak = floatMax(msg.peak[j],
1085 mBar[j].peak * decayFactor);
1086 }
1087 }
1088 else
1089 mBar[j].peak = msg.peak[j];
1090
1091 // This smooths out the RMS signal
1092 float smooth = pow(0.9, (double)msg.numFrames/1024.0);
1093 mBar[j].rms = mBar[j].rms * smooth + msg.rms[j] * (1.0 - smooth);
1094
1095 if (mT - mBar[j].peakHoldTime > mPeakHoldDuration ||
1096 mBar[j].peak > mBar[j].peakHold) {
1097 mBar[j].peakHold = mBar[j].peak;
1098 mBar[j].peakHoldTime = mT;
1099 }
1100
1101 if (mBar[j].peak > mBar[j].peakPeakHold )
1102 mBar[j].peakPeakHold = mBar[j].peak;
1103
1104 if (msg.clipping[j] ||
1105 mBar[j].tailPeakCount+msg.headPeakCount[j] >=
1107 mBar[j].clipping = true;
1108 mBar[j].isclipping = true;
1109 }
1110
1111 mBar[j].tailPeakCount = msg.tailPeakCount[j];
1112#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1113 if (mT > gAudioIO->AILAGetLastDecisionTime()) {
1114 discarded = false;
1115 maxPeak = msg.peak[j] > maxPeak ? msg.peak[j] : maxPeak;
1116 wxPrintf("%[email protected]%f ", msg.peak[j], mT);
1117 }
1118 else {
1119 discarded = true;
1120 wxPrintf("%[email protected]%f discarded\n", msg.peak[j], mT);
1121 }
1122#endif
1123 }
1124 } // while
1125
1126 if (numChanges > 0) {
1127 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1128 if (gAudioIO->AILAIsActive() && mIsInput && !discarded) {
1129 gAudioIO->AILAProcess(maxPeak);
1130 putchar('\n');
1131 }
1132 #endif
1134 }
1135}
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:543
static float ToDB(float v, float range)
Definition: MeterPanel.cpp:948
static float floatMax(float a, float b)
Definition: MeterPanel.cpp:921
void RepaintBarsNow()
Message used to update the MeterPanel.
Definition: MeterPanel.h:55
bool clipping[kMaxMeterBars]
Definition: MeterPanel.h:60
float peak[kMaxMeterBars]
Definition: MeterPanel.h:58
int tailPeakCount[kMaxMeterBars]
Definition: MeterPanel.h:62
int headPeakCount[kMaxMeterBars]
Definition: MeterPanel.h:61
float rms[kMaxMeterBars]
Definition: MeterPanel.h:59
bool Get(MeterUpdateMsg &msg)
Definition: MeterPanel.cpp:230
bool isclipping
Definition: MeterPanel.h:49
float peakPeakHold
Definition: MeterPanel.h:51
float peak
Definition: MeterPanel.h:43
int tailPeakCount
Definition: MeterPanel.h:50
float rms
Definition: MeterPanel.h:44
bool clipping
Definition: MeterPanel.h:48
double peakHoldTime
Definition: MeterPanel.h:46
float peakHold
Definition: MeterPanel.h:45

References MeterUpdateQueue::Clear(), MeterBar::clipping, MeterUpdateMsg::clipping, DB_TO_LINEAR, floatMax(), MeterUpdateQueue::Get(), MeterUpdateMsg::headPeakCount, MeterBar::isclipping, mBar, mDB, mDBRange, mDecay, mDecayRate, mIsInput, mMeterDisabled, mNumBars, mNumPeakSamplesToClip, mPeakHoldDuration, mQueue, mRate, mT, MeterUpdateMsg::numFrames, MeterBar::peak, MeterUpdateMsg::peak, MeterBar::peakHold, MeterBar::peakHoldTime, MeterBar::peakPeakHold, RepaintBarsNow(), MeterBar::rms, MeterUpdateMsg::rms, MeterBar::tailPeakCount, MeterUpdateMsg::tailPeakCount, and ToDB().

Here is the call graph for this function:

◆ OnMonitor()

void MeterPanel::OnMonitor ( wxCommandEvent &  evt)
private

Definition at line 1972 of file MeterPanel.cpp.

1973{
1975}
void StartMonitoring()

References StartMonitoring().

Here is the call graph for this function:

◆ OnMouse()

void MeterPanel::OnMouse ( wxMouseEvent &  evt)
private

Definition at line 725 of file MeterPanel.cpp.

726{
727 if ((evt.GetEventType() == wxEVT_MOTION || evt.Entering() || evt.Leaving())) {
728 mLayoutValid = false;
729 Refresh();
730 }
731
732 if (mStyle == MixerTrackCluster) // MixerTrackCluster style has no menu.
733 return;
734
735 if (evt.Entering()) {
736 mTipTimer.StartOnce(500);
737 }
738 else if(evt.Leaving())
739 mTipTimer.Stop();
740
741 if (evt.RightDown())
742 ShowMenu(evt.GetPosition());
743 else
744 {
745
746 if (mSlider)
747 mSlider->OnMouseEvent(evt);
748 }
749}

References mLayoutValid, mSlider, mStyle, mTipTimer, and ShowMenu().

Here is the call graph for this function:

◆ OnPaint()

void MeterPanel::OnPaint ( wxPaintEvent &  evt)
private

Definition at line 500 of file MeterPanel.cpp.

501{
502#if defined(__WXMAC__)
503 auto paintDC = std::make_unique<wxPaintDC>(this);
504#else
505 std::unique_ptr<wxDC> paintDC{ wxAutoBufferedPaintDCFactory(this) };
506#endif
507 wxDC & destDC = *paintDC;
508 wxColour clrText = theTheme.Colour( clrTrackPanelText );
509 wxColour clrBoxFill = theTheme.Colour( clrMedium );
510
511 if (mLayoutValid == false || (mStyle == MixerTrackCluster ))
512 {
513 // Create a NEW one using current size and select into the DC
514 mBitmap = std::make_unique<wxBitmap>();
515 mBitmap->Create(mWidth, mHeight, destDC);
516 wxMemoryDC dc;
517 dc.SelectObject(*mBitmap);
518
519 // Go calculate all of the layout metrics
520 HandleLayout(dc);
521
522 // Start with a clean background
523 // LLL: Should research USE_AQUA_THEME usefulness...
524//#ifndef USE_AQUA_THEME
525#ifdef EXPERIMENTAL_THEMING
526 //if( !mMeterDisabled )
527 //{
528 // mBkgndBrush.SetColour( GetParent()->GetBackgroundColour() );
529 //}
530#endif
531 mBkgndBrush.SetColour( GetBackgroundColour() );
532 dc.SetPen(*wxTRANSPARENT_PEN);
533 dc.SetBrush(mBkgndBrush);
534 dc.DrawRectangle(0, 0, mWidth, mHeight);
535//#endif
536
537 // MixerTrackCluster style has no icon or L/R labels
539 {
540 dc.SetFont(GetFont());
541 dc.SetTextForeground( clrText );
542 dc.SetTextBackground( clrBoxFill );
543 dc.DrawText(mLeftText, mLeftTextPos.x, mLeftTextPos.y);
544 dc.DrawText(mRightText, mRightTextPos.x, mRightTextPos.y);
545 }
546
547 // Setup the colors for the 3 sections of the meter bars
548 wxColor green(117, 215, 112);
549 wxColor yellow(255, 255, 0);
550 wxColor red(255, 0, 0);
551
552 // Bug #2473 - (Sort of) Hack to make text on meters more
553 // visible with darker backgrounds. It would be better to have
554 // different colors entirely and as part of the theme.
555 if (GetBackgroundColour().GetLuminance() < 0.25)
556 {
557 green = wxColor(117-100, 215-100, 112-100);
558 yellow = wxColor(255-100, 255-100, 0);
559 red = wxColor(255-100, 0, 0);
560 }
561 else if (GetBackgroundColour().GetLuminance() < 0.50)
562 {
563 green = wxColor(117-50, 215-50, 112-50);
564 yellow = wxColor(255-50, 255-50, 0);
565 red = wxColor(255-50, 0, 0);
566 }
567
568 // Draw the meter bars at maximum levels
569 for (unsigned int i = 0; i < mNumBars; i++)
570 {
571 // Give it a recessed look
572 AColor::Bevel(dc, false, mBar[i].b);
573
574 // Draw the clip indicator bevel
575 if (mClip)
576 {
577 AColor::Bevel(dc, false, mBar[i].rClip);
578 }
579
580 // Cache bar rect
581 wxRect r = mBar[i].r;
582
583 if (mGradient)
584 {
585 // Calculate the size of the two gradiant segments of the meter
586 double gradw;
587 double gradh;
588 if (mDB)
589 {
590 gradw = (double) r.GetWidth() / mDBRange * 6.0;
591 gradh = (double) r.GetHeight() / mDBRange * 6.0;
592 }
593 else
594 {
595 gradw = (double) r.GetWidth() / 100 * 25;
596 gradh = (double) r.GetHeight() / 100 * 25;
597 }
598
599 if (mBar[i].vert)
600 {
601 // Draw the "critical" segment (starts at top of meter and works down)
602 r.SetHeight(gradh);
603 dc.GradientFillLinear(r, red, yellow, wxSOUTH);
604
605 // Draw the "warning" segment
606 r.SetTop(r.GetBottom());
607 dc.GradientFillLinear(r, yellow, green, wxSOUTH);
608
609 // Draw the "safe" segment
610 r.SetTop(r.GetBottom());
611 r.SetBottom(mBar[i].r.GetBottom());
612 dc.SetPen(*wxTRANSPARENT_PEN);
613 dc.SetBrush(green);
614 dc.DrawRectangle(r);
615 }
616 else
617 {
618 // Draw the "safe" segment
619 r.SetWidth(r.GetWidth() - (int) (gradw + gradw + 0.5));
620 dc.SetPen(*wxTRANSPARENT_PEN);
621 dc.SetBrush(green);
622 dc.DrawRectangle(r);
623
624 // Draw the "warning" segment
625 r.SetLeft(r.GetRight() + 1);
626 r.SetWidth(floor(gradw));
627 dc.GradientFillLinear(r, green, yellow);
628
629 // Draw the "critical" segment
630 r.SetLeft(r.GetRight() + 1);
631 r.SetRight(mBar[i].r.GetRight());
632 dc.GradientFillLinear(r, yellow, red);
633 }
634#ifdef EXPERIMENTAL_METER_LED_STYLE
635 if (!mBar[i].vert)
636 {
637 wxRect r = mBar[i].r;
638 wxPen BackgroundPen;
639 BackgroundPen.SetColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE) );
640 dc.SetPen( BackgroundPen );
641 int i;
642 for(i=0;i<r.width;i++)
643 {
644 // 2 pixel spacing between the LEDs
645 if( (i%7)<2 ){
646 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+r.height );
647 } else {
648 // The LEDs have triangular ends.
649 // This code shapes the ends.
650 int j = abs( (i%7)-4);
651 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+j +1);
652 AColor::Line( dc, i+r.x, r.y+r.height-j, i+r.x, r.y+r.height );
653 }
654 }
655 }
656#endif
657 }
658 }
659 mRuler.SetTickColour( clrText );
660 dc.SetTextForeground( clrText );
661 // Draw the ruler
662#ifndef EXPERIMENTAL_DA
663 mRuler.Draw(dc);
664#endif
665
666 // Bitmap created...unselect
667 dc.SelectObject(wxNullBitmap);
668 }
669
670 // Copy predrawn bitmap to the dest DC
671 destDC.DrawBitmap(*mBitmap, 0, 0);
672
673 // Go draw the meter bars, Left & Right channels using current levels
674 for (unsigned int i = 0; i < mNumBars; i++)
675 {
676 DrawMeterBar(destDC, &mBar[i]);
677 }
678
679 destDC.SetTextForeground( clrText );
680
681#ifndef EXPERIMENTAL_DA
682 // We can have numbers over the bars, in which case we have to draw them each time.
684 {
685 mRuler.SetTickColour( clrText );
686 // If the text colour is too similar to the meter colour, then we need a background
687 // for the text. We require a total of at least one full-scale RGB difference.
688 int d = theTheme.ColourDistance( clrText, theTheme.Colour( clrMeterOutputRMSBrush ) );
689 if( d < 256 )
690 {
691 destDC.SetBackgroundMode( wxSOLID );
692 destDC.SetTextBackground( clrBoxFill );
693 }
694 mRuler.Draw(destDC);
695 }
696#endif
697
699 {
700 bool highlighted =
701 wxRect{ mSliderPos, mSliderSize }.Contains(
702 ScreenToClient(
703 ::wxGetMousePosition()));
704
705 mSlider->Move(mSliderPos);
706 mSlider->AdjustSize(mSliderSize);
707 mSlider->OnPaint(destDC, highlighted);
708 }
709
710 if (mIsFocused)
711 {
712 auto r = GetClientRect();
713 AColor::DrawFocus(destDC, r);
714 }
715}
static void Bevel(wxDC &dc, bool up, const wxRect &r)
Definition: AColor.cpp:266
static void DrawFocus(wxDC &dc, wxRect &r)
Definition: AColor.cpp:235
void HandleLayout(wxDC &dc)
void DrawMeterBar(wxDC &dc, MeterBar *meterBar)
void SetTickColour(const wxColour &colour)
Definition: Ruler.h:148
void Draw(wxDC &dc) const
Definition: Ruler.cpp:1428
int ColourDistance(wxColour &From, wxColour &To)
Definition: Theme.cpp:307

References AColor::Bevel(), ThemeBase::Colour(), ThemeBase::ColourDistance(), Ruler::Draw(), AColor::DrawFocus(), DrawMeterBar(), GetFont(), HandleLayout(), HorizontalStereoCompact, AColor::Line(), mBar, mBitmap, mBkgndBrush, mClip, mDB, mDBRange, mGradient, mHeight, mIsFocused, mLayoutValid, mLeftText, mLeftTextPos, mNumBars, mRightText, mRightTextPos, mRuler, mSlider, mSliderPos, mSliderSize, mStyle, mWidth, MeterBar::r, Ruler::SetTickColour(), theTheme, and VerticalStereoCompact.

Here is the call graph for this function:

◆ OnPreferences()

void MeterPanel::OnPreferences ( wxCommandEvent &  evt)
private

Definition at line 1977 of file MeterPanel.cpp.

1978{
1979 wxTextCtrl *rate;
1980 wxRadioButton *gradient;
1981 wxRadioButton *rms;
1982 wxRadioButton *db;
1983 wxRadioButton *linear;
1984 wxRadioButton *automatic;
1985 wxRadioButton *horizontal;
1986 wxRadioButton *vertical;
1987 int meterRefreshRate = mMeterRefreshRate;
1988
1989 auto title = mIsInput ? XO("Recording Meter Options") : XO("Playback Meter Options");
1990
1991 // Dialog is a child of the project, rather than of the toolbar.
1992 // This determines where it pops up.
1993
1994 wxDialogWrapper dlg( FindProjectFrame( mProject ), wxID_ANY, title);
1995 dlg.SetName();
1996 ShuttleGui S(&dlg, eIsCreating);
1997 S.StartVerticalLay();
1998 {
1999 S.StartStatic(XO("Refresh Rate"), 0);
2000 {
2001 S.AddFixedText(XO(
2002"Higher refresh rates make the meter show more frequent\nchanges. A rate of 30 per second or less should prevent\nthe meter affecting audio quality on slower machines."));
2003 S.StartHorizontalLay();
2004 {
2005 rate = S.Name(XO("Meter refresh rate per second [1-100]"))
2006 .Validator<IntegerValidator<long>>(
2007 &mMeterRefreshRate, NumValidatorStyle::DEFAULT,
2009 .AddTextBox(XXO("Meter refresh rate per second [1-100]: "),
2010 wxString::Format(wxT("%d"), meterRefreshRate),
2011 10);
2012 }
2013 S.EndHorizontalLay();
2014 }
2015 S.EndStatic();
2016
2017 S.StartHorizontalLay();
2018 {
2019 S.StartStatic(XO("Meter Style"), 0);
2020 {
2021 S.StartVerticalLay();
2022 {
2023 gradient = S.AddRadioButton(XXO("Gradient"), true, mGradient);
2024 rms = S.AddRadioButtonToGroup(XXO("RMS"), false, mGradient);
2025 }
2026 S.EndVerticalLay();
2027 }
2028 S.EndStatic();
2029
2030 S.StartStatic(XO("Meter Type"), 0);
2031 {
2032 S.StartVerticalLay();
2033 {
2034 db = S.AddRadioButton(XXO("dB"), true, mDB);
2035 linear = S.AddRadioButtonToGroup(XXO("Linear"), false, mDB);
2036 }
2037 S.EndVerticalLay();
2038 }
2039 S.EndStatic();
2040
2041 S.StartStatic(XO("Orientation"), 1);
2042 {
2043 S.StartVerticalLay();
2044 {
2045 automatic = S.AddRadioButton(
2046 XXO("Automatic"), AutomaticStereo, mDesiredStyle);
2047 horizontal = S.AddRadioButtonToGroup(
2048 XXO("Horizontal"), HorizontalStereo, mDesiredStyle);
2049 vertical = S.AddRadioButtonToGroup(
2050 XXO("Vertical"), VerticalStereo, mDesiredStyle);
2051 }
2052 S.EndVerticalLay();
2053 }
2054 S.EndStatic();
2055 }
2056 S.EndHorizontalLay();
2057 S.AddStandardButtons();
2058 }
2059 S.EndVerticalLay();
2060 dlg.Layout();
2061 dlg.Fit();
2062
2063 dlg.CenterOnParent();
2064
2065 if (dlg.ShowModal() == wxID_OK)
2066 {
2067 wxArrayStringEx style{
2068 wxT("AutomaticStereo") ,
2069 wxT("HorizontalStereo") ,
2070 wxT("VerticalStereo") ,
2071 };
2072
2073 int s = 0;
2074 s = automatic->GetValue() ? 0 : s;
2075 s = horizontal->GetValue() ? 1 : s;
2076 s = vertical->GetValue() ? 2 : s;
2077
2078 gPrefs->Write(Key(wxT("Style")), style[s]);
2079 gPrefs->Write(Key(wxT("Bars")), gradient->GetValue() ? wxT("Gradient") : wxT("RMS"));
2080 gPrefs->Write(Key(wxT("Type")), db->GetValue() ? wxT("dB") : wxT("Linear"));
2081 gPrefs->Write(Key(wxT("RefreshRate")), rate->GetValue());
2082
2083 gPrefs->Flush();
2084
2085 // Currently, there are 2 playback meters and 2 record meters and any number of
2086 // mixerboard meters, so we have to send out an preferences updated message to
2087 // ensure they all update themselves.
2089 }
2090}
XXO("&Cut/Copy/Paste Toolbar")
static const long MIN_REFRESH_RATE
Definition: MeterPanel.cpp:150
static const long MAX_REFRESH_RATE
Definition: MeterPanel.cpp:151
static int MeterPrefsID()
Definition: MeterPanel.cpp:451
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:70
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
@ eIsCreating
Definition: ShuttleGui.h:39
#define S(N)
Definition: ToChars.cpp:64
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
wxString Key(const wxString &key) const
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Definition: Prefs.cpp:97
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.

References AutomaticStereo, PrefsListener::Broadcast(), eIsCreating, FindProjectFrame(), FileConfig::Flush(), gPrefs, HorizontalStereo, Key(), MAX_REFRESH_RATE, mDB, mDesiredStyle, MeterPrefsID(), mGradient, MIN_REFRESH_RATE, mIsInput, mMeterRefreshRate, mProject, S, wxDialogWrapper::SetName(), title, VerticalStereo, wxT(), XO(), and XXO().

Here is the call graph for this function:

◆ OnSetFocus()

void MeterPanel::OnSetFocus ( wxFocusEvent &  evt)
private

Definition at line 801 of file MeterPanel.cpp.

802{
803 mIsFocused = true;
804 Refresh(false);
805}

References mIsFocused.

◆ OnSize()

void MeterPanel::OnSize ( wxSizeEvent &  evt)
private

Definition at line 717 of file MeterPanel.cpp.

718{
719 GetClientSize(&mWidth, &mHeight);
720
721 mLayoutValid = false;
722 Refresh();
723}

References mHeight, mLayoutValid, and mWidth.

◆ OnTipTimeout()

void MeterPanel::OnTipTimeout ( wxTimerEvent &  evt)
private

Definition at line 1137 of file MeterPanel.cpp.

1138{
1139 if(mSlider)
1140 mSlider->ShowTip(true);
1141}

References mSlider.

◆ RepaintBarsNow()

void MeterPanel::RepaintBarsNow ( )
private

Definition at line 1576 of file MeterPanel.cpp.

1577{
1578 if (mLayoutValid)
1579 {
1580 // Invalidate the bars so they get redrawn
1581 for (unsigned int i = 0; i < mNumBars; i++)
1582 {
1583 Refresh(false);
1584 }
1585
1586 // Immediate redraw (using wxPaintDC)
1587 Update();
1588
1589 return;
1590 }
1591}

References mLayoutValid, and mNumBars.

Referenced by OnMeterUpdate().

Here is the caller graph for this function:

◆ Reset()

void MeterPanel::Reset ( double  sampleRate,
bool  resetClipping 
)
overridevirtual

This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callback).

Implements MeterPanelBase.

Definition at line 898 of file MeterPanel.cpp.

899{
900 mT = 0;
901 mRate = sampleRate;
902 for (int j = 0; j < kMaxMeterBars; j++)
903 {
904 ResetBar(&mBar[j], resetClipping);
905 }
906
907 // wxTimers seem to be a little unreliable - sometimes they stop for
908 // no good reason, so this "primes" it every now and then...
909 mTimer.Stop();
910
911 // While it's stopped, empty the queue
912 mQueue.Clear();
913
914 mLayoutValid = false;
915
916 mTimer.Start(1000 / mMeterRefreshRate);
917
918 Refresh(false);
919}
const int kMaxMeterBars
Definition: MeterPanel.h:37
void ResetBar(MeterBar *bar, bool resetClipping)

References MeterUpdateQueue::Clear(), kMaxMeterBars, mBar, mLayoutValid, mMeterRefreshRate, mQueue, mRate, mT, mTimer, and ResetBar().

Referenced by UpdatePrefs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ResetBar()

void MeterPanel::ResetBar ( MeterBar bar,
bool  resetClipping 
)
private

Definition at line 1172 of file MeterPanel.cpp.

1173{
1174 b->peak = 0.0;
1175 b->rms = 0.0;
1176 b->peakHold = 0.0;
1177 b->peakHoldTime = 0.0;
1178 if (resetClipping)
1179 {
1180 b->clipping = false;
1181 b->peakPeakHold = 0.0;
1182 }
1183 b->isclipping = false;
1184 b->tailPeakCount = 0;
1185}

References MeterBar::clipping, MeterBar::isclipping, MeterBar::peak, MeterBar::peakHold, MeterBar::peakHoldTime, MeterBar::peakPeakHold, MeterBar::rms, and MeterBar::tailPeakCount.

Referenced by Reset().

Here is the caller graph for this function:

◆ RestoreState()

void MeterPanel::RestoreState ( const State state)

Definition at line 1926 of file MeterPanel.cpp.

1927{
1928 if (!state.mSaved)
1929 return;
1930
1931 mMonitoring = state.mMonitoring;
1932 mActive = state.mActive;
1933 //wxLogDebug("Restore state for %p, is %i", this, mActive );
1934
1935 if (mActive)
1936 mTimer.Start(1000 / mMeterRefreshRate);
1937}

References MeterPanel::State::mActive, mActive, mMeterRefreshRate, MeterPanel::State::mMonitoring, mMonitoring, MeterPanel::State::mSaved, and mTimer.

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SaveState()

auto MeterPanel::SaveState ( )

Definition at line 1921 of file MeterPanel.cpp.

1922{
1923 return { true, mMonitoring, mActive };
1924}

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SetActiveStyle()

void MeterPanel::SetActiveStyle ( Style  style)
private

Definition at line 1205 of file MeterPanel.cpp.

1206{
1207 mStyle = newStyle;
1208
1209 // Set dummy ruler bounds so width/height can be retrieved
1210 // NOTE: Make sure the Right and Bottom values are large enough to
1211 // ensure full width/height of digits get calculated.
1212 mRuler.SetBounds(0, 0, 500, 500);
1213
1214 if (mDB)
1215 {
1218 {
1219 mRuler.SetOrientation(wxHORIZONTAL);
1221 }
1222 else
1223 {
1224 mRuler.SetOrientation(wxVERTICAL);
1226 }
1227 }
1228 else
1229 {
1232 {
1233 mRuler.SetOrientation(wxHORIZONTAL);
1234 mRuler.SetRange(0, 1);
1235 }
1236 else
1237 {
1238 mRuler.SetOrientation(wxVERTICAL);
1239 mRuler.SetRange(1, 0);
1240 }
1241 }
1242
1244}
void SetOrientation(int orient)
Definition: Ruler.cpp:174
void GetMaxSize(wxCoord *width, wxCoord *height)
Definition: Ruler.cpp:1603
void SetRange(double min, double max)
Definition: Ruler.cpp:188
void SetFormat(RulerFormat format)
Definition: Ruler.cpp:131
@ LinearDBFormat
Definition: Ruler.h:34
@ RealFormat
Definition: Ruler.h:31

References Ruler::GetMaxSize(), HorizontalStereo, HorizontalStereoCompact, Ruler::LinearDBFormat, mDB, mDBRange, mRuler, mRulerHeight, mRulerWidth, mStyle, Ruler::RealFormat, Ruler::SetBounds(), Ruler::SetFormat(), Ruler::SetOrientation(), and Ruler::SetRange().

Referenced by HandleLayout(), SetStyle(), and UpdatePrefs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetBarAndClip()

void MeterPanel::SetBarAndClip ( int  iBar,
bool  vert 
)
private

Definition at line 1246 of file MeterPanel.cpp.

1247{
1248 // Save the orientation
1249 mBar[iBar].vert = vert;
1250
1251 // Create the bar rectangle and educe to fit inside the bevel
1252 mBar[iBar].r = mBar[iBar].b;
1253 mBar[iBar].r.x += 1;
1254 mBar[iBar].r.width -= 1;
1255 mBar[iBar].r.y += 1;
1256 mBar[iBar].r.height -= 1;
1257
1258 if (vert)
1259 {
1260 if (mClip)
1261 {
1262 // Create the clip rectangle
1263 mBar[iBar].rClip = mBar[iBar].b;
1264 mBar[iBar].rClip.height = 3;
1265
1266 // Make room for the clipping indicator
1267 mBar[iBar].b.y += 3 + gap;
1268 mBar[iBar].b.height -= 3 + gap;
1269 mBar[iBar].r.y += 3 + gap;
1270 mBar[iBar].r.height -= 3 + gap;
1271 }
1272 }
1273 else
1274 {
1275 if (mClip)
1276 {
1277 // Make room for the clipping indicator
1278 mBar[iBar].b.width -= 4;
1279 mBar[iBar].r.width -= 4;
1280
1281 // Create the indicator rectangle
1282 mBar[iBar].rClip = mBar[iBar].b;
1283 mBar[iBar].rClip.x = mBar[iBar].b.GetRight() + 1 + gap; // +1 for bevel
1284 mBar[iBar].rClip.width = 3;
1285 }
1286 }
1287}
wxRect rClip
Definition: MeterPanel.h:47
bool vert
Definition: MeterPanel.h:40

References MeterBar::b, gap, mBar, mClip, MeterBar::r, MeterBar::rClip, and MeterBar::vert.

Referenced by HandleLayout().

Here is the caller graph for this function:

◆ SetFocusFromKbd()

void MeterPanel::SetFocusFromKbd ( )
override

Definition at line 2110 of file MeterPanel.cpp.

2111{
2112 auto temp = TemporarilyAllowFocus();
2113 SetFocus();
2114}
static TempAllowFocus TemporarilyAllowFocus()

References MeterPanelBase::TemporarilyAllowFocus().

Here is the call graph for this function:

◆ SetMixer()

void MeterPanel::SetMixer ( wxCommandEvent &  event)

Definition at line 829 of file MeterPanel.cpp.

830{
831#if USE_PORTMIXER
832 if (mSlider)
833 {
834 float inputVolume;
835 float outputVolume;
836 int inputSource;
837
838 Refresh();
839
840 auto gAudioIO = AudioIO::Get();
841 gAudioIO->GetMixer(&inputSource, &inputVolume, &outputVolume);
842
843 if (mIsInput)
844 inputVolume = mSlider->Get();
845 else
846 outputVolume = mSlider->Get();
847
848 gAudioIO->SetMixer(inputSource, inputVolume, outputVolume);
849
850#if wxUSE_ACCESSIBILITY
851 GetAccessible()->NotifyEvent( wxACC_EVENT_OBJECT_VALUECHANGE,
852 this,
853 wxOBJID_CLIENT,
854 wxACC_SELF );
855#endif
856
857 }
858#endif // USE_PORTMIXER
859}

References AudioIO::Get(), mIsInput, and mSlider.

Referenced by Decrease(), Increase(), and ShowDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetName()

void MeterPanel::SetName ( const TranslatableString name)

Definition at line 1964 of file MeterPanel.cpp.

1965{
1967 if(mSlider)
1968 mSlider->SetName(tip);
1969}

References mSlider, and wxPanelWrapper::SetName().

Referenced by MeterToolBar::Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetStyle()

void MeterPanel::SetStyle ( Style  newStyle)

Definition at line 817 of file MeterPanel.cpp.

818{
819 if (mStyle != newStyle && mDesiredStyle == AutomaticStereo)
820 {
821 SetActiveStyle(newStyle);
822
823 mLayoutValid = false;
824
825 Refresh(false);
826 }
827}

References AutomaticStereo, mDesiredStyle, mLayoutValid, mStyle, and SetActiveStyle().

Here is the call graph for this function:

◆ ShowDialog()

bool MeterPanel::ShowDialog ( )

Definition at line 861 of file MeterPanel.cpp.

862{
863 if (!mSlider)
864 return false;
865
866 auto changed = mSlider->ShowDialog();
867 if (changed)
868 {
869 wxCommandEvent e;
870 SetMixer(e);
871 }
872
873 return changed;
874}

References mSlider, and SetMixer().

Referenced by MeterToolBar::ShowInputGainDialog(), and MeterToolBar::ShowOutputGainDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowMenu()

void MeterPanel::ShowMenu ( const wxPoint &  pos)

Definition at line 1943 of file MeterPanel.cpp.

1944{
1945 wxMenu menu;
1946 // Note: these should be kept in the same order as the enum
1947 if (mIsInput) {
1948 wxMenuItem *mi;
1949 if (mMonitoring)
1950 mi = menu.Append(OnMonitorID, _("Stop Monitoring"));
1951 else
1952 mi = menu.Append(OnMonitorID, _("Start Monitoring"));
1953 mi->Enable(!mActive || mMonitoring);
1954 }
1955
1956 menu.Append(OnPreferencesID, _("Options..."));
1957
1958 BasicMenu::Handle{ &menu }.Popup(
1960 { pos.x, pos.y }
1961 );
1962}
@ OnPreferencesID
Definition: MeterPanel.cpp:265
@ OnMonitorID
Definition: MeterPanel.cpp:264
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Definition: BasicMenu.cpp:209
Window placement information for wxWidgetsBasicUI can be constructed from a wxWindow pointer.

References _, mActive, mIsInput, mMonitoring, OnMonitorID, OnPreferencesID, and BasicMenu::Handle::Popup().

Referenced by OnCharHook(), OnContext(), OnMouse(), and MeterToolBar::Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StartMonitoring()

void MeterPanel::StartMonitoring ( )

Definition at line 1858 of file MeterPanel.cpp.

1859{
1860 bool start = !mMonitoring;
1861
1862 auto gAudioIO = AudioIO::Get();
1863 if (gAudioIO->IsMonitoring()){
1864 gAudioIO->StopStream();
1865 }
1866
1867 if (start && !gAudioIO->IsBusy()){
1869 if (p)
1870 gAudioIO->StartMonitoring(ProjectAudioIO::GetDefaultOptions(*p));
1871
1872 mLayoutValid = false;
1873
1874 Refresh(false);
1875 }
1876}
static AudioIOStartStreamOptions GetDefaultOptions(AudacityProject &project, bool newDefaults=false)
Invoke the global hook, supplying a default argument.

References AudioIO::Get(), ProjectAudioIO::GetDefaultOptions(), mLayoutValid, mMonitoring, and mProject.

Referenced by OnMonitor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StopMonitoring()

void MeterPanel::StopMonitoring ( )

Definition at line 1878 of file MeterPanel.cpp.

1878 {
1879 mMonitoring = false;
1880 auto gAudioIO = AudioIO::Get();
1881 if (gAudioIO->IsMonitoring()){
1882 gAudioIO->StopStream();
1883 }
1884}

References AudioIO::Get(), and mMonitoring.

Here is the call graph for this function:

◆ UpdateDisplay()

void MeterPanel::UpdateDisplay ( unsigned  numChannels,
int  numFrames,
const float *  sampleData 
)
overridevirtual

Update the meters with a block of audio data.

Process the supplied block of audio data, extracting the peak and RMS levels to send to the meter. Also record runs of clipped samples to detect clipping that lies on block boundaries. This method is thread-safe! Feel free to call from a different thread (like from an audio I/O callback).

First overload:

Parameters
numChannelsThe number of channels of audio being played back or recorded.
numFramesThe number of frames (samples) in this data block. It is assumed that there are the same number of frames in each channel.
sampleDataThe audio data itself, as interleaved samples. So indexing through the array we get the first sample of channel, first sample of channel 2 etc up to the first sample of channel (numChannels), then the second sample of channel 1, second sample of channel 2, and so to the second sample of channel (numChannels). The last sample in the array will be the (numFrames) sample for channel (numChannels).

The second overload is for ease of use in MixerBoard.

Implements MeterPanelBase.

Definition at line 958 of file MeterPanel.cpp.

960{
961 auto sptr = sampleData;
962 auto num = std::min(numChannels, mNumBars);
963 MeterUpdateMsg msg;
964
965 memset(&msg, 0, sizeof(msg));
966 msg.numFrames = numFrames;
967
968 for(int i=0; i<numFrames; i++) {
969 for(unsigned int j=0; j<num; j++) {
970 msg.peak[j] = floatMax(msg.peak[j], fabs(sptr[j]));
971 msg.rms[j] += sptr[j]*sptr[j];
972
973 // In addition to looking for mNumPeakSamplesToClip peaked
974 // samples in a row, also send the number of peaked samples
975 // at the head and tail, in case there's a run of peaked samples
976 // that crosses block boundaries
977 if (fabs(sptr[j])>=MAX_AUDIO) {
978 if (msg.headPeakCount[j]==i)
979 msg.headPeakCount[j]++;
980 msg.tailPeakCount[j]++;
982 msg.clipping[j] = true;
983 }
984 else
985 msg.tailPeakCount[j] = 0;
986 }
987 sptr += numChannels;
988 }
989 for(unsigned int j=0; j<mNumBars; j++)
990 msg.rms[j] = sqrt(msg.rms[j]/numFrames);
991
992 mQueue.Put(msg);
993}
int min(int a, int b)
#define MAX_AUDIO
Definition: MemoryX.h:546
bool Put(MeterUpdateMsg &msg)
Definition: MeterPanel.cpp:207

References MeterUpdateMsg::clipping, floatMax(), MeterUpdateMsg::headPeakCount, MAX_AUDIO, min(), mNumBars, mNumPeakSamplesToClip, mQueue, MeterUpdateMsg::numFrames, MeterUpdateMsg::peak, MeterUpdateQueue::Put(), MeterUpdateMsg::rms, and MeterUpdateMsg::tailPeakCount.

Here is the call graph for this function:

◆ UpdatePrefs()

void MeterPanel::UpdatePrefs ( )
overrideprivatevirtual

Implements PrefsListener.

Definition at line 405 of file MeterPanel.cpp.

406{
408
411 gPrefs->Read(Key(wxT("RefreshRate")), 30)));
412 mGradient = gPrefs->Read(Key(wxT("Bars")), wxT("Gradient")) == wxT("Gradient");
413 mDB = gPrefs->Read(Key(wxT("Type")), wxT("dB")) == wxT("dB");
414 mMeterDisabled = gPrefs->Read(Key(wxT("Disabled")), (long)0);
415
417 {
418 wxString style = gPrefs->Read(Key(wxT("Style")));
419 if (style == wxT("AutomaticStereo"))
420 {
422 }
423 else if (style == wxT("HorizontalStereo"))
424 {
426 }
427 else if (style == wxT("VerticalStereo"))
428 {
430 }
431 else
432 {
434 }
435 }
436
437 // Set the desired orientation (resets ruler orientation)
439
440 // Reset to ensure NEW size is retrieved when language changes
441 mLeftSize = wxSize(0, 0);
442 mRightSize = wxSize(0, 0);
443
444 Reset(mRate, false);
445
446 mLayoutValid = false;
447
448 Refresh(false);
449}

References AutomaticStereo, DecibelScaleCutoff, gPrefs, HorizontalStereo, Key(), MAX_REFRESH_RATE, mDB, mDBRange, mDesiredStyle, mGradient, min(), MIN_REFRESH_RATE, mLayoutValid, mLeftSize, mMeterDisabled, mMeterRefreshRate, mRate, mRightSize, Setting< T >::Read(), Reset(), SetActiveStyle(), VerticalStereo, and wxT().

Referenced by UpdateSelectedPrefs().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateSelectedPrefs()

void MeterPanel::UpdateSelectedPrefs ( int  id)
overrideprivatevirtual

Reimplemented from PrefsListener.

Definition at line 457 of file MeterPanel.cpp.

458{
459 if (id == MeterPrefsID())
460 {
461#if USE_PORTMIXER
462 if (mIsInput && mSlider)
463 {
464 // Show or hide the input slider based on whether it works
465 auto gAudioIO = AudioIO::Get();
466 mSlider->SetEnabled(mEnabled && gAudioIO->InputMixerWorks());
467 }
468#endif
469 UpdatePrefs();
470 }
471}

References AudioIO::Get(), mEnabled, MeterPrefsID(), mIsInput, mSlider, and UpdatePrefs().

Here is the call graph for this function:

◆ UpdateSliderControl()

void MeterPanel::UpdateSliderControl ( )

Definition at line 473 of file MeterPanel.cpp.

474{
475#if USE_PORTMIXER
476 float inputVolume;
477 float playbackVolume;
478 int inputSource;
479
480 // Show or hide the input slider based on whether it works
481 auto gAudioIO = AudioIO::Get();
482 if (mIsInput && mSlider)
483 mSlider->SetEnabled(mEnabled && gAudioIO->InputMixerWorks());
484
485 gAudioIO->GetMixer(&inputSource, &inputVolume, &playbackVolume);
486
487 const auto volume = mIsInput ? inputVolume : playbackVolume;
488
489 if (mSlider && (mSlider->Get() != volume))
490 mSlider->Set(volume);
491
492#endif // USE_PORTMIXER
493}

References AudioIO::Get(), mEnabled, mIsInput, and mSlider.

Referenced by MeterToolBar::AdjustInputGain(), MeterToolBar::AdjustOutputGain(), MeterToolBar::ShowInputGainDialog(), MeterToolBar::ShowOutputGainDialog(), and MeterToolBar::UpdateControls().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ MeterAx

friend class MeterAx
friend

Definition at line 316 of file MeterPanel.h.

Member Data Documentation

◆ mActive

bool MeterPanel::mActive
private

Definition at line 283 of file MeterPanel.h.

Referenced by IsActive(), OnAudioIOStatus(), RestoreState(), and ShowMenu().

◆ mAudioCaptureSubscription

Observer::Subscription MeterPanel::mAudioCaptureSubscription
private

Definition at line 251 of file MeterPanel.h.

◆ mAudioIOStatusSubscription

Observer::Subscription MeterPanel::mAudioIOStatusSubscription
private

Definition at line 250 of file MeterPanel.h.

◆ mBar

MeterBar MeterPanel::mBar[kMaxMeterBars]
private

◆ mBitmap

std::unique_ptr<wxBitmap> MeterPanel::mBitmap
private

Definition at line 290 of file MeterPanel.h.

Referenced by DrawMeterBar(), and OnPaint().

◆ mBkgndBrush

wxBrush MeterPanel::mBkgndBrush
private

Definition at line 301 of file MeterPanel.h.

Referenced by DrawMeterBar(), and OnPaint().

◆ mBrush

wxBrush MeterPanel::mBrush
private

Definition at line 298 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mClip

bool MeterPanel::mClip
private

Definition at line 273 of file MeterPanel.h.

Referenced by DrawMeterBar(), OnPaint(), and SetBarAndClip().

◆ mClipBrush

wxBrush MeterPanel::mClipBrush
private

Definition at line 300 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mDB

bool MeterPanel::mDB
private

Definition at line 269 of file MeterPanel.h.

Referenced by OnMeterUpdate(), OnPaint(), OnPreferences(), SetActiveStyle(), and UpdatePrefs().

◆ mDBRange

int MeterPanel::mDBRange
private

Definition at line 270 of file MeterPanel.h.

Referenced by OnMeterUpdate(), OnPaint(), SetActiveStyle(), and UpdatePrefs().

◆ mDecay

bool MeterPanel::mDecay
private

Definition at line 271 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mDecayRate

float MeterPanel::mDecayRate
private

Definition at line 272 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mDesiredStyle

Style MeterPanel::mDesiredStyle
private

Definition at line 267 of file MeterPanel.h.

Referenced by HandleLayout(), OnPreferences(), SetStyle(), and UpdatePrefs().

◆ mDisabledBkgndBrush

wxBrush MeterPanel::mDisabledBkgndBrush
private

Definition at line 302 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mDisabledPen

wxPen MeterPanel::mDisabledPen
private

Definition at line 296 of file MeterPanel.h.

◆ mEnabled

bool MeterPanel::mEnabled { true }
private

Definition at line 311 of file MeterPanel.h.

Referenced by OnAudioCapture(), UpdateSelectedPrefs(), and UpdateSliderControl().

◆ mFocusRect

wxRect MeterPanel::mFocusRect
private

Definition at line 314 of file MeterPanel.h.

◆ mGradient

bool MeterPanel::mGradient
private

Definition at line 268 of file MeterPanel.h.

Referenced by DrawMeterBar(), OnPaint(), OnPreferences(), and UpdatePrefs().

◆ mHeight

int MeterPanel::mHeight
private

Definition at line 259 of file MeterPanel.h.

Referenced by HandleLayout(), OnPaint(), and OnSize().

◆ mIsFocused

bool MeterPanel::mIsFocused
private

Definition at line 313 of file MeterPanel.h.

Referenced by OnKillFocus(), OnPaint(), and OnSetFocus().

◆ mIsInput

bool MeterPanel::mIsInput
private

◆ mLayoutValid

bool MeterPanel::mLayoutValid
private

◆ mLeftSize

wxSize MeterPanel::mLeftSize
private

Definition at line 293 of file MeterPanel.h.

Referenced by HandleLayout(), and UpdatePrefs().

◆ mLeftText

wxString MeterPanel::mLeftText
private

Definition at line 304 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mLeftTextPos

wxPoint MeterPanel::mLeftTextPos
private

Definition at line 291 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mMeterDisabled

long MeterPanel::mMeterDisabled
private

Definition at line 279 of file MeterPanel.h.

Referenced by DrawMeterBar(), IsMeterDisabled(), OnMeterUpdate(), and UpdatePrefs().

◆ mMeterRefreshRate

long MeterPanel::mMeterRefreshRate
private

Definition at line 278 of file MeterPanel.h.

Referenced by OnAudioIOStatus(), OnPreferences(), Reset(), RestoreState(), and UpdatePrefs().

◆ mMonitoring

bool MeterPanel::mMonitoring
private

◆ mNumBars

unsigned MeterPanel::mNumBars
private

◆ mNumPeakSamplesToClip

int MeterPanel::mNumPeakSamplesToClip
private

Definition at line 274 of file MeterPanel.h.

Referenced by OnMeterUpdate(), and UpdateDisplay().

◆ mPeakHoldDuration

double MeterPanel::mPeakHoldDuration
private

Definition at line 275 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mPeakPeakPen

wxPen MeterPanel::mPeakPeakPen
private

Definition at line 297 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mPen

wxPen MeterPanel::mPen
private

Definition at line 295 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mProject

AudacityProject* MeterPanel::mProject
private

Definition at line 253 of file MeterPanel.h.

Referenced by OnAudioCapture(), OnAudioIOStatus(), OnPreferences(), and StartMonitoring().

◆ mQueue

MeterUpdateQueue MeterPanel::mQueue
private

Definition at line 254 of file MeterPanel.h.

Referenced by Clear(), OnMeterUpdate(), Reset(), and UpdateDisplay().

◆ mRate

double MeterPanel::mRate
private

Definition at line 277 of file MeterPanel.h.

Referenced by OnMeterUpdate(), Reset(), and UpdatePrefs().

◆ mRightSize

wxSize MeterPanel::mRightSize
private

Definition at line 294 of file MeterPanel.h.

Referenced by HandleLayout(), and UpdatePrefs().

◆ mRightText

wxString MeterPanel::mRightText
private

Definition at line 305 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mRightTextPos

wxPoint MeterPanel::mRightTextPos
private

Definition at line 292 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mRMSBrush

wxBrush MeterPanel::mRMSBrush
private

Definition at line 299 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mRuler

Ruler MeterPanel::mRuler
private

Definition at line 303 of file MeterPanel.h.

Referenced by HandleLayout(), OnPaint(), and SetActiveStyle().

◆ mRulerHeight

int MeterPanel::mRulerHeight
private

Definition at line 262 of file MeterPanel.h.

Referenced by HandleLayout(), and SetActiveStyle().

◆ mRulerWidth

int MeterPanel::mRulerWidth
private

Definition at line 261 of file MeterPanel.h.

Referenced by HandleLayout(), and SetActiveStyle().

◆ mSlider

std::unique_ptr<LWSlider> MeterPanel::mSlider
private

◆ mSliderPos

wxPoint MeterPanel::mSliderPos
private

Definition at line 308 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mSliderSize

wxSize MeterPanel::mSliderSize
private

Definition at line 309 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mStyle

Style MeterPanel::mStyle
private

◆ mT

double MeterPanel::mT
private

Definition at line 276 of file MeterPanel.h.

Referenced by OnMeterUpdate(), and Reset().

◆ mTimer

wxTimer MeterPanel::mTimer
private

Definition at line 255 of file MeterPanel.h.

Referenced by OnAudioIOStatus(), Reset(), and RestoreState().

◆ mTipTimer

wxTimer MeterPanel::mTipTimer
private

Definition at line 256 of file MeterPanel.h.

Referenced by OnKillFocus(), and OnMouse().

◆ mWidth

int MeterPanel::mWidth
private

Definition at line 258 of file MeterPanel.h.

Referenced by HandleLayout(), OnPaint(), and OnSize().


The documentation for this class was generated from the following files: