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 mPeakPeakPen
 
wxBrush mBrush
 
wxBrush mRMSBrush
 
wxBrush mClipBrush
 
wxBrush mBkgndBrush
 
wxBrush mDisabledBkgndBrush
 
wxBrush mMeterBkgndBrush
 
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 88 of file MeterPanel.h.

Member Enumeration Documentation

◆ Style

Enumerator
AutomaticStereo 
HorizontalStereo 
VerticalStereo 
MixerTrackCluster 
HorizontalStereoCompact 
VerticalStereoCompact 

Definition at line 97 of file MeterPanel.h.

97 {
101 MixerTrackCluster, // Doesn't show menu, icon, or L/R labels, but otherwise like VerticalStereo.
102 HorizontalStereoCompact, // Thinner.
103 VerticalStereoCompact, // Narrower.
104 };
@ HorizontalStereoCompact
Definition: MeterPanel.h:102
@ AutomaticStereo
Definition: MeterPanel.h:98
@ HorizontalStereo
Definition: MeterPanel.h:99
@ VerticalStereo
Definition: MeterPanel.h:100
@ VerticalStereoCompact
Definition: MeterPanel.h:103
@ MixerTrackCluster
Definition: MeterPanel.h:101

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

236: MeterPanelBase(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER | wxWANTS_CHARS),
238 mQueue{ 1024 },
239 mWidth(size.x),
240 mHeight(size.y),
241 mIsInput(isInput),
243 mGradient(true),
244 mDB(true),
246 mDecay(true),
247 mDecayRate(fDecayRate),
248 mClip(true),
251 mT(0),
252 mRate(0),
253 mMonitoring(false),
254 mActive(false),
255 mNumBars(0),
256 mLayoutValid(false),
257 mBitmap{},
259{
260 // i18n-hint: Noun (the meter is used for playback or record level monitoring)
261 SetName( XO("Meter") );
262 // Suppress warnings about the header file
263 wxUnusedVar(SpeakerMenu_xpm);
264 wxUnusedVar(MicMenu_xpm);
265 wxUnusedVar(PrefStyles);
266
268
269 mIsFocused = false;
270
271#if wxUSE_ACCESSIBILITY
272 SetAccessible(safenew MeterAx(this));
273#endif
274
275 // Do this BEFORE UpdatePrefs()!
278 mRuler.SetLabelEdges(true);
279 //mRuler.SetTickColour( wxColour( 0,0,255 ) );
280
282 {
283 mSlider = std::make_unique<LWSlider>(this, XO(""),
284 pos,
285 size,
287 false, /* showlabels */
288 false, /* drawticks */
289 false, /* drawtrack */
290 false /* alwayshidetip */
291 );
292 mSlider->SetScroll(0.1f, 2.0f);
293 }
294
296 UpdatePrefs();
297
298 wxColour backgroundColour = theTheme.Colour(clrMedium);
299 mBkgndBrush = wxBrush(backgroundColour, wxBRUSHSTYLE_SOLID);
300 SetBackgroundColour( backgroundColour );
301
302 mPeakPeakPen = wxPen(theTheme.Colour( clrMeterPeak), 1, wxPENSTYLE_SOLID);
303
306
309
310 if (mIsInput) {
311 mPen = wxPen( theTheme.Colour( clrMeterInputPen ), 1, wxPENSTYLE_SOLID);
312 mBrush = wxBrush( theTheme.Colour( clrMeterInputBrush ), wxBRUSHSTYLE_SOLID);
313 mRMSBrush = wxBrush( theTheme.Colour( clrMeterInputRMSBrush ), wxBRUSHSTYLE_SOLID);
314 mClipBrush = wxBrush( theTheme.Colour( clrMeterInputClipBrush ), wxBRUSHSTYLE_SOLID);
315// mLightPen = wxPen( theTheme.Colour( clrMeterInputLightPen ), 1, wxSOLID);
316// mDarkPen = wxPen( theTheme.Colour( clrMeterInputDarkPen ), 1, wxSOLID);
317 }
318 else {
319 mPen = wxPen( theTheme.Colour( clrMeterOutputPen ), 1, wxPENSTYLE_SOLID);
320 mBrush = wxBrush( theTheme.Colour( clrMeterOutputBrush ), wxBRUSHSTYLE_SOLID);
321 mRMSBrush = wxBrush( theTheme.Colour( clrMeterOutputRMSBrush ), wxBRUSHSTYLE_SOLID);
322 mClipBrush = wxBrush( theTheme.Colour( clrMeterOutputClipBrush ), wxBRUSHSTYLE_SOLID);
323// mLightPen = wxPen( theTheme.Colour( clrMeterOutputLightPen ), 1, wxSOLID);
324// mDarkPen = wxPen( theTheme.Colour( clrMeterOutputDarkPen ), 1, wxSOLID);
325 }
326
327
328 mTipTimer.SetOwner(this, OnTipTimeoutID);
329 mTimer.SetOwner(this, OnMeterUpdateID);
330 // TODO: Yikes. Hard coded sample rate.
331 // JKC: I've looked at this, and it's benignish. It just means that the meter
332 // balistics are right for 44KHz and a bit more frisky than they should be
333 // for higher sample rates.
334 Reset(44100.0, true);
335}
#define PERCENT_SLIDER
Definition: ASlider.h:39
IntSetting DecibelScaleCutoff
Negation of this value is the lowest dB level that should be shown in dB scales.
Definition: Decibels.cpp:12
XO("Cut/Copy/Paste")
#define safenew
Definition: MemoryX.h:10
@ OnMeterUpdateID
Definition: MeterPanel.cpp:204
@ OnTipTimeoutID
Definition: MeterPanel.cpp:207
static const wxChar * PrefStyles[]
Definition: MeterPanel.cpp:196
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:275
void UpdatePrefs() override
Definition: MeterPanel.cpp:342
Style mStyle
Definition: MeterPanel.h:253
wxFont GetFont() const
double mRate
Definition: MeterPanel.h:264
Style mDesiredStyle
Definition: MeterPanel.h:254
bool mClip
Definition: MeterPanel.h:260
int mDBRange
Definition: MeterPanel.h:257
bool mIsInput
Definition: MeterPanel.h:251
Ruler mRuler
Definition: MeterPanel.h:290
Observer::Subscription mAudioCaptureSubscription
Definition: MeterPanel.h:238
wxTimer mTimer
Definition: MeterPanel.h:242
float mDecayRate
Definition: MeterPanel.h:259
bool mDecay
Definition: MeterPanel.h:258
double mPeakHoldDuration
Definition: MeterPanel.h:262
std::unique_ptr< LWSlider > mSlider
Definition: MeterPanel.h:294
double mT
Definition: MeterPanel.h:263
AudacityProject * mProject
Definition: MeterPanel.h:240
unsigned mNumBars
Definition: MeterPanel.h:272
wxBrush mBkgndBrush
Definition: MeterPanel.h:287
friend class MeterAx
Definition: MeterPanel.h:303
void OnAudioIOStatus(AudioIOEvent)
bool mMonitoring
Definition: MeterPanel.h:268
bool mGradient
Definition: MeterPanel.h:255
bool mActive
Definition: MeterPanel.h:270
void UpdateSliderControl()
Definition: MeterPanel.cpp:410
wxBrush mBrush
Definition: MeterPanel.h:284
Observer::Subscription mAudioIOStatusSubscription
Definition: MeterPanel.h:237
std::unique_ptr< wxBitmap > mBitmap
Definition: MeterPanel.h:277
wxTimer mTipTimer
Definition: MeterPanel.h:243
wxPen mPeakPeakPen
Definition: MeterPanel.h:283
int mNumPeakSamplesToClip
Definition: MeterPanel.h:261
wxBrush mClipBrush
Definition: MeterPanel.h:286
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:837
void OnAudioCapture(AudioIOEvent)
wxPen mPen
Definition: MeterPanel.h:282
bool mIsFocused
Definition: MeterPanel.h:300
MeterUpdateQueue mQueue
Definition: MeterPanel.h:241
wxBrush mRMSBrush
Definition: MeterPanel.h:285
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 337 of file MeterPanel.cpp.

338{
339 mQueue.Clear();
340}

References mQueue.

◆ Decrease()

void MeterPanel::Decrease ( float  steps)

Definition at line 826 of file MeterPanel.cpp.

827{
828 if (mSlider)
829 {
830 wxCommandEvent e;
831
832 mSlider->Decrease(steps);
833 SetMixer(e);
834 }
835}
void SetMixer(wxCommandEvent &event)
Definition: MeterPanel.cpp:768

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

