From 90e400b0a7e2b1dbab471d9df9463d4ea1bddd7e Mon Sep 17 00:00:00 2001 From: Steve Daulton Date: Sat, 13 Aug 2016 17:27:55 +0100 Subject: [PATCH 1/5] Add SBSMS option to Change Pitch effect --- src/effects/ChangePitch.cpp | 76 +++++++++++++++++++++++++++++-------- src/effects/ChangePitch.h | 10 +++++ src/effects/SBSMSEffect.cpp | 6 +++ src/effects/SBSMSEffect.h | 1 + 4 files changed, 78 insertions(+), 15 deletions(-) diff --git a/src/effects/ChangePitch.cpp b/src/effects/ChangePitch.cpp index f29272001..bc8da84ee 100644 --- a/src/effects/ChangePitch.cpp +++ b/src/effects/ChangePitch.cpp @@ -18,9 +18,13 @@ the pitch without changing the tempo. #include "../Audacity.h" // for USE_SOUNDTOUCH #if USE_SOUNDTOUCH - #include "ChangePitch.h" +#if USE_SBSMS +#include "sbsms.h" +#include +#endif + #include #include @@ -51,6 +55,7 @@ enum { // // Name Type Key Def Min Max Scale 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% 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_bLoopDetect = false; +#if USE_SBSMS + mUseSBSMS = DEF_UseSBSMS; +#else + mUseSBSMS = false; +#endif + // NULL out these control members because there are some cases where the // event table handlers get called during this method, and those handlers that // can cause trouble check for NULL. @@ -127,6 +138,7 @@ EffectType EffectChangePitch::GetType() bool EffectChangePitch::GetAutomationParameters(EffectAutomationParameters & parms) { parms.Write(KEY_Percentage, m_dPercentChange); + parms.Write(KEY_UseSBSMS, mUseSBSMS); return true; } @@ -140,6 +152,13 @@ bool EffectChangePitch::SetAutomationParameters(EffectAutomationParameters & par m_dPercentChange = Percentage; Calc_SemitonesChange_fromPercentChange(); +#if USE_SBSMS + ReadAndVerifyBool(UseSBSMS); + mUseSBSMS = UseSBSMS; +#else + mUseSBSMS = false; +#endif + return true; } @@ -160,20 +179,37 @@ bool EffectChangePitch::Init() bool EffectChangePitch::Process() { - mSoundTouch = std::make_unique(); - SetTimeWarper(std::make_unique()); - mSoundTouch->setPitchSemiTones((float)(m_dSemitonesChange)); -#ifdef USE_MIDI - // 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; +#if USE_SBSMS + if (mUseSBSMS) + { + double pitchRatio = 1.0 + m_dPercentChange / 100.0; + SelectedRegion region(mT0, mT1); + EffectSBSMS proxy; + proxy.setParameters(1.0, pitchRatio); + + return proxy.DoEffect(mUIParent, mProjectRate, mTracks, mFactory, ®ion, false); + } + else #endif - return EffectSoundTouch::Process(); + { + mSoundTouch = std::make_unique(); + SetTimeWarper(std::make_unique()); + 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() @@ -287,6 +323,17 @@ void EffectChangePitch::PopulateOrExchange(ShuttleGui & S) S.EndHorizontalLay(); } 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(); @@ -460,7 +507,6 @@ void EffectChangePitch::Calc_PercentChange() // handlers - void EffectChangePitch::OnChoice_FromPitch(wxCommandEvent & WXUNUSED(evt)) { if (m_bLoopDetect) diff --git a/src/effects/ChangePitch.h b/src/effects/ChangePitch.h index 5828f4db0..6de394d86 100644 --- a/src/effects/ChangePitch.h +++ b/src/effects/ChangePitch.h @@ -20,6 +20,11 @@ the pitch without changing the tempo. #ifndef __AUDACITY_EFFECT_CHANGEPITCH__ #define __AUDACITY_EFFECT_CHANGEPITCH__ +#if USE_SBSMS +#include "SBSMSEffect.h" +#include +#endif + #include #include #include @@ -108,6 +113,7 @@ private: void Update_Slider_PercentChange(); // Update control per current m_dPercentChange. private: + bool mUseSBSMS; // effect parameters int m_nFromPitch; // per PitchIndex() int m_nFromOctave; // per PitchOctave() @@ -136,6 +142,10 @@ private: wxTextCtrl * m_pTextCtrl_PercentChange; wxSlider * m_pSlider_PercentChange; +#if USE_SBSMS + wxCheckBox * mUseSBSMSCheckBox; +#endif + DECLARE_EVENT_TABLE(); }; diff --git a/src/effects/SBSMSEffect.cpp b/src/effects/SBSMSEffect.cpp index 27279dbb2..596a4b678 100644 --- a/src/effects/SBSMSEffect.cpp +++ b/src/effects/SBSMSEffect.cpp @@ -156,6 +156,12 @@ void EffectSBSMS :: setParameters(double rateStart, double rateEnd, double pitch this->bPitchReferenceInput = bPitchReferenceInput; } +void EffectSBSMS::setParameters(double tempoRatio, double pitchRatio) +{ + setParameters(tempoRatio, tempoRatio, pitchRatio, pitchRatio, + SlideConstant, SlideConstant, false, false, false); +} + std::unique_ptr createTimeWarper(double t0, double t1, double duration, double rateStart, double rateEnd, SlideType rateSlideType) { diff --git a/src/effects/SBSMSEffect.h b/src/effects/SBSMSEffect.h index ddbb6caef..fd5da4648 100644 --- a/src/effects/SBSMSEffect.h +++ b/src/effects/SBSMSEffect.h @@ -28,6 +28,7 @@ public: void setParameters(double rateStart, double rateEnd, double pitchStart, double pitchEnd, SlideType rateSlideType, SlideType pitchSlideType, 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 getRate(double rateStart, double rateEnd, SlideType slideType, double t); private: From 6909bdf398aab9d4390bd38f90dddcdcdeadffac Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 11 Aug 2016 13:06:39 -0400 Subject: [PATCH 2/5] Define and use IteratorRange --- src/MemoryX.h | 12 ++++++++++++ src/Tags.cpp | 2 +- src/Tags.h | 8 +------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/MemoryX.h b/src/MemoryX.h index 7d1dba325..529b31d11 100644 --- a/src/MemoryX.h +++ b/src/MemoryX.h @@ -727,4 +727,16 @@ Final_action finally (F f) return Final_action(f); } +/* + * A convenience for use with range-for + */ +template +struct IteratorRange : public std::pair { + IteratorRange (Iterator &&a, Iterator &&b) + : std::pair { std::move(a), std::move(b) } {} + + Iterator begin() const { return this->first; } + Iterator end() const { return this->second; } +}; + #endif // __AUDACITY_MEMORY_X_H__ diff --git a/src/Tags.cpp b/src/Tags.cpp index 756ee6b6c..6c085555a 100644 --- a/src/Tags.cpp +++ b/src/Tags.cpp @@ -443,7 +443,7 @@ wxString Tags::GetTag(const wxString & name) 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) diff --git a/src/Tags.h b/src/Tags.h index 4fec7a850..dd7d029dc 100644 --- a/src/Tags.h +++ b/src/Tags.h @@ -104,13 +104,7 @@ class AUDACITY_DLL_API Tags final : public XMLTagHandler { bool HasTag(const wxString & name) const; wxString GetTag(const wxString & name) const; - using IterPair = std::pair; - 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; } - }; + using Iterators = IteratorRange; Iterators GetRange() const; void SetTag(const wxString & name, const wxString & value); From 84a6456788a6469d98bd8f584dbae34c248af029 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 13 Aug 2016 16:06:00 -0400 Subject: [PATCH 3/5] Iterate over all clips of a track, including cutlines, where needed --- src/Dependencies.cpp | 2 +- src/UndoManager.cpp | 2 +- src/WaveTrack.h | 75 ++++++++++++++++++++++++++- src/ondemand/ODComputeSummaryTask.cpp | 2 +- src/ondemand/ODDecodeTask.cpp | 2 +- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/Dependencies.cpp b/src/Dependencies.cpp index 0d707fe4a..6352fc2d9 100644 --- a/src/Dependencies.cpp +++ b/src/Dependencies.cpp @@ -63,7 +63,7 @@ static void GetAllSeqBlocks(AudacityProject *project, while (t) { if (t->GetKind() == Track::Wave) { WaveTrack *waveTrack = static_cast(t); - for(const auto &clip : waveTrack->GetClips()) { + for(const auto &clip : waveTrack->GetAllClips()) { Sequence *sequence = clip->GetSequence(); BlockArray &blocks = sequence->GetBlockArray(); int i; diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index 3f18d9aba..56608fe49 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -94,7 +94,7 @@ void UndoManager::CalculateSpaceUsage() while (wt) { // Scan all clips within current track - for(const auto &clip: wt->GetClips()) + for(const auto &clip : wt->GetAllClips()) { // Scan all blockfiles within current clip BlockArray *blocks = clip->GetSequenceBlockArray(); diff --git a/src/WaveTrack.h b/src/WaveTrack.h index a16b538f8..ad35eaa98 100644 --- a/src/WaveTrack.h +++ b/src/WaveTrack.h @@ -333,11 +333,84 @@ class AUDACITY_DLL_API WaveTrack final : public Track { */ 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; } const WaveClipConstHolders &GetClips() const { 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 // to the newly created clip. WaveClip* CreateClip(); diff --git a/src/ondemand/ODComputeSummaryTask.cpp b/src/ondemand/ODComputeSummaryTask.cpp index 88a2dfad1..8e90e274a 100644 --- a/src/ondemand/ODComputeSummaryTask.cpp +++ b/src/ondemand/ODComputeSummaryTask.cpp @@ -182,7 +182,7 @@ void ODComputeSummaryTask::Update() Sequence *seq; //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(); //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. diff --git a/src/ondemand/ODDecodeTask.cpp b/src/ondemand/ODDecodeTask.cpp index eac9b1c7f..a15d41120 100644 --- a/src/ondemand/ODDecodeTask.cpp +++ b/src/ondemand/ODDecodeTask.cpp @@ -140,7 +140,7 @@ void ODDecodeTask::Update() Sequence *seq; //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(); //TODO:this lock is way to big since the whole file is one sequence. find a way to break it down. seq->LockDeleteUpdateMutex(); From 32f24eabb25716e99e8b5bfa548640472cde6917 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 13 Aug 2016 23:16:05 -0400 Subject: [PATCH 4/5] Review uses of safenew... ... add comments and assertions, and use make_unique instead where possible --- src/MixerBoard.cpp | 1 + src/Project.cpp | 5 +++-- src/SplashDialog.cpp | 1 + src/TimerRecordDialog.cpp | 1 + src/effects/Effect.cpp | 2 +- src/toolbars/MeterToolBar.cpp | 1 + src/toolbars/ToolBar.cpp | 1 + src/toolbars/ToolBar.h | 1 + src/toolbars/ToolManager.cpp | 6 ++++++ src/widgets/BackedPanel.cpp | 4 ++-- src/widgets/ErrorDialog.cpp | 2 ++ src/widgets/HelpSystem.cpp | 3 +++ src/widgets/LinkingHtmlWindow.cpp | 2 +- 13 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/MixerBoard.cpp b/src/MixerBoard.cpp index aaf9986c5..216ba7a1f 100644 --- a/src/MixerBoard.cpp +++ b/src/MixerBoard.cpp @@ -934,6 +934,7 @@ MixerBoard::MixerBoard(AudacityProject* pProject, this->LoadMusicalInstruments(); // Set up mMusicalInstruments. mProject = pProject; + wxASSERT(pProject); // to justify safenew mScrolledWindow = safenew MixerBoardScrolledWindow( pProject, // AudacityProject* project, diff --git a/src/Project.cpp b/src/Project.cpp index 89c3332ad..208d9862f 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -169,7 +169,8 @@ scroll information. It also has some status flags. #include "../images/AudacityLogoAlpha.xpm" -std::unique_ptr AudacityProject::msClipboard{ safenew TrackList() }; +std::unique_ptr AudacityProject::msClipboard + { std::make_unique() }; double AudacityProject::msClipT0 = 0.0; double AudacityProject::msClipT1 = 0.0; AudacityProject *AudacityProject::msClipProject = NULL; @@ -829,7 +830,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))), mFrequencySelectionFormatName(gPrefs->Read(wxT("/FrequencySelectionFormatName"), wxT(""))), mBandwidthSelectionFormatName(gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT(""))), - mUndoManager(safenew UndoManager), + mUndoManager(std::make_unique()), 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 diff --git a/src/SplashDialog.cpp b/src/SplashDialog.cpp index 7c75692d0..9efe77d43 100644 --- a/src/SplashDialog.cpp +++ b/src/SplashDialog.cpp @@ -143,6 +143,7 @@ void SplashDialog::Show2( wxWindow * pParent ) if( pSelf == NULL ) { // pParent owns it + wxASSERT(pParent); pSelf = safenew SplashDialog( pParent ); } pSelf->mpHtml->SetPage(HelpText( wxT("welcome") )); diff --git a/src/TimerRecordDialog.cpp b/src/TimerRecordDialog.cpp index ceac1476c..81f91252b 100644 --- a/src/TimerRecordDialog.cpp +++ b/src/TimerRecordDialog.cpp @@ -778,6 +778,7 @@ TimerRecordPathCtrl * TimerRecordDialog::NewPathControl(wxWindow *wParent, const const wxString &sCaption, const wxString &sValue) { TimerRecordPathCtrl * pTextCtrl; + wxASSERT(wParent); // to justify safenew pTextCtrl = safenew TimerRecordPathCtrl(wParent, iID, sValue); pTextCtrl->SetName(sCaption); return pTextCtrl; diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 39438add7..a476b9f51 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -2125,7 +2125,7 @@ Effect::AddedAnalysisTrack::~AddedAnalysisTrack() auto Effect::AddAnalysisTrack(const wxString &name) -> std::shared_ptr { return std::shared_ptr - { safenew AddedAnalysisTrack{ this, name } }; + { safenew AddedAnalysisTrack{ this, name } }; } Effect::ModifiedAnalysisTrack::ModifiedAnalysisTrack diff --git a/src/toolbars/MeterToolBar.cpp b/src/toolbars/MeterToolBar.cpp index 492fe4ee0..037733ce6 100644 --- a/src/toolbars/MeterToolBar.cpp +++ b/src/toolbars/MeterToolBar.cpp @@ -113,6 +113,7 @@ void MeterToolBar::ReCreateButtons() void MeterToolBar::Populate() { + wxASSERT(mProject); // to justify safenew Add((mSizer = safenew wxGridBagSizer()), 1, wxEXPAND); if( mWhichMeters & kWithRecordMeter ){ diff --git a/src/toolbars/ToolBar.cpp b/src/toolbars/ToolBar.cpp index a01c41ea7..1787260a5 100644 --- a/src/toolbars/ToolBar.cpp +++ b/src/toolbars/ToolBar.cpp @@ -758,6 +758,7 @@ AButton * ToolBar::MakeButton(wxWindow *parent, wxImagePtr down2 (OverlayImage(eDown, eStandardDown, xoff + 1, yoff + 1)); wxImagePtr disable2 (OverlayImage(eUp, eDisabled, xoff, yoff)); + wxASSERT(parent); // to justify safenew AButton * button = safenew AButton(parent, id, placement, size, *up2, *hilite2, *down2, *disable2, processdownevents); diff --git a/src/toolbars/ToolBar.h b/src/toolbars/ToolBar.h index 1c26e74e8..e92ce9ee2 100644 --- a/src/toolbars/ToolBar.h +++ b/src/toolbars/ToolBar.h @@ -181,6 +181,7 @@ class ToolBar /* not final */ : public wxPanelWrapper int border = 0, wxObject *userData = NULL); + // Takes ownership of sizer void Add(wxSizer *sizer, int proportion = 0, int flag = 0, diff --git a/src/toolbars/ToolManager.cpp b/src/toolbars/ToolManager.cpp index f33524160..cd050c643 100644 --- a/src/toolbars/ToolManager.cpp +++ b/src/toolbars/ToolManager.cpp @@ -363,6 +363,7 @@ ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent ) mLeft = std::make_unique( 3, &pt[0] ); // Create the indicator frame + // parent is null but FramePtr ensures destruction mIndicator = FramePtr{ safenew wxFrame( NULL, wxID_ANY, wxEmptyString, @@ -410,6 +411,8 @@ ToolManager::ToolManager( AudacityProject *parent, wxWindow *topDockParent ) mBotDock = safenew ToolDock( this, mParent, BotDockID ); // Create all of the toolbars + // All have the project as parent window + wxASSERT(parent); mBars[ ToolsBarID ] = ToolBar::Holder{ safenew ToolsToolBar() }; mBars[ TransportBarID ] = ToolBar::Holder{ safenew ControlToolBar() }; mBars[ RecordMeterBarID ] = ToolBar::Holder{ safenew MeterToolBar( parent, RecordMeterBarID ) }; @@ -583,6 +586,7 @@ void ToolManager::Reset() // Maybe construct a NEW floater // this happens if we have just been bounced out of a dock. if( floater == NULL ) { + wxASSERT(mParent); floater = safenew ToolFrame( mParent, this, bar, wxPoint(-1,-1) ); bar->Reparent( floater ); } @@ -761,6 +765,7 @@ void ToolManager::ReadConfig() bar->Create( mTopDock ); // Construct a NEW floater + wxASSERT(mParent); ToolFrame *f = safenew ToolFrame( mParent, this, bar, wxPoint( x, y ) ); // Set the width and height @@ -1327,6 +1332,7 @@ void ToolManager::OnGrabber( GrabberEvent & event ) mDragBar->SetPositioned(); // Construct a NEW floater + wxASSERT(mParent); mDragWindow = safenew ToolFrame( mParent, this, mDragBar, mp ); // Make sure the ferry is visible diff --git a/src/widgets/BackedPanel.cpp b/src/widgets/BackedPanel.cpp index 78148fe76..0f8357ee9 100644 --- a/src/widgets/BackedPanel.cpp +++ b/src/widgets/BackedPanel.cpp @@ -14,7 +14,7 @@ BackedPanel::BackedPanel(wxWindow * parent, wxWindowID id, const wxSize & size, long style) : wxPanelWrapper(parent, id, pos, size, style) -, mBacking{ safenew wxBitmap(1, 1) } +, mBacking{ std::make_unique(1, 1) } { // 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. @@ -52,7 +52,7 @@ void BackedPanel::ResizeBacking() mBackingDC.SelectObject(wxNullBitmap); wxSize sz = GetClientSize(); - mBacking.reset(safenew wxBitmap); + mBacking = std::make_unique(); mBacking->Create(sz.x, sz.y); //, *dc); mBackingDC.SelectObject(*mBacking); } diff --git a/src/widgets/ErrorDialog.cpp b/src/widgets/ErrorDialog.cpp index 0cb633142..d7e3f48e9 100644 --- a/src/widgets/ErrorDialog.cpp +++ b/src/widgets/ErrorDialog.cpp @@ -184,6 +184,7 @@ void ShowModelessErrorDialog(wxWindow *parent, const wxString &helpURL, const bool Close) { + wxASSERT(parent); ErrorDialog *dlog = safenew ErrorDialog(parent, dlogTitle, message, helpURL, Close, false); dlog->CentreOnParent(); dlog->Show(); @@ -199,6 +200,7 @@ void ShowAliasMissingDialog(AudacityProject *parent, const wxString &helpURL, const bool Close) { + wxASSERT(parent); // to justify safenew 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. // instead put it just above or on the top of the project. diff --git a/src/widgets/HelpSystem.cpp b/src/widgets/HelpSystem.cpp index 47fbe5b8f..60bfc16d9 100644 --- a/src/widgets/HelpSystem.cpp +++ b/src/widgets/HelpSystem.cpp @@ -100,6 +100,7 @@ void HelpSystem::ShowHtmlText(wxWindow *pParent, { LinkingHtmlWindow *html; + wxASSERT(pParent); // to justify safenew auto pFrame = safenew wxFrame { pParent, wxID_ANY, Title, wxDefaultPosition, wxDefaultSize, #if defined(__WXMAC__) @@ -195,6 +196,7 @@ void HelpSystem::ShowHelpDialog(wxWindow *parent, const wxString &remoteURL, bool bModal) { + wxASSERT(parent); // to justify safenew AudacityProject * pProj = GetActiveProject(); wxString HelpMode = wxT("Local"); @@ -341,6 +343,7 @@ void HelpSystem::ShowHelpDialog(wxWindow *parent, wxLogMessage(wxT("webHelpPage %s, localHelpPage %s"), webHelpPage.c_str(), localHelpPage.c_str()); + wxASSERT(parent); // to justify safenew HelpSystem::ShowHelpDialog( parent, localHelpPage, diff --git a/src/widgets/LinkingHtmlWindow.cpp b/src/widgets/LinkingHtmlWindow.cpp index ab674fb3c..2b8d7a53c 100644 --- a/src/widgets/LinkingHtmlWindow.cpp +++ b/src/widgets/LinkingHtmlWindow.cpp @@ -124,7 +124,7 @@ void LinkingHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link) wxFileName( FileNames::HtmlHelpDir(), href.Mid( 10 ) + wxT(".htm") ).GetFullPath(); if( wxFileExists( FileName ) ) { - HelpSystem::ShowHelpDialog(NULL, FileName, wxT("")); + HelpSystem::ShowHelpDialog(this, FileName, wxT("")); return; } else From 41efaeeef08a263033b774a87e0deb34b3f6de0f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 14 Aug 2016 09:32:46 -0400 Subject: [PATCH 5/5] Fix Windows build --- src/DirManager.h | 2 +- src/MemoryX.h | 2 +- src/commands/CommandManager.h | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/DirManager.h b/src/DirManager.h index 2cc2024f0..30fcb055f 100644 --- a/src/DirManager.h +++ b/src/DirManager.h @@ -11,7 +11,7 @@ #ifndef _DIRMANAGER_ #define _DIRMANAGER_ -#include +#include "MemoryX.h" #include #include #include diff --git a/src/MemoryX.h b/src/MemoryX.h index 529b31d11..43b23854e 100644 --- a/src/MemoryX.h +++ b/src/MemoryX.h @@ -733,7 +733,7 @@ Final_action finally (F f) template struct IteratorRange : public std::pair { IteratorRange (Iterator &&a, Iterator &&b) - : std::pair { std::move(a), std::move(b) } {} + : std::pair ( std::move(a), std::move(b) ) {} Iterator begin() const { return this->first; } Iterator end() const { return this->second; } diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index ae0460052..42f09b846 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -44,7 +44,11 @@ struct SubMenuListEntry : name(name_), menu( std::move(menu_) ) {} - // SubMenuListEntry( SubMenuListEntry&& ) = default; + SubMenuListEntry(SubMenuListEntry &&that) + : name(std::move(that.name)) + , menu(std::move(that.menu)) + { + } wxString name; std::unique_ptr menu;