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:897
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 886 of file MeterPanel.cpp.

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

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

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

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

Referenced by HandleLayout(), and OnPaint().

Here is the caller graph for this function:

◆ GetMaxPeak()

float MeterPanel::GetMaxPeak ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1143 of file MeterPanel.cpp.

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

References mBar, and mNumBars.

◆ GetPeakHold()

float MeterPanel::GetPeakHold ( ) const

Definition at line 1153 of file MeterPanel.cpp.

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

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

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

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

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

1187{
1188 return mActive;
1189}

References mActive.

◆ IsClipping()

bool MeterPanel::IsClipping ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1196 of file MeterPanel.cpp.

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

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

1853{
1854 return mMeterDisabled != 0;
1855}

References mMeterDisabled.

◆ IsMonitoring()

bool MeterPanel::IsMonitoring ( ) const

Definition at line 1191 of file MeterPanel.cpp.

1192{
1193 return mMonitoring;
1194}

References mMonitoring.

◆ Key()

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

Definition at line 2093 of file MeterPanel.cpp.

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

1907{
1908 if (
1909 event.type == AudioIOEvent::CAPTURE &&
1910 (event.pProject != mProject || !event.on))
1911 {
1912 mEnabled = !event.on;
1913
1914 if (mSlider)
1915 mSlider->SetEnabled(mEnabled);
1916 }
1917}
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 1885 of file MeterPanel.cpp.

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

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

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

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

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

References mSlider.

◆ OnKillFocus()

void MeterPanel::OnKillFocus ( wxFocusEvent &  evt)
private

Definition at line 806 of file MeterPanel.cpp.

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

References mIsFocused, mSlider, and mTipTimer.

◆ OnMeterUpdate()

void MeterPanel::OnMeterUpdate ( wxTimerEvent &  evt)
private

Definition at line 1039 of file MeterPanel.cpp.

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

1974{
1976}
void StartMonitoring()

References StartMonitoring().

Here is the call graph for this function:

◆ OnMouse()

void MeterPanel::OnMouse ( wxMouseEvent &  evt)
private