1536{
1537 // Cache some metrics
1538 wxCoord x = bar->r.GetLeft();
1539 wxCoord y = bar->r.GetTop();
1540 wxCoord w = bar->r.GetWidth();
1541 wxCoord h = bar->r.GetHeight();
1542 wxCoord ht;
1543 wxCoord wd;
1544
1545 // Setup for erasing the background
1546 dc.SetPen(*wxTRANSPARENT_PEN);
1547 mMeterBkgndBrush.SetColour( theTheme.Colour(clrMeterBackground) );
1548 dc.SetBrush(mMeterBkgndBrush);
1549
1550 if (mGradient)
1551 {
1552 // Map the predrawn bitmap into the source DC
1553 wxMemoryDC srcDC;
1554 srcDC.SelectObject(*mBitmap);
1555
1556 if (bar->vert)
1557 {
1558 // Copy as much of the predrawn meter bar as is required for the
1559 // current peak.
1560 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1561 ht = (int)(bar->peak * (h - 1) + 0.5);
1562
1563 // Blank out the rest
1564 if (h - ht)
1565 {
1566 // ht includes peak value...not really needed but doesn't hurt
1567 dc.DrawRectangle(x, y, w, h - ht);
1568 }
1569
1570 // Copy as much of the predrawn meter bar as is required for the
1571 // current peak.
1572 // +/-1 to include the peak position
1573 if (ht)
1574 {
1575 dc.Blit(x, y + h - ht - 1, w, ht + 1, &srcDC, x, y + h - ht - 1);
1576 }
1577
1578 // Draw the "recent" peak hold line using the predrawn meter bar so that
1579 // it will be the same color as the original level.
1580 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1581 ht = (int)(bar->peakHold * (h - 1) + 0.5);
1582 if (ht > 1)
1583 {
1584 dc.Blit(x, y + h - ht - 1, w, 2, &srcDC, x, y + h - ht - 1);
1585 }
1586
1587 // Draw the "maximum" peak hold line
1588 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1589 dc.SetPen(mPeakPeakPen);
1590 ht = (int)(bar->peakPeakHold * (h - 1) + 0.5);
1591 if (ht > 0)
1592 {
1593 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1594 if (ht > 1)
1595 {
1596 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1597 }
1598 }
1599 }
1600 else
1601 {
1602 // Calculate the peak position
1603 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1604 wd = (int)(bar->peak * (w - 1) + 0.5);
1605
1606 // Blank out the rest
1607 if (w - wd)
1608 {
1609 // wd includes peak value...not really needed but doesn't hurt
1610 dc.DrawRectangle(x + wd, y, w - wd, h);
1611 }
1612
1613 // Copy as much of the predrawn meter bar as is required for the
1614 // current peak. But, only blit() if there's something to copy
1615 // to prevent display corruption.
1616 // +1 to include peak position
1617 if (wd)
1618 {
1619 dc.Blit(x, y, wd + 1, h, &srcDC, x, y);
1620 }
1621
1622 // Draw the "recent" peak hold line using the predrawn meter bar so that
1623 // it will be the same color as the original level.
1624 // -1 to give a 2 pixel width
1625 wd = (int)(bar->peakHold * (w - 1) + 0.5);
1626 if (wd > 1)
1627 {
1628 dc.Blit(x + wd - 1, y, 2, h, &srcDC, x + wd, y);
1629 }
1630
1631 // Draw the "maximum" peak hold line using a themed color
1632 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1633 dc.SetPen(mPeakPeakPen);
1634 wd = (int)(bar->peakPeakHold * (w - 1) + 0.5);
1635 if (wd > 0)
1636 {
1637 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1638 if (wd > 1)
1639 {
1640 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1641 }
1642 }
1643 }
1644
1645 // No longer need the source DC, so unselect the predrawn bitmap
1646 srcDC.SelectObject(wxNullBitmap);
1647 }
1648 else
1649 {
1650 if (bar->vert)
1651 {
1652 // Calculate the peak position
1653 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1654 ht = (int)(bar->peak * (h - 1) + 0.5);
1655
1656 // Blank out the rest
1657 if (h - ht)
1658 {
1659 // ht includes peak value...not really needed but doesn't hurt
1660 dc.DrawRectangle(x, y, w, h - ht);
1661 }
1662
1663 // Draw the peak level
1664 // +/-1 to include the peak position
1665 dc.SetPen(*wxTRANSPARENT_PEN);
1666 dc.SetBrush(mBrush);
1667 if (ht)
1668 {
1669 dc.DrawRectangle(x, y + h - ht - 1, w, ht + 1);
1670 }
1671
1672 // Draw the "recent" peak hold line
1673 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1674 dc.SetPen(mPen);
1675 ht = (int)(bar->peakHold * (h - 1) + 0.5);
1676 if (ht > 0)
1677 {
1678 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1679 if (ht > 1)
1680 {
1681 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1682 }
1683 }
1684
1685 // Calculate the rms position
1686 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1687 // +1 to include the rms position
1688 ht = (int)(bar->rms * (h - 1) + 0.5);
1689
1690 // Draw the RMS level
1691 dc.SetPen(*wxTRANSPARENT_PEN);
1692 dc.SetBrush(mRMSBrush);
1693 if (ht)
1694 {
1695 dc.DrawRectangle(x, y + h - ht - 1, w, ht + 1);
1696 }
1697
1698 // Draw the "maximum" peak hold line
1699 // (h - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1700 dc.SetPen(mPeakPeakPen);
1701 ht = (int)(bar->peakPeakHold * (h - 1) + 0.5);
1702 if (ht > 0)
1703 {
1704 AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
1705 if (ht > 1)
1706 {
1707 AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
1708 }
1709 }
1710 }
1711 else
1712 {
1713 // Calculate the peak position
1714 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1715 wd = (int)(bar->peak * (w - 1) + 0.5);
1716
1717 // Blank out the rest
1718 if (w - wd)
1719 {
1720 // wd includes peak value...not really needed but doesn't hurt
1721 dc.DrawRectangle(x + wd, y, w - wd, h);
1722 }
1723
1724 // Draw the peak level
1725 // +1 to include peak position
1726 dc.SetPen(*wxTRANSPARENT_PEN);
1727 dc.SetBrush(mBrush);
1728 if (wd)
1729 {
1730 dc.DrawRectangle(x, y, wd + 1, h);
1731 }
1732
1733 // Draw the "recent" peak hold line
1734 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1735 dc.SetPen(mPen);
1736 wd = (int)(bar->peakHold * (w - 1) + 0.5);
1737 if (wd > 0)
1738 {
1739 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1740 if (wd > 1)
1741 {
1742 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1743 }
1744 }
1745
1746 // Calculate the rms position
1747 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1748 wd = (int)(bar->rms * (w - 1) + 0.5);
1749
1750 // Draw the rms level
1751 // +1 to include the rms position
1752 dc.SetPen(*wxTRANSPARENT_PEN);
1753 dc.SetBrush(mRMSBrush);
1754 if (wd)
1755 {
1756 dc.DrawRectangle(x, y, wd + 1, h);
1757 }
1758
1759 // Draw the "maximum" peak hold line using a themed color
1760 // (w - 1) corresponds to the mRuler.SetBounds() in HandleLayout()
1761 dc.SetPen(mPeakPeakPen);
1762 wd = (int)(bar->peakPeakHold * (w - 1) + 0.5);
1763 if (wd > 0)
1764 {
1765 AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
1766 if (wd > 1)
1767 {
1768 AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
1769 }
1770 }
1771 }
1772 }
1773
1774 // If meter had a clipping indicator, draw or erase it
1775 // LLL: At least I assume that's what "mClip" is supposed to be for as
1776 // it is always "true".
1777 if (mClip)
1778 {
1779 if (bar->clipping)
1780 {
1781 dc.SetBrush(mClipBrush);
1782 }
1783 else
1784 {
1785 dc.SetBrush(mBkgndBrush);
1786 }
1787 dc.SetPen(*wxTRANSPARENT_PEN);
1788 dc.DrawRectangle(bar->rClip);
1789 }
1790}
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:194
wxBrush mMeterBkgndBrush
Definition: MeterPanel.h:289

References MeterBar::clipping, ThemeBase::Colour(), AColor::Line(), mBitmap, mBkgndBrush, mBrush, mClip, mClipBrush, mGradient, mMeterBkgndBrush, mPeakPeakPen, mPen, mRMSBrush, MeterBar::peak, MeterBar::peakHold, MeterBar::peakPeakHold, MeterBar::r, MeterBar::rClip, MeterBar::rms, theTheme, 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 186 of file MeterPanel.h.

186{ return mDB ? mDBRange : -1; }

◆ GetDesiredStyle()

Style MeterPanel::GetDesiredStyle ( ) const
inline

Definition at line 120 of file MeterPanel.h.

120{ return mDesiredStyle; }

◆ GetFont()

wxFont MeterPanel::GetFont ( ) const
private

Definition at line 1101 of file MeterPanel.cpp.

1102{
1103 int fontSize = 10;
1104#if defined __WXMSW__
1105 fontSize = 8;
1106#endif
1107
1108 return wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
1109}

Referenced by HandleLayout(), and OnPaint().

Here is the caller graph for this function:

◆ GetMaxPeak()

float MeterPanel::GetMaxPeak ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1083 of file MeterPanel.cpp.

1084{
1085 float maxPeak = 0.;
1086
1087 for(unsigned int j=0; j<mNumBars; j++)
1088 maxPeak = mBar[j].peak > maxPeak ? mBar[j].peak : maxPeak;
1089
1090 return(maxPeak);
1091}
MeterBar mBar[kMaxMeterBars]
Definition: MeterPanel.h:273

References mBar, and mNumBars.

◆ GetPeakHold()

float MeterPanel::GetPeakHold ( ) const

Definition at line 1093 of file MeterPanel.cpp.

1094{
1095 auto peakHold = .0f;
1096 for (unsigned int i = 0; i < mNumBars; i++)
1097 peakHold = std::max(peakHold, mBar[i].peakPeakHold);
1098 return peakHold;
1099}

References mBar, and mNumBars.

◆ GetStyle()

Style MeterPanel::GetStyle ( ) const
inline

Definition at line 119 of file MeterPanel.h.

119{ return mStyle; }

◆ HandleLayout()

void MeterPanel::HandleLayout ( wxDC &  dc)
private

Definition at line 1231 of file MeterPanel.cpp.

1232{
1233 // Refresh to reflect any language changes
1234 /* i18n-hint: One-letter abbreviation for Left, in VU Meter */
1235 mLeftText = _("L");
1236 /* i18n-hint: One-letter abbreviation for Right, in VU Meter */
1237 mRightText = _("R");
1238
1239 dc.SetFont(GetFont());
1240 int width = mWidth;
1241 int height = mHeight;
1242 int left = 0;
1243 int top = 0;
1244 int barw;
1245 int barh;
1246 int lside;
1247 int rside;
1248
1249 // MixerTrackCluster has no L/R labels or icon
1251 {
1253 {
1255 }
1256
1258 {
1260 }
1262 {
1264 }
1265
1266 if (mLeftSize.GetWidth() == 0) // Not yet initialized to dc.
1267 {
1268 dc.GetTextExtent(mLeftText, &mLeftSize.x, &mLeftSize.y);
1269 dc.GetTextExtent(mRightText, &mRightSize.x, &mRightSize.y);
1270 }
1271 }
1272
1273 int ltxtWidth = mLeftSize.GetWidth();
1274 int ltxtHeight = mLeftSize.GetHeight();
1275 int rtxtWidth = mRightSize.GetWidth();
1276 int rtxtHeight = mRightSize.GetHeight();
1277
1278 switch (mStyle)
1279 {
1280 default:
1281 wxPrintf(wxT("Style not handled yet!\n"));
1282 break;
1283 case MixerTrackCluster:
1284 // width is now the entire width of the meter canvas
1285 width -= mRulerWidth + left;
1286
1287 // height is now the entire height of the meter canvas
1288 height -= top + gap;
1289
1290 // barw is half of the canvas while allowing for a gap between meters
1291 barw = (width - gap) / 2;
1292
1293 // barh is now the height of the canvas
1294 barh = height;
1295
1296 // We always have 2 bars
1297 mNumBars = 2;
1298
1299 // Save dimensions of the left bevel
1300 mBar[0].b = wxRect(left, top, barw, barh);
1301
1302 // Save dimensions of the right bevel
1303 mBar[1].b = mBar[0].b;
1304 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1305
1306 // Set bar and clipping indicator dimensions
1307 SetBarAndClip(0, true);
1308 SetBarAndClip(1, true);
1309
1310 mRuler.SetBounds(mBar[1].r.GetRight() + 1, // +1 for the bevel
1311 mBar[1].r.GetTop(),
1312 mWidth,
1313 mBar[1].r.GetBottom());
1314 mRuler.OfflimitsPixels(0, 0);
1315 break;
1316 case VerticalStereo:
1317 // Determine required width of each side;
1318 lside = ltxtWidth + gap;
1319 rside = intmax(mRulerWidth, rtxtWidth);
1320
1321 // left is now the right edge of the icon or L label
1322 left = lside;
1323
1324 // Ensure there's a margin between top edge of window and the meters
1325 top = gap;
1326
1327 // Position the L/R labels
1328 mLeftTextPos = wxPoint(left - ltxtWidth - gap, height - gap - ltxtHeight);
1329 mRightTextPos = wxPoint(width - rside - gap, height - gap - rtxtHeight);
1330
1331 // left is now left edge of left bar
1332 left += gap;
1333
1334 // width is now the entire width of the meter canvas
1335 width -= gap + rside + gap + left;
1336
1337 // height is now the entire height of the meter canvas
1338 height -= top + gap;
1339
1340 mSliderPos = wxPoint{ 0, top - gap };
1341 mSliderSize = wxSize{ width, height + 2 * gap };
1342
1343 // barw is half of the canvas while allowing for a gap between meters
1344 barw = (width - gap) / 2;
1345
1346 // barh is now the height of the canvas
1347 barh = height;
1348
1349 // We always have 2 bars
1350 mNumBars = 2;
1351
1352 // Save dimensions of the left bevel
1353 mBar[0].b = wxRect(left, top, barw, barh);
1354
1355 // Save dimensions of the right bevel
1356 mBar[1].b = mBar[0].b;
1357 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1358
1359 // Set bar and clipping indicator dimensions
1360 SetBarAndClip(0, true);
1361 SetBarAndClip(1, true);
1362
1363 mRuler.SetBounds(mBar[1].r.GetRight() + 1, // +1 for the bevel
1364 mBar[1].r.GetTop(),
1365 mWidth,
1366 mBar[1].r.GetBottom());
1367 mRuler.OfflimitsPixels(mRightTextPos.y - gap, mBar[1].r.GetBottom());
1368 break;
1370 // Ensure there's a margin between top edge of window and the meters
1371 top = gap;
1372
1373 // height is now the entire height of the meter canvas
1374 height -= top + gap + ltxtHeight + gap;
1375
1376 mSliderPos = wxPoint{ 0, top - gap };
1377 mSliderSize = wxSize{ width, height + 2 * gap };
1378
1379 // barw is half of the canvas while allowing for a gap between meters
1380 barw = (width / 2) - gap;
1381
1382 // barh is now the height of the canvas
1383 barh = height;
1384
1385 // We always have 2 bars
1386 mNumBars = 2;
1387
1388 // Save dimensions of the left bevel
1389 mBar[0].b = wxRect(left, top, barw, barh);
1390
1391 // Save dimensions of the right bevel
1392 mBar[1].b = mBar[0].b;
1393 mBar[1].b.SetLeft(mBar[0].b.GetRight() + 1 + gap); // +1 for right edge
1394
1395 // Set bar and clipping indicator dimensions
1396 SetBarAndClip(0, true);
1397 SetBarAndClip(1, true);
1398
1399 // L/R is centered horizontally under each bar
1400 mLeftTextPos = wxPoint(mBar[0].b.GetLeft() + ((mBar[0].b.GetWidth() - ltxtWidth) / 2), top + barh + gap);
1401 mRightTextPos = wxPoint(mBar[1].b.GetLeft() + ((mBar[1].b.GetWidth() - rtxtWidth) / 2), top + barh + gap);
1402
1404 mBar[1].r.GetTop(),
1405 (mWidth - mRulerWidth) / 2,
1406 mBar[1].r.GetBottom());
1407 mRuler.OfflimitsPixels(0, 0);
1408 break;
1409 case HorizontalStereo:
1410 // Button right next to dragger.
1411 left = 0;
1412
1413 // Add a gap between bottom of icon and bottom of window
1414 height -= gap;
1415
1416 left = gap;
1417
1418 // Make sure there's room for icon and gap between the bottom of the meter and icon
1419 height -= rtxtHeight + gap;
1420
1421 // L/R is centered vertically and to the left of a each bar
1422 mLeftTextPos = wxPoint(left, (height / 4) - ltxtHeight / 2);
1423 mRightTextPos = wxPoint(left, (height * 3 / 4) - rtxtHeight / 2);
1424
1425 // Add width of widest of the L/R characters
1426 left += intmax(ltxtWidth, rtxtWidth); //, iconWidth);
1427
1428 mSliderPos = wxPoint{ left - gap, 0 };
1429
1430 // Add gap between L/R and meter bevel
1431 left += gap;
1432
1433 // width is now the entire width of the meter canvas
1434 width -= left;
1435
1436 mSliderSize = wxSize{ width + 2 * gap, height };
1437
1438 // barw is now the width of the canvas minus gap between canvas and right window edge
1439 barw = width - gap;
1440
1441 // barh is half of the canvas while allowing for a gap between meters
1442 barh = (height - gap) / 2;
1443
1444 // We always have 2 bars
1445 mNumBars = 2;
1446
1447 // Save dimensions of the top bevel
1448 mBar[0].b = wxRect(left, top, barw, barh);
1449
1450 // Save dimensions of the bottom bevel
1451 mBar[1].b = mBar[0].b;
1452 mBar[1].b.SetTop(mBar[0].b.GetBottom() + 1 + gap); // +1 for bottom edge
1453
1454 // Set bar and clipping indicator dimensions
1455 SetBarAndClip(0, false);
1456 SetBarAndClip(1, false);
1457
1458 mRuler.SetBounds(mBar[1].r.GetLeft(),
1459 mBar[1].r.GetBottom() + 1, // +1 to fit below bevel
1460 mBar[1].r.GetRight(),
1461 mHeight - mBar[1].r.GetBottom() + 1);
1462 break;
1464 left = gap;
1465
1466 // L/R is centered vertically and to the left of a each bar
1467 mLeftTextPos = wxPoint(left, (height / 4) - (ltxtHeight / 2));
1468 mRightTextPos = wxPoint(left, (height * 3 / 4) - (ltxtHeight / 2));
1469
1470 // Add width of widest of the L/R characters
1471 left += intmax(ltxtWidth, rtxtWidth);
1472
1473 mSliderPos = wxPoint{ left - gap, 0 };
1474
1475 // Add gap between L/R and meter bevel
1476 left += gap;
1477
1478 // width is now the entire width of the meter canvas
1479 width -= left;
1480
1481 mSliderSize = wxSize{ width + 2 * gap, height };
1482
1483 // barw is now the width of the canvas minus gap between canvas and window edge
1484 barw = width - gap;
1485
1486 // barh is half of the canvas while allowing for a gap between meters
1487 barh = (height - gap) / 2;
1488
1489 // We always have 2 bars
1490 mNumBars = 2;
1491
1492 // Save dimensions of the top bevel
1493 mBar[0].b = wxRect(left, top, barw, barh);
1494
1495 // Save dimensions of the bottom bevel
1496 // Since the bars butt up against the window's top and bottom edges, we need
1497 // to include an extra pixel in the bottom bar when the window height and
1498 // meter height do not exactly match.
1499 mBar[1].b = mBar[0].b;
1500 mBar[1].b.SetTop(mBar[0].b.GetBottom() + 1 + gap); // +1 for bottom bevel
1501 mBar[1].b.SetHeight(mHeight - mBar[1].b.GetTop() - 1); // +1 for bottom bevel
1502
1503 // Add clipping indicators - do after setting bar/bevel dimensions above
1504 SetBarAndClip(0, false);
1505 SetBarAndClip(1, false);
1506
1507 mRuler.SetBounds(mBar[1].r.GetLeft(),
1508 mBar[1].b.GetTop() - (mRulerHeight / 2),
1509 mBar[1].r.GetRight(),
1510 mBar[1].b.GetTop() - (mRulerHeight / 2));
1511 mRuler.OfflimitsPixels(0, 0);
1512 break;
1513 }
1514
1515 mLayoutValid = true;
1516}
wxT("CloseDown"))
#define _(s)
Definition: Internat.h:73
static int intmax(int a, int b)
Definition: MeterPanel.cpp:872
static const int gap
Definition: MeterPanel.cpp:194
wxString mRightText
Definition: MeterPanel.h:292
wxSize mRightSize
Definition: MeterPanel.h:281
wxPoint mSliderPos
Definition: MeterPanel.h:295
int mRulerHeight
Definition: MeterPanel.h:249
int mRulerWidth
Definition: MeterPanel.h:248
wxString mLeftText
Definition: MeterPanel.h:291
void SetBarAndClip(int iBar, bool vert)
wxPoint mLeftTextPos
Definition: MeterPanel.h:278
wxSize mLeftSize
Definition: MeterPanel.h:280
wxPoint mRightTextPos
Definition: MeterPanel.h:279
wxSize mSliderSize
Definition: MeterPanel.h:296
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:42
wxRect r
Definition: MeterPanel.h:43

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

