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 292 of file MeterPanel.cpp.

299: MeterPanelBase(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER | wxWANTS_CHARS),
301 mQueue{ 1024 },
302 mWidth(size.x),
303 mHeight(size.y),
304 mIsInput(isInput),
306 mGradient(true),
307 mDB(true),
309 mDecay(true),
310 mDecayRate(fDecayRate),
311 mClip(true),
314 mT(0),
315 mRate(0),
316 mMonitoring(false),
317 mActive(false),
318 mNumBars(0),
319 mLayoutValid(false),
320 mBitmap{},
322{
323 // i18n-hint: Noun (the meter is used for playback or record level monitoring)
324 SetName( XO("Meter") );
325 // Suppress warnings about the header file
326 wxUnusedVar(SpeakerMenu_xpm);
327 wxUnusedVar(MicMenu_xpm);
328 wxUnusedVar(PrefStyles);
329
331
332 mIsFocused = false;
333
334#if wxUSE_ACCESSIBILITY
335 SetAccessible(safenew MeterAx(this));
336#endif
337
338 // Do this BEFORE UpdatePrefs()!
341 mRuler.SetLabelEdges(true);
342 //mRuler.SetTickColour( wxColour( 0,0,255 ) );
343
345 {
346 mSlider = std::make_unique<LWSlider>(this, XO(""),
347 pos,
348 size,
350 false, /* showlabels */
351 false, /* drawticks */
352 false, /* drawtrack */
353 false /* alwayshidetip */
354 );
355 mSlider->SetScroll(0.1f, 2.0f);
356 }
357
359 UpdatePrefs();
360
361 wxColour backgroundColour = theTheme.Colour( clrMedium);
362 mBkgndBrush = wxBrush(backgroundColour, wxBRUSHSTYLE_SOLID);
363 SetBackgroundColour( backgroundColour );
364
365 mPeakPeakPen = wxPen(theTheme.Colour( clrMeterPeak), 1, wxPENSTYLE_SOLID);
366 mDisabledPen = wxPen(theTheme.Colour( clrMeterDisabledPen), 1, wxPENSTYLE_SOLID);
367
370
373
374 if (mIsInput) {
375 mPen = wxPen( theTheme.Colour( clrMeterInputPen ), 1, wxPENSTYLE_SOLID);
376 mBrush = wxBrush( theTheme.Colour( clrMeterInputBrush ), wxBRUSHSTYLE_SOLID);
377 mRMSBrush = wxBrush( theTheme.Colour( clrMeterInputRMSBrush ), wxBRUSHSTYLE_SOLID);
378 mClipBrush = wxBrush( theTheme.Colour( clrMeterInputClipBrush ), wxBRUSHSTYLE_SOLID);
379// mLightPen = wxPen( theTheme.Colour( clrMeterInputLightPen ), 1, wxSOLID);
380// mDarkPen = wxPen( theTheme.Colour( clrMeterInputDarkPen ), 1, wxSOLID);
381 }
382 else {
383 mPen = wxPen( theTheme.Colour( clrMeterOutputPen ), 1, wxPENSTYLE_SOLID);
384 mBrush = wxBrush( theTheme.Colour( clrMeterOutputBrush ), wxBRUSHSTYLE_SOLID);
385 mRMSBrush = wxBrush( theTheme.Colour( clrMeterOutputRMSBrush ), wxBRUSHSTYLE_SOLID);
386 mClipBrush = wxBrush( theTheme.Colour( clrMeterOutputClipBrush ), wxBRUSHSTYLE_SOLID);
387// mLightPen = wxPen( theTheme.Colour( clrMeterOutputLightPen ), 1, wxSOLID);
388// mDarkPen = wxPen( theTheme.Colour( clrMeterOutputDarkPen ), 1, wxSOLID);
389 }
390
391// mDisabledBkgndBrush = wxBrush(theTheme.Colour( clrMeterDisabledBrush), wxSOLID);
392 // No longer show a difference in the background colour when not monitoring.
393 // We have the tip instead.
395
396 mTipTimer.SetOwner(this, OnTipTimeoutID);
397 mTimer.SetOwner(this, OnMeterUpdateID);
398 // TODO: Yikes. Hard coded sample rate.
399 // JKC: I've looked at this, and it's benignish. It just means that the meter
400 // balistics are right for 44KHz and a bit more frisky than they should be
401 // for higher sample rates.
402 Reset(44100.0, true);
403}
#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:9
@ OnMeterUpdateID
Definition: MeterPanel.cpp:267
@ OnTipTimeoutID
Definition: MeterPanel.cpp:270
static const wxChar * PrefStyles[]
Definition: MeterPanel.cpp:259
const auto project
THEME_API Theme theTheme
Definition: Theme.cpp:82
static AudioIO * Get()
Definition: AudioIO.cpp:126
static const LinearDBFormat & Instance()
static const LinearUpdater & Instance()
MeterPanelBase(Args &&...args)
bool mLayoutValid
Definition: MeterPanel.h:288
void UpdatePrefs() override
Definition: MeterPanel.cpp:410
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:478
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:899
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:192
void SetFonts(const wxFont &minorFont, const wxFont &majorFont, const wxFont &minorMinorFont)
Definition: Ruler.cpp:231
void SetLabelEdges(bool labelEdges)
Definition: Ruler.cpp:179
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
wxColour & Colour(int iIndex)