Definition at line 724 of file MeterPanel.cpp.

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

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 //if( !mMeterDisabled )
531 //{
532 // mBkgndBrush.SetColour( GetParent()->GetBackgroundColour() );
533 //}
534 mBkgndBrush.SetColour( GetBackgroundColour() );
535 dc.SetPen(*wxTRANSPARENT_PEN);
536 dc.SetBrush(mBkgndBrush);
537 dc.DrawRectangle(0, 0, mWidth, mHeight);
538//#endif
539
540 // MixerTrackCluster style has no icon or L/R labels
542 {
543 dc.SetFont(GetFont());
544 dc.SetTextForeground( clrText );
545 dc.SetTextBackground( clrBoxFill );
546 dc.DrawText(mLeftText, mLeftTextPos.x, mLeftTextPos.y);
547 dc.DrawText(mRightText, mRightTextPos.x, mRightTextPos.y);
548 }
549
550 // Setup the colors for the 3 sections of the meter bars
551 wxColor green(117, 215, 112);
552 wxColor yellow(255, 255, 0);
553 wxColor red(255, 0, 0);
554
555 // Bug #2473 - (Sort of) Hack to make text on meters more
556 // visible with darker backgrounds. It would be better to have
557 // different colors entirely and as part of the theme.
558 if (GetBackgroundColour().GetLuminance() < 0.25)
559 {
560 green = wxColor(117-100, 215-100, 112-100);
561 yellow = wxColor(255-100, 255-100, 0);
562 red = wxColor(255-100, 0, 0);
563 }
564 else if (GetBackgroundColour().GetLuminance() < 0.50)
565 {
566 green = wxColor(117-50, 215-50, 112-50);
567 yellow = wxColor(255-50, 255-50, 0);
568 red = wxColor(255-50, 0, 0);
569 }
570
571 // Draw the meter bars at maximum levels
572 for (unsigned int i = 0; i < mNumBars; i++)
573 {
574 // Give it a recessed look
575 AColor::Bevel(dc, false, mBar[i].b);
576
577 // Draw the clip indicator bevel
578 if (mClip)
579 {
580 AColor::Bevel(dc, false, mBar[i].rClip);
581 }
582
583 // Cache bar rect
584 wxRect r = mBar[i].r;
585
586 if (mGradient)
587 {
588 // Calculate the size of the two gradiant segments of the meter
589 double gradw;
590 double gradh;
591 if (mDB)
592 {
593 gradw = (double) r.GetWidth() / mDBRange * 6.0;
594 gradh = (double) r.GetHeight() / mDBRange * 6.0;
595 }
596 else
597 {
598 gradw = (double) r.GetWidth() / 100 * 25;
599 gradh = (double) r.GetHeight() / 100 * 25;
600 }
601
602 if (mBar[i].vert)
603 {
604 // Draw the "critical" segment (starts at top of meter and works down)
605 r.SetHeight(gradh);
606 dc.GradientFillLinear(r, red, yellow, wxSOUTH);
607
608 // Draw the "warning" segment
609 r.SetTop(r.GetBottom());
610 dc.GradientFillLinear(r, yellow, green, wxSOUTH);
611
612 // Draw the "safe" segment
613 r.SetTop(r.GetBottom());
614 r.SetBottom(mBar[i].r.GetBottom());
615 dc.SetPen(*wxTRANSPARENT_PEN);
616 dc.SetBrush(green);
617 dc.DrawRectangle(r);
618 }
619 else
620 {
621 // Draw the "safe" segment
622 r.SetWidth(r.GetWidth() - (int) (gradw + gradw + 0.5));
623 dc.SetPen(*wxTRANSPARENT_PEN);
624 dc.SetBrush(green);
625 dc.DrawRectangle(r);
626
627 // Draw the "warning" segment
628 r.SetLeft(r.GetRight() + 1);
629 r.SetWidth(floor(gradw));
630 dc.GradientFillLinear(r, green, yellow);
631
632 // Draw the "critical" segment
633 r.SetLeft(r.GetRight() + 1);
634 r.SetRight(mBar[i].r.GetRight());
635 dc.GradientFillLinear(r, yellow, red);
636 }
637#ifdef EXPERIMENTAL_METER_LED_STYLE
638 if (!mBar[i].vert)
639 {
640 wxRect r = mBar[i].r;
641 wxPen BackgroundPen;
642 BackgroundPen.SetColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE) );
643 dc.SetPen( BackgroundPen );
644 int i;
645 for(i=0;i<r.width;i++)
646 {
647 // 2 pixel spacing between the LEDs
648 if( (i%7)<2 ){
649 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+r.height );
650 } else {
651 // The LEDs have triangular ends.
652 // This code shapes the ends.
653 int j = abs( (i%7)-4);
654 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+j +1);
655 AColor::Line( dc, i+r.x, r.y+r.height-j, i+r.x, r.y+r.height );
656 }
657 }
658 }
659#endif
660 }
661 }
662 mRuler.SetTickColour( clrText );
663 dc.SetTextForeground( clrText );
664 // Draw the ruler
665 mRuler.Draw(dc);
666
667 // Bitmap created...unselect
668 dc.SelectObject(wxNullBitmap);
669 }
670
671 // Copy predrawn bitmap to the dest DC
672 destDC.DrawBitmap(*mBitmap, 0, 0);
673
674 // Go draw the meter bars, Left & Right channels using current levels
675 for (unsigned int i = 0; i < mNumBars; i++)
676 {
677 DrawMeterBar(destDC, &mBar[i]);
678 }
679
680 destDC.SetTextForeground( clrText );
681
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
698 {
699 bool highlighted =
700 wxRect{ mSliderPos, mSliderSize }.Contains(
701 ScreenToClient(
702 ::wxGetMousePosition()));
703
704 mSlider->Move(mSliderPos);
705 mSlider->AdjustSize(mSliderSize);
706 mSlider->OnPaint(destDC, highlighted);
707 }
708
709 if (mIsFocused)
710 {
711 auto r = GetClientRect();
712 AColor::DrawFocus(destDC, r);
713 }
714}
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 1978 of file MeterPanel.cpp.

