... when there really is at least one new sample block committed to the table,
which is typically only once in about every six seconds, with the default rate
and sample format.
Also renamed a callback function more aptly, since blocks are not files any
more.
* Fix the reading of autosave files...
... problem was in recreating strings from buffers, but copying too many because
null terminators were lacking.
* Autosave during recording backs up all tracks correctly...
... whether to new track, or appending; and it doesn't lose the other tracks
besides the recording.
It is also unnecessary when just starting to record, so remove one call.
... 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.
Problem:
labelStruct, a copy of the label is initialized before call to RemoveSelectedText() which acts on the real label. So when the label is updated using labelStruct, the selected text has not been removed.
Fix:
Initialize labelStruct after the call to RemoveSelectedText().
It now uses VACUUM INTO instead of the SQLite backup API
in hopes that the copies will be smaller. And VACUUM INTO
is "supposed" to be faster, but time will tell. It's easy
to put the backup API usage back in.
This also fixes a bit I missed with redoing the orphan block
handling that was reported by Paul.
And finally, it renames the AutoRecovery.cpp/.h files and AutoSaveFile
class to ProjectSerializer since the AutoSaveFile class is being
used for regular project documents now and it doesn't write to a
file anymore.
If anyone has a better idea for a name other than ProjectSerializer
feel free to change it. I hate naming things.
Since size_t is different on 64-bit vs 32-bit Windows builds
it was causing assertions when displaying the results.
You can also change the sample format now by adjusting the
defines at the start of the source.
Problem:
On opening, the units were always LUFS, and the "treat stereo as dual-mono" check box was always available.
Fix:
On opening, adjust the controls which depend on the value of the Normalize choice.
... Problem is that the delayed undo handling (in the lambda in AudacityApp ::
OnExceptionInMainLoop) should itself have only non-throwing steps.
But there was a redundant attempt at autosaving in ProjectHistory ::
RollbackState, which itself requires another data base write.
But when "rolling back" the in-memory structures to whatever the current state
of undo history is, we can assume that any required autosave was completed
before the current state of undo history was set.
So for rollback only, do not autosave again when discarding changes and
restoring the state. (But do it still, throwing on failure, when moving around
in the undo history, among saved states. We do want to keep the last autosave
consistent with the in-memory state.)
* Need only CloseLock now, not old Lock and Unlock...
... which were for cross-project cut and paste, but they no longer work and we
need another solution. So delete much old code.
* Fix dangling reference to AudacityProject completely! ...
... in SqliteSampleBlockFactory: retain ONLY the shared pointer to
ProjectFileIO, then pass that, not project, to constructors of blocks.
completing the work of 127696879dcc5ca687ec50a4ccef7acbed563926
* Restore part of the Bug2436 fix...
... which needs the non-default arguments to WaveTrack::EmptyCopy that got lost
at d39590cf41e1e1eac02fc52d88a1ad018824f77b
So that pasted WaveTracks refer to the correct SampleBlockFactory and database
for their project
But this is not yet a sufficient re-fix for the bug
* Complete the fix for cross-project copies and 2436...
... by duplicating sample blocks, in Sequence.cpp, when it is wrong just to
share them.
And to determine which case it is, see whether source and destination Sequences
have the same sample block factories when doing Copy or Paste. Duplicate
when the factories are different. Otherwise sharing is safe and more space
efficient.
This does the analogous to what DirManager::CopyBlockFile did before commit
d39590c.
* ProjectFileIO::SaveProject() won't close original db until done...
... So on the failure path, don't risk closing the original too early, failing
with the new database, and then failing to reopen the original.
Just keep the original open and a new connection open too, until it is
certain that the initial population of the new database is successful.
* Check return value from AutoSaveDelete when saving-as
* Fix the remaining unchecked sqlite3_bind* calls, which are in Autosave...
...similarly to checks in 8b3f9fa
* When saving-as or -copy, open the new database only once
* Check return value from sqlite_initialize
... as std::mutex instead.
One is the mutex for the set of all files.
Another is in Profiler.h, which is now back into CMakeLists because the header
is included in one place. Maybe this utility will find more use again.
Restored one other but commented out, as not necessary now, but need might be
found to put it back again.
The class ODLock was a misnamed thing not specific to the on-demand manager but
used more widely as a thread synchronization utility, functioning as a mutex
object. It was a mistake to remove all uses of it along with the rest of the
on-demand system.
* Docs say: call sqlite3_close even when sqlite3_open returns error
* Be careful of possible failures of AutoSave...
... In ProjectHistory operations, do the AutoSave first and throw if there is
a failure.
Only then change UndoManager's state, confident that it remains consistent with
what was AutoSaved.
* Throw exceptions if lazy opening of project's database fails...
... because the calls to DB() as in Sqlite3SampleBlock may be in deeply nested
places that can't propagate the error codes; and besides, those functions
had been assuming non-null returns from DB(), which might have crashed before,
but now the assumption is correct when the throw didn't happen.
Note that this exception may also happen during attempted Autosave. Uses of
Autosave were reviewed and some changes made in the previous commit.
* Null checks on return from std::make_shared are unnecessary...
... instead std::bad_alloc would be thrown in case of memory exhaustion, which
we don't try to recover from.
* Restore uses of the mayThrow arguments in Sequence...
... that became unused at commit d39590cf41e1e1eac02fc52d88a1ad018824f77b.
It's important to ignore exceptions from SampleBlocks when only displaying, not
editing or playing, and just treat missing data as silence.
Pass the boolean into the SampleBlock routines. But the throwing of exceptions
is not yet implemented.
* SampleBlockFactory functions guaranteed to return non-null or throw...
... which corrects Sequence.cpp, which was assuming non-null results.
This supplies the throw statements that the previous commit comment says were
still lacking.
This corrects the absence of checks of returns from sql_bind_... function calls
in SqliteSampleBlock.cpp. (Other calls remain to be checked elsewhere.)
User visible error messages, carried by the exceptions, might be improved.
* Restore the try/catch in AutoSaveFile::Decode...
... which was introduced at 2ba17c78d6758c2f64f2ccfec9af0c537525cea4
but removed at d39590cf41e1e1eac02fc52d88a1ad018824f77b, yet without removing
the throw statement
which left the program vulnerable to abrupt termination instead of graceful
failure, when uninterpretable auto save contents are detected.
Problem:
Applying macro to project always sets first track as focus.
The problem was introduced by commit 06cddda, which accidentally declared cleanup2 in the wrong scope.
This meant that ProjectHistory::RollBackState() was always called, which eventually causes TrackPanel::OnUndoReset() to be called, which sets the first track to be the focus.
Fix:
Declare cleanup2 in the correct scope.
Preliminary tests show it to be a bit faster than the default
4KB. For a simple example, generate 2-hour chirp dropped from
11 seconds to 7 seconds. Not a lot, but...