816{
817 if (mSlider)
818 {
819 wxCommandEvent e;
820
821 mSlider->Increase(steps);
822 SetMixer(e);
823 }
824}

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

1127{
1128 return mActive;
1129}

References mActive.

◆ IsClipping()

bool MeterPanel::IsClipping ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1136 of file MeterPanel.cpp.

1137{
1138 for (int c = 0; c < mNumBars; c++)
1139 if (mBar[c].clipping)
1140 return true;
1141 return false;
1142}

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

1793{
1794 return mMeterDisabled != 0;
1795}
long mMeterDisabled
Definition: MeterPanel.h:266

References mMeterDisabled.

◆ IsMonitoring()

bool MeterPanel::IsMonitoring ( ) const

Definition at line 1131 of file MeterPanel.cpp.

1132{
1133 return mMonitoring;
1134}

References mMonitoring.

◆ Key()

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

Definition at line 2036 of file MeterPanel.cpp.

2037{
2039 {
2040 return wxT("/Meter/Mixerboard/") + key;
2041 }
2042
2043 if (mIsInput)
2044 {
2045 return wxT("/Meter/Input/") + key;
2046 }
2047
2048 return wxT("/Meter/Output/") + key;
2049}
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 1849 of file MeterPanel.cpp.

1850{
1851 if (
1852 event.type == AudioIOEvent::CAPTURE &&
1853 (event.pProject != mProject || !event.on))
1854 {
1855 mEnabled = !event.on;
1856
1857 if (mSlider)
1858 mSlider->SetEnabled(mEnabled);
1859 }
1860}
bool mEnabled
Definition: MeterPanel.h:298
bool on
Definition: AudioIO.h:68
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:61

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

◆ OnAudioIOStatus()

void MeterPanel::OnAudioIOStatus ( AudioIOEvent  evt)
private

Definition at line 1825 of file MeterPanel.cpp.

1826{
1827 if (evt.type == AudioIOEvent::PAUSE)
1828 return;
1829
1830 if (!mIsInput != (evt.type == AudioIOEvent::PLAYBACK))
1831 return;
1832
1833 AudacityProject *p = evt.pProject;
1834 mActive = evt.on && (p == mProject);
1835 if( mActive ){
1836 mTimer.Start(1000 / mMeterRefreshRate);
1837 if (evt.type == AudioIOEvent::MONITOR)
1839 } else {
1840 mTimer.Stop();
1841 mMonitoring = false;
1842 }
1843
1844 // Only refresh is we're the active meter
1845 if (IsShownOnScreen())
1846 Refresh(false);
1847}
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:265

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

◆ OnCharHook()

void MeterPanel::OnCharHook ( wxKeyEvent &  evt)
private

Definition at line 690 of file MeterPanel.cpp.

691{
692 switch(evt.GetKeyCode())
693 {
694 // These are handled in the OnCharHook handler because, on Windows at least, the
695 // key up event will be passed on to the menu if we show it here. This causes
696 // the default sound to be heard if assigned.
697 case WXK_RETURN:
698 case WXK_NUMPAD_ENTER:
699 case WXK_WINDOWS_MENU:
700 case WXK_MENU:
702 ShowMenu(GetClientRect().GetBottomLeft());
703 else
704 evt.Skip();
705 break;
706 default:
707 evt.Skip();
708 break;
709 }
710}
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 712 of file MeterPanel.cpp.

713{
714 if (mStyle != MixerTrackCluster) // MixerTrackCluster style has no menu.
715 {
716 ShowMenu(GetClientRect().GetBottomLeft());
717 }
718 else
719 {
720 evt.Skip();
721 }
722}

References mStyle, and ShowMenu().

Here is the call graph for this function:

◆ OnErase()

void MeterPanel::OnErase ( wxEraseEvent &  evt)
private

Definition at line 432 of file MeterPanel.cpp.

433{
434 // Ignore it to prevent flashing
435}

◆ OnKeyDown()

void MeterPanel::OnKeyDown ( wxKeyEvent &  evt)
private

Definition at line 724 of file MeterPanel.cpp.

725{
726 switch (evt.GetKeyCode())
727 {
728 case WXK_TAB:
729 if (evt.ShiftDown())
730 Navigate(wxNavigationKeyEvent::IsBackward);
731 else
732 Navigate(wxNavigationKeyEvent::IsForward);
733 break;
734 default:
735 mSlider->OnKeyDown(evt);
736 break;
737 }
738}

References mSlider.

◆ OnKillFocus()

void MeterPanel::OnKillFocus ( wxFocusEvent &  evt)
private

Definition at line 746 of file MeterPanel.cpp.

747{
748 if(mSlider)
749 mSlider->OnKillFocus();
750 mTipTimer.Stop();
751
752 mIsFocused = false;
753 Refresh(false);
754}

References mIsFocused, mSlider, and mTipTimer.

◆ OnMeterUpdate()

void MeterPanel::OnMeterUpdate ( wxTimerEvent &  evt)
private

Definition at line 979 of file MeterPanel.cpp.