1979{
1980 wxTextCtrl *rate;
1981 wxRadioButton *gradient;
1982 wxRadioButton *rms;
1983 wxRadioButton *db;
1984 wxRadioButton *linear;
1985 wxRadioButton *automatic;
1986 wxRadioButton *horizontal;
1987 wxRadioButton *vertical;
1988 int meterRefreshRate = mMeterRefreshRate;
1989
1990 auto title = mIsInput ? XO("Recording Meter Options") : XO("Playback Meter Options");
1991
1992 // Dialog is a child of the project, rather than of the toolbar.
1993 // This determines where it pops up.
1994
1995 wxDialogWrapper dlg( FindProjectFrame( mProject ), wxID_ANY, title);
1996 dlg.SetName();
1997 ShuttleGui S(&dlg, eIsCreating);
1998 S.StartVerticalLay();
1999 {
2000 S.StartStatic(XO("Refresh Rate"), 0);
2001 {
2002 S.AddFixedText(XO(
2003"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."));
2004 S.StartHorizontalLay();
2005 {
2006 rate = S.Name(XO("Meter refresh rate per second [1-100]"))
2007 .Validator<IntegerValidator<long>>(
2008 &mMeterRefreshRate, NumValidatorStyle::DEFAULT,
2010 .AddTextBox(XXO("Meter refresh rate per second [1-100]: "),
2011 wxString::Format(wxT("%d"), meterRefreshRate),
2012 10);
2013 }
2014 S.EndHorizontalLay();
2015 }
2016 S.EndStatic();
2017
2018 S.StartHorizontalLay();
2019 {
2020 S.StartStatic(XO("Meter Style"), 0);
2021 {
2022 S.StartVerticalLay();
2023 {
2024 gradient = S.AddRadioButton(XXO("Gradient"), true, mGradient);
2025 rms = S.AddRadioButtonToGroup(XXO("RMS"), false, mGradient);
2026 }
2027 S.EndVerticalLay();
2028 }
2029 S.EndStatic();
2030
2031 S.StartStatic(XO("Meter Type"), 0);
2032 {
2033 S.StartVerticalLay();
2034 {
2035 db = S.AddRadioButton(XXO("dB"), true, mDB);
2036 linear = S.AddRadioButtonToGroup(XXO("Linear"), false, mDB);
2037 }
2038 S.EndVerticalLay();
2039 }
2040 S.EndStatic();
2041
2042 S.StartStatic(XO("Orientation"), 1);
2043 {
2044 S.StartVerticalLay();
2045 {
2046 automatic = S.AddRadioButton(
2047 XXO("Automatic"), AutomaticStereo, mDesiredStyle);
2048 horizontal = S.AddRadioButtonToGroup(
2049 XXO("Horizontal"), HorizontalStereo, mDesiredStyle);
2050 vertical = S.AddRadioButtonToGroup(
2051 XXO("Vertical"), VerticalStereo, mDesiredStyle);
2052 }
2053 S.EndVerticalLay();
2054 }
2055 S.EndStatic();
2056 }
2057 S.EndHorizontalLay();
2058 S.AddStandardButtons();
2059 }
2060 S.EndVerticalLay();
2061 dlg.Layout();
2062 dlg.Fit();
2063
2064 dlg.CenterOnParent();
2065
2066 if (dlg.ShowModal() == wxID_OK)
2067 {
2069 wxT("AutomaticStereo") ,
2070 wxT("HorizontalStereo") ,
2071 wxT("VerticalStereo") ,
2072 };
2073
2074 int s = 0;
2075 s = automatic->GetValue() ? 0 : s;
2076 s = horizontal->GetValue() ? 1 : s;
2077 s = vertical->GetValue() ? 2 : s;
2078
2079 gPrefs->Write(Key(wxT("Style")), style[s]);
2080 gPrefs->Write(Key(wxT("Bars")), gradient->GetValue() ? wxT("Gradient") : wxT("RMS"));
2081 gPrefs->Write(Key(wxT("Type")), db->GetValue() ? wxT("dB") : wxT("Linear"));
2082 gPrefs->Write(Key(wxT("RefreshRate")), rate->GetValue());
2083
2084 gPrefs->Flush();
2085
2086 // Currently, there are 2 playback meters and 2 record meters and any number of
2087 // mixerboard meters, so we have to send out an preferences updated message to
2088 // ensure they all update themselves.
2090 }
2091}
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 800 of file MeterPanel.cpp.

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

