mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
Fix the reading of autosave files... (#610)
* 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.
This commit is contained in:
parent
06f22e942b
commit
cea658d9eb
@ -854,10 +854,8 @@ void ProjectAudioManager::OnAudioIORate(int rate)
|
|||||||
|
|
||||||
void ProjectAudioManager::OnAudioIOStartRecording()
|
void ProjectAudioManager::OnAudioIOStartRecording()
|
||||||
{
|
{
|
||||||
auto &projectFileIO = ProjectFileIO::Get( mProject );
|
// Auto-save was done here before, but it is unnecessary, provided there
|
||||||
// Before recording is started, auto-save the file. The file will have
|
// are sufficient autosaves when pushing or modifying undo states.
|
||||||
// empty tracks at the bottom where the recording will be put into
|
|
||||||
projectFileIO.AutoSave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called after recording has stopped and all tracks have flushed.
|
// This is called after recording has stopped and all tracks have flushed.
|
||||||
@ -931,7 +929,7 @@ void ProjectAudioManager::OnAudioIONewBlockFiles(const WaveTrackArray *tracks)
|
|||||||
{
|
{
|
||||||
auto &project = mProject;
|
auto &project = mProject;
|
||||||
auto &projectFileIO = ProjectFileIO::Get( project );
|
auto &projectFileIO = ProjectFileIO::Get( project );
|
||||||
projectFileIO.AutoSave(tracks);
|
projectFileIO.AutoSave(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectAudioManager::OnCommitRecording()
|
void ProjectAudioManager::OnCommitRecording()
|
||||||
|
@ -1059,7 +1059,7 @@ void ProjectFileIO::WriteXMLHeader(XMLWriter &xmlFile) const
|
|||||||
xmlFile.Write(wxT(">\n"));
|
xmlFile.Write(wxT(">\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFileIO::WriteXML(XMLWriter &xmlFile, const WaveTrackArray *tracks)
|
void ProjectFileIO::WriteXML(XMLWriter &xmlFile, bool recording)
|
||||||
// may throw
|
// may throw
|
||||||
{
|
{
|
||||||
auto pProject = mpProject.lock();
|
auto pProject = mpProject.lock();
|
||||||
@ -1092,31 +1092,36 @@ void ProjectFileIO::WriteXML(XMLWriter &xmlFile, const WaveTrackArray *tracks)
|
|||||||
tags.WriteXML(xmlFile);
|
tags.WriteXML(xmlFile);
|
||||||
|
|
||||||
unsigned int ndx = 0;
|
unsigned int ndx = 0;
|
||||||
if (tracks)
|
tracklist.Any().Visit([&](Track *t)
|
||||||
{
|
{
|
||||||
for (auto track : *tracks)
|
auto useTrack = t;
|
||||||
{
|
if ( recording ) {
|
||||||
track->WriteXML(xmlFile);
|
// When append-recording, there is a temporary "shadow" track accumulating
|
||||||
|
// changes and displayed on the screen but it is not yet part of the
|
||||||
|
// regular track list. That is the one that we want to back up.
|
||||||
|
// SubstitutePendingChangedTrack() fetches the shadow, if the track has
|
||||||
|
// one, else it gives the same track back.
|
||||||
|
useTrack = t->SubstitutePendingChangedTrack().get();
|
||||||
}
|
}
|
||||||
}
|
else if ( useTrack->GetId() == TrackId{} ) {
|
||||||
else
|
// This is a track added during a non-appending recording that is
|
||||||
{
|
// not yet in the undo history. The UndoManager skips backing it up
|
||||||
tracklist.Any().Visit([&](Track *t)
|
// when pushing. Don't auto-save it.
|
||||||
{
|
return;
|
||||||
t->WriteXML(xmlFile);
|
}
|
||||||
});
|
useTrack->WriteXML(xmlFile);
|
||||||
}
|
});
|
||||||
|
|
||||||
xmlFile.EndTag(wxT("project"));
|
xmlFile.EndTag(wxT("project"));
|
||||||
|
|
||||||
//TIMER_STOP( xml_writer_timer );
|
//TIMER_STOP( xml_writer_timer );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectFileIO::AutoSave(const WaveTrackArray *tracks)
|
bool ProjectFileIO::AutoSave(bool recording)
|
||||||
{
|
{
|
||||||
ProjectSerializer autosave;
|
ProjectSerializer autosave;
|
||||||
WriteXMLHeader(autosave);
|
WriteXMLHeader(autosave);
|
||||||
WriteXML(autosave, tracks);
|
WriteXML(autosave, recording);
|
||||||
|
|
||||||
if (WriteDoc("autosave", autosave))
|
if (WriteDoc("autosave", autosave))
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ public:
|
|||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool AutoSave(const WaveTrackArray *tracks = nullptr);
|
bool AutoSave(bool recording = false);
|
||||||
bool AutoSaveDelete(sqlite3 *db = nullptr);
|
bool AutoSaveDelete(sqlite3 *db = nullptr);
|
||||||
|
|
||||||
bool LoadProject(const FilePath &fileName);
|
bool LoadProject(const FilePath &fileName);
|
||||||
@ -81,7 +81,7 @@ public:
|
|||||||
|
|
||||||
XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
|
XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
|
||||||
void WriteXMLHeader(XMLWriter &xmlFile) const;
|
void WriteXMLHeader(XMLWriter &xmlFile) const;
|
||||||
void WriteXML(XMLWriter &xmlFile, const WaveTrackArray *tracks = nullptr) /* not override */;
|
void WriteXML(XMLWriter &xmlFile, bool recording = false) /* not override */;
|
||||||
|
|
||||||
wxLongLong GetFreeDiskSpace();
|
wxLongLong GetFreeDiskSpace();
|
||||||
|
|
||||||
|
@ -291,22 +291,27 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
|
|||||||
return iter->second;
|
return iter->second;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto Convert = [&mCharSize](char *in, int len) -> wxString
|
auto ReadString = [&mCharSize, &in, &bytes](int len) -> wxString
|
||||||
{
|
{
|
||||||
|
bytes.reserve( len + 4 );
|
||||||
|
auto data = bytes.data();
|
||||||
|
in.Read( data, len );
|
||||||
|
// Make a null terminator of the widest type
|
||||||
|
memset( data + len, '\0', 4 );
|
||||||
wxUString str;
|
wxUString str;
|
||||||
|
|
||||||
switch (mCharSize)
|
switch (mCharSize)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
str.assignFromUTF8(in, len);
|
str.assignFromUTF8(data, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
str.assignFromUTF16((wxChar16 *) in, len / 2);
|
str.assignFromUTF16((wxChar16 *) data, len / 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
str = wxU32CharBuffer::CreateNonOwned((wxChar32 *) in, len / 4);
|
str = wxU32CharBuffer::CreateNonOwned((wxChar32 *) data, len / 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -345,10 +350,7 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
|
|||||||
|
|
||||||
in.Read(&id, sizeof(id));
|
in.Read(&id, sizeof(id));
|
||||||
in.Read(&len, sizeof(len));
|
in.Read(&len, sizeof(len));
|
||||||
bytes.reserve(len);
|
mIds[id] = ReadString(len);
|
||||||
in.Read(bytes.data(), len);
|
|
||||||
|
|
||||||
mIds[id] = Convert(bytes.data(), len);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -374,10 +376,7 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
|
|||||||
|
|
||||||
in.Read(&id, sizeof(id));
|
in.Read(&id, sizeof(id));
|
||||||
in.Read(&len, sizeof(len));
|
in.Read(&len, sizeof(len));
|
||||||
bytes.reserve(len);
|
out.WriteAttr(Lookup(id), ReadString(len));
|
||||||
in.Read(bytes.data(), len);
|
|
||||||
|
|
||||||
out.WriteAttr(Lookup(id), Convert(bytes.data(), len));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -476,10 +475,7 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
in.Read(&len, sizeof(len));
|
in.Read(&len, sizeof(len));
|
||||||
bytes.reserve(len);
|
out.WriteData(ReadString(len));
|
||||||
in.Read(bytes.data(), len);
|
|
||||||
|
|
||||||
out.WriteData(Convert(bytes.data(), len));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -488,10 +484,7 @@ wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer, BlockIDs &block
|
|||||||
int len;
|
int len;
|
||||||
|
|
||||||
in.Read(&len, sizeof(len));
|
in.Read(&len, sizeof(len));
|
||||||
bytes.reserve(len);
|
out.Write(ReadString(len));
|
||||||
in.Read(bytes.data(), len);
|
|
||||||
|
|
||||||
out.Write(Convert(bytes.data(), len));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user