1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-26 09:08:44 +02:00

Separate an abstract base class from MeterPanel...

... to break its cycle with AudioIO
This commit is contained in:
Paul Licameli 2019-06-04 00:20:42 -04:00
parent 51051ee933
commit 17c04d1749
7 changed files with 47 additions and 27 deletions

@ -306,7 +306,7 @@ void AudioIOBase::HandleDeviceChange()
#endif // USE_PORTMIXER #endif // USE_PORTMIXER
} }
void AudioIOBase::SetCaptureMeter(AudacityProject *project, MeterPanel *meter) void AudioIOBase::SetCaptureMeter(AudacityProject *project, MeterPanelBase *meter)
{ {
if (( mOwningProject ) && ( mOwningProject != project)) if (( mOwningProject ) && ( mOwningProject != project))
return; return;
@ -320,7 +320,7 @@ void AudioIOBase::SetCaptureMeter(AudacityProject *project, MeterPanel *meter)
mInputMeter.Release(); mInputMeter.Release();
} }
void AudioIOBase::SetPlaybackMeter(AudacityProject *project, MeterPanel *meter) void AudioIOBase::SetPlaybackMeter(AudacityProject *project, MeterPanelBase *meter)
{ {
if (( mOwningProject ) && ( mOwningProject != project)) if (( mOwningProject ) && ( mOwningProject != project))
return; return;

@ -31,7 +31,7 @@ class AudioIOBase;
class AudacityProject; class AudacityProject;
class AudioIOListener; class AudioIOListener;
class BoundedEnvelope; class BoundedEnvelope;
class MeterPanel; class MeterPanelBase;
using PRCrossfadeData = std::vector< std::vector < float > >; using PRCrossfadeData = std::vector< std::vector < float > >;
#define BAD_STREAM_TIME (-DBL_MAX) #define BAD_STREAM_TIME (-DBL_MAX)
@ -83,7 +83,7 @@ struct AudioIOStartStreamOptions
{} {}
AudacityProject *pProject{}; AudacityProject *pProject{};
MeterPanel *captureMeter{}, *playbackMeter{}; MeterPanelBase *captureMeter{}, *playbackMeter{};
BoundedEnvelope *envelope; // for time warping BoundedEnvelope *envelope; // for time warping
AudioIOListener* listener; AudioIOListener* listener;
double rate; double rate;
@ -111,8 +111,8 @@ class AudioIOBase /* not final */
public: public:
static AudioIOBase *Get(); static AudioIOBase *Get();
void SetCaptureMeter(AudacityProject *project, MeterPanel *meter); void SetCaptureMeter(AudacityProject *project, MeterPanelBase *meter);
void SetPlaybackMeter(AudacityProject *project, MeterPanel *meter); void SetPlaybackMeter(AudacityProject *project, MeterPanelBase *meter);
/** \brief update state after changing what audio devices are selected /** \brief update state after changing what audio devices are selected
* *
@ -268,8 +268,8 @@ protected:
PaStream *mPortStreamV19; PaStream *mPortStreamV19;
wxWeakRef<MeterPanel> mInputMeter{}; wxWeakRef<MeterPanelBase> mInputMeter{};
wxWeakRef<MeterPanel> mOutputMeter{}; wxWeakRef<MeterPanelBase> mOutputMeter{};
#if USE_PORTMIXER #if USE_PORTMIXER
PxMixer *mPortMixer; PxMixer *mPortMixer;

@ -55,12 +55,12 @@ bool ProjectAudioIO::IsAudioActive() const
gAudioIO->IsStreamActive(GetAudioIOToken()); gAudioIO->IsStreamActive(GetAudioIOToken());
} }
MeterPanel *ProjectAudioIO::GetPlaybackMeter() MeterPanelBase *ProjectAudioIO::GetPlaybackMeter()
{ {
return mPlaybackMeter; return mPlaybackMeter;
} }
void ProjectAudioIO::SetPlaybackMeter(MeterPanel *playback) void ProjectAudioIO::SetPlaybackMeter(MeterPanelBase *playback)
{ {
auto &project = mProject; auto &project = mProject;
mPlaybackMeter = playback; mPlaybackMeter = playback;
@ -71,12 +71,12 @@ void ProjectAudioIO::SetPlaybackMeter(MeterPanel *playback)
} }
} }
MeterPanel *ProjectAudioIO::GetCaptureMeter() MeterPanelBase *ProjectAudioIO::GetCaptureMeter()
{ {
return mCaptureMeter; return mCaptureMeter;
} }
void ProjectAudioIO::SetCaptureMeter(MeterPanel *capture) void ProjectAudioIO::SetCaptureMeter(MeterPanelBase *capture)
{ {
auto &project = mProject; auto &project = mProject;
mCaptureMeter = capture; mCaptureMeter = capture;

@ -14,7 +14,7 @@ Paul Licameli split from AudacityProject.h
#include "ClientData.h" // to inherit #include "ClientData.h" // to inherit
class AudacityProject; class AudacityProject;
class MeterPanel; class MeterPanelBase;
///\ brief Holds per-project state needed for interaction with AudioIO, ///\ brief Holds per-project state needed for interaction with AudioIO,
/// including the audio stream token and pointers to meters /// including the audio stream token and pointers to meters
@ -32,17 +32,17 @@ public:
bool IsAudioActive() const; bool IsAudioActive() const;
void SetAudioIOToken(int token); void SetAudioIOToken(int token);
MeterPanel *GetPlaybackMeter(); MeterPanelBase *GetPlaybackMeter();
void SetPlaybackMeter(MeterPanel *playback); void SetPlaybackMeter(MeterPanelBase *playback);
MeterPanel *GetCaptureMeter(); MeterPanelBase *GetCaptureMeter();
void SetCaptureMeter(MeterPanel *capture); void SetCaptureMeter(MeterPanelBase *capture);
private: private:
AudacityProject &mProject; AudacityProject &mProject;
// Project owned meters // Project owned meters
MeterPanel *mPlaybackMeter{}; MeterPanelBase *mPlaybackMeter{};
MeterPanel *mCaptureMeter{}; MeterPanelBase *mCaptureMeter{};
int mAudioIOToken{ -1 }; int mAudioIOToken{ -1 };
}; };

@ -893,7 +893,7 @@ void ControlToolBar::StopPlaying(bool stopStream /* = true*/)
// also clean the MeterQueues // also clean the MeterQueues
if( project ) { if( project ) {
auto &projectAudioIO = ProjectAudioIO::Get( *project ); auto &projectAudioIO = ProjectAudioIO::Get( *project );
MeterPanel *meter = projectAudioIO.GetPlaybackMeter(); auto meter = projectAudioIO.GetPlaybackMeter();
if( meter ) { if( meter ) {
meter->Clear(); meter->Clear();
} }

@ -292,7 +292,7 @@ MeterPanel::MeterPanel(AudacityProject *project,
const wxSize& size /*= wxDefaultSize*/, const wxSize& size /*= wxDefaultSize*/,
Style style /*= HorizontalStereo*/, Style style /*= HorizontalStereo*/,
float fDecayRate /*= 60.0f*/) float fDecayRate /*= 60.0f*/)
: wxPanelWrapper(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER | wxWANTS_CHARS), : MeterPanelBase(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER | wxWANTS_CHARS),
mProject(project), mProject(project),
mQueue(1024), mQueue(1024),
mWidth(size.x), mWidth(size.x),
@ -2151,6 +2151,10 @@ MeterAx::~MeterAx()
{ {
} }
MeterPanelBase::~MeterPanelBase()
{
}
// Performs the default action. childId is 0 (the action for this object) // Performs the default action. childId is 0 (the action for this object)
// or > 0 (the action for a child). // or > 0 (the action for a child).
// Return wxACC_NOT_SUPPORTED if there is no default action for this // Return wxACC_NOT_SUPPORTED if there is no default action for this

@ -87,11 +87,27 @@ class MeterUpdateQueue
class MeterAx; class MeterAx;
class MeterPanelBase /* not final */
: public wxPanelWrapper
{
public:
using wxPanelWrapper::wxPanelWrapper;
~MeterPanelBase() override;
virtual void Clear() = 0;
virtual void Reset(double sampleRate, bool resetClipping) = 0;
virtual void UpdateDisplay(unsigned numChannels,
int numFrames, float *sampleData) = 0;
virtual bool IsMeterDisabled() const = 0;
virtual float GetMaxPeak() const = 0;
private:
};
/********************************************************************//** /********************************************************************//**
\brief MeterPanel is a panel that paints the meter used for monitoring \brief MeterPanel is a panel that paints the meter used for monitoring
or playback. or playback.
************************************************************************/ ************************************************************************/
class MeterPanel final : public wxPanelWrapper, private PrefsListener class MeterPanel final : public MeterPanelBase, private PrefsListener
{ {
DECLARE_DYNAMIC_CLASS(MeterPanel) DECLARE_DYNAMIC_CLASS(MeterPanel)
@ -121,7 +137,7 @@ class MeterPanel final : public wxPanelWrapper, private PrefsListener
void SetFocusFromKbd() override; void SetFocusFromKbd() override;
void Clear(); void Clear() override;
Style GetStyle() const { return mStyle; } Style GetStyle() const { return mStyle; }
Style GetDesiredStyle() const { return mDesiredStyle; } Style GetDesiredStyle() const { return mDesiredStyle; }
@ -132,7 +148,7 @@ class MeterPanel final : public wxPanelWrapper, private PrefsListener
* This method is thread-safe! Feel free to call from a * This method is thread-safe! Feel free to call from a
* different thread (like from an audio I/O callback). * different thread (like from an audio I/O callback).
*/ */
void Reset(double sampleRate, bool resetClipping); void Reset(double sampleRate, bool resetClipping) override;
/** \brief Update the meters with a block of audio data /** \brief Update the meters with a block of audio data
* *
@ -157,7 +173,7 @@ class MeterPanel final : public wxPanelWrapper, private PrefsListener
* The second overload is for ease of use in MixerBoard. * The second overload is for ease of use in MixerBoard.
*/ */
void UpdateDisplay(unsigned numChannels, void UpdateDisplay(unsigned numChannels,
int numFrames, float *sampleData); int numFrames, float *sampleData) override;
// Vaughan, 2010-11-29: This not currently used. See comments in MixerTrackCluster::UpdateMeter(). // Vaughan, 2010-11-29: This not currently used. See comments in MixerTrackCluster::UpdateMeter().
//void UpdateDisplay(int numChannels, int numFrames, //void UpdateDisplay(int numChannels, int numFrames,
@ -171,9 +187,9 @@ class MeterPanel final : public wxPanelWrapper, private PrefsListener
* This method is thread-safe! Feel free to call from a * This method is thread-safe! Feel free to call from a
* different thread (like from an audio I/O callback). * different thread (like from an audio I/O callback).
*/ */
bool IsMeterDisabled() const; bool IsMeterDisabled() const override;
float GetMaxPeak() const; float GetMaxPeak() const override;
bool IsClipping() const; bool IsClipping() const;