This time it has the potential to produce much smaller
output files since it ONLY copies the active blocks and
not all of the blocks related to undo history. This is
done for "Save As" and "Backup Project". Normal save
can't take advantage of this, but then it really doesn't
need it as it has to depend on vacuuming.
The vacuuming at close has been adjusted to utilize CopyTo()
so it should produce similarly small files as long as the
vacuuming happens when the project is definitely closing.
This time it has the potential to produce much smaller
output files since it ONLY copies the active blocks and
not all of the blocks related to undo history.
Near as I can tell, it's pretty much done. Feeding all manner of
.aup projects will definitely need to be done. It would be best
to feed it REAL projects, not the contrived ones I've been playing
with.
... 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.