980{
981 MeterUpdateMsg msg;
982 int numChanges = 0;
983#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
984 double maxPeak = 0.0;
985 bool discarded = false;
986#endif
987
988 // We shouldn't receive any events if the meter is disabled, but clear it to be safe
989 if (mMeterDisabled) {
990 mQueue.Clear();
991 return;
992 }
993
994
995 // There may have been several update messages since the last
996 // time we got to this function. Catch up to real-time by
997 // popping them off until there are none left. It is necessary
998 // to process all of them, otherwise we won't handle peaks and
999 // peak-hold bars correctly.
1000 while(mQueue.Get(msg)) {
1001 numChanges++;
1002 double deltaT = msg.numFrames / mRate;
1003
1004 mT += deltaT;
1005 for(unsigned int j=0; j<mNumBars; j++) {
1006 mBar[j].isclipping = false;
1007
1008 //
1009 if (mDB) {
1010 msg.peak[j] = ToDB(msg.peak[j], mDBRange);
1011 msg.rms[j] = ToDB(msg.rms[j], mDBRange);
1012 }
1013
1014 if (mDecay) {
1015 if (mDB) {
1016 float decayAmount = mDecayRate * deltaT / mDBRange;
1017 mBar[j].peak = floatMax(msg.peak[j],
1018 mBar[j].peak - decayAmount);
1019 }
1020 else {
1021 double decayAmount = mDecayRate * deltaT;
1022 double decayFactor = DB_TO_LINEAR(-decayAmount);
1023 mBar[j].peak = floatMax(msg.peak[j],
1024 mBar[j].peak * decayFactor);
1025 }
1026 }
1027 else
1028 mBar[j].peak = msg.peak[j];
1029
1030 // This smooths out the RMS signal
1031 float smooth = pow(0.9, (double)msg.numFrames/1024.0);
1032 mBar[j].rms = mBar[j].rms * smooth + msg.rms[j] * (1.0 - smooth);
1033
1034 if (mT - mBar[j].peakHoldTime > mPeakHoldDuration ||
1035 mBar[j].peak > mBar[j].peakHold) {
1036 mBar[j].peakHold = mBar[j].peak;
1037 mBar[j].peakHoldTime = mT;
1038 }
1039
1040 if (mBar[j].peak > mBar[j].peakPeakHold )
1041 mBar[j].peakPeakHold = mBar[j].peak;
1042
1043 if (msg.clipping[j] ||
1044 mBar[j].tailPeakCount+msg.headPeakCount[j] >=
1046 mBar[j].clipping = true;
1047 mBar[j].isclipping = true;
1048 }
1049
1050 mBar[j].tailPeakCount = msg.tailPeakCount[j];
1051#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1052 if (mT > gAudioIO->AILAGetLastDecisionTime()) {
1053 discarded = false;
1054 maxPeak = msg.peak[j] > maxPeak ? msg.peak[j] : maxPeak;
1055 wxPrintf("%f@%f ", msg.peak[j], mT);
1056 }
1057 else {
1058 discarded = true;
1059 wxPrintf("%f@%f discarded\n", msg.peak[j], mT);
1060 }
1061#endif
1062 }
1063 } // while
1064
1065 if (numChanges > 0) {
1066 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1067 if (gAudioIO->AILAIsActive() && mIsInput && !discarded) {
1068 gAudioIO->AILAProcess(maxPeak);
1069 putchar('\n');
1070 }
1071 #endif
1073 }
1074}
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:338
static float ToDB(float v, float range)
Definition: MeterPanel.cpp:887
static float floatMax(float a, float b)
Definition: MeterPanel.cpp:860
void RepaintBarsNow()
Message used to update the MeterPanel.
Definition: MeterPanel.h:56
bool clipping[kMaxMeterBars]
Definition: MeterPanel.h:61
float peak[kMaxMeterBars]
Definition: MeterPanel.h:59
int tailPeakCount[kMaxMeterBars]
Definition: MeterPanel.h:63
int headPeakCount[kMaxMeterBars]
Definition: MeterPanel.h:62
float rms[kMaxMeterBars]
Definition: MeterPanel.h:60
bool isclipping
Definition: MeterPanel.h:50
float peakPeakHold
Definition: MeterPanel.h:52
float peak
Definition: MeterPanel.h:44
int tailPeakCount
Definition: MeterPanel.h:51
float rms
Definition: MeterPanel.h:45
bool clipping
Definition: MeterPanel.h:49
double peakHoldTime
Definition: MeterPanel.h:47
float peakHold
Definition: MeterPanel.h:46

References MeterBar::clipping, MeterUpdateMsg::clipping, DB_TO_LINEAR, floatMax(), 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 1916 of file MeterPanel.cpp.

1917{
1919}
void StartMonitoring()

References StartMonitoring().

Here is the call graph for this function:

◆ OnMouse()

void MeterPanel::OnMouse ( wxMouseEvent &  evt)
private

Definition at line 664 of file MeterPanel.cpp.

665{
666 if ((evt.GetEventType() == wxEVT_MOTION || evt.Entering() || evt.Leaving())) {
667 mLayoutValid = false;
668 Refresh();
669 }
670
671 if (mStyle == MixerTrackCluster) // MixerTrackCluster style has no menu.
672 return;
673
674 if (evt.Entering()) {
675 mTipTimer.StartOnce(500);
676 }
677 else if(evt.Leaving())
678 mTipTimer.Stop();
679
680 if (evt.RightDown())
681 ShowMenu(evt.GetPosition());
682 else
683 {
684
685 if (mSlider)
686 mSlider->OnMouseEvent(evt);
687 }
688}

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

438{
439#if defined(__WXMAC__)
440 auto paintDC = std::make_unique<wxPaintDC>(this);
441#else
442 std::unique_ptr<wxDC> paintDC{ wxAutoBufferedPaintDCFactory(this) };
443#endif
444 wxDC & destDC = *paintDC;
445 wxColour clrText = theTheme.Colour( clrTrackPanelText );
446 wxColour clrBoxFill = theTheme.Colour( clrMedium );
447
448 if (mLayoutValid == false || (mStyle == MixerTrackCluster ))
449 {
450 // Create a NEW one using current size and select into the DC
451 mBitmap = std::make_unique<wxBitmap>();
452 mBitmap->Create(mWidth, mHeight, destDC);
453 wxMemoryDC dc;
454 dc.SelectObject(*mBitmap);
455
456 // Go calculate all of the layout metrics
457 HandleLayout(dc);
458
459 mBkgndBrush.SetColour( GetBackgroundColour() );
460 dc.SetPen(*wxTRANSPARENT_PEN);
461 dc.SetBrush(mBkgndBrush);
462 dc.DrawRectangle(0, 0, mWidth, mHeight);
463
464 // MixerTrackCluster style has no icon or L/R labels
466 {
467 dc.SetFont(GetFont());
468 dc.SetTextForeground( clrText );
469 dc.SetTextBackground( clrBoxFill );
470 dc.DrawText(mLeftText, mLeftTextPos.x, mLeftTextPos.y);
471 dc.DrawText(mRightText, mRightTextPos.x, mRightTextPos.y);
472 }
473
474 // Setup the colors for the 3 sections of the meter bars
475 wxColor green(117, 215, 112);
476 wxColor yellow(255, 255, 0);
477 wxColor red(255, 0, 0);
478
479 // Bug #2473 - (Sort of) Hack to make text on meters more
480 // visible with darker backgrounds. It would be better to have
481 // different colors entirely and as part of the theme.
482 if (GetBackgroundColour().GetLuminance() < 0.25)
483 {
484 green = wxColor(117-100, 215-100, 112-100);
485 yellow = wxColor(255-100, 255-100, 0);
486 red = wxColor(255-100, 0, 0);
487 }
488 else if (GetBackgroundColour().GetLuminance() < 0.50)
489 {
490 green = wxColor(117-50, 215-50, 112-50);
491 yellow = wxColor(255-50, 255-50, 0);
492 red = wxColor(255-50, 0, 0);
493 }
494
495 // Draw the meter bars at maximum levels
496 for (unsigned int i = 0; i < mNumBars; i++)
497 {
498 // Cache bar rect
499 wxRect r = mBar[i].r;
500
501 if (mGradient)
502 {
503 // Calculate the size of the two gradiant segments of the meter
504 double gradw;
505 double gradh;
506 if (mDB)
507 {
508 gradw = (double) r.GetWidth() / mDBRange * 6.0;
509 gradh = (double) r.GetHeight() / mDBRange * 6.0;
510 }
511 else
512 {
513 gradw = (double) r.GetWidth() / 100 * 25;
514 gradh = (double) r.GetHeight() / 100 * 25;
515 }
516
517 if (mBar[i].vert)
518 {
519 // Draw the "critical" segment (starts at top of meter and works down)
520 r.SetHeight(gradh);
521 dc.GradientFillLinear(r, red, yellow, wxSOUTH);
522
523 // Draw the "warning" segment
524 r.SetTop(r.GetBottom());
525 dc.GradientFillLinear(r, yellow, green, wxSOUTH);
526
527 // Draw the "safe" segment
528 r.SetTop(r.GetBottom());
529 r.SetBottom(mBar[i].r.GetBottom());
530 dc.SetPen(*wxTRANSPARENT_PEN);
531 dc.SetBrush(green);
532 dc.DrawRectangle(r);
533 }
534 else
535 {
536 // Draw the "safe" segment
537 r.SetWidth(r.GetWidth() - (int) (gradw + gradw + 0.5));
538 dc.SetPen(*wxTRANSPARENT_PEN);
539 dc.SetBrush(green);
540 dc.DrawRectangle(r);
541
542 // Draw the "warning" segment
543 r.SetLeft(r.GetRight() + 1);
544 r.SetWidth(floor(gradw));
545 dc.GradientFillLinear(r, green, yellow);
546
547 // Draw the "critical" segment
548 r.SetLeft(r.GetRight() + 1);
549 r.SetRight(mBar[i].r.GetRight());
550 dc.GradientFillLinear(r, yellow, red);
551 }
552#ifdef EXPERIMENTAL_METER_LED_STYLE
553 if (!mBar[i].vert)
554 {
555 wxRect r = mBar[i].r;
556 wxPen BackgroundPen;
557 BackgroundPen.SetColour( wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE) );
558 dc.SetPen( BackgroundPen );
559 int i;
560 for(i=0;i<r.width;i++)
561 {
562 // 2 pixel spacing between the LEDs
563 if( (i%7)<2 ){
564 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+r.height );
565 } else {
566 // The LEDs have triangular ends.
567 // This code shapes the ends.
568 int j = abs( (i%7)-4);
569 AColor::Line( dc, i+r.x, r.y, i+r.x, r.y+j +1);
570 AColor::Line( dc, i+r.x, r.y+r.height-j, i+r.x, r.y+r.height );
571 }
572 }
573 }
574#endif
575 }
576 }
577
578 {//Strokes
579 dc.SetPen(AColor::darkPen[0]);
580 dc.SetBrush(*wxTRANSPARENT_BRUSH);
581
582 //Stroke around group
583 dc.DrawRectangle(wxRect(
584 mBar[0].r.GetTopLeft(),
585 mBar[mNumBars - 1].r.GetBottomRight()
586 ).Inflate(1));
587
588 //strokes between meters
589 for(unsigned n = 0; n < mNumBars - 1; ++n)
590 dc.DrawLine(mBar[n].b.GetBottomLeft(), mBar[n].b.GetBottomRight());
591 if constexpr (gap > 0)
592 {
593 for(unsigned n = 1; n < mNumBars; ++n)
594 dc.DrawLine(mBar[n].b.GetTopLeft(), mBar[n].b.GetTopRight());
595 }
596
597 //stroke around clip indicators
598 for(unsigned n = 0; n < mNumBars; ++n)
599 dc.DrawRectangle(wxRect(mBar[n].rClip).Inflate(1));
600 }
601
602 mRuler.SetTickColour( clrText );
603 dc.SetTextForeground( clrText );
604
605 mRuler.Draw(dc); // Draw the ruler
606
607 // Bitmap created...unselect
608 dc.SelectObject(wxNullBitmap);
609 }
610
611 // Copy predrawn bitmap to the dest DC
612 destDC.DrawBitmap(*mBitmap, 0, 0);
613
614 // Go draw the meter bars, Left & Right channels using current levels
615 for (unsigned int i = 0; i < mNumBars; i++)
616 {
617 DrawMeterBar(destDC, &mBar[i]);
618 }
619
620 destDC.SetTextForeground( clrText );
621
622 // We can have numbers over the bars, in which case we have to draw them each time.
624 {
625 mRuler.SetTickColour( clrText );
626 // If the text colour is too similar to the meter colour, then we need a background
627 // for the text. We require a total of at least one full-scale RGB difference.
628 int d = theTheme.ColourDistance( clrText, theTheme.Colour( clrMeterOutputRMSBrush ) );
629 if( d < 256 )
630 {
631 destDC.SetBackgroundMode( wxSOLID );
632 destDC.SetTextBackground( clrBoxFill );
633 }
634 mRuler.Draw(destDC);
635 }
636
638 {
639 bool highlighted =
640 wxRect{ mSliderPos, mSliderSize }.Contains(
641 ScreenToClient(
642 ::wxGetMousePosition()));
643
644 mSlider->Move(mSliderPos);
645 mSlider->AdjustSize(mSliderSize);
646 mSlider->OnPaint(destDC, highlighted);
647 }
648
649 if (mIsFocused)
650 {
651 auto r = GetClientRect();
652 AColor::DrawFocus(destDC, r);
653 }
654}
static wxPen darkPen[2]
Definition: AColor.h:103
static void DrawFocus(wxDC &dc, wxRect &r)
Definition: AColor.cpp:247
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:285

