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
 
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
369
372
373 if (mIsInput) {
374 mPen = wxPen( theTheme.Colour( clrMeterInputPen ), 1, wxPENSTYLE_SOLID);
375 mBrush = wxBrush( theTheme.Colour( clrMeterInputBrush ), wxBRUSHSTYLE_SOLID);
376 mRMSBrush = wxBrush( theTheme.Colour( clrMeterInputRMSBrush ), wxBRUSHSTYLE_SOLID);
377 mClipBrush = wxBrush( theTheme.Colour( clrMeterInputClipBrush ), wxBRUSHSTYLE_SOLID);
378// mLightPen = wxPen( theTheme.Colour( clrMeterInputLightPen ), 1, wxSOLID);
379// mDarkPen = wxPen( theTheme.Colour( clrMeterInputDarkPen ), 1, wxSOLID);
380 }
381 else {
382 mPen = wxPen( theTheme.Colour( clrMeterOutputPen ), 1, wxPENSTYLE_SOLID);
383 mBrush = wxBrush( theTheme.Colour( clrMeterOutputBrush ), wxBRUSHSTYLE_SOLID);
384 mRMSBrush = wxBrush( theTheme.Colour( clrMeterOutputRMSBrush ), wxBRUSHSTYLE_SOLID);
385 mClipBrush = wxBrush( theTheme.Colour( clrMeterOutputClipBrush ), wxBRUSHSTYLE_SOLID);
386// mLightPen = wxPen( theTheme.Colour( clrMeterOutputLightPen ), 1, wxSOLID);
387// mDarkPen = wxPen( theTheme.Colour( clrMeterOutputDarkPen ), 1, wxSOLID);
388 }
389
390
391 mTipTimer.SetOwner(this, OnTipTimeoutID);
392 mTimer.SetOwner(this, OnMeterUpdateID);
393 // TODO: Yikes. Hard coded sample rate.
394 // JKC: I've looked at this, and it's benignish. It just means that the meter
395 // balistics are right for 44KHz and a bit more frisky than they should be
396 // for higher sample rates.
397 Reset(44100.0, true);
398}
#define PERCENT_SLIDER
Definition: ASlider.h:39
IntSetting DecibelScaleCutoff
Negation of this value is the lowest dB level that should be shown in dB scales.
Definition: Decibels.cpp:12
XO("Cut/Copy/Paste")
#define safenew
Definition: MemoryX.h:10
@ 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:405
Style mStyle
Definition: MeterPanel.h:266
wxFont GetFont() const
double mRate
Definition: MeterPanel.h:277
Style mDesiredStyle
Definition: MeterPanel.h:267
bool mClip
Definition: MeterPanel.h:273
int mDBRange
Definition: MeterPanel.h:270
bool mIsInput
Definition: MeterPanel.h:264
Ruler mRuler
Definition: MeterPanel.h:302
Observer::Subscription mAudioCaptureSubscription
Definition: MeterPanel.h:251
wxTimer mTimer
Definition: MeterPanel.h:255
float mDecayRate
Definition: MeterPanel.h:272
bool mDecay
Definition: MeterPanel.h:271
double mPeakHoldDuration
Definition: MeterPanel.h:275
std::unique_ptr< LWSlider > mSlider
Definition: MeterPanel.h:306
double mT
Definition: MeterPanel.h:276
AudacityProject * mProject
Definition: MeterPanel.h:253
unsigned mNumBars
Definition: MeterPanel.h:285
wxBrush mBkgndBrush
Definition: MeterPanel.h:300
friend class MeterAx
Definition: MeterPanel.h:315
void OnAudioIOStatus(AudioIOEvent)
bool mMonitoring
Definition: MeterPanel.h:281
bool mGradient
Definition: MeterPanel.h:268
bool mActive
Definition: MeterPanel.h:283
void UpdateSliderControl()
Definition: MeterPanel.cpp:473
wxBrush mBrush
Definition: MeterPanel.h:297
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:296
int mNumPeakSamplesToClip
Definition: MeterPanel.h:274
wxBrush mClipBrush
Definition: MeterPanel.h:299
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:892
void OnAudioCapture(AudioIOEvent)
wxPen mPen
Definition: MeterPanel.h:295
bool mIsFocused
Definition: MeterPanel.h:312
MeterUpdateQueue mQueue
Definition: MeterPanel.h:254
wxBrush mRMSBrush
Definition: MeterPanel.h:298
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 400 of file MeterPanel.cpp.

401{
402 mQueue.Clear();
403}

References MeterUpdateQueue::Clear(), and mQueue.

Here is the call graph for this function:

◆ Decrease()

void MeterPanel::Decrease ( float  steps)

Definition at line 881 of file MeterPanel.cpp.

882{
883 if (mSlider)
884 {
885 wxCommandEvent e;
886
887 mSlider->Decrease(steps);
888 SetMixer(e);
889 }
890}
void SetMixer(wxCommandEvent &event)
Definition: MeterPanel.cpp:823

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

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

1157{
1158 int fontSize = 10;
1159#if defined __WXMSW__
1160 fontSize = 8;
1161#endif
1162
1163 return wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
1164}

Referenced by HandleLayout(), and OnPaint().

Here is the caller graph for this function:

◆ GetMaxPeak()

float MeterPanel::GetMaxPeak ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1138 of file MeterPanel.cpp.

1139{
1140 float maxPeak = 0.;
1141
1142 for(unsigned int j=0; j<mNumBars; j++)
1143 maxPeak = mBar[j].peak > maxPeak ? mBar[j].peak : maxPeak;
1144
1145 return(maxPeak);
1146}
MeterBar mBar[kMaxMeterBars]
Definition: MeterPanel.h:286

References mBar, and mNumBars.

◆ GetPeakHold()

float MeterPanel::GetPeakHold ( ) const

Definition at line 1148 of file MeterPanel.cpp.

1149{
1150 auto peakHold = .0f;
1151 for (unsigned int i = 0; i < mNumBars; i++)
1152 peakHold = std::max(peakHold, mBar[i].peakPeakHold);
1153 return peakHold;
1154}

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

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

871{
872 if (mSlider)
873 {
874 wxCommandEvent e;
875
876 mSlider->Increase(steps);
877 SetMixer(e);
878 }
879}

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

1182{
1183 return mActive;
1184}

References mActive.

◆ IsClipping()

bool MeterPanel::IsClipping ( ) const
overridevirtual

Implements MeterPanelBase.

Definition at line 1191 of file MeterPanel.cpp.

1192{
1193 for (int c = 0; c < mNumBars; c++)
1194 if (mBar[c].clipping)
1195 return true;
1196 return false;
1197}

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

1848{
1849 return mMeterDisabled != 0;
1850}

References mMeterDisabled.

◆ IsMonitoring()

bool MeterPanel::IsMonitoring ( ) const

Definition at line 1186 of file MeterPanel.cpp.

1187{
1188 return mMonitoring;
1189}

References mMonitoring.

◆ Key()

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

Definition at line 2088 of file MeterPanel.cpp.

2089{
2091 {
2092 return wxT("/Meter/Mixerboard/") + key;
2093 }
2094
2095 if (mIsInput)
2096 {
2097 return wxT("/Meter/Input/") + key;
2098 }
2099
2100 return wxT("/Meter/Output/") + key;
2101}
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 1901 of file MeterPanel.cpp.

1902{
1903 if (
1904 event.type == AudioIOEvent::CAPTURE &&
1905 (event.pProject != mProject || !event.on))
1906 {
1907 mEnabled = !event.on;
1908
1909 if (mSlider)
1910 mSlider->SetEnabled(mEnabled);
1911 }
1912}
bool mEnabled
Definition: MeterPanel.h:310
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 1880 of file MeterPanel.cpp.

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

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

768{
769 if (mStyle != MixerTrackCluster) // MixerTrackCluster style has no menu.
770 {
771 ShowMenu(GetClientRect().GetBottomLeft());
772 }
773 else
774 {
775 evt.Skip();
776 }
777}

References mStyle, and ShowMenu().

Here is the call graph for this function:

◆ OnErase()

void MeterPanel::OnErase ( wxEraseEvent &  evt)
private

Definition at line 495 of file MeterPanel.cpp.

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

◆ OnKeyDown()

void MeterPanel::OnKeyDown ( wxKeyEvent &  evt)
private

Definition at line 779 of file MeterPanel.cpp.

780{
781 switch (evt.GetKeyCode())
782 {
783 case WXK_TAB:
784 if (evt.ShiftDown())
785 Navigate(wxNavigationKeyEvent::IsBackward);
786 else
787 Navigate(wxNavigationKeyEvent::IsForward);
788 break;
789 default:
790 mSlider->OnKeyDown(evt);
791 break;
792 }
793}

References mSlider.

◆ OnKillFocus()

void MeterPanel::OnKillFocus ( wxFocusEvent &  evt)
private

Definition at line 801 of file MeterPanel.cpp.

802{
803 if(mSlider)
804 mSlider->OnKillFocus();
805 mTipTimer.Stop();
806
807 mIsFocused = false;
808 Refresh(false);
809}

References mIsFocused, mSlider, and mTipTimer.

◆ OnMeterUpdate()

void MeterPanel::OnMeterUpdate ( wxTimerEvent &  evt)
private

Definition at line 1034 of file MeterPanel.cpp.

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

1969{
1971}
void StartMonitoring()

References StartMonitoring().

Here is the call graph for this function:

◆ OnMouse()

void MeterPanel::OnMouse ( wxMouseEvent &  evt)
private

Definition at line 719 of file MeterPanel.cpp.

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

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

Here is the call graph for this function:

◆ OnPaint()

void MeterPanel::OnPaint ( wxPaintEvent &  evt)
private

Definition at line 500 of file MeterPanel.cpp.

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

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

796{
797 mIsFocused = true;
798 Refresh(false);
799}

References mIsFocused.

◆ OnSize()

void MeterPanel::OnSize ( wxSizeEvent &  evt)
private

Definition at line 711 of file MeterPanel.cpp.

712{
713 GetClientSize(&mWidth, &mHeight);
714
715 mLayoutValid = false;
716 Refresh();
717}

References mHeight, mLayoutValid, and mWidth.

◆ OnTipTimeout()

void MeterPanel::OnTipTimeout ( wxTimerEvent &  evt)
private

Definition at line 1131 of file MeterPanel.cpp.

1132{
1133 if(mSlider)
1134 mSlider->ShowTip(true);
1135}

References mSlider.

◆ RepaintBarsNow()

void MeterPanel::RepaintBarsNow ( )
private

Definition at line 1570 of file MeterPanel.cpp.

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

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

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

1167{
1168 b->peak = 0.0;
1169 b->rms = 0.0;
1170 b->peakHold = 0.0;
1171 b->peakHoldTime = 0.0;
1172 if (resetClipping)
1173 {
1174 b->clipping = false;
1175 b->peakPeakHold = 0.0;
1176 }
1177 b->isclipping = false;
1178 b->tailPeakCount = 0;
1179}

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

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

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

1918{
1919 return { true, mMonitoring, mActive };
1920}

Referenced by MeterToolBar::ReCreateButtons().

Here is the caller graph for this function:

◆ SetActiveStyle()

void MeterPanel::SetActiveStyle ( Style  style)
private

Definition at line 1199 of file MeterPanel.cpp.

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

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

2107{
2108 auto temp = TemporarilyAllowFocus();
2109 SetFocus();
2110}
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 823 of file MeterPanel.cpp.

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

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

1961{
1963 if(mSlider)
1964 mSlider->SetName(tip);
1965}

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

812{
813 if (mStyle != newStyle && mDesiredStyle == AutomaticStereo)
814 {
815 SetActiveStyle(newStyle);
816
817 mLayoutValid = false;
818
819 Refresh(false);
820 }
821}

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

Here is the call graph for this function:

◆ ShowDialog()

bool MeterPanel::ShowDialog ( )

Definition at line 855 of file MeterPanel.cpp.

856{
857 if (!mSlider)
858 return false;
859
860 auto changed = mSlider->ShowDialog();
861 if (changed)
862 {
863 wxCommandEvent e;
864 SetMixer(e);
865 }
866
867 return changed;
868}

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

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

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

1872 {
1873 mMonitoring = false;
1874 auto gAudioIO = AudioIO::Get();
1875 if (gAudioIO->IsMonitoring()){
1876 gAudioIO->StopStream();
1877 }
1878}

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

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

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

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

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

Here is the call graph for this function:

◆ UpdateSliderControl()

void MeterPanel::UpdateSliderControl ( )

Definition at line 473 of file MeterPanel.cpp.

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

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

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

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

Friends And Related Function Documentation

◆ MeterAx

friend class MeterAx
friend

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

Referenced by DrawMeterBar(), and OnPaint().

◆ mBrush

wxBrush MeterPanel::mBrush
private

Definition at line 297 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 299 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 301 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mEnabled

bool MeterPanel::mEnabled { true }
private

Definition at line 310 of file MeterPanel.h.

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

◆ mFocusRect

wxRect MeterPanel::mFocusRect
private

Definition at line 313 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 312 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 303 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 296 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 304 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 298 of file MeterPanel.h.

Referenced by DrawMeterBar().

◆ mRuler

Ruler MeterPanel::mRuler
private

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

Referenced by HandleLayout(), and OnPaint().

◆ mSliderSize

wxSize MeterPanel::mSliderSize
private

Definition at line 308 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: