diff --git a/.gitignore b/.gitignore index 2e7c7a485..3da21734f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ *.log *.tlog *.ipch +*.opensdf # Precompiled Headers *.gch @@ -40,3 +41,5 @@ *.out *.app win/resetPrefs.txt +src/RevisionIdent.h + diff --git a/.travis.yml b/.travis.yml index 38a024927..2a6024293 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ before_install: - sudo apt-get update -qq - sudo apt-get install -y libwxgtk2.8-dev + - git show -s --format="wxT(\"%h of %cd\")" + - git show -s --format="wxT(\"%h of %cd\")" > ./src/RevisionIdent.h language: cpp compiler: - gcc diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index 940f35209..48511ef85 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -966,6 +966,7 @@ 28D587CC0E264CF4009C7DEA /* LV2Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28D587C90E264CF4009C7DEA /* LV2Effect.cpp */; }; 28D65C720B97E54B000E001A /* AutoDuck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28D65C700B97E54B000E001A /* AutoDuck.cpp */; }; 28D65C760B97E573000E001A /* DtmfGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28D65C740B97E573000E001A /* DtmfGen.cpp */; }; + 28D8425C1AD8D69D00551353 /* SelectedRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28D8425B1AD8D69D00551353 /* SelectedRegion.cpp */; }; 28DA07390E4F5CEC003933C5 /* ExportFFmpegDialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28DA07380E4F5CEC003933C5 /* ExportFFmpegDialogs.cpp */; }; 28DABFBE0FF19DB100AC7848 /* RealFFTf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28DABFBC0FF19DB100AC7848 /* RealFFTf.cpp */; }; 28DB34790FDC2C5D0011F589 /* ResponseQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28DB34780FDC2C5D0011F589 /* ResponseQueue.cpp */; }; @@ -3757,6 +3758,8 @@ 28D65C710B97E54B000E001A /* AutoDuck.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = AutoDuck.h; sourceTree = ""; tabWidth = 3; }; 28D65C740B97E573000E001A /* DtmfGen.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = DtmfGen.cpp; sourceTree = ""; tabWidth = 3; }; 28D65C750B97E573000E001A /* DtmfGen.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = DtmfGen.h; sourceTree = ""; tabWidth = 3; }; + 28D8425A1AD8D69D00551353 /* RevisionIdent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RevisionIdent.h; sourceTree = ""; }; + 28D8425B1AD8D69D00551353 /* SelectedRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectedRegion.cpp; sourceTree = ""; }; 28DA07370E4F5CEC003933C5 /* ExportFFmpegDialogs.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = ExportFFmpegDialogs.h; sourceTree = ""; tabWidth = 3; }; 28DA07380E4F5CEC003933C5 /* ExportFFmpegDialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = ExportFFmpegDialogs.cpp; sourceTree = ""; tabWidth = 3; }; 28DABFBC0FF19DB100AC7848 /* RealFFTf.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = RealFFTf.cpp; sourceTree = ""; tabWidth = 3; }; @@ -5128,12 +5131,14 @@ EDFCEBA318894B2A00C98E51 /* RealFFTf48x.h */, 1790B0D209883BFD008A330A /* Resample.cpp */, 1790B0D309883BFD008A330A /* Resample.h */, + 28D8425A1AD8D69D00551353 /* RevisionIdent.h */, 1790B0D409883BFD008A330A /* RingBuffer.cpp */, 1790B0D509883BFD008A330A /* RingBuffer.h */, 1790B0D609883BFD008A330A /* SampleFormat.cpp */, 1790B0D709883BFD008A330A /* SampleFormat.h */, 285DE1F80BF03C7800A20DF0 /* Screenshot.cpp */, 285DE1F90BF03C7800A20DF0 /* Screenshot.h */, + 28D8425B1AD8D69D00551353 /* SelectedRegion.cpp */, 2813897919E6163C004111ED /* SelectedRegion.h */, 1790B0DA09883BFD008A330A /* Sequence.cpp */, 1790B0DB09883BFD008A330A /* Sequence.h */, @@ -9251,6 +9256,7 @@ 28BB98051A15BE6800D1CC80 /* NoiseReduction.cpp in Sources */, 28285C801A27A81600BC2205 /* AudioUnitCocoaHelper.mm in Sources */, 28D000A51A32920C00367B21 /* DeviceChange.cpp in Sources */, + 28D8425C1AD8D69D00551353 /* SelectedRegion.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/AboutDialog.cpp b/src/AboutDialog.cpp index 4f8410f46..830d10822 100644 --- a/src/AboutDialog.cpp +++ b/src/AboutDialog.cpp @@ -549,6 +549,10 @@ void AboutDialog::PopulateInformationPage( ShuttleGui & S ) // Current date AddBuildinfoRow(&informationStr, _("Program build date: "), __TDATE__); + AddBuildinfoRow(&informationStr, _("Commit Id:"), +#include "RevisionIdent.h" +); + #ifdef __WXDEBUG__ AddBuildinfoRow(&informationStr, _("Build type:"), _("Debug build")); #else diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 9fd579009..e9ed18079 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -3888,7 +3888,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, } // Wrap to start if looping - if (gAudioIO->mPlayLooped && gAudioIO->mTime >= gAudioIO->mT1) + while (gAudioIO->mPlayLooped && gAudioIO->mTime >= gAudioIO->mT1) { // LL: This is not exactly right, but I'm at my wits end trying to // figure it out. Feel free to fix it. :-) diff --git a/src/Envelope.cpp b/src/Envelope.cpp index 12e99a946..a5658f047 100644 --- a/src/Envelope.cpp +++ b/src/Envelope.cpp @@ -656,14 +656,14 @@ void Envelope::CollapseRegion(double t0, double t1) // envelope point applies to the first sample, but the t=tracklen // envelope point applies one-past the last actual sample. // Rather than going to a .5-offset-index, we special case the framing. -void Envelope::Paste(double t0, Envelope *e) +void Envelope::Paste(double t0, const Envelope *e) { - bool pointsAdded = false; + const bool wasEmpty = (this->mEnv.Count() == 0); -// JC: The old analysis of cases and the resulting code here is way more complex than needed. -// TODO: simplify the analysis and simplify the code. + // JC: The old analysis of cases and the resulting code here is way more complex than needed. + // TODO: simplify the analysis and simplify the code. - if (e->mEnv.Count() == 0 && this->mEnv.Count() == 0 && e->mDefaultValue == this->mDefaultValue) + if (e->mEnv.Count() == 0 && wasEmpty && e->mDefaultValue == this->mDefaultValue) { // msmeyer: The envelope is empty and has the same default value, so // there is nothing that must be inserted, just return. This avoids @@ -672,16 +672,6 @@ void Envelope::Paste(double t0, Envelope *e) mTrackLen += e->mTrackLen; return; } - if (this->mEnv.Count() != 0) - { - // inserting a clip with a possibly empty envelope into one with an envelope - // so add end points to e, in case they are not there - double leftval = e->GetValue(0+e->mOffset); - double rightval = e->GetValue(e->mTrackLen+e->mOffset); - e->Insert(0, leftval); - e->Insert(e->mTrackLen, rightval); - pointsAdded = true; // we need to delete them later so's not to corrupt 'e' for later use - } t0 = wxMin(t0 - mOffset, mTrackLen); // t0 now has origin of zero double deltat = e->mTrackLen; @@ -834,17 +824,24 @@ Old analysis of cases: } // Copy points from inside the selection + + if (!wasEmpty) { + // Add end points in case they are not not in e. + // If they are in e, no harm, because the repeated Insert + // calls for the start and end times will have no effect. + const double leftval = e->GetValue(0 + e->mOffset); + const double rightval = e->GetValue(e->mTrackLen + e->mOffset); + Insert(t0, leftval); + Insert(t0 + e->mTrackLen, rightval); + } + len = e->mEnv.Count(); for (i = 0; i < len; i++) - pos=Insert(t0 + e->mEnv[i]->GetT(), e->mEnv[i]->GetVal()); + Insert(t0 + e->mEnv[i]->GetT(), e->mEnv[i]->GetVal()); /* if(len != 0) for (i = 0; i < mEnv.Count(); i++) wxLogDebug(wxT("Fixed i %d when %.18f val %f"),i,mEnv[i]->GetT(),mEnv[i]->GetVal()); */ - - if(pointsAdded) - while(e->mEnv.Count() != 0) - e->Delete(0); // they were not there when we entered this } // Deletes 'unneeded' points, starting from the left. diff --git a/src/Envelope.h b/src/Envelope.h index 691985199..1a33abc0f 100644 --- a/src/Envelope.h +++ b/src/Envelope.h @@ -140,7 +140,7 @@ class Envelope : public XMLTagHandler { // Handling Cut/Copy/Paste events void CollapseRegion(double t0, double t1); void CopyFrom(const Envelope * e, double t0, double t1); - void Paste(double t0, Envelope *e); + void Paste(double t0, const Envelope *e); void InsertSpace(double t0, double tlen); void RemoveUnneededPoints(double time = -1, double tolerence = 0.001); diff --git a/src/InterpolateAudio.cpp b/src/InterpolateAudio.cpp index ce2ec2e92..173b07d32 100644 --- a/src/InterpolateAudio.cpp +++ b/src/InterpolateAudio.cpp @@ -103,6 +103,7 @@ void InterpolateAudio(float *buffer, int len, InterpolateAudio(buffer2, len, len-numBad, numBad); for(i=0; igetT0(), 8); - xmlFile.WriteAttr(wxT("t1"), mLabels[i]->getT1(), 8); + mLabels[i]->getSelectedRegion() + .WriteXMLAttributes(xmlFile, wxT("t"), wxT("t1")); // PRL: to do: write other selection fields xmlFile.WriteAttr(wxT("title"), mLabels[i]->title); xmlFile.EndTag(wxT("label")); diff --git a/src/LabelTrack.h b/src/LabelTrack.h index acfe33fbf..c45112a1c 100644 --- a/src/LabelTrack.h +++ b/src/LabelTrack.h @@ -56,6 +56,7 @@ public: void DrawTextBox( wxDC & dc, const wxRect & r); void DrawHighlight( wxDC & dc, int xPos1, int xPos2, int charHeight); void getXPos( wxDC & dc, int * xPos1, int cursorPos); + const SelectedRegion &getSelectedRegion() const { return selectedRegion; } double getDuration() const { return selectedRegion.duration(); } double getT0() const { return selectedRegion.t0(); } double getT1() const { return selectedRegion.t1(); } @@ -169,11 +170,11 @@ class AUDACITY_DLL_API LabelTrack : public Track static bool IsTextClipSupported(); // methods to set flags - void SetDragXPos(const int d) { mDragXPos = d; }; - void SetInBox(bool inTextBox) { mInBox = inTextBox; }; - void SetResetCursorPos(bool resetFlag) { mResetCursorPos = resetFlag; }; - void SetWrongDragging(bool rightFlag) { mRightDragging = rightFlag; }; - void SetDrawCursor(bool drawCursorFlag) { mDrawCursor = drawCursorFlag; }; + void SetDragXPos(const int d) { mDragXPos = d; } + void SetInBox(bool inTextBox) { mInBox = inTextBox; } + void SetResetCursorPos(bool resetFlag) { mResetCursorPos = resetFlag; } + void SetWrongDragging(bool rightFlag) { mRightDragging = rightFlag; } + void SetDrawCursor(bool drawCursorFlag) { mDrawCursor = drawCursorFlag; } bool HandleMouse(const wxMouseEvent & evt, wxRect & r, double h, double pps, SelectedRegion *newSel); @@ -202,7 +203,7 @@ class AUDACITY_DLL_API LabelTrack : public Track //get current cursor position bool CalcCursorX(wxWindow * parent, int * x); - int getCurrentCursorPosition() const { return mCurrentCursorPos; }; + int getCurrentCursorPosition() const { return mCurrentCursorPos; } void MayAdjustLabel( int iLabel, int iEdge, bool bAllowSwapping, double fNewTime); void MayMoveLabel( int iLabel, int iEdge, double fNewTime); diff --git a/src/Makefile.am b/src/Makefile.am index ad95ee09b..82ed2f51c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -185,10 +185,12 @@ audacity_SOURCES = \ RealFFTf48x.h \ Resample.cpp \ Resample.h \ + RevisionIdent.h \ RingBuffer.cpp \ RingBuffer.h \ Screenshot.cpp \ Screenshot.h \ + SelectedRegion.cpp \ SelectedRegion.h \ Shuttle.cpp \ Shuttle.h \ diff --git a/src/Makefile.in b/src/Makefile.in index 6ed825f64..aaafdd0ab 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -304,12 +304,12 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h Resample.cpp \ - Resample.h RingBuffer.cpp RingBuffer.h Screenshot.cpp \ - Screenshot.h SelectedRegion.h Shuttle.cpp Shuttle.h \ - ShuttleGui.cpp ShuttleGui.h ShuttlePrefs.cpp ShuttlePrefs.h \ - Snap.cpp Snap.h SoundActivatedRecord.cpp \ - SoundActivatedRecord.h Spectrum.cpp Spectrum.h \ - SplashDialog.cpp SplashDialog.h SseMathFuncs.cpp \ + Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \ + Screenshot.cpp Screenshot.h SelectedRegion.cpp \ + SelectedRegion.h Shuttle.cpp Shuttle.h ShuttleGui.cpp \ + ShuttleGui.h ShuttlePrefs.cpp ShuttlePrefs.h Snap.cpp Snap.h \ + SoundActivatedRecord.cpp SoundActivatedRecord.h Spectrum.cpp \ + Spectrum.h SplashDialog.cpp SplashDialog.h SseMathFuncs.cpp \ SseMathFuncs.h Tags.cpp Tags.h Theme.cpp Theme.h \ ThemeAsCeeCode.h TimeDialog.cpp TimeDialog.h \ TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \ @@ -546,7 +546,8 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \ audacity-Profiler.$(OBJEXT) audacity-Project.$(OBJEXT) \ audacity-RealFFTf.$(OBJEXT) audacity-RealFFTf48x.$(OBJEXT) \ audacity-Resample.$(OBJEXT) audacity-RingBuffer.$(OBJEXT) \ - audacity-Screenshot.$(OBJEXT) audacity-Shuttle.$(OBJEXT) \ + audacity-Screenshot.$(OBJEXT) \ + audacity-SelectedRegion.$(OBJEXT) audacity-Shuttle.$(OBJEXT) \ audacity-ShuttleGui.$(OBJEXT) audacity-ShuttlePrefs.$(OBJEXT) \ audacity-Snap.$(OBJEXT) \ audacity-SoundActivatedRecord.$(OBJEXT) \ @@ -1173,12 +1174,12 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h Resample.cpp \ - Resample.h RingBuffer.cpp RingBuffer.h Screenshot.cpp \ - Screenshot.h SelectedRegion.h Shuttle.cpp Shuttle.h \ - ShuttleGui.cpp ShuttleGui.h ShuttlePrefs.cpp ShuttlePrefs.h \ - Snap.cpp Snap.h SoundActivatedRecord.cpp \ - SoundActivatedRecord.h Spectrum.cpp Spectrum.h \ - SplashDialog.cpp SplashDialog.h SseMathFuncs.cpp \ + Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \ + Screenshot.cpp Screenshot.h SelectedRegion.cpp \ + SelectedRegion.h Shuttle.cpp Shuttle.h ShuttleGui.cpp \ + ShuttleGui.h ShuttlePrefs.cpp ShuttlePrefs.h Snap.cpp Snap.h \ + SoundActivatedRecord.cpp SoundActivatedRecord.h Spectrum.cpp \ + Spectrum.h SplashDialog.cpp SplashDialog.h SseMathFuncs.cpp \ SseMathFuncs.h Tags.cpp Tags.h Theme.cpp Theme.h \ ThemeAsCeeCode.h TimeDialog.cpp TimeDialog.h \ TimerRecordDialog.cpp TimerRecordDialog.h TimeTrack.cpp \ @@ -2029,6 +2030,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-RingBuffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-SampleFormat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Screenshot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-SelectedRegion.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Sequence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Shuttle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ShuttleGui.Po@am__quote@ @@ -3266,6 +3268,20 @@ audacity-Screenshot.obj: Screenshot.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-Screenshot.obj `if test -f 'Screenshot.cpp'; then $(CYGPATH_W) 'Screenshot.cpp'; else $(CYGPATH_W) '$(srcdir)/Screenshot.cpp'; fi` +audacity-SelectedRegion.o: SelectedRegion.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-SelectedRegion.o -MD -MP -MF $(DEPDIR)/audacity-SelectedRegion.Tpo -c -o audacity-SelectedRegion.o `test -f 'SelectedRegion.cpp' || echo '$(srcdir)/'`SelectedRegion.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-SelectedRegion.Tpo $(DEPDIR)/audacity-SelectedRegion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SelectedRegion.cpp' object='audacity-SelectedRegion.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-SelectedRegion.o `test -f 'SelectedRegion.cpp' || echo '$(srcdir)/'`SelectedRegion.cpp + +audacity-SelectedRegion.obj: SelectedRegion.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-SelectedRegion.obj -MD -MP -MF $(DEPDIR)/audacity-SelectedRegion.Tpo -c -o audacity-SelectedRegion.obj `if test -f 'SelectedRegion.cpp'; then $(CYGPATH_W) 'SelectedRegion.cpp'; else $(CYGPATH_W) '$(srcdir)/SelectedRegion.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-SelectedRegion.Tpo $(DEPDIR)/audacity-SelectedRegion.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='SelectedRegion.cpp' object='audacity-SelectedRegion.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-SelectedRegion.obj `if test -f 'SelectedRegion.cpp'; then $(CYGPATH_W) 'SelectedRegion.cpp'; else $(CYGPATH_W) '$(srcdir)/SelectedRegion.cpp'; fi` + audacity-Shuttle.o: Shuttle.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-Shuttle.o -MD -MP -MF $(DEPDIR)/audacity-Shuttle.Tpo -c -o audacity-Shuttle.o `test -f 'Shuttle.cpp' || echo '$(srcdir)/'`Shuttle.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-Shuttle.Tpo $(DEPDIR)/audacity-Shuttle.Po diff --git a/src/Menus.cpp b/src/Menus.cpp index 19dbebdfa..4fa931a30 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -1214,6 +1214,10 @@ void AudacityProject::CreateMenusAndCommands() AudioIOBusyFlag); c->AddCommand(wxT("PlayOneSec"), _("Play One Second"), FN(OnPlayOneSecond), wxT("1")); c->AddCommand(wxT("PlayToSelection"),_("Play To Selection"), FN(OnPlayToSelection), wxT("B")); + c->AddCommand(wxT("PlayBeforeSelectionStart"),_("Play Before Selection Start"), FN(OnPlayBeforeSelectionStart), wxT("Shift+F5")); + c->AddCommand(wxT("PlayAfterSelectionStart"),_("Play After Selection Start"), FN(OnPlayAfterSelectionStart), wxT("Shift+F6")); + c->AddCommand(wxT("PlayBeforeSelectionEnd"),_("Play Before Selection End"), FN(OnPlayBeforeSelectionEnd), wxT("Shift+F7")); + c->AddCommand(wxT("PlayAfterSelectionEnd"),_("Play After Selection End"), FN(OnPlayAfterSelectionEnd), wxT("Shift+F8")); c->AddCommand(wxT("PlayCutPreview"), _("Play Cut Preview"), FN(OnPlayCutPreview), wxT("C")); c->AddCommand(wxT("SelStart"), _("Selection to Start"), FN(OnSelToStart), wxT("Shift+Home")); @@ -2252,6 +2256,74 @@ void AudacityProject::OnPlayToSelection() GetControlToolBar()->PlayPlayRegion(t0, t1); } +// The next 4 functions provide a limited version of the +// functionality of OnPlayToSelection() for keyboard users + +void AudacityProject::OnPlayBeforeSelectionStart() +{ + if( !MakeReadyToPlay() ) + return; + + double t0 = mViewInfo.selectedRegion.t0(); + double beforeLen; + gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0); + + mLastPlayMode = oneSecondPlay; // this disables auto scrolling, as in OnPlayToSelection() + + GetControlToolBar()->PlayPlayRegion(t0 - beforeLen, t0); +} + +void AudacityProject::OnPlayAfterSelectionStart() +{ + if( !MakeReadyToPlay() ) + return; + + double t0 = mViewInfo.selectedRegion.t0(); + double t1 = mViewInfo.selectedRegion.t1(); + double afterLen; + gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0); + + mLastPlayMode = oneSecondPlay; // this disables auto scrolling, as in OnPlayToSelection() + + if ( t1 - t0 > 0.0 && t1 - t0 < afterLen ) + GetControlToolBar()->PlayPlayRegion(t0, t1); + else + GetControlToolBar()->PlayPlayRegion(t0, t0 + afterLen); +} + +void AudacityProject::OnPlayBeforeSelectionEnd() +{ + if( !MakeReadyToPlay() ) + return; + + double t0 = mViewInfo.selectedRegion.t0(); + double t1 = mViewInfo.selectedRegion.t1(); + double beforeLen; + gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 1.0); + + mLastPlayMode = oneSecondPlay; // this disables auto scrolling, as in OnPlayToSelection() + + if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen ) + GetControlToolBar()->PlayPlayRegion(t0, t1); + else + GetControlToolBar()->PlayPlayRegion(t1 - beforeLen, t1); +} + + +void AudacityProject::OnPlayAfterSelectionEnd() +{ + if( !MakeReadyToPlay() ) + return; + + double t1 = mViewInfo.selectedRegion.t1(); + double afterLen; + gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0); + + mLastPlayMode = oneSecondPlay; // this disables auto scrolling, as in OnPlayToSelection() + + GetControlToolBar()->PlayPlayRegion(t1, t1 + afterLen); +} + void AudacityProject::OnPlayLooped() { if( !MakeReadyToPlay(true) ) diff --git a/src/Menus.h b/src/Menus.h index b3d792410..c84ea9e9a 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -93,6 +93,10 @@ void OnPlayStop(); void OnPlayStopSelect(); void OnPlayOneSecond(); void OnPlayToSelection(); +void OnPlayBeforeSelectionStart(); +void OnPlayAfterSelectionStart(); +void OnPlayBeforeSelectionEnd(); +void OnPlayAfterSelectionEnd(); void OnPlayLooped(); void OnPlayCutPreview(); diff --git a/src/Project.cpp b/src/Project.cpp index 85d88e4f7..e7f08d2b3 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -741,6 +741,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample)), mSnapTo(gPrefs->Read(wxT("/SnapTo"), SNAP_OFF)), mSelectionFormat(gPrefs->Read(wxT("/SelectionFormat"), wxT(""))), + mFrequencySelectionFormatName(gPrefs->Read(wxT("/FrequencySelectionFormatName"), wxT(""))), + mBandwidthSelectionFormatName(gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT(""))), mDirty(false), mRuler(NULL), mTrackPanel(NULL), @@ -773,6 +775,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mLastEffectType(0), mTimerRecordCanceled(false), mMenuClose(false) + , mbInitializingScrollbar(false) { int widths[] = {-2, -1}; mStatusBar = CreateStatusBar(2); @@ -1253,16 +1256,16 @@ void AudacityProject::SSBL_SetFrequencySelectionFormatName(const wxString & form gPrefs->Flush(); } -const wxString & AudacityProject::SSBL_GetLogFrequencySelectionFormatName() +const wxString & AudacityProject::SSBL_GetBandwidthSelectionFormatName() { - return GetLogFrequencySelectionFormatName(); + return GetBandwidthSelectionFormatName(); } -void AudacityProject::SSBL_SetLogFrequencySelectionFormatName(const wxString & formatName) +void AudacityProject::SSBL_SetBandwidthSelectionFormatName(const wxString & formatName) { - mLogFrequencySelectionFormatName = formatName; + mBandwidthSelectionFormatName = formatName; - gPrefs->Write(wxT("/LogFrequencySelectionFormatName"), mLogFrequencySelectionFormatName); + gPrefs->Write(wxT("/BandwidthSelectionFormatName"), mBandwidthSelectionFormatName); gPrefs->Flush(); } @@ -1299,17 +1302,17 @@ void AudacityProject::SetFrequencySelectionFormatName(const wxString & formatNam #endif } -const wxString & AudacityProject::GetLogFrequencySelectionFormatName() const +const wxString & AudacityProject::GetBandwidthSelectionFormatName() const { - return mLogFrequencySelectionFormatName; + return mBandwidthSelectionFormatName; } -void AudacityProject::SetLogFrequencySelectionFormatName(const wxString & formatName) +void AudacityProject::SetBandwidthSelectionFormatName(const wxString & formatName) { - SSBL_SetLogFrequencySelectionFormatName(formatName); + SSBL_SetBandwidthSelectionFormatName(formatName); #ifdef EXPERIMENTAL_SPECTRAL_EDITING if (GetSpectralSelectionBar()) { - GetSpectralSelectionBar()->SetLogFrequencySelectionFormatName(formatName); + GetSpectralSelectionBar()->SetBandwidthSelectionFormatName(formatName); } #endif } @@ -1508,7 +1511,16 @@ void AudacityProject::FixScrollbars() mViewInfo.sbarH = (wxInt64) (mViewInfo.h * mViewInfo.zoom); int lastv = mViewInfo.vpos; - mViewInfo.vpos = mVsbar->GetThumbPosition() * mViewInfo.scrollStep; + // PRL: Can someone else find a more elegant solution to bug 812, than + // introducing this boolean member variable? + // Setting mVSbar earlier, int HandlXMLTag, didn't succeed in restoring + // the vertical scrollbar to its saved position. So defer that till now. + // mbInitializingScrollbar should be true only at the start of the life + // of an AudacityProject reopened from disk. + if (!mbInitializingScrollbar) { + mViewInfo.vpos = mVsbar->GetThumbPosition() * mViewInfo.scrollStep; + } + mbInitializingScrollbar = false; if (mViewInfo.vpos >= totalHeight) mViewInfo.vpos = totalHeight - 1; @@ -2808,6 +2820,7 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) wxString fileVersion = _(""); wxString audacityVersion = _(""); int requiredTags = 0; + long longVpos = 0; // loop through attrs, which is a null-terminated list of // attribute-value pairs @@ -2834,19 +2847,19 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) } } - if (!wxStrcmp(attr, wxT("version"))) + else if (!wxStrcmp(attr, wxT("version"))) { fileVersion = value; bFileVersionFound = true; requiredTags++; } - if (!wxStrcmp(attr, wxT("audacityversion"))) { + else if (!wxStrcmp(attr, wxT("audacityversion"))) { audacityVersion = value; requiredTags++; } - if (!wxStrcmp(attr, wxT("projname"))) { + else if (!wxStrcmp(attr, wxT("projname"))) { wxString projName; wxString projPath; @@ -2911,46 +2924,46 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs) requiredTags++; } - if (!wxStrcmp(attr, wxT("sel0"))) { - double t0; - Internat::CompatibleToDouble(value, &t0); - mViewInfo.selectedRegion.setT0(t0, false); + else if (mViewInfo.selectedRegion + .HandleXMLAttribute(attr, value, wxT("sel0"), wxT("sel1"))) { } - if (!wxStrcmp(attr, wxT("sel1"))) { - double t1; - Internat::CompatibleToDouble(value, &t1); - mViewInfo.selectedRegion.setT1(t1, false); - } - - // PRL: to do: persistence of other fields of the selection - - long longVpos = 0; - if (!wxStrcmp(attr, wxT("vpos"))) + else if (!wxStrcmp(attr, wxT("vpos"))) + // Just assign a variable, put the value in its place later wxString(value).ToLong(&longVpos); - mViewInfo.track = NULL; - mViewInfo.vpos = longVpos; - if (!wxStrcmp(attr, wxT("h"))) + else if (!wxStrcmp(attr, wxT("h"))) Internat::CompatibleToDouble(value, &mViewInfo.h); - if (!wxStrcmp(attr, wxT("zoom"))) + else if (!wxStrcmp(attr, wxT("zoom"))) Internat::CompatibleToDouble(value, &mViewInfo.zoom); - if (!wxStrcmp(attr, wxT("rate"))) { + else if (!wxStrcmp(attr, wxT("rate"))) { Internat::CompatibleToDouble(value, &mRate); GetSelectionBar()->SetRate(mRate); } - if (!wxStrcmp(attr, wxT("snapto"))) { + else if (!wxStrcmp(attr, wxT("snapto"))) { SetSnapTo(wxString(value) == wxT("on") ? true : false); } - if (!wxStrcmp(attr, wxT("selectionformat"))) { + else if (!wxStrcmp(attr, wxT("selectionformat"))) SetSelectionFormat(value); - } + + else if (!wxStrcmp(attr, wxT("frequencyformat"))) + SetFrequencySelectionFormatName(value); + + else if (!wxStrcmp(attr, wxT("bandwidthformat"))) + SetBandwidthSelectionFormatName(value); } // while + if (longVpos != 0) { + // PRL: It seems this must happen after SetSnapTo + mViewInfo.track = NULL; + mViewInfo.vpos = longVpos; + mbInitializingScrollbar = true; + } + // Specifically detect newer versions of Audacity // WARNING: This will need review/revision if we ever have a version string // such as 1.5.10, i.e. with 2 digit numbers. @@ -3117,8 +3130,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile) xmlFile.WriteAttr(wxT("projname"), projName); xmlFile.WriteAttr(wxT("version"), wxT(AUDACITY_FILE_FORMAT_VERSION)); xmlFile.WriteAttr(wxT("audacityversion"), AUDACITY_VERSION_STRING); - xmlFile.WriteAttr(wxT("sel0"), mViewInfo.selectedRegion.t0(), 10); - xmlFile.WriteAttr(wxT("sel1"), mViewInfo.selectedRegion.t1(), 10); + mViewInfo.selectedRegion + .WriteXMLAttributes(xmlFile, wxT("sel0"), wxT("sel1")); // PRL: to do: persistence of other fields of the selection xmlFile.WriteAttr(wxT("vpos"), mViewInfo.vpos); xmlFile.WriteAttr(wxT("h"), mViewInfo.h, 10); @@ -3126,6 +3139,8 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile) xmlFile.WriteAttr(wxT("rate"), mRate); xmlFile.WriteAttr(wxT("snapto"), GetSnapTo() ? wxT("on") : wxT("off")); xmlFile.WriteAttr(wxT("selectionformat"), GetSelectionFormat()); + xmlFile.WriteAttr(wxT("frequencyformat"), GetFrequencySelectionFormatName()); + xmlFile.WriteAttr(wxT("bandwidthformat"), GetBandwidthSelectionFormatName()); mTags->WriteXML(xmlFile); diff --git a/src/Project.h b/src/Project.h index e36d60671..8602644a7 100644 --- a/src/Project.h +++ b/src/Project.h @@ -110,10 +110,10 @@ enum PlayMode { class ImportXMLTagHandler : public XMLTagHandler { public: - ImportXMLTagHandler(AudacityProject* pProject) { mProject = pProject; }; + ImportXMLTagHandler(AudacityProject* pProject) { mProject = pProject; } virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs); - virtual XMLTagHandler *HandleXMLChild(const wxChar * WXUNUSED(tag)) { return NULL; }; + virtual XMLTagHandler *HandleXMLChild(const wxChar * WXUNUSED(tag)) { return NULL; } // Don't want a WriteXML method because ImportXMLTagHandler is not a WaveTrack. // tags are instead written by AudacityProject::WriteXML. @@ -135,7 +135,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, const wxPoint & pos, const wxSize & size); virtual ~AudacityProject(); - TrackList *GetTracks() { return mTracks; }; + TrackList *GetTracks() { return mTracks; } UndoManager *GetUndoManager() { return &mUndoManager; } sampleFormat GetDefaultFormat() { return mDefaultFormat; } @@ -221,7 +221,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, bool GetDirty() { return mDirty; } void SetProjectTitle(); - TrackPanel * GetTrackPanel(){return mTrackPanel;}; + TrackPanel * GetTrackPanel(){return mTrackPanel;} bool GetIsEmpty() { return mTracks->IsEmpty(); } @@ -327,8 +327,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, void SetFrequencySelectionFormatName(const wxString & format); const wxString & GetFrequencySelectionFormatName() const; - void SetLogFrequencySelectionFormatName(const wxString & format); - const wxString & GetLogFrequencySelectionFormatName() const; + void SetBandwidthSelectionFormatName(const wxString & format); + const wxString & GetBandwidthSelectionFormatName() const; // Scrollbars @@ -387,8 +387,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, Meter *GetCaptureMeter(); void SetCaptureMeter(Meter *capture); - LyricsWindow* GetLyricsWindow() { return mLyricsWindow; }; - MixerBoard* GetMixerBoard() { return mMixerBoard; }; + LyricsWindow* GetLyricsWindow() { return mLyricsWindow; } + MixerBoard* GetMixerBoard() { return mMixerBoard; } // SelectionBarListener callback methods @@ -407,8 +407,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, virtual const wxString & SSBL_GetFrequencySelectionFormatName(); virtual void SSBL_SetFrequencySelectionFormatName(const wxString & formatName); - virtual const wxString & SSBL_GetLogFrequencySelectionFormatName(); - virtual void SSBL_SetLogFrequencySelectionFormatName(const wxString & formatName); + virtual const wxString & SSBL_GetBandwidthSelectionFormatName(); + virtual void SSBL_SetBandwidthSelectionFormatName(const wxString & formatName); virtual void SSBL_ModifySpectralSelection(double &bottom, double &top, bool done); @@ -464,8 +464,8 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, static bool GetCacheBlockFiles(); public: - bool IsSoloSimple() { return mSoloPref == wxT("Simple"); }; - bool IsSoloNone() { return mSoloPref == wxT("None"); }; + bool IsSoloSimple() { return mSoloPref == wxT("Simple"); } + bool IsSoloNone() { return mSoloPref == wxT("None"); } private: @@ -488,7 +488,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, int mSnapTo; wxString mSelectionFormat; wxString mFrequencySelectionFormatName; - wxString mLogFrequencySelectionFormatName; + wxString mBandwidthSelectionFormatName; TrackList *mLastSavedTracks; @@ -618,7 +618,9 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, // Are we currently closing as the result of a menu command? bool mMenuClose; - DECLARE_EVENT_TABLE() + bool mbInitializingScrollbar; + + DECLARE_EVENT_TABLE() }; typedef void (AudacityProject::*audCommandFunction)(); diff --git a/src/RevisionIdent.h b/src/RevisionIdent.h new file mode 100644 index 000000000..a0bee9b61 --- /dev/null +++ b/src/RevisionIdent.h @@ -0,0 +1,28 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + Audacity(R) is copyright (c) 1999-2015 Audacity Team. + License: GPL v2. See License.txt. + + RevisionIdent.h + + +********************************************************************//*! + +\file RevisionIdent.h + + This entire file will be replaced by the revision identifier string + based on the branch SHA when the automated build system builds + Audacity. That striing will look something like: + + "7f2e839 of + Thu Apr 9 20:03:11 2015 +0100" + +*//********************************************************************/ + +// The string below is what you get if +// the build system does not replace this file. + +wxT("No revision identifier was provided") + diff --git a/src/SelectedRegion.cpp b/src/SelectedRegion.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/SelectedRegion.h b/src/SelectedRegion.h index 93af015bd..d1bc741de 100644 --- a/src/SelectedRegion.h +++ b/src/SelectedRegion.h @@ -28,6 +28,10 @@ #include "Audacity.h" #include "Experimental.h" +#include +#include +class XMLWriter; + class AUDACITY_DLL_API SelectedRegion { // Maintains the invariant: t1() >= t0() @@ -156,15 +160,31 @@ public: #ifdef EXPERIMENTAL_SPECTRAL_EDITING // Returns true iff the bounds got swapped - bool setF0(double f) { + bool setF0(double f, bool maySwap = true) { + if (f < 0) + f = UndefinedFrequency; mF0 = f; - return ensureFrequencyOrdering(); + if (maySwap) + return ensureFrequencyOrdering(); + else { + if (mF1 >= 0 && mF1 < mF0) + mF1 = mF0; + return false; + } } // Returns true iff the bounds got swapped - bool setF1(double f) { + bool setF1(double f, bool maySwap = true) { + if (f < 0) + f = UndefinedFrequency; mF1 = f; - return ensureFrequencyOrdering(); + if (maySwap) + return ensureFrequencyOrdering(); + else { + if (mF0 >= 0 && mF1 < mF0) + mF0 = mF1; + return false; + } } // Returns true iff the bounds got swapped @@ -176,6 +196,30 @@ public: } #endif + // Serialization: historically, selections were written to file + // in two places (project, and each label) but only as attributes + // in the tags, and different names were used in the two places. + // For compatibility, continue that, but possibly add attributes + // as SelectedRegion is extended. Therefore, this is not an + // XMLTagHandler. + + static const wxChar *sDefaultT0Name; + static const wxChar *sDefaultT1Name; + + // Serialize, not with tags of its own, but as attributes within a tag. + // Don't add more legacy arguments as the structure grows. + void WriteXMLAttributes + (XMLWriter &xmlFile, + const wxChar *legacyT0Name = sDefaultT0Name, + const wxChar *legacyT1Name = sDefaultT1Name) const; + + // Return true iff the attribute is recognized. + // Don't add more legacy arguments as the structure grows. + bool HandleXMLAttribute + (const wxChar *attr, const wxChar *value, + const wxChar *legacyT0Name = sDefaultT0Name, + const wxChar *legacyT1Name = sDefaultT1Name); + private: bool ensureOrdering() { diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 36f035bca..d24c40566 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1468,6 +1468,22 @@ void TrackPanel::MakeParentResize() mListener->TP_HandleResize(); } +void TrackPanel::HandleEscapeKey() +{ + switch (mMouseCapture) + { + case IsZooming: + case IsVZooming: + SetCapturedTrack(NULL, IsUncaptured); + if (HasCapture()) + ReleaseMouse(); + Refresh(false); + return; + default: + return; + } +} + void TrackPanel::HandleAltKey(bool down) { mLastMouseEvent.m_altDown = down; @@ -5963,6 +5979,11 @@ void TrackPanel::OnKeyDown(wxKeyEvent & event) { Track *t = GetFocusedTrack(); + if (event.GetKeyCode() == WXK_ESCAPE) { + HandleEscapeKey(); + return; + } + #ifdef EXPERIMENTAL_SPECTRAL_EDITING #ifdef SPECTRAL_EDITING_ESC_KEY // Test for pinning and unpinning of the center frequency @@ -6126,7 +6147,8 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event) if (event.ButtonDown()) { SetFocus(); - CaptureMouse(); + if (!HasCapture()) + CaptureMouse(); } else if (event.ButtonUp()) { if (HasCapture()) @@ -9815,3 +9837,69 @@ TrackPanel *(*TrackPanel::FactoryFunction)( TrackPanelListener * listener, AdornedRulerPanel * ruler) = TrackPanelFactory; + + + +/********************************************************************** + +Audacity: A Digital Audio Editor + +SelectedRegion.cpp + +Paul Licameli + +*******************************************************************/ + +#include "Internat.h" +#include "SelectedRegion.h" +#include "xml/XMLWriter.h" + +const wxChar *SelectedRegion::sDefaultT0Name = wxT("selStart"); +const wxChar *SelectedRegion::sDefaultT1Name = wxT("selEnd"); + +namespace { +const wxChar *sDefaultF0Name = wxT("selLow"); +const wxChar *sDefaultF1Name = wxT("selHigh"); +} + +void SelectedRegion::WriteXMLAttributes +(XMLWriter &xmlFile, +const wxChar *legacyT0Name, const wxChar *legacyT1Name) const +{ + xmlFile.WriteAttr(legacyT0Name, t0(), 10); + xmlFile.WriteAttr(legacyT1Name, t1(), 10); +#ifdef EXPERIMENTAL_SPECTRAL_EDITING + if (f0() >= 0) + xmlFile.WriteAttr(sDefaultF0Name, f0(), 10); + if (f1() >= 0) + xmlFile.WriteAttr(sDefaultF1Name, f1(), 10); +#endif +} + +bool SelectedRegion::HandleXMLAttribute +(const wxChar *attr, const wxChar *value, +const wxChar *legacyT0Name, const wxChar *legacyT1Name) +{ + typedef bool (SelectedRegion::*Setter)(double, bool); + Setter setter = 0; + if (!wxStrcmp(attr, legacyT0Name)) + setter = &SelectedRegion::setT0; + else if (!wxStrcmp(attr, legacyT1Name)) + setter = &SelectedRegion::setT1; +#ifdef EXPERIMENTAL_SPECTRAL_EDITING + else if (!wxStrcmp(attr, sDefaultF0Name)) + setter = &SelectedRegion::setF0; + else if (!wxStrcmp(attr, sDefaultF1Name)) + setter = &SelectedRegion::setF1; +#endif + else + return false; + + double dblValue; + if (!Internat::CompatibleToDouble(value, &dblValue)) + return false; + + // False means don't flip time or frequency boundaries + (void)(this->*setter)(dblValue, false); + return true; +} diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 7bd95b8fc..5c637d64c 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -208,6 +208,7 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel { //virtual void SetSelectionFormat(int iformat) //virtual void SetSnapTo(int snapto) + void HandleEscapeKey(); virtual void HandleAltKey(bool down); virtual void HandleShiftKey(bool down); virtual void HandleControlKey(bool down); diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 4e4d0c185..0543d08ec 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -26,6 +26,7 @@ drawing). Cache's the Spectrogram frequency samples. *//*******************************************************************/ #include +#include #include #include @@ -311,7 +312,7 @@ WaveClip::WaveClip(DirManager *projDirManager, sampleFormat format, int rate) mIsPlaceholder = false; } -WaveClip::WaveClip(WaveClip& orig, DirManager *projDirManager) +WaveClip::WaveClip(const WaveClip& orig, DirManager *projDirManager) { // essentially a copy constructor - but you must pass in the // current project's DirManager, because we might be copying @@ -1221,34 +1222,34 @@ bool WaveClip::CreateFromCopy(double t0, double t1, WaveClip* other) return true; } -bool WaveClip::Paste(double t0, WaveClip* other) +bool WaveClip::Paste(double t0, const WaveClip* other) { - WaveClip* pastedClip; + const bool clipNeedsResampling = other->mRate != mRate; + const bool clipNeedsNewFormat = + other->mSequence->GetSampleFormat() != mSequence->GetSampleFormat(); + std::auto_ptr newClip; + const WaveClip* pastedClip; - bool clipNeedsResampling = other->mRate != mRate; - - if (clipNeedsResampling) + if (clipNeedsResampling || clipNeedsNewFormat) { - // The other clip's rate is different to our's, so resample - pastedClip = new WaveClip(*other, mSequence->GetDirManager()); - if (!pastedClip->Resample(mRate)) - { - delete pastedClip; - return false; - } + newClip.reset(new WaveClip(*other, mSequence->GetDirManager())); + if (clipNeedsResampling) + // The other clip's rate is different from ours, so resample + if (!newClip->Resample(mRate)) + return false; + if (clipNeedsNewFormat) + // Force sample formats to match. + newClip->ConvertToSampleFormat(mSequence->GetSampleFormat()); + pastedClip = newClip.get(); } else { - // No resampling needed, just use original clip without making a copy + // No resampling or format change needed, just use original clip without making a copy pastedClip = other; } sampleCount s0; TimeToSamplesClip(t0, &s0); - // Force sample formats to match. - if (pastedClip->mSequence->GetSampleFormat() != mSequence->GetSampleFormat()) - pastedClip->ConvertToSampleFormat(mSequence->GetSampleFormat()); - bool result = false; if (mSequence->Paste(s0, pastedClip->mSequence)) { @@ -1270,12 +1271,6 @@ bool WaveClip::Paste(double t0, WaveClip* other) result = true; } - if (clipNeedsResampling) - { - // Clip was constructed as a copy, so delete it - delete pastedClip; - } - return result; } diff --git a/src/WaveClip.h b/src/WaveClip.h index 22c2c8383..6a296291e 100644 --- a/src/WaveClip.h +++ b/src/WaveClip.h @@ -69,7 +69,7 @@ private: WaveClip(const WaveClip&) { wxFAIL_MSG(wxT("It is an error to copy a WaveClip without specifying the DirManager.")); - }; + } WaveClip& operator=(const WaveClip& orig) { WaveClip bogus(orig); @@ -83,7 +83,7 @@ public: // essentially a copy constructor - but you must pass in the // current project's DirManager, because we might be copying // from one project to another - WaveClip(WaveClip& orig, DirManager *projDirManager); + WaveClip(const WaveClip& orig, DirManager *projDirManager); virtual ~WaveClip(); @@ -179,7 +179,7 @@ public: bool ClearAndAddCutLine(double t0, double t1); /// Paste data from other clip, resampling it if not equal rate - bool Paste(double t0, WaveClip* other); + bool Paste(double t0, const WaveClip* other); /** Insert silence - note that this is an efficient operation for large * amounts of silence */ @@ -232,8 +232,8 @@ public: SpecPxCache *mSpecPxCache; // AWD, Oct 2009: for pasting whitespace at the end of selection - bool GetIsPlaceholder() { return mIsPlaceholder; }; - void SetIsPlaceholder(bool val) { mIsPlaceholder = val; }; + bool GetIsPlaceholder() const { return mIsPlaceholder; } + void SetIsPlaceholder(bool val) { mIsPlaceholder = val; } protected: wxRect mDisplayRect; diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index 6cc29b7a0..07324e147 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -1734,7 +1734,7 @@ bool WaveTrack::GetRMS(float *rms, double t0, double t1) } } } - *rms = sqrt(sumsq/length); + *rms = length > 0.0 ? sqrt(sumsq / length) : 0.0; return result; } diff --git a/src/toolbars/SpectralSelectionBar.cpp b/src/toolbars/SpectralSelectionBar.cpp index b60d5f3d2..7ea5f3229 100644 --- a/src/toolbars/SpectralSelectionBar.cpp +++ b/src/toolbars/SpectralSelectionBar.cpp @@ -76,7 +76,7 @@ BEGIN_EVENT_TABLE(SpectralSelectionBar, ToolBar) EVT_TEXT(OnHighID, SpectralSelectionBar::OnCtrl) EVT_CHOICE(OnChoiceID, SpectralSelectionBar::OnChoice) EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, SpectralSelectionBar::OnUpdate) - EVT_COMMAND(wxID_ANY, EVT_LOGFREQUENCYTEXTCTRL_UPDATED, SpectralSelectionBar::OnUpdate) + EVT_COMMAND(wxID_ANY, EVT_BANDWIDTHTEXTCTRL_UPDATED, SpectralSelectionBar::OnUpdate) END_EVENT_TABLE() static const wxString preferencePath @@ -117,8 +117,8 @@ void SpectralSelectionBar::Populate() wxString frequencyFormatName = mListener ? mListener->SSBL_GetFrequencySelectionFormatName() : wxString(wxEmptyString); - wxString logFrequencyFormatName = mListener - ? mListener->SSBL_GetLogFrequencySelectionFormatName() + wxString bandwidthFormatName = mListener + ? mListener->SSBL_GetBandwidthSelectionFormatName() : wxString(wxEmptyString); wxFlexGridSizer *mainSizer = new wxFlexGridSizer(1, 1, 1); @@ -151,7 +151,7 @@ void SpectralSelectionBar::Populate() subSizer->Add(mCenterCtrl, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); mWidthCtrl = new NumericTextCtrl( - NumericConverter::LOG_FREQUENCY, this, OnWidthID, logFrequencyFormatName, 0.0); + NumericConverter::BANDWIDTH, this, OnWidthID, bandwidthFormatName, 0.0); mWidthCtrl->SetName(wxString(_("Bandwidth:"))); mWidthCtrl->EnableMenu(); subSizer->Add(mWidthCtrl, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 0); @@ -192,7 +192,7 @@ void SpectralSelectionBar::UpdatePrefs() if (mbCenterAndWidth) { - wxCommandEvent e(EVT_LOGFREQUENCYTEXTCTRL_UPDATED); + wxCommandEvent e(EVT_BANDWIDTHTEXTCTRL_UPDATED); e.SetInt(mWidthCtrl->GetFormatIndex()); OnUpdate(e); } @@ -208,7 +208,7 @@ void SpectralSelectionBar::SetListener(SpectralSelectionBarListener *l) { mListener = l; SetFrequencySelectionFormatName(mListener->SSBL_GetFrequencySelectionFormatName()); - SetLogFrequencySelectionFormatName(mListener->SSBL_GetLogFrequencySelectionFormatName()); + SetBandwidthSelectionFormatName(mListener->SSBL_GetBandwidthSelectionFormatName()); }; void SpectralSelectionBar::OnSize(wxSizeEvent &evt) @@ -312,9 +312,9 @@ void SpectralSelectionBar::OnUpdate(wxCommandEvent &evt) mListener->SSBL_SetFrequencySelectionFormatName(frequencyFormatName); } else if (mbCenterAndWidth && - type == EVT_LOGFREQUENCYTEXTCTRL_UPDATED) { - wxString logFrequencyFormatName = mWidthCtrl->GetBuiltinName(index); - mListener->SSBL_SetLogFrequencySelectionFormatName(logFrequencyFormatName); + type == EVT_BANDWIDTHTEXTCTRL_UPDATED) { + wxString bandwidthFormatName = mWidthCtrl->GetBuiltinName(index); + mListener->SSBL_SetBandwidthSelectionFormatName(bandwidthFormatName); } // ToolBar::ReCreateButtons() will get rid of our sizers and controls @@ -377,12 +377,12 @@ void SpectralSelectionBar::SetFrequencySelectionFormatName(const wxString & form OnUpdate(e); } -void SpectralSelectionBar::SetLogFrequencySelectionFormatName(const wxString & formatName) +void SpectralSelectionBar::SetBandwidthSelectionFormatName(const wxString & formatName) { if (mbCenterAndWidth) { mWidthCtrl->SetFormatName(formatName); - wxCommandEvent e(EVT_LOGFREQUENCYTEXTCTRL_UPDATED); + wxCommandEvent e(EVT_BANDWIDTHTEXTCTRL_UPDATED); e.SetInt(mWidthCtrl->GetFormatIndex()); OnUpdate(e); } diff --git a/src/toolbars/SpectralSelectionBar.h b/src/toolbars/SpectralSelectionBar.h index 2e1193a22..953d13045 100644 --- a/src/toolbars/SpectralSelectionBar.h +++ b/src/toolbars/SpectralSelectionBar.h @@ -43,7 +43,7 @@ public: void SetFrequencies(double bottom, double top); void SetFrequencySelectionFormatName(const wxString & formatName); - void SetLogFrequencySelectionFormatName(const wxString & formatName); + void SetBandwidthSelectionFormatName(const wxString & formatName); void SetListener(SpectralSelectionBarListener *l); private: diff --git a/src/toolbars/SpectralSelectionBarListener.h b/src/toolbars/SpectralSelectionBarListener.h index 0801c9074..852bdcfc3 100644 --- a/src/toolbars/SpectralSelectionBarListener.h +++ b/src/toolbars/SpectralSelectionBarListener.h @@ -14,22 +14,21 @@ #include "../Audacity.h" class wxString; -class SelectedRegion; class AUDACITY_DLL_API SpectralSelectionBarListener { public: - SpectralSelectionBarListener(){}; - virtual ~SpectralSelectionBarListener(){}; + SpectralSelectionBarListener(){} + virtual ~SpectralSelectionBarListener(){} virtual double SSBL_GetRate() const = 0; virtual const wxString & SSBL_GetFrequencySelectionFormatName() = 0; virtual void SSBL_SetFrequencySelectionFormatName(const wxString & formatName) = 0; - virtual const wxString & SSBL_GetLogFrequencySelectionFormatName() = 0; - virtual void SSBL_SetLogFrequencySelectionFormatName(const wxString & formatName) = 0; + virtual const wxString & SSBL_GetBandwidthSelectionFormatName() = 0; + virtual void SSBL_SetBandwidthSelectionFormatName(const wxString & formatName) = 0; virtual void SSBL_ModifySpectralSelection(double &bottom, double &top, bool done) = 0; }; diff --git a/src/widgets/NumericTextCtrl.cpp b/src/widgets/NumericTextCtrl.cpp index 509d1d823..2fe7530cb 100644 --- a/src/widgets/NumericTextCtrl.cpp +++ b/src/widgets/NumericTextCtrl.cpp @@ -486,7 +486,7 @@ const BuiltinFormatString FrequencyConverterFormats[] = { * array of string pairs for name of the format and the format string * needed to create that format output. This is used for the pop-up * list of formats to choose from in the control. */ -const BuiltinFormatString LogFrequencyConverterFormats[] = { +const BuiltinFormatString BandwidthConverterFormats[] = { { /* i18n-hint: Name of display format that shows log of frequency * in octaves */ @@ -546,10 +546,10 @@ NumericConverter::NumericConverter(Type type, mNBuiltins = sizeof(FrequencyConverterFormats) / sizeof (FrequencyConverterFormats[0]); break; - case LOG_FREQUENCY: - mBuiltinFormatStrings = LogFrequencyConverterFormats; - mNBuiltins = sizeof(LogFrequencyConverterFormats) / - sizeof (LogFrequencyConverterFormats[0]); + case BANDWIDTH: + mBuiltinFormatStrings = BandwidthConverterFormats; + mNBuiltins = sizeof(BandwidthConverterFormats) / + sizeof(BandwidthConverterFormats[0]); default: break; } @@ -1099,7 +1099,7 @@ void NumericConverter::Adjust(int steps, int dir) DEFINE_EVENT_TYPE(EVT_TIMETEXTCTRL_UPDATED) DEFINE_EVENT_TYPE(EVT_FREQUENCYTEXTCTRL_UPDATED) -DEFINE_EVENT_TYPE(EVT_LOGFREQUENCYTEXTCTRL_UPDATED) +DEFINE_EVENT_TYPE(EVT_BANDWIDTHTEXTCTRL_UPDATED) BEGIN_EVENT_TABLE(NumericTextCtrl, wxControl) EVT_ERASE_BACKGROUND(NumericTextCtrl::OnErase) @@ -1470,8 +1470,8 @@ void NumericTextCtrl::OnContext(wxContextMenuEvent &event) case NumericConverter::FREQUENCY: eventType = EVT_FREQUENCYTEXTCTRL_UPDATED; break; - case NumericConverter::LOG_FREQUENCY: - eventType = EVT_LOGFREQUENCYTEXTCTRL_UPDATED; + case NumericConverter::BANDWIDTH: + eventType = EVT_BANDWIDTHTEXTCTRL_UPDATED; break; default: wxASSERT(false); diff --git a/src/widgets/NumericTextCtrl.h b/src/widgets/NumericTextCtrl.h index 722ecc2a8..631042e01 100644 --- a/src/widgets/NumericTextCtrl.h +++ b/src/widgets/NumericTextCtrl.h @@ -32,7 +32,7 @@ // update their formats to agree. DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TIMETEXTCTRL_UPDATED, -1); DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_FREQUENCYTEXTCTRL_UPDATED, -1); -DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_LOGFREQUENCYTEXTCTRL_UPDATED, +DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_BANDWIDTHTEXTCTRL_UPDATED, -1); /** \brief struct to hold a formatting control string and it's user facing name @@ -53,7 +53,7 @@ public: enum Type { TIME, FREQUENCY, - LOG_FREQUENCY, + BANDWIDTH, }; NumericConverter(Type type, diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index 26d6ff45c..b58e7c107 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -293,6 +293,7 @@ + @@ -529,6 +530,8 @@ + + diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index f7e26c35c..5fc0f8aae 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -837,6 +837,9 @@ src + + src + @@ -1670,6 +1673,12 @@ src + + src + + + src + @@ -1684,15 +1693,6 @@ - - nyquist - - - nyquist - - - nyquist - @@ -1812,6 +1812,9 @@ nyquist + + +