References MeterBar::b, ThemeBase::Colour(), ThemeBase::ColourDistance(), AColor::darkPen, Ruler::Draw(), AColor::DrawFocus(), DrawMeterBar(), gap, GetFont(), HandleLayout(), HorizontalStereoCompact, AColor::Line(), mBar, mBitmap, mBkgndBrush, 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 1921 of file MeterPanel.cpp.

1922{
1923 wxTextCtrl *rate;
1924 wxRadioButton *gradient;
1925 wxRadioButton *rms;
1926 wxRadioButton *db;
1927 wxRadioButton *linear;
1928 wxRadioButton *automatic;
1929 wxRadioButton *horizontal;
1930 wxRadioButton *vertical;
1931 int meterRefreshRate = mMeterRefreshRate;
1932
1933 auto title = mIsInput ? XO("Recording Meter Options") : XO("Playback Meter Options");
1934
1935 // Dialog is a child of the project, rather than of the toolbar.
1936 // This determines where it pops up.
1937
1938 wxDialogWrapper dlg( FindProjectFrame( mProject ), wxID_ANY, title);
1939 dlg.SetName();
1940 ShuttleGui S(&dlg, eIsCreating);
1941 S.StartVerticalLay();
1942 {
1943 S.StartStatic(XO("Refresh Rate"), 0);
1944 {
1945 S.AddFixedText(XO(
1946"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."));
1947 S.StartHorizontalLay();
1948 {
1949 rate = S.Name(XO("Meter refresh rate per second [1-100]"))
1950 .Validator<IntegerValidator<long>>(
1951 &mMeterRefreshRate, NumValidatorStyle::DEFAULT,
1953 .AddTextBox(XXO("Meter refresh rate per second [1-100]: "),
1954 wxString::Format(wxT("%d"), meterRefreshRate),
1955 10);
1956 }
1957 S.EndHorizontalLay();
1958 }
1959 S.EndStatic();
1960
1961 S.StartHorizontalLay();
1962 {
1963 S.StartStatic(XO("Meter Style"), 0);
1964 {
1965 S.StartVerticalLay();
1966 {
1967 gradient = S.AddRadioButton(XXO("Gradient"), true, mGradient);
1968 rms = S.AddRadioButtonToGroup(XXO("RMS"), false, mGradient);
1969 }
1970 S.EndVerticalLay();
1971 }
1972 S.EndStatic();
1973
1974 S.StartStatic(XO("Meter Type"), 0);
1975 {
1976 S.StartVerticalLay();
1977 {
1978 db = S.AddRadioButton(XXO("dB"), true, mDB);
1979 linear = S.AddRadioButtonToGroup(XXO("Linear"), false, mDB);
1980 }
1981 S.EndVerticalLay();
1982 }
1983 S.EndStatic();
1984
1985 S.StartStatic(XO("Orientation"), 1);
1986 {
1987 S.StartVerticalLay();
1988 {
1989 automatic = S.AddRadioButton(
1990 XXO("Automatic"), AutomaticStereo, mDesiredStyle);
1991 horizontal = S.AddRadioButtonToGroup(
1992 XXO("Horizontal"), HorizontalStereo, mDesiredStyle);
1993 vertical = S.AddRadioButtonToGroup(
1994 XXO("Vertical"), VerticalStereo, mDesiredStyle);
1995 }
1996 S.EndVerticalLay();
1997 }
1998 S.EndStatic();
1999 }
2000 S.EndHorizontalLay();
2001 S.AddStandardButtons();
2002 }
2003 S.EndVerticalLay();
2004 dlg.Layout();
2005 dlg.Fit();
2006
2007 dlg.CenterOnParent();
2008
2009 if (dlg.ShowModal() == wxID_OK)
2010 {
2012 wxT("AutomaticStereo") ,
2013 wxT("HorizontalStereo") ,
2014 wxT("VerticalStereo") ,
2015 };
2016
2017 int s = 0;
2018 s = automatic->GetValue() ? 0 : s;
2019 s = horizontal->GetValue() ? 1 : s;
2020 s = vertical->GetValue() ? 2 : s;
2021
2022 gPrefs->Write(Key(wxT("Style")), style[s]);
2023 gPrefs->Write(Key(wxT("Bars")), gradient->GetValue() ? wxT("Gradient") : wxT("RMS"));
2024 gPrefs->Write(Key(wxT("Type")), db->GetValue() ? wxT("dB") : wxT("Linear"));
2025 gPrefs->Write(Key(wxT("RefreshRate")), rate->GetValue());
2026
2027 gPrefs->Flush();
2028
2029 // Currently, there are 2 playback meters and 2 record meters and any number of
2030 // mixerboard meters, so we have to send out an preferences updated message to
2031 // ensure they all update themselves.
2033 }
2034}
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:388
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 740 of file MeterPanel.cpp.

741{
742 mIsFocused = true;
743 Refresh(false);
744}

References mIsFocused.

◆ OnSize()

void MeterPanel::OnSize ( wxSizeEvent &  evt)
private

Definition at line 656 of file MeterPanel.cpp.

657{
658 GetClientSize(&mWidth, &mHeight);
659
660 mLayoutValid = false;
661 Refresh();
662}

References mHeight, mLayoutValid, and mWidth.

◆ OnTipTimeout()

void MeterPanel::OnTipTimeout ( wxTimerEvent &  evt)
private

