1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-05 14:18:53 +02:00

Manage block files with std::shared_ptr, BlockHash stores weak_ptr

This commit is contained in:
Paul Licameli 2016-08-16 12:30:18 -04:00
commit 3dfed7a79a
28 changed files with 390 additions and 406 deletions

View File

@ -338,7 +338,7 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag,
BlockArray array;
array.resize(1);
dirManager->SetLoadingTarget(&array, 0);
BlockFile *& blockFile = array[0].f;
auto &blockFile = array[0].f;
if (!dirManager->HandleXMLTag(tag, attrs) || !blockFile)
{

View File

@ -101,7 +101,6 @@ ArrayOf<char> BlockFile::fullSummary;
/// @param samples The number of samples this BlockFile contains.
BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
mLockCount(0),
mRefCount(1),
mFileName(std::move(fileName)),
mLen(samples),
mSummaryInfo(samples)
@ -109,10 +108,15 @@ BlockFile::BlockFile(wxFileNameWrapper &&fileName, sampleCount samples):
mSilentLog=FALSE;
}
// static
unsigned long BlockFile::gBlockFileDestructionCount { 0 };
BlockFile::~BlockFile()
{
if (!IsLocked() && mFileName.HasName())
wxRemoveFile(mFileName.GetFullPath());
++gBlockFileDestructionCount;
}
/// Returns the file name of the disk file associated with this
@ -160,28 +164,6 @@ bool BlockFile::IsLocked()
return mLockCount > 0;
}
/// Increases the reference count of this block by one. Only
/// DirManager should call this method.
void BlockFile::Ref() const
{
mRefCount++;
BLOCKFILE_DEBUG_OUTPUT("Ref", mRefCount);
}
/// Decreases the reference count of this block by one. If this
/// causes the count to become zero, deletes the associated disk
/// file and deletes this object
bool BlockFile::Deref() const
{
mRefCount--;
BLOCKFILE_DEBUG_OUTPUT("Deref", mRefCount);
if (mRefCount <= 0) {
delete this;
return true;
} else
return false;
}
/// Get a buffer containing a summary block describing this sample
/// data. This must be called by derived classes when they
/// are constructed, to allow them to construct their summary data,

View File