Member Function Documentation

◆ Clear()

void MeterPanel::Clear ( )
overridevirtual

Implements MeterPanelBase.

Definition at line 405 of file MeterPanel.cpp.

406{
407 mQueue.Clear();
408}

References MeterUpdateQueue::Clear(), and mQueue.

Here is the call graph for this function:

◆ Decrease()

void MeterPanel::Decrease ( float  steps)

Definition at line 888 of file MeterPanel.cpp.

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

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 1594 of file MeterPanel.cpp.

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

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

Referenced by HandleLayout(), and OnPaint().

Here is the caller graph for this function:

◆ GetMaxPeak()

float MeterPanel::GetMaxPeak ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1145 of file MeterPanel.cpp.

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

References mBar, and mNumBars.

◆ GetPeakHold()

float MeterPanel::GetPeakHold ( ) const

Definition at line 1155 of file MeterPanel.cpp.

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

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 1290 of file MeterPanel.cpp.

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

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

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 1188 of file MeterPanel.cpp.

1189{
1190 return mActive;
1191}

References mActive.

◆ IsClipping()

bool MeterPanel::IsClipping ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1198 of file MeterPanel.cpp.

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

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 1854 of file MeterPanel.cpp.

1855{
1856 return mMeterDisabled != 0;
1857}

References mMeterDisabled.

◆ IsMonitoring()

bool MeterPanel::IsMonitoring ( ) const

Definition at line 1193 of file MeterPanel.cpp.

1194{
1195 return mMonitoring;
1196}

References mMonitoring.

◆ Key()

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

Definition at line 2095 of file MeterPanel.cpp.

2096{
2098 {
2099 return wxT("/Meter/Mixerboard/") + key;
2100 }
2101
2102 if (mIsInput)
2103 {
2104 return wxT("/Meter/Input/") + key;
2105 }
2106
2107 return wxT("/Meter/Output/") + key;
2108}
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 1908 of file MeterPanel.cpp.

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

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

◆ OnAudioIOStatus()

void MeterPanel::OnAudioIOStatus ( AudioIOEvent  evt)
private

Definition at line 1887 of file MeterPanel.cpp.

1888{
1889 if (!mIsInput != (evt.type == AudioIOEvent::PLAYBACK))
1890 return;
1891
1892 AudacityProject *p = evt.pProject;
1893 mActive = evt.on && (p == mProject);
1894 if( mActive ){
1895 mTimer.Start(1000 / mMeterRefreshRate);
1896 if (evt.type == AudioIOEvent::MONITOR)
1898 } else {
1899 mTimer.Stop();
1900 mMonitoring = false;
1901 }
1902
1903 // Only refresh is we're the active meter
1904 if (IsShownOnScreen())
1905 Refresh(false);
1906}
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

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 752 of file MeterPanel.cpp.

753{
754 switch(evt.GetKeyCode())
755 {
756 // These are handled in the OnCharHook handler because, on Windows at least, the
757 // key up event will be passed on to the menu if we show it here. This causes
758 // the default sound to be heard if assigned.
759 case WXK_RETURN:
760 case WXK_NUMPAD_ENTER:
761 case WXK_WINDOWS_MENU:
762 case WXK_MENU:
764 ShowMenu(GetClientRect().GetBottomLeft());
765 else
766 evt.Skip();
767 break;
768 default:
769 evt.Skip();
770 break;
771 }
772}
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 774 of file MeterPanel.cpp.

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

References mStyle, and ShowMenu().

Here is the call graph for this function:

◆ OnErase()

void MeterPanel::OnErase ( wxEraseEvent &  evt)
private

Definition at line 500 of file MeterPanel.cpp.

501{
502 // Ignore it to prevent flashing
503}

◆ OnKeyDown()