Definition at line 1076 of file MeterPanel.cpp.

1077{
1078 if(mSlider)
1079 mSlider->ShowTip(true);
1080}

References mSlider.

◆ RepaintBarsNow()

void MeterPanel::RepaintBarsNow ( )
private

Definition at line 1518 of file MeterPanel.cpp.

1519{
1520 if (mLayoutValid)
1521 {
1522 // Invalidate the bars so they get redrawn
1523 for (unsigned int i = 0; i < mNumBars; i++)
1524 {
1525 Refresh(false);
1526 }
1527
1528 // Immediate redraw (using wxPaintDC)
1529 Update();
1530
1531 return;
1532 }
1533}

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

838{
839 mT = 0;
841 for (int j = 0; j < kMaxMeterBars; j++)
842 {
843 ResetBar(&mBar[j], resetClipping);
844 }
845
846 // wxTimers seem to be a little unreliable - sometimes they stop for
847 // no good reason, so this "primes" it every now and then...
848 mTimer.Stop();
849
850 // While it's stopped, empty the queue
851 mQueue.Clear();
852
853 mLayoutValid = false;
854
855 mTimer.Start(1000 / mMeterRefreshRate);
856
857 Refresh(false);
858}
const int kMaxMeterBars
Definition: MeterPanel.h:38
void ResetBar(MeterBar *bar, bool resetClipping)

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

1112{
1113 b->peak = 0.0;
1114 b->rms = 0.0;
1115 b->peakHold = 0.0;
1116 b->peakHoldTime = 0.0;
1117 if (resetClipping)
1118 {
1119 b->clipping = false;
1120 b->peakPeakHold = 0.0;
1121 }
1122 b->isclipping = false;
1123 b->tailPeakCount = 0;
1124}

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

1871{
1872 if (!state.mSaved)
1873 return;
1874
1875 mMonitoring = state.mMonitoring;
1876 mActive = state.mActive;
1877 //wxLogDebug("Restore state for %p, is %i", this, mActive );
1878
1879 if (mActive)
1880 mTimer.Start(1000 / mMeterRefreshRate);
1881}

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

1866{
1867 return { true, mMonitoring, mActive };
1868}

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SetActiveStyle()

void MeterPanel::SetActiveStyle ( Style  style)
private

Definition at line 1144 of file MeterPanel.cpp.

1145{
1146 mStyle = newStyle;
1147
1148 // Set dummy ruler bounds so width/height can be retrieved
1149 // NOTE: Make sure the Right and Bottom values are large enough to
1150 // ensure full width/height of digits get calculated.
1151 mRuler.SetBounds(0, 0, 500, 500);
1152
1153 if (mDB)
1154 {
1157 {
1158 mRuler.SetOrientation(wxHORIZONTAL);
1160 }
1161 else
1162 {
1163 mRuler.SetOrientation(wxVERTICAL);
1165 }
1166 }
1167 else
1168 {
1171 {
1172 mRuler.SetOrientation(wxHORIZONTAL);
1173 mRuler.SetRange(0, 1);
1174 }
1175 else
1176 {
1177 mRuler.SetOrientation(wxVERTICAL);
1178 mRuler.SetRange(1, 0);
1179 }
1180 }
1181
1183}
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 1185 of file MeterPanel.cpp.

1186{
1187 constexpr static auto StrokeWidth = 1;
1188 //either width or height, depending on meter orientation
1189 constexpr static auto ClipIndicatorSize = 3;
1190 constexpr static auto ClipIndicatorPadding = 1;
1191 // Save the orientation
1192 mBar[iBar].vert = vert;
1193
1194 if (mClip)
1195 {
1196 // Create the clip rectangle and adjust
1197 // meter's boundaries
1198 if (vert)
1199 {
1200 mBar[iBar].rClip = wxRect(
1201 mBar[iBar].b.x + StrokeWidth,
1202 mBar[iBar].b.y + StrokeWidth,
1203 mBar[iBar].b.width - StrokeWidth * 2,
1204 ClipIndicatorSize
1205 );
1206
1207 // Make room for the clipping indicator
1208 constexpr auto yOffset =
1209 gap + ClipIndicatorPadding + StrokeWidth * 2 + ClipIndicatorSize;
1210 mBar[iBar].b.y += yOffset;
1211 mBar[iBar].b.height -= yOffset;
1212 }
1213 else
1214 {
1215 mBar[iBar].rClip = wxRect(
1216 mBar[iBar].b.GetRight() - StrokeWidth - ClipIndicatorSize + 1,
1217 mBar[iBar].b.GetTop() + StrokeWidth,
1218 ClipIndicatorSize,
1219 mBar[iBar].b.height - StrokeWidth * 2
1220 );
1221 // Make room for the clipping indicator
1222 mBar[iBar].b.width -=
1223 gap + ClipIndicatorPadding + StrokeWidth * 2 + ClipIndicatorSize;
1224 }
1225 }
1226 // Create the bar rectangle and educe to fit inside the bevel
1227 mBar[iBar].r = mBar[iBar].b;
1228 mBar[iBar].r.Deflate(StrokeWidth);
1229}
wxRect rClip
Definition: MeterPanel.h:48
bool vert
Definition: MeterPanel.h:41

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

2055{
2056 auto temp = TemporarilyAllowFocus();
2057 SetFocus();
2058}
static TempAllowFocus TemporarilyAllowFocus()
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
Definition: BasicUI.h:392

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

Here is the call graph for this function:

◆ SetMixer()

void MeterPanel::SetMixer ( wxCommandEvent &  event)

Definition at line 768 of file MeterPanel.cpp.

769{
770#if USE_PORTMIXER
771 if (mSlider)
772 {
773 float inputVolume;
774 float outputVolume;
775 int inputSource;
776
777 Refresh();
778
779 auto gAudioIO = AudioIO::Get();
780 gAudioIO->GetMixer(&inputSource, &inputVolume, &outputVolume);
781
782 if (mIsInput)
783 inputVolume = mSlider->Get();
784 else
785 outputVolume = mSlider->Get();
786
787 gAudioIO->SetMixer(inputSource, inputVolume, outputVolume);
788
789#if wxUSE_ACCESSIBILITY
790 GetAccessible()->NotifyEvent( wxACC_EVENT_OBJECT_VALUECHANGE,
791 this,
792 wxOBJID_CLIENT,
793 wxACC_SELF );
794#endif
795
796 }
797#endif // USE_PORTMIXER
798}

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

1909{
1911 if(mSlider)
1912 mSlider->SetName(tip);
1913}

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

757{
758 if (mStyle != newStyle && mDesiredStyle == AutomaticStereo)
759 {
760 SetActiveStyle(newStyle);
761
762 mLayoutValid = false;
763
764 Refresh(false);
765 }
766}

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

Here is the call graph for this function:

◆ ShowDialog()

bool MeterPanel::ShowDialog ( )

Definition at line 800 of file MeterPanel.cpp.

801{
802 if (!mSlider)
803 return false;
804
805 auto changed = mSlider->ShowDialog();
806 if (changed)
807 {
808 wxCommandEvent e;
809 SetMixer(e);
810 }
811
812 return changed;
813}

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

1888{
1889 wxMenu menu;
1890 // Note: these should be kept in the same order as the enum
1891 if (mIsInput) {
1892 wxMenuItem *mi;
1893 if (mMonitoring)
1894 mi = menu.Append(OnMonitorID, _("Disable Silent Monitoring"));
1895 else
1896 mi = menu.Append(OnMonitorID, _("Enable Silent Monitoring"));
1897 mi->Enable(!mActive || mMonitoring);
1898 }
1899
1900 menu.Append(OnPreferencesID, _("Options..."));
1901
1902 BasicMenu::Handle{ &menu }.Popup(
1904 { pos.x, pos.y }
1905 );
1906}
@ OnPreferencesID
Definition: MeterPanel.cpp:206
@ OnMonitorID
Definition: MeterPanel.cpp:205
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 1797 of file MeterPanel.cpp.

1798{
1799 bool start = !mMonitoring;
1800
1801 auto gAudioIO = AudioIO::Get();
1802 if (gAudioIO->IsMonitoring()){
1803 gAudioIO->StopStream();
1804 }
1805
1806 if (start && !gAudioIO->IsBusy()){
1808 if (p)
1809 gAudioIO->StartMonitoring(ProjectAudioIO::GetDefaultOptions(*p));
1810
1811 mLayoutValid = false;
1812
1813 Refresh(false);
1814 }
1815}
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 1817 of file MeterPanel.cpp.

1817 {
1818 mMonitoring = false;
1819 auto gAudioIO = AudioIO::Get();
1820 if (gAudioIO->IsMonitoring()){
1821 gAudioIO->StopStream();
1822 }
1823}

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