@ -43,6 +43,15 @@ class SummaryInfo {
class BlockFile;
using BlockFilePtr = std::shared_ptr<BlockFile>;
template< typename Result, typename... Args >
inline std::shared_ptr< Result > make_blockfile (Args && ... args)
{
return std::make_shared< Result > ( std::forward< Args > ( args )... );
}
class PROFILE_DLL_API BlockFile /* not final, abstract */ {
public:
@ -52,6 +61,8 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
BlockFile(wxFileNameWrapper &&fileName, sampleCount samples);
virtual ~BlockFile();
static unsigned long gBlockFileDestructionCount;
// Reading
/// Retrieves audio data from this BlockFile
@ -127,7 +138,7 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
virtual bool IsSummaryBeingComputed(){return false;}
/// Create a NEW BlockFile identical to this, using the given filename
virtual BlockFile * Copy(wxFileNameWrapper &&newFileName) = 0;
virtual BlockFilePtr Copy(wxFileNameWrapper &&newFileName) = 0;
virtual wxLongLong GetSpaceUsage() const = 0;
@ -154,17 +165,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
private:
friend class DirManager;
friend class AudacityApp;
//needed for Ref/Deref access.
friend class ODComputeSummaryTask;
friend class ODDecodeTask;
friend class ODPCMAliasBlockFile;
virtual void Ref() const;
virtual bool Deref() const;
virtual int RefCount(){return mRefCount;}
protected:
/// Calculate summary data for the given sample data
/// Overrides have differing details of memory management
@ -185,7 +185,6 @@ class PROFILE_DLL_API BlockFile /* not final, abstract */ {
private:
int mLockCount;
mutable int mRefCount;
static ArrayOf<char> fullSummary;

View File

@ -45,9 +45,10 @@
WX_DECLARE_HASH_MAP(wxString, AliasedFile *,
wxStringHash, wxStringEqual, AliasedFileHash);
WX_DECLARE_HASH_MAP(BlockFile *, BlockFile *,
// These two hash types are used only inside short scopes
// so it is safe to key them by plain pointers.
WX_DECLARE_HASH_MAP(BlockFile *, BlockFilePtr,
wxPointerHash, wxPointerEqual, ReplacedBlockFileHash);
WX_DECLARE_HASH_MAP(BlockFile *, bool,
wxPointerHash, wxPointerEqual, BoolBlockFileHash);
@ -89,14 +90,11 @@ static void ReplaceBlockFiles(AudacityProject *project,
int i;
for (i = 0; i < (int)blocks.size(); i++) {
if (hash.count(blocks[i]->f) > 0) {
BlockFile *src = blocks[i]->f;
BlockFile *dst = hash[src];
dirManager->Deref(src);
dirManager->Ref(dst);
blocks[i]->f = dst;
auto &f = blocks[i]->f;
const auto src = &*f;
if (hash.count( src ) > 0) {
const auto &dst = hash[src];
f = dst;
}
}
}
@ -113,12 +111,12 @@ void FindDependencies(AudacityProject *project,
BoolBlockFileHash blockFileHash;
for (const auto &blockFile : blocks) {
BlockFile *f = blockFile->f;
if (f->IsAlias() && (blockFileHash.count(f) == 0))
const auto &f = blockFile->f;
if (f->IsAlias() && (blockFileHash.count( &*f ) == 0))
{
// f is an alias block we have not yet counted.
blockFileHash[f] = true; // Don't count the same blockfile twice.
AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
blockFileHash[ &*f ] = true; // Don't count the same blockfile twice.
auto aliasBlockFile = static_cast<AliasBlockFile*>( &*f );
const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
// In DirManager::ProjectFSCK(), if the user has chosen to
@ -183,11 +181,11 @@ static void RemoveDependencies(AudacityProject *project,
ReplacedBlockFileHash blockFileHash;
wxLongLong completedBytes = 0;
for (const auto blockFile : blocks) {
BlockFile *f = blockFile->f;
if (f->IsAlias() && (blockFileHash.count(f) == 0))
const auto &f = blockFile->f;
if (f->IsAlias() && (blockFileHash.count( &*f ) == 0))
{
// f is an alias block we have not yet processed.
AliasBlockFile *aliasBlockFile = static_cast<AliasBlockFile*>(f);
auto aliasBlockFile = static_cast<AliasBlockFile*>( &*f );
const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
const wxString &fileNameStr = fileName.GetFullPath();
@ -197,7 +195,7 @@ static void RemoveDependencies(AudacityProject *project,
// Convert it from an aliased file to an actual file in the project.
unsigned int len = aliasBlockFile->GetLength();
BlockFile *newBlockFile;
BlockFilePtr newBlockFile;
{
SampleBuffer buffer(len, format);
f->ReadData(buffer.ptr(), format, 0, len);
@ -206,7 +204,7 @@ static void RemoveDependencies(AudacityProject *project,
}
// Update our hash so we know what block files we've done
blockFileHash[f] = newBlockFile;
blockFileHash[ &*f ] = newBlockFile;
// Update the progress bar
completedBytes += SAMPLE_SIZE(format) * len;
@ -221,11 +219,6 @@ static void RemoveDependencies(AudacityProject *project,
// However, that didn't actually change any references to these
// blockfiles in the Sequences, so we do that next...
ReplaceBlockFiles(project, blockFileHash);
// Subtract one from reference count of NEW block files; they're
// now all referenced the proper number of times by the Sequences
for (const auto &pair : blockFileHash)
dirManager->Deref(pair.second);
}
//

View File

@ -319,6 +319,8 @@ DirManager::DirManager()
{
wxLogDebug(wxT("DirManager: Created new instance."));
mLastBlockFileDestructionCount = BlockFile::gBlockFileDestructionCount;
// Seed the random number generator.
// this need not be strictly uniform or random, but it should give
// unclustered numbers
@ -347,8 +349,11 @@ DirManager::DirManager()
// toplevel pool hash is fully populated to begin
{
int i;
for(i=0; i< 256; i++) dirTopPool[i]=0;
// We can bypass the accessor function while initializing
auto &balanceInfo = mBalanceInfo;
auto &dirTopPool = balanceInfo.dirTopPool;
for(int i = 0; i < 256; ++i)
dirTopPool[i] = 0;
}
// Make sure there is plenty of space for temp files
@ -435,6 +440,8 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
saved version of the old project must not be moved,
otherwise the old project would not be safe.) */
int trueTotal = 0;
{
/*i18n-hint: This title appears on a dialog that indicates the progress in doing something.*/
ProgressDialog progress(_("Progress"),
@ -447,12 +454,15 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
int count = 0;
while ((iter != mBlockFileHash.end()) && success)
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->IsLocked())
success = CopyToNewProjectDirectory(b);
success = CopyToNewProjectDirectory( &*b );
else{
success = MoveToNewProjectDirectory(b);
success = MoveToNewProjectDirectory( &*b );
}
progress.Update(count, total);
@ -461,6 +471,9 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
count++;
}
// in case there are any nulls
trueTotal = count;
if (!success) {
// If the move failed, we try to move/copy as many files
// back as possible so that no damage was done. (No sense
@ -473,8 +486,12 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
MoveToNewProjectDirectory(b);
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
MoveToNewProjectDirectory(&*b);
if (count >= 0)
progress.Update(count, total);
@ -496,7 +513,7 @@ bool DirManager::SetProject(wxString& newProjPath, wxString& newProjName, const
// loading a project; in this latter case, the movement code does
// nothing because SetProject is called before there are any
// blockfiles. Cleanup code trigger is the same
if (mBlockFileHash.size()>0){
if (trueTotal > 0) {
// Clean up after ourselves; look for empty directories in the old
// and NEW project directories. The easiest way to do this is to
// recurse depth-first and rmdir every directory seen in old and
@ -638,6 +655,12 @@ int DirManager::BalanceMidAdd(int topnum, int midkey)
{
// enter the midlevel directory if it doesn't exist
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
if(dirMidPool.find(midkey) == dirMidPool.end() &&
dirMidFull.find(midkey) == dirMidFull.end()){
dirMidPool[midkey]=0;
@ -656,6 +679,10 @@ int DirManager::BalanceMidAdd(int topnum, int midkey)
void DirManager::BalanceFileAdd(int midkey)
{
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
// increment the midlevel directory usage information
if(dirMidPool.find(midkey) != dirMidPool.end()){
dirMidPool[midkey]++;
@ -688,11 +715,46 @@ void DirManager::BalanceInfoAdd(const wxString &file)
}
}
auto DirManager::GetBalanceInfo() -> BalanceInfo &
{
// Before returning the map,
// see whether any block files have disappeared,
// and if so update
auto count = BlockFile::gBlockFileDestructionCount;
if ( mLastBlockFileDestructionCount != count ) {
auto it = mBlockFileHash.begin(), end = mBlockFileHash.end();
while (it != end)
{
BlockFilePtr ptr { it->second.lock() };
if (!ptr) {
auto name = it->first;
mBlockFileHash.erase( it++ );
BalanceInfoDel( name );
}
else
++it;
}
}
mLastBlockFileDestructionCount = count;
return mBalanceInfo;
}
// Note that this will try to clean up directories out from under even
// locked blockfiles; this is actually harmless as the rmdir will fail
// on non-empty directories.
void DirManager::BalanceInfoDel(const wxString &file)
{
// do not use GetBalanceInfo(),
// rather this function will be called from there.
auto &balanceInfo = mBalanceInfo;
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirMidFull = balanceInfo.dirMidFull;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
const wxChar *s=file.c_str();
if(s[0]==wxT('e')){
// this is one of the modern two-deep managed files
@ -754,6 +816,11 @@ void DirManager::BalanceInfoDel(const wxString &file)
// perform maintainence
wxFileNameWrapper DirManager::MakeBlockFileName()
{
auto &balanceInfo = GetBalanceInfo();
auto &dirMidPool = balanceInfo.dirMidPool;
auto &dirTopPool = balanceInfo.dirTopPool;
auto &dirTopFull = balanceInfo.dirTopFull;
wxFileNameWrapper ret;
wxString baseFileName;
@ -841,7 +908,7 @@ wxFileNameWrapper DirManager::MakeBlockFileName()
baseFileName.Printf(wxT("e%02x%02x%03x"),topnum,midnum,filenum);
if (mBlockFileHash.find(baseFileName) == mBlockFileHash.end()){
if (!ContainsBlockFile(baseFileName)) {
// not in the hash, good.
if (!this->AssignFile(ret, baseFileName, true))
{
@ -863,7 +930,7 @@ wxFileNameWrapper DirManager::MakeBlockFileName()
return std::move(ret);
}
BlockFile *DirManager::NewSimpleBlockFile(
BlockFilePtr DirManager::NewSimpleBlockFile(
samplePtr sampleData, sampleCount sampleLen,
sampleFormat format,
bool allowDeferredWrite)
@ -871,26 +938,24 @@ BlockFile *DirManager::NewSimpleBlockFile(
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
BlockFile *newBlockFile =
new SimpleBlockFile(std::move(filePath), sampleData, sampleLen, format,
allowDeferredWrite);
auto newBlockFile = make_blockfile<SimpleBlockFile>
(std::move(filePath), sampleData, sampleLen, format, allowDeferredWrite);
mBlockFileHash[fileName]=newBlockFile;
mBlockFileHash[fileName] = newBlockFile;
return newBlockFile;
}
BlockFile *DirManager::NewAliasBlockFile(
BlockFilePtr DirManager::NewAliasBlockFile(
const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName = filePath.GetName();
BlockFile *newBlockFile =
new PCMAliasBlockFile(std::move(filePath),
wxFileNameWrapper{aliasedFile},
aliasStart, aliasLen, aliasChannel);
auto newBlockFile = make_blockfile<PCMAliasBlockFile>
(std::move(filePath), wxFileNameWrapper{aliasedFile},
aliasStart, aliasLen, aliasChannel);
mBlockFileHash[fileName]=newBlockFile;
aliasList.Add(aliasedFile);
@ -898,16 +963,16 @@ BlockFile *DirManager::NewAliasBlockFile(
return newBlockFile;
}
BlockFile *DirManager::NewODAliasBlockFile(
BlockFilePtr DirManager::NewODAliasBlockFile(
const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
BlockFile *newBlockFile =
new ODPCMAliasBlockFile(std::move(filePath),
wxFileNameWrapper{aliasedFile}, aliasStart, aliasLen, aliasChannel);
auto newBlockFile = make_blockfile<ODPCMAliasBlockFile>
(std::move(filePath), wxFileNameWrapper{aliasedFile},
aliasStart, aliasLen, aliasChannel);
mBlockFileHash[fileName]=newBlockFile;
aliasList.Add(aliasedFile);
@ -915,16 +980,16 @@ BlockFile *DirManager::NewODAliasBlockFile(
return newBlockFile;
}
BlockFile *DirManager::NewODDecodeBlockFile(
BlockFilePtr DirManager::NewODDecodeBlockFile(
const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel, int decodeType)
{
wxFileNameWrapper filePath{ MakeBlockFileName() };
const wxString fileName{ filePath.GetName() };
BlockFile *newBlockFile =
new ODDecodeBlockFile(std::move(filePath),
wxFileNameWrapper{aliasedFile}, aliasStart, aliasLen, aliasChannel, decodeType);
auto newBlockFile = make_blockfile<ODDecodeBlockFile>
(std::move(filePath), wxFileNameWrapper{ aliasedFile },
aliasStart, aliasLen, aliasChannel, decodeType);
mBlockFileHash[fileName]=newBlockFile;
aliasList.Add(aliasedFile); //OD TODO: check to see if we need to remove this when done decoding.
@ -939,26 +1004,29 @@ bool DirManager::ContainsBlockFile(const BlockFile *b) const
return false;
auto result = b->GetFileName();
BlockHash::const_iterator it = mBlockFileHash.find(result.name.GetName());
return it != mBlockFileHash.end() && it->second == b;
if (it == mBlockFileHash.end())
return false;
BlockFilePtr ptr = it->second.lock();
return ptr && (b == &*ptr);
}
bool DirManager::ContainsBlockFile(const wxString &filepath) const
{
// check what the hash returns in case the blockfile is from a different project
BlockHash::const_iterator it = mBlockFileHash.find(filepath);
return it != mBlockFileHash.end();
return it != mBlockFileHash.end() &&
BlockFilePtr{ it->second.lock() };
}
// Adds one to the reference count of the block file,
// UNLESS it is "locked", then it makes a NEW copy of
// the BlockFile.
BlockFile *DirManager::CopyBlockFile(BlockFile *b)
BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b)
{
auto result = b->GetFileName();
const auto &fn = result.name;
if (!b->IsLocked()) {
b->Ref();
//mchinen:July 13 2009 - not sure about this, but it needs to be added to the hash to be able to save if not locked.
//note that this shouldn't hurt mBlockFileHash's that already contain the filename, since it should just overwrite.
//but it's something to watch out for.
@ -970,7 +1038,7 @@ BlockFile *DirManager::CopyBlockFile(BlockFile *b)
}
// Copy the blockfile
BlockFile *b2;
BlockFilePtr b2;
if (!fn.IsOk())
// Block files with uninitialized filename (i.e. SilentBlockFile)
// just need an in-memory copy.
@ -991,7 +1059,7 @@ BlockFile *DirManager::CopyBlockFile(BlockFile *b)
{
if( !wxCopyFile(fn.GetFullPath(),
newFile.GetFullPath()) )
return NULL;
return {};
}
// Done with fn
@ -1000,7 +1068,7 @@ BlockFile *DirManager::CopyBlockFile(BlockFile *b)
b2 = b->Copy(std::move(newFile));
if (b2 == NULL)
return NULL;
return {};
mBlockFileHash[newName]=b2;
aliasList.Add(newPath);
@ -1014,9 +1082,9 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
if( mLoadingTarget == NULL )
return false;
BlockFile* pBlockFile = NULL;
BlockFilePtr pBlockFile {};
BlockFile *&target = mLoadingTarget->at(mLoadingTargetIdx).f;
BlockFilePtr &target = mLoadingTarget->at(mLoadingTargetIdx).f;
if (!wxStricmp(tag, wxT("silentblockfile"))) {
// Silent blocks don't actually have a file associated, so
@ -1079,7 +1147,6 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
// See http://bugzilla.audacityteam.org/show_bug.cgi?id=451#c13.
// Lock pBlockFile so that the ~BlockFile() will not DELETE the file on disk.
pBlockFile->Lock();
delete pBlockFile;
return false;
}
else
@ -1092,20 +1159,19 @@ bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
//
wxString name = target->GetFileName().name.GetName();
BlockFile *retrieved = mBlockFileHash[name];
auto &wRetrieved = mBlockFileHash[name];
BlockFilePtr retrieved = wRetrieved.lock();
if (retrieved) {
// Lock it in order to DELETE it safely, i.e. without having
// it DELETE the file, too...
target->Lock();
delete target;
Ref(retrieved); // Add one to its reference count
target = retrieved;
return true;
}
// This is a NEW object
mBlockFileHash[name] = target;
wRetrieved = target;
// MakeBlockFileName wasn't used so we must add the directory
// balancing information
BalanceInfoAdd(name);
@ -1192,38 +1258,6 @@ bool DirManager::CopyToNewProjectDirectory(BlockFile *f)
return MoveOrCopyToNewProjectDirectory(f, true);
}
void DirManager::Ref(BlockFile * f)
{
f->Ref();
//printf("Ref(%d): %s\n",
// f->mRefCount,
// (const char *)f->mFileName.GetFullPath().mb_str());
}
int DirManager::GetRefCount(BlockFile * f)
{
return f->mRefCount;
}
void DirManager::Deref(BlockFile * f)
{
const wxString theFileName = f->GetFileName().name.GetName();
//printf("Deref(%d): %s\n",
// f->mRefCount-1,
// (const char *)f->mFileName.GetFullPath().mb_str());
if (f->Deref()) {
// If Deref() returned true, the reference count reached zero
// and this block is no longer needed. Remove it from the hash
// table.
mBlockFileHash.erase(theFileName);
BalanceInfoDel(theFileName);
}
}
bool DirManager::EnsureSafeFilename(const wxFileName &fName)
{
// Quick check: If it's not even in our alias list,
@ -1284,13 +1318,17 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
// don't worry, we don't rely on this cast unless IsAlias is true
AliasBlockFile *ab = (AliasBlockFile*)b;
auto ab = static_cast< AliasBlockFile * > ( &*b );
// don't worry, we don't rely on this cast unless ISDataAvailable is false
// which means that it still needs to access the file.
ODDecodeBlockFile *db = (ODDecodeBlockFile*)b;
auto db = static_cast< ODDecodeBlockFile * > ( &*b );
if (b->IsAlias() && ab->GetAliasedFileName() == fName) {
needToRename = true;
@ -1323,9 +1361,13 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
AliasBlockFile *ab = (AliasBlockFile*)b;
ODDecodeBlockFile *db = (ODDecodeBlockFile*)b;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
auto ab = static_cast< AliasBlockFile * > ( &*b );
auto db = static_cast< ODDecodeBlockFile * > ( &*b );
if (b->IsAlias() && (ab->GetAliasedFileName() == fName))
ab->UnlockRead();
@ -1347,9 +1389,13 @@ bool DirManager::EnsureSafeFilename(const wxFileName &fName)
BlockHash::iterator iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
AliasBlockFile *ab = (AliasBlockFile*)b;
ODDecodeBlockFile *db = (ODDecodeBlockFile*)b;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
auto ab = static_cast< AliasBlockFile * > ( &*b );
auto db = static_cast< ODDecodeBlockFile * > ( &*b );
if (b->IsAlias() && ab->GetAliasedFileName() == fName)
{
@ -1477,11 +1523,17 @@ _("Project check of \"%s\" folder \
BlockHash::iterator iter = missingAliasedFileAUFHash.begin();
while (iter != missingAliasedFileAUFHash.end())
{
// This type caste is safe. We checked that it's an alias block file earlier.
AliasBlockFile *b = (AliasBlockFile*)iter->second;
// This type cast is safe. We checked that it's an alias block file earlier.
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
continue;
auto ab = static_cast< AliasBlockFile * > ( &*b );
if (action == 1)
// Silence error logging for this block in this session.
b->SilenceAliasLog();
ab->SilenceAliasLog();
else if (action == 2)
{
// silence the blockfiles by yanking the filename
@ -1490,8 +1542,8 @@ _("Project check of \"%s\" folder \
// There, if the mAliasedFileName is bad, it zeroes the data.
wxFileNameWrapper dummy;
dummy.Clear();
b->ChangeAliasedFileName(std::move(dummy));
b->Recover();
ab->ChangeAliasedFileName(std::move(dummy));
ab->Recover();
nResult = FSCKstatus_CHANGED | FSCKstatus_SAVE_AUP;
}
++iter;
@ -1539,7 +1591,12 @@ _("Project check of \"%s\" folder \
BlockHash::iterator iter = missingAUFHash.begin();
while (iter != missingAUFHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
continue;
if(action==0){
//regenerate from data
b->Recover();
@ -1598,7 +1655,12 @@ _("Project check of \"%s\" folder \
BlockHash::iterator iter = missingAUHash.begin();
while (iter != missingAUHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
wxASSERT(b);
if (!b)
continue;
if (action == 2)
{
//regenerate with zeroes
@ -1705,10 +1767,15 @@ void DirManager::FindMissingAliasedFiles(
while (iter != mBlockFileHash.end())
{
wxString key = iter->first; // file name and extension
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->IsAlias())
{
const wxFileName &aliasedFileName = ((AliasBlockFile*)b)->GetAliasedFileName();
const wxFileName &aliasedFileName =
static_cast< AliasBlockFile* > ( &*b )->GetAliasedFileName();
wxString aliasedFileFullPath = aliasedFileName.GetFullPath();
// wxEmptyString can happen if user already chose to "replace... with silence".
if ((aliasedFileFullPath != wxEmptyString) &&
@ -1719,7 +1786,7 @@ void DirManager::FindMissingAliasedFiles(
missingAliasedFilePathHash.end()) // Add it only once.
// Not actually using the block here, just the path,
// so set the block to NULL to create the entry.
missingAliasedFilePathHash[aliasedFileFullPath] = NULL;
missingAliasedFilePathHash[aliasedFileFullPath] = {};
}
}
++iter;
@ -1740,7 +1807,11 @@ void DirManager::FindMissingAUFs(
while (iter != mBlockFileHash.end())
{
const wxString &key = iter->first;
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->IsAlias() && b->IsSummaryAvailable())
{
/* don't look in hash; that might find files the user moved
@ -1766,7 +1837,11 @@ void DirManager::FindMissingAUs(
while (iter != mBlockFileHash.end())
{
const wxString &key = iter->first;
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (!b->IsAlias())
{
wxFileNameWrapper fileName{ MakeBlockFilePath(key) };
@ -1866,7 +1941,11 @@ void DirManager::FillBlockfilesCache()
iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->GetNeedFillCache())
numNeed++;
++iter;
@ -1882,7 +1961,11 @@ void DirManager::FillBlockfilesCache()
int current = 0;
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->GetNeedFillCache() && (GetFreeMemory() > lowMem)) {
b->FillCache();
}
@ -1903,7 +1986,11 @@ void DirManager::WriteCacheToDisk()
iter = mBlockFileHash.begin();
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->GetNeedWriteCacheToDisk())
numNeed++;
++iter;
@ -1919,7 +2006,11 @@ void DirManager::WriteCacheToDisk()
int current = 0;
while (iter != mBlockFileHash.end())
{
BlockFile *b = iter->second;
BlockFilePtr b = iter->second.lock();
if (!b)
continue;
if (b->GetNeedWriteCacheToDisk())
{
b->WriteCacheToDisk();

View File

@ -32,7 +32,12 @@ class SequenceTest;
#define FSCKstatus_SAVE_AUP 0x4 // used in combination with FSCKstatus_CHANGED
WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, DirHash);
WX_DECLARE_HASH_MAP(wxString, BlockFile*, wxStringHash, wxStringEqual, BlockHash);
class BlockFile;
using BlockFilePtr = std::shared_ptr<BlockFile>;
WX_DECLARE_HASH_MAP(wxString, std::weak_ptr<BlockFile>, wxStringHash,
wxStringEqual, BlockHash);
wxMemorySize GetFreeMemory();
@ -56,18 +61,22 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
wxLongLong GetFreeDiskSpace();
BlockFile *NewSimpleBlockFile(samplePtr sampleData,
BlockFilePtr
NewSimpleBlockFile(samplePtr sampleData,
sampleCount sampleLen,
sampleFormat format,
bool allowDeferredWrite = false);
BlockFile *NewAliasBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
BlockFilePtr
NewAliasBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel);
BlockFile *NewODAliasBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
BlockFilePtr
NewODAliasBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel);
BlockFile *NewODDecodeBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
BlockFilePtr
NewODDecodeBlockFile( const wxString &aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel, int decodeType);
/// Returns true if the blockfile pointed to by b is contained by the DirManager
@ -78,7 +87,7 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
// Adds one to the reference count of the block file,
// UNLESS it is "locked", then it makes a NEW copy of
// the BlockFile.
BlockFile *CopyBlockFile(BlockFile *b);
BlockFilePtr CopyBlockFile(const BlockFilePtr &b);
BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format);
void SaveBlockFile(BlockFile *f, int depth, FILE *fp);
@ -93,12 +102,6 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
bool EnsureSafeFilename(const wxFileName &fName);
void Ref(BlockFile * f);
void Deref(BlockFile * f);
// For debugging only
int GetRefCount(BlockFile * f);
void SetLoadingTarget(BlockArray *pArray, unsigned idx)
{
mLoadingTarget = pArray;
@ -171,10 +174,19 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
bool MoveOrCopyToNewProjectDirectory(BlockFile *f, bool copy);
BlockHash mBlockFileHash; // repository for blockfiles
DirHash dirTopPool; // available toplevel dirs
DirHash dirTopFull; // full toplevel dirs
DirHash dirMidPool; // available two-level dirs
DirHash dirMidFull; // full two-level dirs
// Hashes for management of the sub-directory tree of _data
struct BalanceInfo
{
DirHash dirTopPool; // available toplevel dirs
DirHash dirTopFull; // full toplevel dirs
DirHash dirMidPool; // available two-level dirs
DirHash dirMidFull; // full two-level dirs
} mBalanceInfo;
// Accessor for the balance info, may need to do a delayed update for
// deletion in case other threads delete block files
BalanceInfo &GetBalanceInfo();
void BalanceInfoDel(const wxString&);
void BalanceInfoAdd(const wxString&);
@ -196,6 +208,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler {
sampleCount mMaxSamples; // max samples per block
unsigned long mLastBlockFileDestructionCount { 0 };
static wxString globaltemp;
wxString mytemp;
static int numDirManagers;

View File

@ -34,6 +34,7 @@ using std::isinf;
namespace std {
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::tr1::static_pointer_cast;
using std::tr1::remove_reference;
template<typename X> struct default_delete

View File

@ -75,19 +75,6 @@ Sequence::Sequence(const Sequence &orig, const std::shared_ptr<DirManager> &proj
Sequence::~Sequence()
{
DerefAllFiles();
}
void Sequence::DerefAllFiles()
{
for (size_t i = 0, nn = mBlock.size(); i < nn; i++)
{
BlockFile *& pOldFile = mBlock[i].f;
if (pOldFile) {
mDirManager->Deref(pOldFile);
pOldFile = NULL;
}
}
}
sampleCount Sequence::GetMaxBlockSize() const
@ -176,7 +163,7 @@ bool Sequence::ConvertToSampleFormat(sampleFormat format, bool* pbChanged)
for (size_t i = 0, nn = mBlock.size(); i < nn && bSuccess; i++)
{
SeqBlock &oldSeqBlock = mBlock[i];
BlockFile* oldBlockFile = oldSeqBlock.f;
const auto &oldBlockFile = oldSeqBlock.f;
sampleCount len = oldBlockFile->GetLength();
@ -210,8 +197,6 @@ bool Sequence::ConvertToSampleFormat(sampleFormat format, bool* pbChanged)
// Invalidate all the old, non-aliased block files.
// Aliased files will be converted at save, per comment above.
DerefAllFiles();
// Replace with NEW blocks.
mBlock.swap(newBlockArray);
}
@ -277,7 +262,7 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
{
float block0Min, block0Max, block0RMS;
const SeqBlock &theBlock = mBlock[block0];
BlockFile *const theFile = theBlock.f;
const auto &theFile = theBlock.f;
theFile->GetMinMax(&block0Min, &block0Max, &block0RMS);
if (block0Min < min || block0Max > max) {
@ -302,7 +287,7 @@ bool Sequence::GetMinMax(sampleCount start, sampleCount len,
{
float block1Min, block1Max, block1RMS;
const SeqBlock &theBlock = mBlock[block1];
BlockFile *const theFile = theBlock.f;
const auto &theFile = theBlock.f;
theFile->GetMinMax(&block1Min, &block1Max, &block1RMS);
if (block1Min < min || block1Max > max) {
@ -351,7 +336,7 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
for (unsigned b = block0 + 1; b < block1; b++) {
float blockMin, blockMax, blockRMS;
const SeqBlock &theBlock = mBlock[b];
BlockFile *const theFile = theBlock.f;
const auto &theFile = theBlock.f;
theFile->GetMinMax(&blockMin, &blockMax, &blockRMS);
const sampleCount fileLen = theFile->GetLength();
@ -364,7 +349,7 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
// If not, we need read some samples and summaries from disk.
{
const SeqBlock &theBlock = mBlock[block0];
BlockFile *const theFile = theBlock.f;
const auto &theFile = theBlock.f;
s0 = start - theBlock.start;
l0 = len;
maxl0 = theBlock.start + theFile->GetLength() - start;
@ -381,7 +366,7 @@ bool Sequence::GetRMS(sampleCount start, sampleCount len,
if (block1 > block0) {
const SeqBlock &theBlock = mBlock[block1];
BlockFile *const theFile = theBlock.f;
const auto &theFile = theBlock.f;
s0 = 0;
l0 = (start + len) - theBlock.start;
@ -429,7 +414,7 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
const SeqBlock &block0 = mBlock[b0];
if (s0 != block0.start) {
BlockFile *const file = block0.f;
const auto &file = block0.f;
blocklen = std::min(s1, block0.start + file->GetLength()) - s0;
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
Get(b0, buffer.ptr(), mSampleFormat, s0, blocklen);
@ -446,7 +431,7 @@ bool Sequence::Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &d
// Do the last block
if (b1 > b0) {
const SeqBlock &block = mBlock[b1];
BlockFile *const file = block.f;
const auto &file = block.f;
blocklen = (s1 - block.start);
wxASSERT(file->IsAlias() || (blocklen <= mMaxSamples)); // Vaughan, 2012-02-29
if (blocklen < file->GetLength()) {
@ -547,10 +532,9 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
mSampleFormat, block,
splitPoint, length - splitPoint);
BlockFile *const file =
auto file =
mDirManager->NewSimpleBlockFile(buffer.ptr(), largerBlockLen, mSampleFormat);
mDirManager->Deref(block.f);
block.f = file;
for (unsigned int i = b + 1; i < numBlocks; i++)
@ -617,7 +601,7 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
for (i = 2; i < srcNumBlocks - 2; i++) {
const SeqBlock &block = srcBlock[i];
BlockFile *const file = mDirManager->CopyBlockFile(block.f);
auto file = mDirManager->CopyBlockFile(block.f);
if (!file) {
wxASSERT(false); // TODO: Handle this better, alert the user of failure.
return false;
@ -635,8 +619,6 @@ bool Sequence::Paste(sampleCount s, const Sequence *src)
Blockify(newBlock, s + lastStart, sampleBuffer.ptr(), rightLen);
}
mDirManager->Deref(splitBlock.f);
// Copy remaining blocks to NEW block array and
// swap the NEW block array in for the old
for (i = b + 1; i < numBlocks; i++)
@ -676,20 +658,18 @@ bool Sequence::InsertSilence(sampleCount s0, sampleCount len)
sTrack.mBlock.reserve((len + idealSamples - 1) / idealSamples);
BlockFile *silentFile = 0;
BlockFilePtr silentFile {};
if (len >= idealSamples)
silentFile = new SilentBlockFile(idealSamples);
silentFile = make_blockfile<SilentBlockFile>(idealSamples);
while (len >= idealSamples) {
sTrack.mBlock.push_back(SeqBlock(silentFile, pos));
mDirManager->Ref(silentFile);
pos += idealSamples;
len -= idealSamples;
}
if (silentFile)
mDirManager->Deref(silentFile);
if (len) {
sTrack.mBlock.push_back(SeqBlock(new SilentBlockFile(len), pos));
sTrack.mBlock.push_back(SeqBlock(
make_blockfile<SilentBlockFile>(len), pos));
pos += len;
}
@ -771,9 +751,9 @@ unsigned int Sequence::GetODFlags()
{
unsigned int ret = 0;
for (unsigned int i = 0; i < mBlock.size(); i++) {
BlockFile *const file = mBlock[i].f;
const auto &file = mBlock[i].f;
if(!file->IsDataAvailable())
ret |= (static_cast<ODDecodeBlockFile*>(file))->GetDecodeType();
ret |= (static_cast< ODDecodeBlockFile * >( &*file ))->GetDecodeType();
else if(!file->IsSummaryAvailable())
ret |= ODTask::eODPCMSummary;
}
@ -971,7 +951,7 @@ void Sequence::HandleXMLEndTag(const wxChar *tag)
Internat::ToString(((wxLongLong)mMaxSamples).ToDouble(), 0).c_str());
len = mMaxSamples;
}
block.f = new SilentBlockFile(len);
block.f = make_blockfile<SilentBlockFile>(len);
wxLogWarning(
wxT("Gap detected in project file. Replacing missing block file with silence."));
mErrorOpening = true;
@ -1114,7 +1094,7 @@ int Sequence::FindBlock(sampleCount pos) const
bool Sequence::Read(samplePtr buffer, sampleFormat format,
const SeqBlock &b, sampleCount start, sampleCount len) const
{
BlockFile *f = b.f;
const auto &f = b.f;
wxASSERT(start >= 0);
wxASSERT(start + len <= f->GetLength());
@ -1150,11 +1130,8 @@ bool Sequence::CopyWrite(SampleBuffer &scratch,
Read(scratch.ptr(), mSampleFormat, b, 0, length);
memcpy(scratch.ptr() + start*sampleSize, buffer, len*sampleSize);
BlockFile *const oldBlockFile = b.f;
b.f = mDirManager->NewSimpleBlockFile(scratch.ptr(), length, mSampleFormat);
mDirManager->Deref(oldBlockFile);
return true;
}
@ -1232,8 +1209,7 @@ bool Sequence::Set(samplePtr buffer, sampleFormat format,
if (start == block.start &&
blen == fileLength) {
mDirManager->Deref(block.f);
block.f = new SilentBlockFile(blen);
block.f = make_blockfile<SilentBlockFile>(blen);
}
else {
// Odd partial blocks of silence at start or end.
@ -1541,9 +1517,9 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
);
// FIXME: TRAP_ERR This could throw an exception that should(?) be converted to return false.
if (blockFileLog)
static_cast<SimpleBlockFile*>(newLastBlock.f)->SaveXML(*blockFileLog);
static_cast< SimpleBlockFile * >( &*newLastBlock.f )
->SaveXML( *blockFileLog );
mDirManager->Deref(lastBlock.f);
lastBlock = newLastBlock;
len -= addLen;
@ -1554,7 +1530,7 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
while (len) {
const sampleCount idealSamples = GetIdealBlockSize();
const sampleCount l = std::min(idealSamples, len);
BlockFile *pFile;
BlockFilePtr pFile;
if (format == mSampleFormat) {
pFile = mDirManager->NewSimpleBlockFile(buffer, l, mSampleFormat,
blockFileLog != NULL);
@ -1567,7 +1543,7 @@ bool Sequence::Append(samplePtr buffer, sampleFormat format,
// FIXME: TRAP_ERR This could throw an exception that should(?) be converted to return false.
if (blockFileLog)
static_cast<SimpleBlockFile*>(pFile)->SaveXML(*blockFileLog);
static_cast< SimpleBlockFile * >( &*pFile )->SaveXML( *blockFileLog );
mBlock.push_back(SeqBlock(pFile, mNumSamples));
@ -1649,12 +1625,10 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
Read(scratch.ptr() + (pos * sampleSize), mSampleFormat,
b, pos + len, newLen - pos);
BlockFile *const oldFile = b.f;
b = SeqBlock(
mDirManager->NewSimpleBlockFile(scratch.ptr(), newLen, mSampleFormat),
b.start
);
mDirManager->Deref(oldFile);
for (unsigned int j = b0 + 1; j < numBlocks; j++)
mBlock[j].start -= len;
@ -1685,7 +1659,7 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
if (!scratch.ptr())
scratch.Allocate(scratchSize, mSampleFormat);
Read(scratch.ptr(), mSampleFormat, preBlock, 0, preBufferLen);
BlockFile *const pFile =
auto pFile =
mDirManager->NewSimpleBlockFile(scratch.ptr(), preBufferLen, mSampleFormat);
newBlock.push_back(SeqBlock(pFile, preBlock.start));
@ -1703,8 +1677,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
newBlock.erase(newBlock.end() - 1);
Blockify(newBlock, prepreBlock.start, scratch.ptr(), sum);
mDirManager->Deref(prepreBlock.f);
}
}
else {
@ -1712,15 +1684,6 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
// right on the beginning of a block.
}
if (b0 != b1) {
mDirManager->Deref(preBlock.f);
}
// Next, DELETE blocks strictly between b0 and b1
for (i = b0 + 1; i < b1; i++) {
mDirManager->Deref(mBlock[i].f);
}
// Now, symmetrically, grab the samples in block b1 after the
// deletion point into postBuffer. If this is enough samples
// for its own block, or if this would be the last block in
@ -1736,7 +1699,7 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
scratch.Allocate(postBufferLen, mSampleFormat);
sampleCount pos = (start + len) - postBlock.start;
Read(scratch.ptr(), mSampleFormat, postBlock, pos, postBufferLen);
BlockFile *const file =
auto file =
mDirManager->NewSimpleBlockFile(scratch.ptr(), postBufferLen, mSampleFormat);
newBlock.push_back(SeqBlock(file, start));
@ -1755,15 +1718,12 @@ bool Sequence::Delete(sampleCount start, sampleCount len)
Blockify(newBlock, start, scratch.ptr(), sum);
b1++;
mDirManager->Deref(postpostBlock.f);
}
}
else {
// The sample where we begin deletion happens to fall
// right on the end of a block.
}
mDirManager->Deref(postBlock.f);
// Copy the remaining blocks over from the old array
for (i = b1 + 1; i < numBlocks; i++)
@ -1820,11 +1780,11 @@ void Sequence::DebugPrintf(wxString *dest) const
for (i = 0; i < mBlock.size(); i++) {
const SeqBlock &seqBlock = mBlock[i];
*dest += wxString::Format
(wxT(" Block %3u: start %8lld, len %8lld, refs %d, "),
(wxT(" Block %3u: start %8lld, len %8lld, refs %ld, "),
i,
(long long) seqBlock.start,
seqBlock.f ? (long long) seqBlock.f->GetLength() : 0,
seqBlock.f ? mDirManager->GetRefCount(seqBlock.f) : 0);
seqBlock.f ? seqBlock.f.use_count() : 0);
if (seqBlock.f)
*dest += seqBlock.f->GetFileName().name.GetFullName();
@ -1855,7 +1815,7 @@ int Sequence::GetMaxDiskBlockSize()
return sMaxDiskBlockSize;
}
void Sequence::AppendBlockFile(BlockFile* blockFile)
void Sequence::AppendBlockFile(const BlockFilePtr &blockFile)
{
// We assume blockFile has the correct ref count already

View File

@ -30,20 +30,22 @@ typedef wxLongLong_t sampleCount; /** < A native 64-bit integer type, because
#endif
class BlockFile;
using BlockFilePtr = std::shared_ptr<BlockFile>;
class DirManager;
// This is an internal data structure! For advanced use only.
class SeqBlock {
public:
BlockFile * f;
BlockFilePtr f;
///the sample in the global wavetrack that this block starts at.
sampleCount start;
SeqBlock()
: f(NULL), start(0)
: f{}, start(0)
{}
SeqBlock(BlockFile *f_, sampleCount start_)
SeqBlock(const BlockFilePtr &f_, sampleCount start_)
: f(f_), start(start_)
{}
@ -123,7 +125,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
// be registered within the dir manager hash. This is the case
// when the blockfile is created using DirManager::NewSimpleBlockFile or
// loaded from an XML file via DirManager::HandleXMLTag
void AppendBlockFile(BlockFile* blockFile);
void AppendBlockFile(const BlockFilePtr &blockFile);
bool SetSilence(sampleCount s0, sampleCount len);
bool InsertSilence(sampleCount s0, sampleCount len);
@ -236,8 +238,6 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
// Private methods
//
void DerefAllFiles();
int FindBlock(sampleCount pos) const;
bool AppendBlock(const SeqBlock &b);

View File

@ -100,17 +100,17 @@ void UndoManager::CalculateSpaceUsage()
BlockArray *blocks = clip->GetSequenceBlockArray();
for (const auto &block : *blocks)
{
BlockFile *file = block.f;
const auto &file = block.f;
// Accumulate space used by the file if the file didn't exist
// in the previous level
if (prev->count(file) == 0 && cur->count(file) == 0)
if (prev->count( &*file ) == 0 && cur->count( &*file ) == 0)
{
space[i] += file->GetSpaceUsage().GetValue();
}
// Add file to current set
cur->insert(file);
cur->insert( &*file );
}
}

View File

@ -51,14 +51,12 @@ LegacyAliasBlockFile::~LegacyAliasBlockFile()
/// the summary data to a NEW file.
///
/// @param newFileName The filename to copy the summary data to.
BlockFile *LegacyAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr LegacyAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
BlockFile *newBlockFile =
new LegacyAliasBlockFile(std::move(newFileName),
wxFileNameWrapper{mAliasedFileName}, mAliasStart,
mLen, mAliasChannel,
mSummaryInfo.totalSummaryBytes,
mSummaryInfo.fields < 3);
auto newBlockFile = make_blockfile<LegacyAliasBlockFile>
(std::move(newFileName), wxFileNameWrapper{ mAliasedFileName },
mAliasStart, mLen, mAliasChannel,
mSummaryInfo.totalSummaryBytes, mSummaryInfo.fields < 3);
return newBlockFile;
}
@ -83,7 +81,7 @@ void LegacyAliasBlockFile::SaveXML(XMLWriter &xmlFile)
// BuildFromXML methods should always return a BlockFile, not NULL,
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
BlockFile *LegacyAliasBlockFile::BuildFromXML(const wxString &projDir, const wxChar **attrs)
BlockFilePtr LegacyAliasBlockFile::BuildFromXML(const wxString &projDir, const wxChar **attrs)
{
wxFileNameWrapper summaryFileName;
wxFileNameWrapper aliasFileName;
@ -133,9 +131,9 @@ BlockFile *LegacyAliasBlockFile::BuildFromXML(const wxString &projDir, const wxC
}
}
return new LegacyAliasBlockFile(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel,
summaryLen, noRMS);
return make_blockfile<LegacyAliasBlockFile>
(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel, summaryLen, noRMS);
}
// regenerates the summary info, doesn't deal with missing alias files

View File

@ -32,10 +32,10 @@ class LegacyAliasBlockFile final : public PCMAliasBlockFile
virtual ~LegacyAliasBlockFile();
void SaveXML(XMLWriter &xmlFile) override;
BlockFile *Copy(wxFileNameWrapper &&fileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
void Recover() override;
static BlockFile *BuildFromXML(const wxString &projDir, const wxChar **attrs);
static BlockFilePtr BuildFromXML(const wxString &projDir, const wxChar **attrs);
};
#endif

View File

@ -294,7 +294,7 @@ void LegacyBlockFile::SaveXML(XMLWriter &xmlFile)
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
/// static
BlockFile *LegacyBlockFile::BuildFromXML(const wxString &projDir, const wxChar **attrs,
BlockFilePtr LegacyBlockFile::BuildFromXML(const wxString &projDir, const wxChar **attrs,
sampleCount len, sampleFormat format)
{
wxFileNameWrapper fileName;
@ -328,19 +328,19 @@ BlockFile *LegacyBlockFile::BuildFromXML(const wxString &projDir, const wxChar *
}
}
return new LegacyBlockFile(std::move(fileName), format, summaryLen, len, noRMS);
return make_blockfile<LegacyBlockFile>
(std::move(fileName), format, summaryLen, len, noRMS);
}
/// Create a copy of this BlockFile, but using a different disk file.
///
/// @param newFileName The name of the NEW file to use.
BlockFile *LegacyBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr LegacyBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
return new LegacyBlockFile(std::move(newFileName),
mFormat,
mSummaryInfo.totalSummaryBytes,
mLen,
mSummaryInfo.fields < 3);
return make_blockfile<LegacyBlockFile>
(std::move(newFileName),
mFormat, mSummaryInfo.totalSummaryBytes,
mLen, mSummaryInfo.fields < 3);
}
wxLongLong LegacyBlockFile::GetSpaceUsage() const

View File

@ -54,13 +54,13 @@ class LegacyBlockFile final : public BlockFile {
sampleCount start, sampleCount len) const override;
/// Create a NEW block file identical to this one
BlockFile *Copy(wxFileNameWrapper &&newFileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
/// Write an XML representation of this file
void SaveXML(XMLWriter &xmlFile) override;
wxLongLong GetSpaceUsage() const override;
void Recover() override;
static BlockFile *BuildFromXML(const wxString &dir, const wxChar **attrs,
static BlockFilePtr BuildFromXML(const wxString &dir, const wxChar **attrs,
sampleCount len,
sampleFormat format);

View File

@ -158,9 +158,9 @@ bool ODDecodeBlockFile::Read64K(float *buffer, sampleCount start, sampleCount le
/// Construct a NEW PCMAliasBlockFile based on this one.
/// otherwise construct an ODPCMAliasBlockFile that still needs to be computed.
/// @param newFileName The filename to copy the summary data to.
BlockFile *ODDecodeBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr ODDecodeBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
BlockFile *newBlockFile;
BlockFilePtr newBlockFile;
//mAliasedFile can change so we lock readdatamutex, which is responsible for it.
LockRead();
@ -172,10 +172,10 @@ BlockFile *ODDecodeBlockFile::Copy(wxFileNameWrapper &&newFileName)
else
{
//Summary File might exist in this case, but it probably (99.999% of the time) won't.
newBlockFile = new ODDecodeBlockFile(std::move(newFileName),
wxFileNameWrapper{mAudioFileName}, mAliasStart,
mLen, mAliasChannel, mType,
mMin, mMax, mRMS,IsSummaryAvailable());
newBlockFile = make_blockfile<ODDecodeBlockFile>
(std::move(newFileName), wxFileNameWrapper{mAudioFileName},
mAliasStart, mLen, mAliasChannel, mType,
mMin, mMax, mRMS, IsSummaryAvailable());
//The client code will need to schedule this blockfile for OD decoding if it is going to a NEW track.
//It can do this by checking for IsDataAvailable()==false.
}
@ -222,7 +222,7 @@ void ODDecodeBlockFile::SaveXML(XMLWriter &xmlFile)
// BuildFromXML methods should always return a BlockFile, not NULL,
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
BlockFile *ODDecodeBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
BlockFilePtr ODDecodeBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
{
wxFileNameWrapper summaryFileName;
wxFileNameWrapper audioFileName;
@ -274,10 +274,9 @@ BlockFile *ODDecodeBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
}
}
return new ODDecodeBlockFile(std::move(summaryFileName), std::move(audioFileName),
aliasStart, aliasLen, aliasChannel,decodeType,
0,0,0, false);
return make_blockfile<ODDecodeBlockFile>
(std::move(summaryFileName), std::move(audioFileName),
aliasStart, aliasLen, aliasChannel, decodeType, 0, 0, 0, false);
}

View File

@ -77,13 +77,13 @@ class ODDecodeBlockFile final : public SimpleBlockFile
///Makes NEW ODPCMAliasBlockFile or PCMAliasBlockFile depending on summary availability
BlockFile *Copy(wxFileNameWrapper &&fileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
///Saves as xml ODPCMAliasBlockFile or PCMAliasBlockFile depending on summary availability
void SaveXML(XMLWriter &xmlFile) override;
///Reconstructs from XML a ODPCMAliasBlockFile and reschedules it for OD loading
static BlockFile *BuildFromXML(DirManager &dm, const wxChar **attrs);
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs);
///Writes the summary file if summary data is available
void Recover(void) override;

View File

@ -74,33 +74,6 @@ ODPCMAliasBlockFile::~ODPCMAliasBlockFile()
{
}
/// Increases the reference count of this block by one. Only
/// DirManager should call this method.
/// This method has been overidden to be threadsafe. It is important especially
/// if two blockfiles deref at the same time resulting in a double deletion of the file
void ODPCMAliasBlockFile::Ref() const
{
mRefMutex.Lock();
BlockFile::Ref();
mRefMutex.Unlock();
}
/// Decreases the reference count of this block by one. If this
/// causes the count to become zero, deletes the associated disk
/// file and deletes this object
bool ODPCMAliasBlockFile::Deref() const
{
bool ret;
mDerefMutex.Lock();
ret = BlockFile::Deref();
if(!ret)
{
//Deref returns true when deleted, in which case we should not be touching instance variables, or ever calling this function again.
mDerefMutex.Unlock();
}
return ret;
}
//Check to see if we have the file for these calls.
@ -216,9 +189,9 @@ bool ODPCMAliasBlockFile::Read64K(float *buffer, sampleCount start, sampleCount
/// Construct a NEW PCMAliasBlockFile based on this one.
/// otherwise construct an ODPCMAliasBlockFile that still needs to be computed.
/// @param newFileName The filename to copy the summary data to.
BlockFile *ODPCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr ODPCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
BlockFile *newBlockFile;
BlockFilePtr newBlockFile;
//mAliasedFile can change so we lock readdatamutex, which is responsible for it.
LockRead();
@ -228,19 +201,18 @@ BlockFile *ODPCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
//PCMAliasBlockFile is to lock on exit, and this will cause orphaned blockfiles..
if(IsSummaryAvailable() && mHasBeenSaved)
{
newBlockFile = new PCMAliasBlockFile(std::move(newFileName),
wxFileNameWrapper{mAliasedFileName}, mAliasStart,
mLen, mAliasChannel,
mMin, mMax, mRMS);
newBlockFile = make_blockfile<PCMAliasBlockFile>
(std::move(newFileName), wxFileNameWrapper{mAliasedFileName},
mAliasStart, mLen, mAliasChannel, mMin, mMax, mRMS);
}
else
{
//Summary File might exist in this case, but it might not.
newBlockFile = new ODPCMAliasBlockFile(std::move(newFileName),
wxFileNameWrapper{mAliasedFileName}, mAliasStart,
mLen, mAliasChannel,
mMin, mMax, mRMS,IsSummaryAvailable());
newBlockFile = make_blockfile<ODPCMAliasBlockFile>
(std::move(newFileName), wxFileNameWrapper{mAliasedFileName},
mAliasStart, mLen, mAliasChannel, mMin, mMax, mRMS,
IsSummaryAvailable());
//The client code will need to schedule this blockfile for OD summarizing if it is going to a NEW track.
}
@ -290,7 +262,7 @@ void ODPCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
// BuildFromXML methods should always return a BlockFile, not NULL,
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
BlockFile *ODPCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
BlockFilePtr ODPCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
{
wxFileNameWrapper summaryFileName;
wxFileNameWrapper aliasFileName;
@ -339,9 +311,9 @@ BlockFile *ODPCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attr
}
}
return new ODPCMAliasBlockFile(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel,
0,0,0, false);
return make_blockfile<ODPCMAliasBlockFile>
(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel, 0, 0, 0, false);
}

View File

@ -75,13 +75,13 @@ class ODPCMAliasBlockFile final : public PCMAliasBlockFile
bool Read64K(float *buffer, sampleCount start, sampleCount len) override;
///Makes NEW ODPCMAliasBlockFile or PCMAliasBlockFile depending on summary availability
BlockFile *Copy(wxFileNameWrapper &&fileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
///Saves as xml ODPCMAliasBlockFile or PCMAliasBlockFile depending on summary availability
void SaveXML(XMLWriter &xmlFile) override;
///Reconstructs from XML a ODPCMAliasBlockFile and reschedules it for OD loading
static BlockFile *BuildFromXML(DirManager &dm, const wxChar **attrs);
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs);
///Writes the summary file if summary data is available
void Recover(void) override;
@ -143,13 +143,6 @@ protected:
sampleFormat format, ArrayOf<char> &cleanup) override;
private:
//Thread-safe versions
void Ref() const override;
bool Deref() const override;
//needed for Ref/Deref access.
friend class DirManager;
friend class ODComputeSummaryTask;
friend class ODDecodeTask;
ODLock mWriteSummaryMutex;
@ -162,11 +155,6 @@ protected:
//lock the read data - libsndfile can't handle two reads at once?
mutable ODLock mReadDataMutex;
//lock the Ref counting
mutable ODLock mDerefMutex;
mutable ODLock mRefMutex;
mutable ODLock mSummaryAvailableMutex;
bool mSummaryAvailable;
bool mSummaryBeingComputed;

View File

@ -150,12 +150,11 @@ int PCMAliasBlockFile::ReadData(samplePtr data, sampleFormat format,
/// the summary data to a NEW file.
///
/// @param newFileName The filename to copy the summary data to.
BlockFile *PCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr PCMAliasBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
BlockFile *newBlockFile = new PCMAliasBlockFile(std::move(newFileName),
wxFileNameWrapper{mAliasedFileName}, mAliasStart,
mLen, mAliasChannel,
mMin, mMax, mRMS);
auto newBlockFile = make_blockfile<PCMAliasBlockFile>
(std::move(newFileName), wxFileNameWrapper{mAliasedFileName},
mAliasStart, mLen, mAliasChannel, mMin, mMax, mRMS);
return newBlockFile;
}
@ -179,7 +178,7 @@ void PCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
// BuildFromXML methods should always return a BlockFile, not NULL,
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
BlockFile *PCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
BlockFilePtr PCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
{
wxFileNameWrapper summaryFileName;
wxFileNameWrapper aliasFileName;
@ -249,9 +248,9 @@ BlockFile *PCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
}
}
return new PCMAliasBlockFile(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel,
min, max, rms);
return make_blockfile<PCMAliasBlockFile>
(std::move(summaryFileName), std::move(aliasFileName),
aliasStart, aliasLen, aliasChannel, min, max, rms);
}
void PCMAliasBlockFile::Recover(void)

View File

@ -41,10 +41,10 @@ class PCMAliasBlockFile /* not final */ : public AliasBlockFile
sampleCount start, sampleCount len) const override;
void SaveXML(XMLWriter &xmlFile) override;
BlockFile *Copy(wxFileNameWrapper &&fileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&fileName) override;
void Recover() override;
static BlockFile *BuildFromXML(DirManager &dm, const wxChar **attrs);
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs);
};
#endif

View File

@ -51,7 +51,7 @@ void SilentBlockFile::SaveXML(XMLWriter &xmlFile)
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
/// static
BlockFile *SilentBlockFile::BuildFromXML(DirManager & WXUNUSED(dm), const wxChar **attrs)
BlockFilePtr SilentBlockFile::BuildFromXML(DirManager & WXUNUSED(dm), const wxChar **attrs)
{
long nValue;
sampleCount len = 0;
@ -71,13 +71,13 @@ BlockFile *SilentBlockFile::BuildFromXML(DirManager & WXUNUSED(dm), const wxChar
len = nValue;
}
return new SilentBlockFile(len);
return make_blockfile<SilentBlockFile>(len);
}
/// Create a copy of this BlockFile
BlockFile *SilentBlockFile::Copy(wxFileNameWrapper &&)
BlockFilePtr SilentBlockFile::Copy(wxFileNameWrapper &&)
{
BlockFile *newBlockFile = new SilentBlockFile(mLen);
auto newBlockFile = make_blockfile<SilentBlockFile>(mLen);
return newBlockFile;
}

View File

@ -39,13 +39,13 @@ class SilentBlockFile final : public BlockFile {
sampleCount start, sampleCount len) const override;
/// Create a NEW block file identical to this one
BlockFile *Copy(wxFileNameWrapper &&newFileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
/// Write an XML representation of this file
void SaveXML(XMLWriter &xmlFile) override;
wxLongLong GetSpaceUsage() const override;
void Recover() override { };
static BlockFile *BuildFromXML(DirManager &dm, const wxChar **attrs);
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs);
};
#endif

View File

@ -492,7 +492,7 @@ void SimpleBlockFile::SaveXML(XMLWriter &xmlFile)
// even if the result is flawed (e.g., refers to nonexistent file),
// as testing will be done in DirManager::ProjectFSCK().
/// static
BlockFile *SimpleBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
BlockFilePtr SimpleBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
{
wxFileNameWrapper fileName;
float min = 0.0f, max = 0.0f, rms = 0.0f;
@ -532,16 +532,17 @@ BlockFile *SimpleBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs)
}
}
return new SimpleBlockFile(std::move(fileName), len, min, max, rms);
return make_blockfile<SimpleBlockFile>
(std::move(fileName), len, min, max, rms);
}
/// Create a copy of this BlockFile, but using a different disk file.
///
/// @param newFileName The name of the NEW file to use.
BlockFile *SimpleBlockFile::Copy(wxFileNameWrapper &&newFileName)
BlockFilePtr SimpleBlockFile::Copy(wxFileNameWrapper &&newFileName)
{
BlockFile *newBlockFile = new SimpleBlockFile(std::move(newFileName), mLen,
mMin, mMax, mRMS);
auto newBlockFile = make_blockfile<SimpleBlockFile>
(std::move(newFileName), mLen, mMin, mMax, mRMS);
return newBlockFile;
}

View File

@ -68,14 +68,14 @@ class PROFILE_DLL_API SimpleBlockFile /* not final */ : public BlockFile {
sampleCount start, sampleCount len) const override;
/// Create a NEW block file identical to this one
BlockFile *Copy(wxFileNameWrapper &&newFileName) override;
BlockFilePtr Copy(wxFileNameWrapper &&newFileName) override;
/// Write an XML representation of this file
void SaveXML(XMLWriter &xmlFile) override;
wxLongLong GetSpaceUsage() const override;
void Recover() override;
static BlockFile *BuildFromXML(DirManager &dm, const wxChar **attrs);
static BlockFilePtr BuildFromXML(DirManager &dm, const wxChar **attrs);
bool GetNeedWriteCacheToDisk() override;
void WriteCacheToDisk() override;

View File

@ -49,8 +49,6 @@ void ODComputeSummaryTask::Terminate()
//The terminate block won't allow DoSomeInternal and this method to be run async, so this is thread-safe.
//Deref the block files since they are ref'ed when put into the array.
mBlockFilesMutex.Lock();
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
mBlockFilesMutex.Unlock();
}
@ -66,7 +64,6 @@ void ODComputeSummaryTask::DoSomeInternal()
return;
}
ODPCMAliasBlockFile* bf;
sampleCount blockStartSample = 0;
sampleCount blockEndSample = 0;
bool success =false;
@ -74,12 +71,12 @@ void ODComputeSummaryTask::DoSomeInternal()
mBlockFilesMutex.Lock();
for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++)
{
bf = mBlockFiles[0];
const auto &bf = mBlockFiles[0];
//first check to see if the ref count is at least 2. It should have one
//from when we added it to this instance's mBlockFiles array, and one from
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
if(bf->RefCount()>=2)
if(bf.use_count() >= 2)
{
bf->DoWriteSummary();
success = true;
@ -94,8 +91,6 @@ void ODComputeSummaryTask::DoSomeInternal()
mMaxBlockFiles--;
}
//Release the refcount we placed on it.
bf->Deref();
//take it out of the array - we are done with it.
mBlockFiles.erase(mBlockFiles.begin());
@ -170,7 +165,7 @@ void ODComputeSummaryTask::CalculatePercentComplete()
///by default left to right, or frome the point the user has clicked.
void ODComputeSummaryTask::Update()
{
std::vector<ODPCMAliasBlockFile*> tempBlocks;
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > tempBlocks;
mWaveTrackMutex.Lock();
@ -202,11 +197,11 @@ void ODComputeSummaryTask::Update()
{
//if there is data but no summary, this blockfile needs summarizing.
SeqBlock &block = (*blocks)[i];
BlockFile *const file = block.f;
const auto &file = block.f;
if(file->IsDataAvailable() && !file->IsSummaryAvailable())
{
file->Ref();
ODPCMAliasBlockFile *const odpcmaFile = static_cast<ODPCMAliasBlockFile*>(file);
const auto odpcmaFile =
std::static_pointer_cast<ODPCMAliasBlockFile>(file);
odpcmaFile->SetStart(block.start);
odpcmaFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
@ -235,11 +230,9 @@ void ODComputeSummaryTask::Update()
///Computes the summary calculation queue order of the blockfiles
void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks)
void ODComputeSummaryTask::OrderBlockFiles
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks)
{
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
@ -253,7 +246,7 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
//check to see if the refcount is at least two before we add it to the list.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//If there isn't, then the block was deleted for some reason and we should ignore it.
if(unorderedBlocks[i]->RefCount()>=2)
if(unorderedBlocks[i].use_count() >= 2)
{
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
//and add ones that are closer.
@ -277,7 +270,6 @@ void ODComputeSummaryTask::OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &un
else
{
//Otherwise, let it be deleted and forget about it.
unorderedBlocks[i]->Deref();
}
}
}

View File

@ -64,7 +64,8 @@ protected:
void Update() override;
///Orders the input as either On-Demand or default layered order.
void OrderBlockFiles(std::vector<ODPCMAliasBlockFile*> &unorderedBlocks);
void OrderBlockFiles
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks);
///tells us whether or not Update has been run at least once.
void MarkUpdateRan();
@ -72,7 +73,7 @@ protected:
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
ODLock mBlockFilesMutex;
std::vector<ODPCMAliasBlockFile*> mBlockFiles;
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > mBlockFiles;
int mMaxBlockFiles;
int mComputedBlockFiles;
ODLock mHasUpdateRanMutex;

View File

@ -42,7 +42,6 @@ void ODDecodeTask::DoSomeInternal()
return;
}
ODDecodeBlockFile* bf;
ODFileDecoder* decoder;
sampleCount blockStartSample = 0;
sampleCount blockEndSample = 0;
@ -50,21 +49,21 @@ void ODDecodeTask::DoSomeInternal()
for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++)
{
bf = mBlockFiles[0];
const auto &bf = mBlockFiles[0];
int ret = 1;
//first check to see if the ref count is at least 2. It should have one
//from when we added it to this instance's mBlockFiles array, and one from
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
if(bf->RefCount()>=2)
if(bf.use_count()>=2)
{
//OD TODO: somehow pass the bf a reference to the decoder that manages it's file.
//we need to ensure that the filename won't change or be moved. We do this by calling LockRead(),
//which the dirmanager::EnsureSafeFilename also does.
bf->LockRead();
//Get the decoder. If the file was moved, we need to create another one and init it.
decoder=GetOrCreateMatchingFileDecoder(bf);
decoder = GetOrCreateMatchingFileDecoder( &*bf );
if(!decoder->IsInitialized())
decoder->Init();
bf->SetODFileDecoder(decoder);
@ -87,7 +86,6 @@ void ODDecodeTask::DoSomeInternal()
//Release the refcount we placed on it if we are successful
if(ret >= 0 ) {
bf->Deref();
//take it out of the array - we are done with it.
mBlockFiles.erase(mBlockFiles.begin());
@ -127,8 +125,7 @@ bool ODDecodeTask::SeekingAllowed()
///by default creates the order of the wavetrack to load.
void ODDecodeTask::Update()
{
std::vector<ODDecodeBlockFile*> tempBlocks;
std::vector< std::shared_ptr< ODDecodeBlockFile > > tempBlocks;
mWaveTrackMutex.Lock();
@ -155,12 +152,12 @@ void ODDecodeTask::Update()
{
//since we have more than one ODBlockFile, we will need type flags to cast.
SeqBlock &block = (*blocks)[i];
BlockFile *const file = block.f;
ODDecodeBlockFile *oddbFile;
const auto &file = block.f;
std::shared_ptr<ODDecodeBlockFile> oddbFile;
if (!file->IsDataAvailable() &&
(oddbFile = static_cast<ODDecodeBlockFile*>(file))->GetDecodeType() == this->GetODType())
(oddbFile =
std::static_pointer_cast<ODDecodeBlockFile>(file))->GetDecodeType() == this->GetODType())
{
file->Ref();
oddbFile->SetStart(block.start);
oddbFile->SetClipOffset((sampleCount)(clip->GetStartTime()*clip->GetRate()));
@ -187,11 +184,9 @@ void ODDecodeTask::Update()
///Orders the input as either On-Demand or default layered order.
void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks)
void ODDecodeTask::OrderBlockFiles
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks)
{
//we are going to take things out of the array. But first deref them since we ref them when we put them in.
for(unsigned int i=0;i<mBlockFiles.size();i++)
mBlockFiles[i]->Deref();
mBlockFiles.clear();
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
//for now just put them in linear. We start the order from the first block that includes the ondemand sample
@ -204,7 +199,7 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
//check to see if the refcount is at least two before we add it to the list.
//There should be one Ref() from the one added by this ODTask, and one from the track.
//If there isn't, then the block was deleted for some reason and we should ignore it.
if(unorderedBlocks[i]->RefCount()>=2)
if(unorderedBlocks[i].use_count() >= 2)
{
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
//and add ones that are closer.
@ -228,8 +223,6 @@ void ODDecodeTask::OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlo
}
else
{
//Otherwise, let it be deleted and forget about it.
unorderedBlocks[i]->Deref();
}
}

View File

@ -85,10 +85,11 @@ protected:
void Update() override;
///Orders the input as either On-Demand or default layered order.
void OrderBlockFiles(std::vector<ODDecodeBlockFile*> &unorderedBlocks);
void OrderBlockFiles
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks);
std::vector<ODDecodeBlockFile*> mBlockFiles;
std::vector<std::shared_ptr<ODDecodeBlockFile>> mBlockFiles;
std::vector<movable_ptr<ODFileDecoder>> mDecoders;
int mMaxBlockFiles;