void MeterPanel::OnKeyDown ( wxKeyEvent &  evt)
private

Definition at line 786 of file MeterPanel.cpp.

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

References mSlider.

◆ OnKillFocus()

void MeterPanel::OnKillFocus ( wxFocusEvent &  evt)
private

Definition at line 808 of file MeterPanel.cpp.

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

References mIsFocused, mSlider, and mTipTimer.

◆ OnMeterUpdate()

void MeterPanel::OnMeterUpdate ( wxTimerEvent &  evt)
private

Definition at line 1041 of file MeterPanel.cpp.

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

1976{
1978}
void StartMonitoring()

References StartMonitoring().

Here is the call graph for this function:

◆ OnMouse()

void MeterPanel::OnMouse ( wxMouseEvent &  evt)
private

Definition at line 726 of file MeterPanel.cpp.

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

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 505 of file MeterPanel.cpp.

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

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

References AutomaticStereo, PrefsListener::Broadcast(), eIsCreating, FindProjectFrame(), audacity::BasicSettings::Flush(), gPrefs, HorizontalStereo, Key(), MAX_REFRESH_RATE, mDB, mDesiredStyle, MeterPrefsID(), mGradient, MIN_REFRESH_RATE, mIsInput, mMeterRefreshRate, mProject, S, wxDialogWrapper::SetName(), anonymous_namespace{AudacityDontAskAgainMessageDialog.cpp}::style, title, VerticalStereo, audacity::BasicSettings::Write(), wxT(), XO(), and XXO().

Here is the call graph for this function:

◆ OnSetFocus()

void MeterPanel::OnSetFocus ( wxFocusEvent &  evt)
private

Definition at line 802 of file MeterPanel.cpp.

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

References mIsFocused.

◆ OnSize()

void MeterPanel::OnSize ( wxSizeEvent &  evt)
private

Definition at line 718 of file MeterPanel.cpp.

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

References mHeight, mLayoutValid, and mWidth.

◆ OnTipTimeout()

void MeterPanel::OnTipTimeout ( wxTimerEvent &  evt)
private

Definition at line 1138 of file MeterPanel.cpp.

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

References mSlider.

◆ RepaintBarsNow()

void MeterPanel::RepaintBarsNow ( )
private

Definition at line 1577 of file MeterPanel.cpp.

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

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 899 of file MeterPanel.cpp.

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

References MeterUpdateQueue::Clear(), kMaxMeterBars, mBar, mLayoutValid, mMeterRefreshRate, mQueue, mRate, mT, mTimer, ResetBar(), and anonymous_namespace{ClipSegmentTest.cpp}::sampleRate.

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 1173 of file MeterPanel.cpp.

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

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 1929 of file MeterPanel.cpp.

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

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 1924 of file MeterPanel.cpp.

1925{
1926 return { true, mMonitoring, mActive };
1927}

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SetActiveStyle()

void MeterPanel::SetActiveStyle ( Style  style)
private

Definition at line 1206 of file MeterPanel.cpp.

1207{
1208 mStyle = newStyle;
1209
1210 // Set dummy ruler bounds so width/height can be retrieved
1211 // NOTE: Make sure the Right and Bottom values are large enough to
1212 // ensure full width/height of digits get calculated.
1213 mRuler.SetBounds(0, 0, 500, 500);
1214
1215 if (mDB)
1216 {
1219 {
1220 mRuler.SetOrientation(wxHORIZONTAL);
1222 }
1223 else
1224 {
1225 mRuler.SetOrientation(wxVERTICAL);
1227 }
1228 }
1229 else
1230 {
1233 {
1234 mRuler.SetOrientation(wxHORIZONTAL);
1235 mRuler.SetRange(0, 1);
1236 }
1237 else
1238 {
1239 mRuler.SetOrientation(wxVERTICAL);
1240 mRuler.SetRange(1, 0);
1241 }
1242 }
1243
1245}
static const RealFormat & LinearInstance()
Definition: RealFormat.cpp:14
void SetOrientation(int orient)
Definition: Ruler.cpp:141
void SetFormat(const RulerFormat *pFormat)
Definition: Ruler.cpp:104
void GetMaxSize(wxCoord *width, wxCoord *height)
Definition: Ruler.cpp:616
void SetRange(double min, double max)
Definition: Ruler.cpp:152

References Ruler::GetMaxSize(), HorizontalStereo, HorizontalStereoCompact, LinearDBFormat::Instance(), RealFormat::LinearInstance(), mDB, mDBRange, mRuler, mRulerHeight, mRulerWidth, mStyle, 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 1247 of file MeterPanel.cpp.

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