899{
900 auto sptr = sampleData;
901 auto num = std::min(numChannels, mNumBars);
902 MeterUpdateMsg msg;
903
904 memset(&msg, 0, sizeof(msg));
905 msg.numFrames = numFrames;
906
907 for(int i=0; i<numFrames; i++) {
908 for(unsigned int j=0; j<num; j++) {
909 msg.peak[j] = floatMax(msg.peak[j], fabs(sptr[j]));
910 msg.rms[j] += sptr[j]*sptr[j];
911
912 // In addition to looking for mNumPeakSamplesToClip peaked
913 // samples in a row, also send the number of peaked samples
914 // at the head and tail, in case there's a run of peaked samples
915 // that crosses block boundaries
916 if (fabs(sptr[j])>=MAX_AUDIO) {
917 if (msg.headPeakCount[j]==i)
918 msg.headPeakCount[j]++;
919 msg.tailPeakCount[j]++;
921 msg.clipping[j] = true;
922 }
923 else
924 msg.tailPeakCount[j] = 0;
925 }
926 sptr += numChannels;
927 }
928 for(unsigned int j=0; j<mNumBars; j++)
929 msg.rms[j] = sqrt(msg.rms[j]/numFrames);
930
931 mQueue.Put(msg);
932}
int min(int a, int b)
#define MAX_AUDIO
Definition: MemoryX.h:341
__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, 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 342 of file MeterPanel.cpp.

343{
345
348 gPrefs->Read(Key(wxT("RefreshRate")), 30L)));
349 mGradient = gPrefs->Read(Key(wxT("Bars")), wxT("Gradient")) == wxT("Gradient");
350 mDB = gPrefs->Read(Key(wxT("Type")), wxT("dB")) == wxT("dB");
351 mMeterDisabled = gPrefs->Read(Key(wxT("Disabled")), 0L);
352
354 {
355 wxString style = gPrefs->Read(Key(wxT("Style")));
356 if (style == wxT("AutomaticStereo"))
357 {
359 }
360 else if (style == wxT("HorizontalStereo"))
361 {
363 }
364 else if (style == wxT("VerticalStereo"))
365 {
367 }
368 else
369 {
371 }
372 }
373
374 // Set the desired orientation (resets ruler orientation)
376
377 // Reset to ensure NEW size is retrieved when language changes
378 mLeftSize = wxSize(0, 0);
379 mRightSize = wxSize(0, 0);
380
381 Reset(mRate, false);
382
383 mLayoutValid = false;
384
385 Refresh(false);
386}
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 394 of file MeterPanel.cpp.

395{
396 if (id == MeterPrefsID())
397 {
398#if USE_PORTMIXER
399 if (mIsInput && mSlider)
400 {
401 // Show or hide the input slider based on whether it works
402 auto gAudioIO = AudioIO::Get();
403 mSlider->SetEnabled(mEnabled && gAudioIO->InputMixerWorks());
404 }
405#endif
406 UpdatePrefs();
407 }
408}

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

Here is the call graph for this function:

◆ UpdateSliderControl()

void MeterPanel::UpdateSliderControl ( )

Definition at line 410 of file MeterPanel.cpp.

411{
412#if USE_PORTMIXER
413 float inputVolume;
414 float playbackVolume;
415 int inputSource;
416
417 // Show or hide the input slider based on whether it works
418 auto gAudioIO = AudioIO::Get();
419 if (mIsInput && mSlider)
420 mSlider->SetEnabled(mEnabled && gAudioIO->InputMixerWorks());
421
422 gAudioIO->GetMixer(&inputSource, &inputVolume, &playbackVolume);
423
424 const auto volume = mIsInput ? inputVolume : playbackVolume;
425
426 if (mSlider && (mSlider->Get() != volume))
427 mSlider->Set(volume);
428
429#endif // USE_PORTMIXER
430}

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 303 of file MeterPanel.h.

Member Data Documentation

◆ mActive

bool MeterPanel::mActive
private

Definition at line 270 of file MeterPanel.h.

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

◆ mAudioCaptureSubscription

Observer::Subscription MeterPanel::mAudioCaptureSubscription
private

Definition at line 238 of file MeterPanel.h.

◆ mAudioIOStatusSubscription

Observer::Subscription MeterPanel::mAudioIOStatusSubscription
private

Definition at line 237 of file MeterPanel.h.

◆ mBar

MeterBar MeterPanel::mBar[kMaxMeterBars] {}
private

◆ mBitmap

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

Definition at line 277 of file MeterPanel.h.

Referenced by DrawMeterBar(), and OnPaint().

◆ mBkgndBrush

wxBrush MeterPanel::mBkgndBrush
private

Definition at line 287 of file MeterPanel.h.

Referenced by DrawMeterBar(), and OnPaint().

◆ mBrush

wxBrush MeterPanel::mBrush
private

Definition at line 284 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mClip

bool MeterPanel::mClip
private

Definition at line 260 of file MeterPanel.h.

Referenced by DrawMeterBar(), and SetBarAndClip().

◆ mClipBrush

wxBrush MeterPanel::mClipBrush
private

Definition at line 286 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mDB

bool MeterPanel::mDB
private

Definition at line 256 of file MeterPanel.h.

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

◆ mDBRange

int MeterPanel::mDBRange
private

Definition at line 257 of file MeterPanel.h.

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

◆ mDecay

bool MeterPanel::mDecay
private

Definition at line 258 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mDecayRate

float MeterPanel::mDecayRate {}
private

Definition at line 259 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mDesiredStyle

Style MeterPanel::mDesiredStyle
private

Definition at line 254 of file MeterPanel.h.

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

◆ mDisabledBkgndBrush

wxBrush MeterPanel::mDisabledBkgndBrush
private

Definition at line 288 of file MeterPanel.h.

◆ mEnabled

bool MeterPanel::mEnabled { true }
private

Definition at line 298 of file MeterPanel.h.

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

◆ mFocusRect

wxRect MeterPanel::mFocusRect
private

Definition at line 301 of file MeterPanel.h.

◆ mGradient

bool MeterPanel::mGradient
private

Definition at line 255 of file MeterPanel.h.

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

◆ mHeight

int MeterPanel::mHeight
private

Definition at line 246 of file MeterPanel.h.

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

◆ mIsFocused

bool MeterPanel::mIsFocused {}
private

Definition at line 300 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 280 of file MeterPanel.h.

Referenced by HandleLayout(), and UpdatePrefs().

◆ mLeftText

wxString MeterPanel::mLeftText
private

Definition at line 291 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mLeftTextPos

wxPoint MeterPanel::mLeftTextPos
private

Definition at line 278 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mMeterBkgndBrush

wxBrush MeterPanel::mMeterBkgndBrush
private

Definition at line 289 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mMeterDisabled

long MeterPanel::mMeterDisabled {}
private

Definition at line 266 of file MeterPanel.h.

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

◆ mMeterRefreshRate

long MeterPanel::mMeterRefreshRate {}
private

Definition at line 265 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 261 of file MeterPanel.h.

Referenced by OnMeterUpdate(), and UpdateDisplay().

◆ mPeakHoldDuration

double MeterPanel::mPeakHoldDuration
private

Definition at line 262 of file MeterPanel.h.

Referenced by OnMeterUpdate().

◆ mPeakPeakPen

wxPen MeterPanel::mPeakPeakPen
private

Definition at line 283 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mPen

wxPen MeterPanel::mPen
private

Definition at line 282 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mProject

AudacityProject* MeterPanel::mProject
private

Definition at line 240 of file MeterPanel.h.

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

◆ mQueue

MeterUpdateQueue MeterPanel::mQueue
private

Definition at line 241 of file MeterPanel.h.

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

◆ mRate

double MeterPanel::mRate
private

Definition at line 264 of file MeterPanel.h.

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

◆ mRightSize

wxSize MeterPanel::mRightSize
private

Definition at line 281 of file MeterPanel.h.

Referenced by HandleLayout(), and UpdatePrefs().

◆ mRightText

wxString MeterPanel::mRightText
private

Definition at line 292 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mRightTextPos

wxPoint MeterPanel::mRightTextPos
private

Definition at line 279 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mRMSBrush

wxBrush MeterPanel::mRMSBrush
private

Definition at line 285 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mRuler

Ruler MeterPanel::mRuler
private

Definition at line 290 of file MeterPanel.h.

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

◆ mRulerHeight

int MeterPanel::mRulerHeight {}
private

Definition at line 249 of file MeterPanel.h.

Referenced by HandleLayout(), and SetActiveStyle().

◆ mRulerWidth

int MeterPanel::mRulerWidth {}
private

Definition at line 248 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 295 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mSliderSize

wxSize MeterPanel::mSliderSize
private

Definition at line 296 of file MeterPanel.h.

Referenced by HandleLayout(), and OnPaint().

◆ mStyle

Style MeterPanel::mStyle {}
private

◆ mT

double MeterPanel::mT
private

Definition at line 263 of file MeterPanel.h.

Referenced by OnMeterUpdate(), and Reset().

◆ mTimer

wxTimer MeterPanel::mTimer
private

Definition at line 242 of file MeterPanel.h.

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

◆ mTipTimer

wxTimer MeterPanel::mTipTimer
private

Definition at line 243 of file MeterPanel.h.

Referenced by OnKillFocus(), and OnMouse().

◆ mWidth

int MeterPanel::mWidth
private

Definition at line 245 of file MeterPanel.h.

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


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