References mIsFocused.

◆ OnSize()

void MeterPanel::OnSize ( wxSizeEvent &  evt)
private

Definition at line 716 of file MeterPanel.cpp.

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

References mHeight, mLayoutValid, and mWidth.

◆ OnTipTimeout()

void MeterPanel::OnTipTimeout ( wxTimerEvent &  evt)
private

Definition at line 1136 of file MeterPanel.cpp.

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

References mSlider.

◆ RepaintBarsNow()

void MeterPanel::RepaintBarsNow ( )
private

Definition at line 1575 of file MeterPanel.cpp.

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

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

898{
899 mT = 0;
901 for (int j = 0; j < kMaxMeterBars; j++)
902 {
903 ResetBar(&mBar[j], resetClipping);
904 }
905
906 // wxTimers seem to be a little unreliable - sometimes they stop for
907 // no good reason, so this "primes" it every now and then...
908 mTimer.Stop();
909
910 // While it's stopped, empty the queue
911 mQueue.Clear();
912
913 mLayoutValid = false;
914
915 mTimer.Start(1000 / mMeterRefreshRate);
916
917 Refresh(false);
918}
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 1171 of file MeterPanel.cpp.

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

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

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

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

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

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SetActiveStyle()

void MeterPanel::SetActiveStyle ( Style  style)
private

Definition at line 1204 of file MeterPanel.cpp.

1205{
1206 mStyle = newStyle;
1207
1208 // Set dummy ruler bounds so width/height can be retrieved
1209 // NOTE: Make sure the Right and Bottom values are large enough to
1210 // ensure full width/height of digits get calculated.
1211 mRuler.SetBounds(0, 0, 500, 500);
1212
1213 if (mDB)
1214 {
1217 {
1218 mRuler.SetOrientation(wxHORIZONTAL);
1220 }
1221 else
1222 {
1223 mRuler.SetOrientation(wxVERTICAL);
1225 }
1226 }
1227 else
1228 {
1231 {
1232 mRuler.SetOrientation(wxHORIZONTAL);
1233 mRuler.SetRange(0, 1);
1234 }
1235 else
1236 {
1237 mRuler.SetOrientation(wxVERTICAL);
1238 mRuler.SetRange(1, 0);
1239 }
1240 }
1241
1243}
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:612
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 1245 of file MeterPanel.cpp.

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

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

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

Here is the call graph for this function:

◆ SetMixer()

void MeterPanel::SetMixer ( wxCommandEvent &  event)

Definition at line 828 of file MeterPanel.cpp.

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

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

1966{
1968 if(mSlider)
1969 mSlider->SetName(tip);
1970}

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

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

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

Here is the call graph for this function:

◆ ShowDialog()

bool MeterPanel::ShowDialog ( )

Definition at line 860 of file MeterPanel.cpp.

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

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

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

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

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

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

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