2114{
2115 auto temp = TemporarilyAllowFocus();
2116 SetFocus();
2117}
static TempAllowFocus TemporarilyAllowFocus()
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
Definition: BasicUI.h:382

References BasicUI::SetFocus(), and MeterPanelBase::TemporarilyAllowFocus().

Here is the call graph for this function:

◆ SetMixer()

void MeterPanel::SetMixer ( wxCommandEvent &  event)

Definition at line 830 of file MeterPanel.cpp.

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

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 1967 of file MeterPanel.cpp.

1968{
1970 if(mSlider)
1971 mSlider->SetName(tip);
1972}

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 818 of file MeterPanel.cpp.

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

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

Here is the call graph for this function:

◆ ShowDialog()

bool MeterPanel::ShowDialog ( )

Definition at line 862 of file MeterPanel.cpp.

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

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 1946 of file MeterPanel.cpp.

1947{
1948 wxMenu menu;
1949 // Note: these should be kept in the same order as the enum
1950 if (mIsInput) {
1951 wxMenuItem *mi;
1952 if (mMonitoring)
1953 mi = menu.Append(OnMonitorID, _("Disable Silent Monitoring"));
1954 else
1955 mi = menu.Append(OnMonitorID, _("Enable Silent Monitoring"));
1956 mi->Enable(!mActive || mMonitoring);
1957 }
1958
1959 menu.Append(OnPreferencesID, _("Options..."));
1960
1961 BasicMenu::Handle{ &menu }.Popup(
1963 { pos.x, pos.y }
1964 );
1965}
@ OnPreferencesID
Definition: MeterPanel.cpp:269
@ OnMonitorID
Definition: MeterPanel.cpp:268
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 1859 of file MeterPanel.cpp.

1860{
1861 bool start = !mMonitoring;
1862
1863 auto gAudioIO = AudioIO::Get();
1864 if (gAudioIO->IsMonitoring()){
1865 gAudioIO->StopStream();
1866 }
1867
1868 if (start && !gAudioIO->IsBusy()){
1870 if (p)
1871 gAudioIO->StartMonitoring(ProjectAudioIO::GetDefaultOptions(*p));
1872
1873 mLayoutValid = false;
1874
1875 Refresh(false);
1876 }
1877}
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 1879 of file MeterPanel.cpp.

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

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 959 of file MeterPanel.cpp.

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

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

Here is the call graph for this function:

◆ UpdatePrefs()

void MeterPanel::UpdatePrefs ( )
overrideprivatevirtual

Implements PrefsListener.

Definition at line 410 of file MeterPanel.cpp.

411{
413
416 gPrefs->Read(Key(wxT("RefreshRate")), 30L)));
417 mGradient = gPrefs->Read(Key(wxT("Bars")), wxT("Gradient")) == wxT("Gradient");
418 mDB = gPrefs->Read(Key(wxT("Type")), wxT("dB")) == wxT("dB");
419 mMeterDisabled = gPrefs->Read(Key(wxT("Disabled")), 0L);
420
422 {
423 wxString style = gPrefs->Read(Key(wxT("Style")));
424 if (style == wxT("AutomaticStereo"))
425 {
427 }
428 else if (style == wxT("HorizontalStereo"))
429 {
431 }
432 else if (style == wxT("VerticalStereo"))
433 {
435 }
436 else
437 {
439 }
440 }
441
442 // Set the desired orientation (resets ruler orientation)
444
445 // Reset to ensure NEW size is retrieved when language changes
446 mLeftSize = wxSize(0, 0);
447 mRightSize = wxSize(0, 0);
448
449 Reset(mRate, false);
450
451 mLayoutValid = false;
452
453 Refresh(false);
454}
virtual bool Read(const wxString &key, bool *value) const =0

References AutomaticStereo, DecibelScaleCutoff, gPrefs, HorizontalStereo, Key(), MAX_REFRESH_RATE, mDB, mDBRange, mDesiredStyle, mGradient, min(), MIN_REFRESH_RATE, mLayoutValid, mLeftSize, mMeterDisabled, mMeterRefreshRate, mRate, mRightSize, audacity::BasicSettings::Read(), Setting< T >::Read(), Reset(), SetActiveStyle(), anonymous_namespace{AudacityDontAskAgainMessageDialog.cpp}::style, 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 462 of file MeterPanel.cpp.

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

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

Here is the call graph for this function:

◆ UpdateSliderControl()

void MeterPanel::UpdateSliderControl ( )

Definition at line 478 of file MeterPanel.cpp.

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

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: