mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 16:19:43 +02:00
More exception-safety for recording...
... Do not call Autosave (which might fail) when recovering from exceptions in recording, but rely on the last good Autosave that happened during recording. If dropout labels are needed, then immediately modify the undo history item, but we can accept it if that modification fails. Also, be sure NOT to skip Autosave in all other places that push the undo history. Make Autosave the default unless otherwise specified. Finally removed one unnecessary call to Autosave.
This commit is contained in:
parent
975ee0cc07
commit
06f22e942b
@ -28,6 +28,7 @@ Paul Licameli split from ProjectManager.cpp
|
||||
#include "ProjectStatus.h"
|
||||
#include "TimeTrack.h"
|
||||
#include "TrackPanelAx.h"
|
||||
#include "UndoManager.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "WaveTrack.h"
|
||||
#include "toolbars/ToolManager.h"
|
||||
@ -870,38 +871,6 @@ void ProjectAudioManager::OnAudioIOStopRecording()
|
||||
// Only push state if we were capturing and not monitoring
|
||||
if (projectAudioIO.GetAudioIOToken() > 0)
|
||||
{
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto gAudioIO = AudioIO::Get();
|
||||
auto &intervals = gAudioIO->LostCaptureIntervals();
|
||||
if (intervals.size()) {
|
||||
// Make a track with labels for recording errors
|
||||
auto uTrack = TrackFactory::Get( project ).NewLabelTrack();
|
||||
auto pTrack = uTrack.get();
|
||||
tracks.Add( uTrack );
|
||||
/* i18n-hint: A name given to a track, appearing as its menu button.
|
||||
The translation should be short or else it will not display well.
|
||||
At most, about 11 Latin characters.
|
||||
Dropout is a loss of a short sequence of audio sample data from the
|
||||
recording */
|
||||
pTrack->SetName(_("Dropouts"));
|
||||
long counter = 1;
|
||||
for (auto &interval : intervals)
|
||||
pTrack->AddLabel(
|
||||
SelectedRegion{ interval.first,
|
||||
interval.first + interval.second },
|
||||
wxString::Format(wxT("%ld"), counter++));
|
||||
ShowWarningDialog(&window, wxT("DropoutDetected"), XO("\
|
||||
Recorded audio was lost at the labeled locations. Possible causes:\n\
|
||||
\n\
|
||||
Other applications are competing with Audacity for processor time\n\
|
||||
\n\
|
||||
You are saving directly to a slow external storage device\n\
|
||||
"
|
||||
),
|
||||
false,
|
||||
XXO("Turn off dropout detection"));
|
||||
}
|
||||
|
||||
auto &history = ProjectHistory::Get( project );
|
||||
|
||||
if (IsTimerRecordCancelled()) {
|
||||
@ -910,13 +879,52 @@ You are saving directly to a slow external storage device\n\
|
||||
// Reset timer record
|
||||
ResetTimerRecordCancelled();
|
||||
}
|
||||
else
|
||||
else {
|
||||
// Add to history
|
||||
history.PushState(XO("Recorded Audio"), XO("Record"));
|
||||
}
|
||||
// We want this to have NOFAIL-GUARANTEE if we get here from exception
|
||||
// handling of recording, and that means we rely on the last autosave
|
||||
// successully committed to the database, not risking a failure
|
||||
history.PushState(XO("Recorded Audio"), XO("Record"),
|
||||
UndoPush::NOAUTOSAVE);
|
||||
|
||||
// Now we auto-save again to get the project to a "normal" state again.
|
||||
projectFileIO.AutoSave();
|
||||
// Now, we may add a label track to give information about
|
||||
// dropouts. We allow failure of this.
|
||||
auto &tracks = TrackList::Get( project );
|
||||
auto gAudioIO = AudioIO::Get();
|
||||
auto &intervals = gAudioIO->LostCaptureIntervals();
|
||||
if (intervals.size()) {
|
||||
// Make a track with labels for recording errors
|
||||
auto uTrack = TrackFactory::Get( project ).NewLabelTrack();
|
||||
auto pTrack = uTrack.get();
|
||||
tracks.Add( uTrack );
|
||||
/* i18n-hint: A name given to a track, appearing as its menu button.
|
||||
The translation should be short or else it will not display well.
|
||||
At most, about 11 Latin characters.
|
||||
Dropout is a loss of a short sequence of audio sample data from the
|
||||
recording */
|
||||
pTrack->SetName(_("Dropouts"));
|
||||
long counter = 1;
|
||||
for (auto &interval : intervals)
|
||||
pTrack->AddLabel(
|
||||
SelectedRegion{ interval.first,
|
||||
interval.first + interval.second },
|
||||
wxString::Format(wxT("%ld"), counter++));
|
||||
|
||||
history.ModifyState( true ); // this might fail and throw
|
||||
|
||||
ShowWarningDialog(&window, wxT("DropoutDetected"), XO("\
|
||||
Recorded audio was lost at the labeled locations. Possible causes:\n\
|
||||
\n\
|
||||
Other applications are competing with Audacity for processor time\n\
|
||||
\n\
|
||||
You are saving directly to a slow external storage device\n\
|
||||
"
|
||||
),
|
||||
false,
|
||||
XXO("Turn off dropout detection"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectAudioManager::OnAudioIONewBlockFiles(const WaveTrackArray *tracks)
|
||||
|
@ -87,7 +87,7 @@ namespace {
|
||||
void ProjectHistory::PushState(
|
||||
const TranslatableString &desc, const TranslatableString &shortDesc)
|
||||
{
|
||||
PushState(desc, shortDesc, UndoPush::AUTOSAVE);
|
||||
PushState(desc, shortDesc, UndoPush::NONE);
|
||||
}
|
||||
|
||||
void ProjectHistory::PushState(const TranslatableString &desc,
|
||||
@ -96,7 +96,7 @@ void ProjectHistory::PushState(const TranslatableString &desc,
|
||||
{
|
||||
auto &project = mProject;
|
||||
auto &projectFileIO = ProjectFileIO::Get( project );
|
||||
if((flags & UndoPush::AUTOSAVE) != UndoPush::MINIMAL)
|
||||
if((flags & UndoPush::NOAUTOSAVE) == UndoPush::NONE)
|
||||
AutoSaveOrThrow( projectFileIO );
|
||||
|
||||
// remaining no-fail operations "commit" the changes of undo manager state
|
||||
|
@ -281,7 +281,7 @@ void UndoManager::PushState(const TrackList * l,
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ( ((flags & UndoPush::CONSOLIDATE) != UndoPush::MINIMAL) &&
|
||||
if ( (flags & UndoPush::CONSOLIDATE) != UndoPush::NONE &&
|
||||
// compare full translations not msgids!
|
||||
lastAction.Translation() == longDescription.Translation() &&
|
||||
mayConsolidate ) {
|
||||
|
@ -97,9 +97,9 @@ using SpaceArray = std::vector <unsigned long long> ;
|
||||
// Default is AUTOSAVE
|
||||
// Frequent/faster actions use CONSOLIDATE
|
||||
enum class UndoPush : unsigned char {
|
||||
MINIMAL = 0,
|
||||
NONE = 0,
|
||||
CONSOLIDATE = 1 << 0,
|
||||
AUTOSAVE = 1 << 1
|
||||
NOAUTOSAVE = 1 << 1
|
||||
};
|
||||
|
||||
inline UndoPush operator | (UndoPush a, UndoPush b)
|
||||
@ -126,7 +126,7 @@ class AUDACITY_DLL_API UndoManager final
|
||||
const std::shared_ptr<Tags> &tags,
|
||||
const TranslatableString &longDescription,
|
||||
const TranslatableString &shortDescription,
|
||||
UndoPush flags = UndoPush::AUTOSAVE);
|
||||
UndoPush flags = UndoPush::NONE);
|
||||
void ModifyState(const TrackList * l,
|
||||
const SelectedRegion &selectedRegion, const std::shared_ptr<Tags> &tags);
|
||||
void ClearStates();
|
||||
|
@ -168,7 +168,7 @@ void DoPanTracks(AudacityProject &project, float PanValue)
|
||||
for (auto left : count == 0 ? range : selectedRange )
|
||||
left->SetPan( PanValue );
|
||||
|
||||
auto flags = UndoPush::AUTOSAVE;
|
||||
auto flags = UndoPush::NONE;
|
||||
ProjectHistory::Get( project )
|
||||
/*i18n-hint: One or more audio tracks have been panned*/
|
||||
.PushState(XO("Panned audio track(s)"), XO("Pan Track"), flags);
|
||||
@ -799,7 +799,7 @@ void OnResample(const CommandContext &context)
|
||||
}
|
||||
|
||||
int ndx = 0;
|
||||
auto flags = UndoPush::AUTOSAVE;
|
||||
auto flags = UndoPush::NONE;
|
||||
for (auto wt : tracks.Selected< WaveTrack >())
|
||||
{
|
||||
auto msg = XO("Resampling track %d").Format( ++ndx );
|
||||
|
@ -261,7 +261,7 @@ UIHandle::Result StretchHandle::Release
|
||||
or present tense is fine here. If unsure, go for whichever is
|
||||
shorter.*/
|
||||
XO("Stretch"),
|
||||
UndoPush::CONSOLIDATE | UndoPush::AUTOSAVE);
|
||||
UndoPush::CONSOLIDATE);
|
||||
return RefreshAll;
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,7 @@ UIHandle::Result SampleHandle::Release
|
||||
mClickedTrack.reset(); //Set this to NULL so it will catch improper drag events.
|
||||
ProjectHistory::Get( *pProject ).PushState(XO("Moved Samples"),
|
||||
XO("Sample Edit"),
|
||||
UndoPush::CONSOLIDATE | UndoPush::AUTOSAVE);
|
||||
UndoPush::CONSOLIDATE);
|
||||
|
||||
// No change to draw since last drag
|
||||
return RefreshCode::RefreshNone;
|
||||
|
@ -837,7 +837,7 @@ UIHandle::Result TimeShiftHandle::Release
|
||||
consolidate = true;
|
||||
}
|
||||
ProjectHistory::Get( *pProject ).PushState(msg, XO("Time-Shift"),
|
||||
consolidate ? (UndoPush::CONSOLIDATE) : (UndoPush::AUTOSAVE));
|
||||
consolidate ? (UndoPush::CONSOLIDATE) : (UndoPush::NONE));
|
||||
|
||||
return result | FixScrollbars;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user