1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-12 22:57:43 +02:00

Merge branch 'master' into deletes

This commit is contained in:
Paul Licameli 2016-08-14 10:20:26 -04:00
commit 17faf86967
27 changed files with 200 additions and 36 deletions

View File

@ -63,7 +63,7 @@ static void GetAllSeqBlocks(AudacityProject *project,
while (t) { while (t) {
if (t->GetKind() == Track::Wave) { if (t->GetKind() == Track::Wave) {
WaveTrack *waveTrack = static_cast<WaveTrack*>(t); WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
for(const auto &clip : waveTrack->GetClips()) { for(const auto &clip : waveTrack->GetAllClips()) {
Sequence *sequence = clip->GetSequence(); Sequence *sequence = clip->GetSequence();
BlockArray &blocks = sequence->GetBlockArray(); BlockArray &blocks = sequence->GetBlockArray();
int i; int i;

View File

@ -11,7 +11,7 @@
#ifndef _DIRMANAGER_ #ifndef _DIRMANAGER_
#define _DIRMANAGER_ #define _DIRMANAGER_
#include <MemoryX.h> #include "MemoryX.h"
#include <wx/list.h> #include <wx/list.h>
#include <wx/string.h> #include <wx/string.h>
#include <wx/filename.h> #include <wx/filename.h>

View File

@ -727,4 +727,16 @@ Final_action<F> finally (F f)
return Final_action<F>(f); return Final_action<F>(f);
} }
/*
* A convenience for use with range-for
*/
template <typename Iterator>
struct IteratorRange : public std::pair<Iterator, Iterator> {
IteratorRange (Iterator &&a, Iterator &&b)
: std::pair<Iterator, Iterator> ( std::move(a), std::move(b) ) {}
Iterator begin() const { return this->first; }
Iterator end() const { return this->second; }
};
#endif // __AUDACITY_MEMORY_X_H__ #endif // __AUDACITY_MEMORY_X_H__

View File

@ -934,6 +934,7 @@ MixerBoard::MixerBoard(AudacityProject* pProject,
this->LoadMusicalInstruments(); // Set up mMusicalInstruments. this->LoadMusicalInstruments(); // Set up mMusicalInstruments.
mProject = pProject; mProject = pProject;
wxASSERT(pProject); // to justify safenew
mScrolledWindow = mScrolledWindow =
safenew MixerBoardScrolledWindow( safenew MixerBoardScrolledWindow(
pProject, // AudacityProject* project, pProject, // AudacityProject* project,

View File

@ -169,7 +169,8 @@ scroll information. It also has some status flags.
#include "../images/AudacityLogoAlpha.xpm" #include "../images/AudacityLogoAlpha.xpm"
std::unique_ptr<TrackList> AudacityProject::msClipboard{ safenew TrackList() }; std::unique_ptr<TrackList> AudacityProject::msClipboard
{ std::make_unique<TrackList>() };
double AudacityProject::msClipT0 = 0.0; double AudacityProject::msClipT0 = 0.0;
double AudacityProject::msClipT1 = 0.0; double AudacityProject::msClipT1 = 0.0;
AudacityProject *AudacityProject::msClipProject = NULL; AudacityProject *AudacityProject::msClipProject = NULL;
@ -829,7 +830,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))), mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))),
mFrequencySelectionFormatName(gPrefs->Read(wxT("/FrequencySelectionFormatName"), wxT(""))), mFrequencySelectionFormatName(gPrefs->Read(wxT("/FrequencySelectionFormatName"), wxT(""))),
mBandwidthSelectionFormatName(gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT(""))), mBandwidthSelectionFormatName(gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT(""))),
mUndoManager(safenew UndoManager), mUndoManager(std::make_unique<UndoManager>()),
mViewInfo(0.0, 1.0, ZoomInfo::GetDefaultZoom()) mViewInfo(0.0, 1.0, ZoomInfo::GetDefaultZoom())
{ {
// Note that the first field of the status bar is a dummy, and it's width is set // Note that the first field of the status bar is a dummy, and it's width is set

View File

@ -143,6 +143,7 @@ void SplashDialog::Show2( wxWindow * pParent )
if( pSelf == NULL ) if( pSelf == NULL )
{ {
// pParent owns it // pParent owns it
wxASSERT(pParent);
pSelf = safenew SplashDialog( pParent ); pSelf = safenew SplashDialog( pParent );
} }
pSelf->mpHtml->SetPage(HelpText( wxT("welcome") )); pSelf->mpHtml->SetPage(HelpText( wxT("welcome") ));

View File

@ -443,7 +443,7 @@ wxString Tags::GetTag(const wxString & name) const
Tags::Iterators Tags::GetRange() const Tags::Iterators Tags::GetRange() const
{ {
return std::make_pair(mMap.begin(), mMap.end()); return { mMap.begin(), mMap.end() };
} }
void Tags::SetTag(const wxString & name, const wxString & value) void Tags::SetTag(const wxString & name, const wxString & value)

View File

@ -104,13 +104,7 @@ class AUDACITY_DLL_API Tags final : public XMLTagHandler {
bool HasTag(const wxString & name) const; bool HasTag(const wxString & name) const;
wxString GetTag(const wxString & name) const; wxString GetTag(const wxString & name) const;
using IterPair = std::pair<TagMap::const_iterator, TagMap::const_iterator>; using Iterators = IteratorRange<TagMap::const_iterator>;
struct Iterators : public IterPair {
Iterators(IterPair p) : IterPair(p) {}
// Define begin() and end() for convenience in range-for
auto begin() -> decltype(first) const { return first; }
auto end() -> decltype(second) const { return second; }
};
Iterators GetRange() const; Iterators GetRange() const;
void SetTag(const wxString & name, const wxString & value); void SetTag(const wxString & name, const wxString & value);

View File

@ -778,6 +778,7 @@ TimerRecordPathCtrl * TimerRecordDialog::NewPathControl(wxWindow *wParent, const
const wxString &sCaption, const wxString &sValue) const wxString &sCaption, const wxString &sValue)
{ {
TimerRecordPathCtrl * pTextCtrl; TimerRecordPathCtrl * pTextCtrl;
wxASSERT(wParent); // to justify safenew
pTextCtrl = safenew TimerRecordPathCtrl(wParent, iID, sValue); pTextCtrl = safenew TimerRecordPathCtrl(wParent, iID, sValue);
pTextCtrl->SetName(sCaption); pTextCtrl->SetName(sCaption);
return pTextCtrl; return pTextCtrl;

View File

@ -94,7 +94,7 @@ void UndoManager::CalculateSpaceUsage()
while (wt) while (wt)
{ {
// Scan all clips within current track // Scan all clips within current track
for(const auto &clip: wt->GetClips()) for(const auto &clip : wt->GetAllClips())
{ {
// Scan all blockfiles within current clip // Scan all blockfiles within current clip
BlockArray *blocks = clip->GetSequenceBlockArray(); BlockArray *blocks = clip->GetSequenceBlockArray();

View File

@ -333,11 +333,84 @@ class AUDACITY_DLL_API WaveTrack final : public Track {
*/ */
double LongSamplesToTime(sampleCount pos) const; double LongSamplesToTime(sampleCount pos) const;
// Get access to the clips in the tracks. // Get access to the (visible) clips in the tracks, in unspecified order
// (not necessarioy sequenced in time).
WaveClipHolders &GetClips() { return mClips; } WaveClipHolders &GetClips() { return mClips; }
const WaveClipConstHolders &GetClips() const const WaveClipConstHolders &GetClips() const
{ return reinterpret_cast< const WaveClipConstHolders& >( mClips ); } { return reinterpret_cast< const WaveClipConstHolders& >( mClips ); }
// Get access to all clips (in some unspecified sequence),
// including those hidden in cutlines.
class AllClipsIterator
: public std::iterator< std::forward_iterator_tag, WaveClip* >
{
public:
// Constructs an "end" iterator
AllClipsIterator () {}
// Construct a "begin" iterator
explicit AllClipsIterator( WaveTrack &track )
{
push( track.mClips );
}
WaveClip *operator * () const
{
if (mStack.empty())
return nullptr;
else
return mStack.back().first->get();
}
AllClipsIterator &operator ++ ()
{
// The unspecified sequence is a post-order, but there is no
// promise whether sister nodes are ordered in time.
if ( !mStack.empty() ) {
auto &pair = mStack.back();
if ( ++pair.first == pair.second ) {
mStack.pop_back();
}
else
push( (*pair.first)->GetCutLines() );
}
return *this;
}
// Define == well enough to serve for loop termination test
friend bool operator ==
(const AllClipsIterator &a, const AllClipsIterator &b)
{ return a.mStack.empty() == b.mStack.empty(); }
friend bool operator !=
(const AllClipsIterator &a, const AllClipsIterator &b)
{ return !( a == b ); }
private:
void push( WaveClipHolders &clips )
{
auto pClips = &clips;
while (!pClips->empty()) {
auto first = pClips->begin();
mStack.push_back( Pair( first, pClips->end() ) );
pClips = &(*first)->GetCutLines();
}
}
using Iterator = WaveClipHolders::iterator;
using Pair = std::pair< Iterator, Iterator >;
using Stack = std::vector< Pair >;
Stack mStack;
};
IteratorRange< AllClipsIterator > GetAllClips()
{
return { AllClipsIterator{ *this }, AllClipsIterator{ } };
}
// Create NEW clip and add it to this track. Returns a pointer // Create NEW clip and add it to this track. Returns a pointer
// to the newly created clip. // to the newly created clip.
WaveClip* CreateClip(); WaveClip* CreateClip();

View File

@ -44,7 +44,11 @@ struct SubMenuListEntry
: name(name_), menu( std::move(menu_) ) : name(name_), menu( std::move(menu_) )
{} {}
// SubMenuListEntry( SubMenuListEntry&& ) = default; SubMenuListEntry(SubMenuListEntry &&that)
: name(std::move(that.name))
, menu(std::move(that.menu))
{
}
wxString name; wxString name;
std::unique_ptr<wxMenu> menu; std::unique_ptr<wxMenu> menu;

View File

@ -18,9 +18,13 @@ the pitch without changing the tempo.
#include "../Audacity.h" // for USE_SOUNDTOUCH #include "../Audacity.h" // for USE_SOUNDTOUCH
#if USE_SOUNDTOUCH #if USE_SOUNDTOUCH
#include "ChangePitch.h" #include "ChangePitch.h"
#if USE_SBSMS
#include "sbsms.h"
#include <wx/valgen.h>
#endif
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
@ -51,6 +55,7 @@ enum {
// //
// Name Type Key Def Min Max Scale // Name Type Key Def Min Max Scale
Param( Percentage, double, XO("Percentage"), 0.0, -99.0, 3000.0, 1 ); Param( Percentage, double, XO("Percentage"), 0.0, -99.0, 3000.0, 1 );
Param( UseSBSMS, bool, XO("SBSMS"), false, false, true, 1 );
// We warp the slider to go up to 400%, but user can enter up to 3000% // We warp the slider to go up to 400%, but user can enter up to 3000%
static const double kSliderMax = 100.0; // warped above zero to actually go up to 400% static const double kSliderMax = 100.0; // warped above zero to actually go up to 400%
@ -80,6 +85,12 @@ EffectChangePitch::EffectChangePitch()
m_dStartFrequency = 0.0; // 0.0 => uninitialized m_dStartFrequency = 0.0; // 0.0 => uninitialized
m_bLoopDetect = false; m_bLoopDetect = false;
#if USE_SBSMS
mUseSBSMS = DEF_UseSBSMS;
#else
mUseSBSMS = false;
#endif
// NULL out these control members because there are some cases where the // NULL out these control members because there are some cases where the
// event table handlers get called during this method, and those handlers that // event table handlers get called during this method, and those handlers that
// can cause trouble check for NULL. // can cause trouble check for NULL.
@ -127,6 +138,7 @@ EffectType EffectChangePitch::GetType()
bool EffectChangePitch::GetAutomationParameters(EffectAutomationParameters & parms) bool EffectChangePitch::GetAutomationParameters(EffectAutomationParameters & parms)
{ {
parms.Write(KEY_Percentage, m_dPercentChange); parms.Write(KEY_Percentage, m_dPercentChange);
parms.Write(KEY_UseSBSMS, mUseSBSMS);
return true; return true;
} }
@ -140,6 +152,13 @@ bool EffectChangePitch::SetAutomationParameters(EffectAutomationParameters & par
m_dPercentChange = Percentage; m_dPercentChange = Percentage;
Calc_SemitonesChange_fromPercentChange(); Calc_SemitonesChange_fromPercentChange();
#if USE_SBSMS
ReadAndVerifyBool(UseSBSMS);
mUseSBSMS = UseSBSMS;
#else
mUseSBSMS = false;
#endif
return true; return true;
} }
@ -160,20 +179,37 @@ bool EffectChangePitch::Init()
bool EffectChangePitch::Process() bool EffectChangePitch::Process()
{ {
mSoundTouch = std::make_unique<SoundTouch>(); #if USE_SBSMS
SetTimeWarper(std::make_unique<IdentityTimeWarper>()); if (mUseSBSMS)
mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange)); {
#ifdef USE_MIDI double pitchRatio = 1.0 + m_dPercentChange / 100.0;
// Note: m_dSemitonesChange is private to ChangePitch because it only SelectedRegion region(mT0, mT1);
// needs to pass it along to mSoundTouch (above). I added mSemitones EffectSBSMS proxy;
// to SoundTouchEffect (the super class) to convey this value proxy.setParameters(1.0, pitchRatio);
// to process Note tracks. This approach minimizes changes to existing
// code, but it would be cleaner to change all m_dSemitonesChange to return proxy.DoEffect(mUIParent, mProjectRate, mTracks, mFactory, &region, false);
// mSemitones, make mSemitones exist with or without USE_MIDI, and }
// eliminate the next line: else
mSemitones = m_dSemitonesChange;
#endif #endif
return EffectSoundTouch::Process(); {
mSoundTouch = std::make_unique<SoundTouch>();
SetTimeWarper(std::make_unique<IdentityTimeWarper>());
mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange));
#ifdef USE_MIDI
// Pitch shifting note tracks is currently only supported by SoundTouchEffect
// and non-real-time-preview effects require an audio track selection.
//
// Note: m_dSemitonesChange is private to ChangePitch because it only
// needs to pass it along to mSoundTouch (above). I added mSemitones
// to SoundTouchEffect (the super class) to convey this value
// to process Note tracks. This approach minimizes changes to existing
// code, but it would be cleaner to change all m_dSemitonesChange to
// mSemitones, make mSemitones exist with or without USE_MIDI, and
// eliminate the next line:
mSemitones = m_dSemitonesChange;
#endif
return EffectSoundTouch::Process();
}
} }
bool EffectChangePitch::CheckWhetherSkipEffect() bool EffectChangePitch::CheckWhetherSkipEffect()
@ -287,6 +323,17 @@ void EffectChangePitch::PopulateOrExchange(ShuttleGui & S)
S.EndHorizontalLay(); S.EndHorizontalLay();
} }
S.EndStatic(); S.EndStatic();
#if USE_SBSMS
S.StartMultiColumn(2);
{
mUseSBSMSCheckBox = S.AddCheckBox(_("Use high quality stretching (slow)"),
mUseSBSMS? wxT("true") : wxT("false"));
mUseSBSMSCheckBox->SetValidator(wxGenericValidator(&mUseSBSMS));
}
S.EndMultiColumn();
#endif
} }
S.EndVerticalLay(); S.EndVerticalLay();
@ -460,7 +507,6 @@ void EffectChangePitch::Calc_PercentChange()
// handlers // handlers
void EffectChangePitch::OnChoice_FromPitch(wxCommandEvent & WXUNUSED(evt)) void EffectChangePitch::OnChoice_FromPitch(wxCommandEvent & WXUNUSED(evt))
{ {
if (m_bLoopDetect) if (m_bLoopDetect)

View File

@ -20,6 +20,11 @@ the pitch without changing the tempo.
#ifndef __AUDACITY_EFFECT_CHANGEPITCH__ #ifndef __AUDACITY_EFFECT_CHANGEPITCH__
#define __AUDACITY_EFFECT_CHANGEPITCH__ #define __AUDACITY_EFFECT_CHANGEPITCH__
#if USE_SBSMS
#include "SBSMSEffect.h"
#include <wx/checkbox.h>
#endif
#include <wx/choice.h> #include <wx/choice.h>
#include <wx/event.h> #include <wx/event.h>
#include <wx/slider.h> #include <wx/slider.h>
@ -108,6 +113,7 @@ private:
void Update_Slider_PercentChange(); // Update control per current m_dPercentChange. void Update_Slider_PercentChange(); // Update control per current m_dPercentChange.
private: private:
bool mUseSBSMS;
// effect parameters // effect parameters
int m_nFromPitch; // per PitchIndex() int m_nFromPitch; // per PitchIndex()
int m_nFromOctave; // per PitchOctave() int m_nFromOctave; // per PitchOctave()
@ -136,6 +142,10 @@ private:
wxTextCtrl * m_pTextCtrl_PercentChange; wxTextCtrl * m_pTextCtrl_PercentChange;
wxSlider * m_pSlider_PercentChange; wxSlider * m_pSlider_PercentChange;
#if USE_SBSMS
wxCheckBox * mUseSBSMSCheckBox;
#endif
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
}; };

View File

@ -2125,7 +2125,7 @@ Effect::AddedAnalysisTrack::~AddedAnalysisTrack()
auto Effect::AddAnalysisTrack(const wxString &name) -> std::shared_ptr<AddedAnalysisTrack> auto Effect::AddAnalysisTrack(const wxString &name) -> std::shared_ptr<AddedAnalysisTrack>
{ {
return std::shared_ptr<AddedAnalysisTrack> return std::shared_ptr<AddedAnalysisTrack>
{ safenew AddedAnalysisTrack{ this, name } }; { safenew AddedAnalysisTrack{ this, name } };
} }
Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack

View File

@ -156,6 +156,12 @@ void EffectSBSMS :: setParameters(double rateStart, double rateEnd, double pitch
this->bPitchReferenceInput = bPitchReferenceInput; this->bPitchReferenceInput = bPitchReferenceInput;
} }
void EffectSBSMS::setParameters(double tempoRatio, double pitchRatio)
{
setParameters(tempoRatio, tempoRatio, pitchRatio, pitchRatio,
SlideConstant, SlideConstant, false, false, false);
}
std::unique_ptr<TimeWarper> createTimeWarper(double t0, double t1, double duration, std::unique_ptr<TimeWarper> createTimeWarper(double t0, double t1, double duration,
double rateStart, double rateEnd, SlideType rateSlideType) double rateStart, double rateEnd, SlideType rateSlideType)
{ {

View File

@ -28,6 +28,7 @@ public:
void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd,
SlideType rateSlideType, SlideType pitchSlideType, SlideType rateSlideType, SlideType pitchSlideType,
bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput); bool bLinkRatePitch, bool bRateReferenceInput, bool bPitchReferenceInput);
void setParameters(double tempoRatio, double pitchRatio); // Constant ratio (tempoRatio, pitchRatio)
static double getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime); static double getInvertedStretchedTime(double rateStart, double rateEnd, SlideType slideType, double outputTime);
static double getRate(double rateStart, double rateEnd, SlideType slideType, double t); static double getRate(double rateStart, double rateEnd, SlideType slideType, double t);
private: private:

