From b1beb20ae931d5f55f3617ef7e0acd2f12d4d1f3 Mon Sep 17 00:00:00 2001 From: Leland Lucius Date: Sun, 21 Jun 2020 18:53:54 -0500 Subject: [PATCH] AUP3: Remove obsolete audio file cache --- src/BlockFile.h | 9 -- src/DirManager.cpp | 94 ----------- src/DirManager.h | 8 - src/ProjectAudioManager.cpp | 5 +- src/ProjectFileManager.cpp | 7 - src/Sequence.cpp | 13 +- src/blockfile/SimpleBlockFile.cpp | 249 ++++-------------------------- src/blockfile/SimpleBlockFile.h | 24 +-- src/prefs/DirectoriesPrefs.cpp | 22 --- 9 files changed, 38 insertions(+), 393 deletions(-) diff --git a/src/BlockFile.h b/src/BlockFile.h index 9bfcde336..4eb5a5e58 100644 --- a/src/BlockFile.h +++ b/src/BlockFile.h @@ -77,15 +77,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ { // Other Properties - // Write cache to disk, if it has any - virtual bool GetNeedWriteCacheToDisk() { return false; } - virtual void WriteCacheToDisk() { /* no cache by default */ } - - // Fill read cache of block file, if it has any - virtual bool GetNeedFillCache() { return false; } - - virtual void FillCache() /* noexcept */ { /* no cache by default */ } - /// Stores a representation of this file in XML virtual void SaveXML(XMLWriter &xmlFile) = 0; diff --git a/src/DirManager.cpp b/src/DirManager.cpp index 05823f12b..4dc815828 100644 --- a/src/DirManager.cpp +++ b/src/DirManager.cpp @@ -1689,97 +1689,3 @@ void DirManager::RemoveOrphanBlockfiles() wxRemoveFile(orphan); } -void DirManager::FillBlockfilesCache() -{ -#ifdef DEPRECATED_AUDIO_CACHE - // See http://bugzilla.audacityteam.org/show_bug.cgi?id=545. - bool cacheBlockFiles = false; - gPrefs->Read(wxT("/Directories/CacheBlockFiles"), &cacheBlockFiles); - - if (!cacheBlockFiles) - return; // user opted not to cache block files - - int lowMem = gPrefs->Read(wxT("/Directories/CacheLowMem"), 16l); - if (lowMem < 16) { - lowMem = 16; - } - lowMem <<= 20; - - BlockHash::iterator iter; - int numNeed = 0; - - iter = mBlockFileHash.begin(); - while (iter != mBlockFileHash.end()) - { - BlockFilePtr b = iter->second.lock(); - if (b) { - if (b->GetNeedFillCache()) - numNeed++; - } - ++iter; - } - - if (numNeed == 0) - return; - - ProgressDialog progress(XO("Caching audio"), - XO("Caching audio into memory")); - - iter = mBlockFileHash.begin(); - int current = 0; - while (iter != mBlockFileHash.end()) - { - BlockFilePtr b = iter->second.lock(); - if (b) { - if (b->GetNeedFillCache() && (GetFreeMemory() > lowMem)) { - b->FillCache(); - } - - if (ProgressResult::Cancelled != progress.Update(current, numNeed)) - break; // user cancelled progress dialog, stop caching - current++; - } - ++iter; - } -#endif // DEPRECATED_AUDIO_CACHE -} - -void DirManager::WriteCacheToDisk() -{ - BlockHash::iterator iter; - int numNeed = 0; - - iter = mBlockFileHash.begin(); - while (iter != mBlockFileHash.end()) - { - BlockFilePtr b = iter->second.lock(); - if (b) { - if (b->GetNeedWriteCacheToDisk()) - numNeed++; - } - ++iter; - } - - if (numNeed == 0) - return; - - ProgressDialog progress(XO("Saving recorded audio"), - XO("Saving recorded audio to disk")); - - iter = mBlockFileHash.begin(); - int current = 0; - while (iter != mBlockFileHash.end()) - { - BlockFilePtr b = iter->second.lock(); - if (b) { - if (b->GetNeedWriteCacheToDisk()) - { - b->WriteCacheToDisk(); - progress.Update(current, numNeed); - } - current++; - } - ++iter; - } -} - diff --git a/src/DirManager.h b/src/DirManager.h index c0226677a..9034dc536 100644 --- a/src/DirManager.h +++ b/src/DirManager.h @@ -226,14 +226,6 @@ class PROFILE_DLL_API DirManager final // auto recovery is cancelled and should be retried later static void SetDontDeleteTempFiles() { dontDeleteTempFiles = true; } - // Write all write-cached block files to disc, if any - void WriteCacheToDisk(); - - // (Try to) fill cache of blockfiles, if caching is enabled (otherwise do - // nothing) - // A no-fail operation that does not throw - void FillBlockfilesCache(); - private: wxFileNameWrapper MakeBlockFileName(); diff --git a/src/ProjectAudioManager.cpp b/src/ProjectAudioManager.cpp index e96070c01..065659af4 100644 --- a/src/ProjectAudioManager.cpp +++ b/src/ProjectAudioManager.cpp @@ -916,9 +916,6 @@ You are saving directly to a slow external storage device\n\ history.PushState(XO("Recorded Audio"), XO("Record")); } - // Write all cached files to disk, if any - dirManager.WriteCacheToDisk(); - // Now we auto-save again to get the project to a "normal" state again. projectFileIO.AutoSave(); } @@ -1170,4 +1167,4 @@ GetPropertiesOfSelected(const AudacityProject &proj) result.rateOfSelected = rateOfSelection; return result; -} \ No newline at end of file +} diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 814470819..bbef85b29 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -1284,11 +1284,6 @@ void ProjectFileManager::OpenFile(const FilePath &fileNameArg, bool addtohistory bool closed = false; auto cleanup = finally( [&] { if (! closed ) { - if ( bParseSuccess ) { - // This is a no-fail: - dirManager.FillBlockfilesCache(); - } - // For an unknown reason, OSX requires that the project window be // raised if a recovery took place. window.CallAfter( [&] { window.Raise(); } ); @@ -1567,7 +1562,5 @@ bool ProjectFileManager::Import( } } - // This is a no-fail: - dirManager.FillBlockfilesCache(); return true; } diff --git a/src/Sequence.cpp b/src/Sequence.cpp index 6552e5af8..abe4c2fa3 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -460,12 +460,11 @@ namespace { BlockFilePtr NewSimpleBlockFile( DirManager &dm, samplePtr sampleData, size_t sampleLen, - sampleFormat format, - bool allowDeferredWrite = false) + sampleFormat format) { return dm.NewBlockFile( [&]( wxFileNameWrapper filePath ) { return make_blockfile( - std::move(filePath), sampleData, sampleLen, format, allowDeferredWrite); + std::move(filePath), sampleData, sampleLen, format); } ); } } @@ -1555,9 +1554,7 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, SeqBlock newLastBlock( NewSimpleBlockFile( *mDirManager, - buffer2.ptr(), newLastBlockLen, mSampleFormat, - blockFileLog != NULL - ), + buffer2.ptr(), newLastBlockLen, mSampleFormat), lastBlock.start ); @@ -1581,12 +1578,12 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, BlockFilePtr pFile; if (format == mSampleFormat) { pFile = NewSimpleBlockFile( *mDirManager, - buffer, addedLen, mSampleFormat, blockFileLog != NULL); + buffer, addedLen, mSampleFormat); } else { CopySamples(buffer, format, buffer2.ptr(), mSampleFormat, addedLen); pFile = NewSimpleBlockFile( *mDirManager, - buffer2.ptr(), addedLen, mSampleFormat, blockFileLog != NULL); + buffer2.ptr(), addedLen, mSampleFormat); } if (blockFileLog) diff --git a/src/blockfile/SimpleBlockFile.cpp b/src/blockfile/SimpleBlockFile.cpp index 78dde9eed..0eb82a95a 100644 --- a/src/blockfile/SimpleBlockFile.cpp +++ b/src/blockfile/SimpleBlockFile.cpp @@ -26,28 +26,6 @@ supply data and have the constructor write the file. The other is for when the file already exists and we simply want to create the data structure to refer to it. -The block file can be cached in two ways. Caching is enabled if the -preference "/Directories/CacheBlockFiles" is set, otherwise disabled. The -default is to disable caching. - -* Read-caching: If caching is enabled, all block files will always be - read-cached. Block files on disk will be read as soon as they are created - and held in memory. New block files will be written to disk, but held in - memory, so they are never read from disk in the current session. - -* Write-caching: If caching is enabled and the parameter allowDeferredWrite - is enabled at the block file constructor, NEW block files are held in memory - and written to disk only when WriteCacheToDisk() is called. This is used - during recording to prevent disk access. After recording, WriteCacheToDisk() - will be called on all block files and they will be written to disk. During - normal editing, no write cache is active, that is, any block files will be - written to disk instantly. - - Even with write cache, auto recovery during normal editing will work as - expected. However, auto recovery during recording will not work (not even - manual auto recovery, because the files are never written physically to - disk). - *//****************************************************************//** \class auHeader @@ -98,9 +76,7 @@ static wxUint32 SwapUintEndianess(wxUint32 in) /// @param allowDeferredWrite Allow deferred write-caching SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName, samplePtr sampleData, size_t sampleLen, - sampleFormat format, - bool allowDeferredWrite /* = false */, - bool bypassCache /* = false */): + sampleFormat format): BlockFile { (baseFileName.SetExt(wxT("au")), std::move(baseFileName)), sampleLen @@ -108,33 +84,10 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName, { mFormat = format; - mCache.active = false; - - bool useCache = GetCache() && (!bypassCache); - - if (!(allowDeferredWrite && useCache) && !bypassCache) - { - bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL); - if (!bSuccess) - throw FileException{ - FileException::Cause::Write, GetFileName().name }; - } - - if (useCache) { - //wxLogDebug("SimpleBlockFile::SimpleBlockFile(): Caching block file data."); - mCache.active = true; - mCache.needWrite = true; - mCache.format = format; - const auto sampleDataSize = sampleLen * SAMPLE_SIZE(format); - mCache.sampleData.reinit(sampleDataSize); - memcpy(mCache.sampleData.get(), sampleData, sampleDataSize); - ArrayOf cleanup; - void* summaryData = BlockFile::CalcSummary(sampleData, sampleLen, - format, cleanup); - mCache.summaryData.reinit(mSummaryInfo.totalSummaryBytes); - memcpy(mCache.summaryData.get(), summaryData, - mSummaryInfo.totalSummaryBytes); - } + bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL); + if (!bSuccess) + throw FileException{ + FileException::Cause::Write, GetFileName().name }; } /// Construct a SimpleBlockFile memory structure that will point to an @@ -151,8 +104,6 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&existingFile, size_t len, mMin = min; mMax = max; mRMS = rms; - - mCache.active = false; } SimpleBlockFile::~SimpleBlockFile() @@ -268,74 +219,6 @@ bool SimpleBlockFile::WriteSimpleBlockFile( return true; } -// This function should try to fill the cache, but just return without effect -// (not throwing) if there is failure. -void SimpleBlockFile::FillCache() -{ - if (mCache.active) - return; // cache is already filled - - // Check sample format - wxFFile file(mFileName.GetFullPath(), wxT("rb")); - if (!file.IsOpened()) - { - // Don't read into cache if file not available - return; - } - - auHeader header; - - if (file.Read(&header, sizeof(header)) != sizeof(header)) - { - // Corrupt file - return; - } - - wxUint32 encoding; - - if (header.magic == 0x2e736e64) - encoding = header.encoding; // correct endianness - else - encoding = SwapUintEndianess(header.encoding); - - switch (encoding) - { - case AU_SAMPLE_FORMAT_16: - mCache.format = int16Sample; - break; - case AU_SAMPLE_FORMAT_24: - mCache.format = int24Sample; - break; - default: - // floatSample is a safe default (we will never loose data) - mCache.format = floatSample; - break; - } - - file.Close(); - - // Read samples into cache - mCache.sampleData.reinit(mLen * SAMPLE_SIZE(mCache.format)); - if (ReadData(mCache.sampleData.get(), mCache.format, 0, mLen, - // no exceptions! - false) != mLen) - { - // Could not read all samples - mCache.sampleData.reset(); - return; - } - - // Read summary data into cache - // Fills with zeroes in case of failure: - ReadSummary(mCache.summaryData); - - // Cache is active but already on disk - mCache.active = true; - mCache.needWrite = false; - - //wxLogDebug("SimpleBlockFile::FillCache(): Successfully read simple block file into cache."); -} - /// Read the summary section of the disk file. /// /// @param *data The buffer to write the data to. It must be at least @@ -343,43 +226,35 @@ void SimpleBlockFile::FillCache() bool SimpleBlockFile::ReadSummary(ArrayOf &data) { data.reinit( mSummaryInfo.totalSummaryBytes ); - if (mCache.active) { - //wxLogDebug("SimpleBlockFile::ReadSummary(): Summary is already in cache."); - memcpy(data.get(), mCache.summaryData.get(), mSummaryInfo.totalSummaryBytes); - return true; - } - else + //wxLogDebug("SimpleBlockFile::ReadSummary(): Reading summary from disk."); + + wxFFile file(mFileName.GetFullPath(), wxT("rb")); + { - //wxLogDebug("SimpleBlockFile::ReadSummary(): Reading summary from disk."); - - wxFFile file(mFileName.GetFullPath(), wxT("rb")); - - { - Optional silence{}; - if (mSilentLog) - silence.emplace(); - // FIXME: TRAP_ERR no report to user of absent summary files? - // filled with zero instead. - if (!file.IsOpened()){ - memset(data.get(), 0, mSummaryInfo.totalSummaryBytes); - mSilentLog = TRUE; - return false; - } - } - mSilentLog = FALSE; - - // The offset is just past the au header - if( !file.Seek(sizeof(auHeader)) || - file.Read(data.get(), mSummaryInfo.totalSummaryBytes) != - mSummaryInfo.totalSummaryBytes ) { + Optional silence{}; + if (mSilentLog) + silence.emplace(); + // FIXME: TRAP_ERR no report to user of absent summary files? + // filled with zero instead. + if (!file.IsOpened()){ memset(data.get(), 0, mSummaryInfo.totalSummaryBytes); + mSilentLog = TRUE; return false; } - - FixSummary(data.get()); - - return true; } + mSilentLog = FALSE; + + // The offset is just past the au header + if( !file.Seek(sizeof(auHeader)) || + file.Read(data.get(), mSummaryInfo.totalSummaryBytes) != + mSummaryInfo.totalSummaryBytes ) { + memset(data.get(), 0, mSummaryInfo.totalSummaryBytes); + return false; + } + + FixSummary(data.get()); + + return true; } /// Read the data portion of the block file using libsndfile. Convert it @@ -392,28 +267,8 @@ bool SimpleBlockFile::ReadSummary(ArrayOf &data) size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format, size_t start, size_t len, bool mayThrow) const { - if (mCache.active) - { - //wxLogDebug("SimpleBlockFile::ReadData(): Data are already in cache."); - - auto framesRead = std::min(len, std::max(start, mLen) - start); - CopySamples( - (samplePtr)(mCache.sampleData.get() + - start * SAMPLE_SIZE(mCache.format)), - mCache.format, data, format, framesRead); - - if ( framesRead < len ) { - if (mayThrow) - // Not the best exception class? - throw FileException{ FileException::Cause::Read, mFileName }; - ClearSamples(data, format, framesRead, len - framesRead); - } - - return framesRead; - } - else - return CommonReadData( mayThrow, - mFileName, mSilentLog, nullptr, 0, 0, data, format, start, len); + return CommonReadData( mayThrow, + mFileName, mSilentLog, nullptr, 0, 0, data, format, start, len); } void SimpleBlockFile::SaveXML(XMLWriter &xmlFile) @@ -491,12 +346,6 @@ BlockFilePtr SimpleBlockFile::Copy(wxFileNameWrapper &&newFileName) auto SimpleBlockFile::GetSpaceUsage() const -> DiskByteCount { - if (mCache.active && mCache.needWrite) - { - // We don't know space usage yet - return 0; - } - // Don't know the format, so it must be read from the file if (mFormat == (sampleFormat) 0) { @@ -504,7 +353,6 @@ auto SimpleBlockFile::GetSpaceUsage() const -> DiskByteCount wxFFile file(mFileName.GetFullPath(), wxT("rb")); if (!file.IsOpened()) { - // Don't read into cache if file not available return 0; } @@ -575,41 +423,6 @@ void SimpleBlockFile::Recover(){ } -void SimpleBlockFile::WriteCacheToDisk() -{ - if (!GetNeedWriteCacheToDisk()) - return; - - if (WriteSimpleBlockFile(mCache.sampleData.get(), mLen, mCache.format, - mCache.summaryData.get())) - mCache.needWrite = false; -} - -bool SimpleBlockFile::GetNeedWriteCacheToDisk() -{ - return mCache.active && mCache.needWrite; -} - -bool SimpleBlockFile::GetCache() -{ -#ifdef DEPRECATED_AUDIO_CACHE - // See http://bugzilla.audacityteam.org/show_bug.cgi?id=545. - bool cacheBlockFiles = false; - gPrefs->Read(wxT("/Directories/CacheBlockFiles"), &cacheBlockFiles); - if (!cacheBlockFiles) - return false; - - int lowMem = gPrefs->Read(wxT("/Directories/CacheLowMem"), 16l); - if (lowMem < 16) { - lowMem = 16; - } - lowMem <<= 20; - return (GetFreeMemory() > lowMem); -#else - return false; -#endif -} - static DirManager::RegisteredBlockFileDeserializer sRegistration { "simpleblockfile", []( DirManager &dm, const wxChar **attrs ){ diff --git a/src/blockfile/SimpleBlockFile.h b/src/blockfile/SimpleBlockFile.h index 505b9f21e..935277efc 100644 --- a/src/blockfile/SimpleBlockFile.h +++ b/src/blockfile/SimpleBlockFile.h @@ -15,15 +15,6 @@ class DirManager; -struct SimpleBlockFileCache { - bool active; - bool needWrite; - sampleFormat format; - ArrayOf sampleData, summaryData; - - SimpleBlockFileCache() {} -}; - // The AU formats we care about enum { AU_SAMPLE_FORMAT_16 = 3, @@ -48,9 +39,7 @@ class PROFILE_DLL_API SimpleBlockFile /* not final */ : public BlockFile { /// Create a disk file and write summary and sample data to it SimpleBlockFile(wxFileNameWrapper &&baseFileName, samplePtr sampleData, size_t sampleLen, - sampleFormat format, - bool allowDeferredWrite = false, - bool bypassCache = false ); + sampleFormat format); /// Create the memory structure to refer to the given block file SimpleBlockFile(wxFileNameWrapper &&existingFile, size_t len, float min, float max, float rms); @@ -75,21 +64,10 @@ class PROFILE_DLL_API SimpleBlockFile /* not final */ : public BlockFile { static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs); - bool GetNeedWriteCacheToDisk() override; - void WriteCacheToDisk() override; - - bool GetNeedFillCache() override { return !mCache.active; } - - void FillCache() /* noexcept */ override; - protected: bool WriteSimpleBlockFile(samplePtr sampleData, size_t sampleLen, sampleFormat format, void* summaryData); - static bool GetCache(); - void ReadIntoCache(); - - SimpleBlockFileCache mCache; private: mutable sampleFormat mFormat; // may be found lazily diff --git a/src/prefs/DirectoriesPrefs.cpp b/src/prefs/DirectoriesPrefs.cpp index 34ee1c10f..da7cc4224 100644 --- a/src/prefs/DirectoriesPrefs.cpp +++ b/src/prefs/DirectoriesPrefs.cpp @@ -120,28 +120,6 @@ void DirectoriesPrefs::PopulateOrExchange(ShuttleGui & S) } S.EndStatic(); -#ifdef DEPRECATED_AUDIO_CACHE - // See http://bugzilla.audacityteam.org/show_bug.cgi?id=545. - S.StartStatic(XO("Audio cache")); - { - S.TieCheckBox(XO("Play and/or record using &RAM (useful for slow drives)"), - wxT("/Directories/CacheBlockFiles"), - false); - - S.StartTwoColumn(); - { - S.TieIntegerTextBox(XO("Mi&nimum Free Memory (MB):"), - {wxT("/Directories/CacheLowMem"), 16}, - 9); - } - S.EndTwoColumn(); - - S.AddVariableText(XO( -"If the available system memory falls below this value, audio will no longer\nbe cached in memory and will be written to disk."), - false, 0, 600); - } - S.EndStatic(); -#endif // DEPRECATED_AUDIO_CACHE S.EndScroller(); }