View File

@ -182,7 +182,7 @@ void ODComputeSummaryTask::Update()
Sequence *seq; Sequence *seq;
//gather all the blockfiles that we should process in the wavetrack. //gather all the blockfiles that we should process in the wavetrack.
for (const auto &clip : mWaveTracks[j]->GetClips()) { for (const auto &clip : mWaveTracks[j]->GetAllClips()) {
seq = clip->GetSequence(); seq = clip->GetSequence();
//This lock may be way too big since the whole file is one sequence. //This lock may be way too big since the whole file is one sequence.
//TODO: test for large files and find a way to break it down. //TODO: test for large files and find a way to break it down.

View File

@ -140,7 +140,7 @@ void ODDecodeTask::Update()
Sequence *seq; Sequence *seq;
//gather all the blockfiles that we should process in the wavetrack. //gather all the blockfiles that we should process in the wavetrack.
for (const auto &clip : mWaveTracks[j]->GetClips()) { for (const auto &clip : mWaveTracks[j]->GetAllClips()) {
seq = clip->GetSequence(); seq = clip->GetSequence();
//TODO:this lock is way to big since the whole file is one sequence. find a way to break it down. //TODO:this lock is way to big since the whole file is one sequence. find a way to break it down.
seq->LockDeleteUpdateMutex(); seq->LockDeleteUpdateMutex();

View File

@ -113,6 +113,7 @@ void MeterToolBar::ReCreateButtons()
void MeterToolBar::Populate() void MeterToolBar::Populate()
{ {
wxASSERT(mProject); // to justify safenew
Add((mSizer = safenew wxGridBagSizer()), 1, wxEXPAND); Add((mSizer = safenew wxGridBagSizer()), 1, wxEXPAND);
if( mWhichMeters & kWithRecordMeter ){ if( mWhichMeters & kWithRecordMeter ){

View File

@ -758,6 +758,7 @@ AButton * ToolBar::MakeButton(wxWindow *parent,
wxImagePtr down2 (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1)); wxImagePtr down2 (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1));
wxImagePtr disable2 (OverlayImage(eUp, eDisabled, xoff, yoff)); wxImagePtr disable2 (OverlayImage(eUp, eDisabled, xoff, yoff));
wxASSERT(parent); // to justify safenew
AButton * button = AButton * button =
safenew AButton(parent, id, placement, size, *up2, *hilite2, *down2, safenew AButton(parent, id, placement, size, *up2, *hilite2, *down2,
*disable2, processdownevents); *disable2, processdownevents);

View File

@ -181,6 +181,7 @@ class ToolBar /* not final */ : public wxPanelWrapper
int border = 0, int border = 0,
wxObject *userData = NULL); wxObject *userData = NULL);
// Takes ownership of sizer
void Add(wxSizer *sizer, void Add(wxSizer *sizer,
int proportion = 0, int proportion = 0,
int flag = 0, int flag = 0,

View File

@ -363,6 +363,7 @@ ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent )
mLeft = std::make_unique<wxRegion>( 3, &pt[0] ); mLeft = std::make_unique<wxRegion>( 3, &pt[0] );
// Create the indicator frame // Create the indicator frame
// parent is null but FramePtr ensures destruction
mIndicator = FramePtr{ safenew wxFrame( NULL, mIndicator = FramePtr{ safenew wxFrame( NULL,
wxID_ANY, wxID_ANY,
wxEmptyString, wxEmptyString,
@ -410,6 +411,8 @@ ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent )
mBotDock = safenew ToolDock( this, mParent, BotDockID ); mBotDock = safenew ToolDock( this, mParent, BotDockID );
// Create all of the toolbars // Create all of the toolbars
// All have the project as parent window
wxASSERT(parent);
mBars[ ToolsBarID ] = ToolBar::Holder{ safenew ToolsToolBar() }; mBars[ ToolsBarID ] = ToolBar::Holder{ safenew ToolsToolBar() };
mBars[ TransportBarID ] = ToolBar::Holder{ safenew ControlToolBar() }; mBars[ TransportBarID ] = ToolBar::Holder{ safenew ControlToolBar() };
mBars[ RecordMeterBarID ] = ToolBar::Holder{ safenew MeterToolBar( parent, RecordMeterBarID ) }; mBars[ RecordMeterBarID ] = ToolBar::Holder{ safenew MeterToolBar( parent, RecordMeterBarID ) };
@ -583,6 +586,7 @@ void ToolManager::Reset()
// Maybe construct a NEW floater // Maybe construct a NEW floater
// this happens if we have just been bounced out of a dock. // this happens if we have just been bounced out of a dock.
if( floater == NULL ) { if( floater == NULL ) {
wxASSERT(mParent);
floater = safenew ToolFrame( mParent, this, bar, wxPoint(-1,-1) ); floater = safenew ToolFrame( mParent, this, bar, wxPoint(-1,-1) );
bar->Reparent( floater ); bar->Reparent( floater );
} }
@ -761,6 +765,7 @@ void ToolManager::ReadConfig()
bar->Create( mTopDock ); bar->Create( mTopDock );
// Construct a NEW floater // Construct a NEW floater
wxASSERT(mParent);
ToolFrame *f = safenew ToolFrame( mParent, this, bar, wxPoint( x, y ) ); ToolFrame *f = safenew ToolFrame( mParent, this, bar, wxPoint( x, y ) );
// Set the width and height // Set the width and height
@ -1327,6 +1332,7 @@ void ToolManager::OnGrabber( GrabberEvent & event )
mDragBar->SetPositioned(); mDragBar->SetPositioned();
// Construct a NEW floater // Construct a NEW floater
wxASSERT(mParent);
mDragWindow = safenew ToolFrame( mParent, this, mDragBar, mp ); mDragWindow = safenew ToolFrame( mParent, this, mDragBar, mp );
// Make sure the ferry is visible // Make sure the ferry is visible

View File

@ -14,7 +14,7 @@ BackedPanel::BackedPanel(wxWindow * parent, wxWindowID id,
const wxSize & size, const wxSize & size,
long style) long style)
: wxPanelWrapper(parent, id, pos, size, style) : wxPanelWrapper(parent, id, pos, size, style)
, mBacking{ safenew wxBitmap(1, 1) } , mBacking{ std::make_unique<wxBitmap>(1, 1) }
{ {
// Preinit the backing DC and bitmap so routines that require it will // Preinit the backing DC and bitmap so routines that require it will
// not cause a crash if they run before the panel is fully initialized. // not cause a crash if they run before the panel is fully initialized.
@ -52,7 +52,7 @@ void BackedPanel::ResizeBacking()
mBackingDC.SelectObject(wxNullBitmap); mBackingDC.SelectObject(wxNullBitmap);
wxSize sz = GetClientSize(); wxSize sz = GetClientSize();
mBacking.reset(safenew wxBitmap); mBacking = std::make_unique<wxBitmap>();
mBacking->Create(sz.x, sz.y); //, *dc); mBacking->Create(sz.x, sz.y); //, *dc);
mBackingDC.SelectObject(*mBacking); mBackingDC.SelectObject(*mBacking);
} }

View File

@ -184,6 +184,7 @@ void ShowModelessErrorDialog(wxWindow *parent,
const wxString &helpURL, const wxString &helpURL,
const bool Close) const bool Close)
{ {
wxASSERT(parent);
ErrorDialog *dlog = safenew ErrorDialog(parent, dlogTitle, message, helpURL, Close, false); ErrorDialog *dlog = safenew ErrorDialog(parent, dlogTitle, message, helpURL, Close, false);
dlog->CentreOnParent(); dlog->CentreOnParent();
dlog->Show(); dlog->Show();
@ -199,6 +200,7 @@ void ShowAliasMissingDialog(AudacityProject *parent,
const wxString &helpURL, const wxString &helpURL,
const bool Close) const bool Close)
{ {
wxASSERT(parent); // to justify safenew
ErrorDialog *dlog = safenew AliasedFileMissingDialog(parent, dlogTitle, message, helpURL, Close, false); ErrorDialog *dlog = safenew AliasedFileMissingDialog(parent, dlogTitle, message, helpURL, Close, false);
// Don't center because in many cases (effect, export, etc) there will be a progress bar in the center that blocks this. // Don't center because in many cases (effect, export, etc) there will be a progress bar in the center that blocks this.
// instead put it just above or on the top of the project. // instead put it just above or on the top of the project.

View File

@ -100,6 +100,7 @@ void HelpSystem::ShowHtmlText(wxWindow *pParent,
{ {
LinkingHtmlWindow *html; LinkingHtmlWindow *html;
wxASSERT(pParent); // to justify safenew
auto pFrame = safenew wxFrame { auto pFrame = safenew wxFrame {
pParent, wxID_ANY, Title, wxDefaultPosition, wxDefaultSize, pParent, wxID_ANY, Title, wxDefaultPosition, wxDefaultSize,
#if defined(__WXMAC__) #if defined(__WXMAC__)
@ -195,6 +196,7 @@ void HelpSystem::ShowHelpDialog(wxWindow *parent,
const wxString &remoteURL, const wxString &remoteURL,
bool bModal) bool bModal)
{ {
wxASSERT(parent); // to justify safenew
AudacityProject * pProj = GetActiveProject(); AudacityProject * pProj = GetActiveProject();
wxString HelpMode = wxT("Local"); wxString HelpMode = wxT("Local");
@ -341,6 +343,7 @@ void HelpSystem::ShowHelpDialog(wxWindow *parent,
wxLogMessage(wxT("webHelpPage %s, localHelpPage %s"), wxLogMessage(wxT("webHelpPage %s, localHelpPage %s"),
webHelpPage.c_str(), localHelpPage.c_str()); webHelpPage.c_str(), localHelpPage.c_str());
wxASSERT(parent); // to justify safenew
HelpSystem::ShowHelpDialog( HelpSystem::ShowHelpDialog(
parent, parent,
localHelpPage, localHelpPage,

View File

@ -124,7 +124,7 @@ void LinkingHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
wxFileName( FileNames::HtmlHelpDir(), href.Mid( 10 ) + wxT(".htm") ).GetFullPath(); wxFileName( FileNames::HtmlHelpDir(), href.Mid( 10 ) + wxT(".htm") ).GetFullPath();
if( wxFileExists( FileName ) ) if( wxFileExists( FileName ) )
{ {
HelpSystem::ShowHelpDialog(NULL, FileName, wxT("")); HelpSystem::ShowHelpDialog(this, FileName, wxT(""));
return; return;
} }
else else