Update of /cvsroot/audacity/audacity-src/src/blockfile
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv4140/blockfile
Modified Files:
ODPCMAliasBlockFile.cpp ODPCMAliasBlockFile.h
Log Message:
Support for save for OD. mutex issues fixes. tentative exportffmpeg mac
compile fix.
Index: ODPCMAliasBlockFile.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/blockfile/ODPCMAliasBlockFile.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ODPCMAliasBlockFile.cpp 7 Aug 2008 00:06:40 -0000 1.11
+++ ODPCMAliasBlockFile.cpp 10 Aug 2008 02:31:09 -0000 1.12
@@ -31,6 +31,9 @@
#include "../FileFormats.h"
#include "../Internat.h"
+//#include <errno.h>
+
+
const int aheaderTagLen = 20;
char aheaderTag[aheaderTagLen + 1] = "AudacityBlockFile112";
@@ -41,21 +44,30 @@
PCMAliasBlockFile(fileName, aliasedFile, aliasStart, aliasLen,
aliasChannel,false)
{
- mSummaryAvailable=mSummaryBeingComputed=false;
+ mSummaryAvailable=mSummaryBeingComputed=mHasBeenSaved=false;
+ mFileNameChar = new
char[strlen(mFileName.GetFullPath().mb_str(wxConvUTF8))+1];
+ strcpy(mFileNameChar,mFileName.GetFullPath().mb_str(wxConvUTF8));
+
+
}
+///summaryAvailable should be true if the file has been written already.
ODPCMAliasBlockFile::ODPCMAliasBlockFile(wxFileName existingFileName,
wxFileName aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel,
- float min, float max, float rms):
+ float min, float max, float rms, bool summaryAvailable):
PCMAliasBlockFile(existingFileName, aliasedFile, aliasStart, aliasLen,
aliasChannel, min, max, rms)
{
- mSummaryAvailable=mSummaryBeingComputed=false;
-}
+ mSummaryAvailable=summaryAvailable;
+ mSummaryBeingComputed=mHasBeenSaved=false;
+ mFileNameChar = new
char[strlen(mFileName.GetFullPath().mb_str(wxConvUTF8))+1];
+ strcpy(mFileNameChar,mFileName.GetFullPath().mb_str(wxConvUTF8));
+ }
ODPCMAliasBlockFile::~ODPCMAliasBlockFile()
{
+ delete [] mFileNameChar;
}
@@ -64,8 +76,12 @@
{
if(IsSummaryAvailable())
{
+ wxLongLong ret;
+ mFileNameMutex.Unlock();
wxFFile summaryFile(mFileName.GetFullPath());
- return summaryFile.Length();
+ ret= summaryFile.Length();
+ mFileNameMutex.Unlock();
+ return ret;
}
else
{
@@ -73,6 +89,30 @@
}
}
+/// Locks the blockfile only if it has a file that exists. This needs to be
done
+/// so that the unsaved ODPCMAliasBlockfiles are deleted upon exit
+void ODPCMAliasBlockFile::Lock()
+{
+ if(IsSummaryAvailable()&&mHasBeenSaved)
+ PCMAliasBlockFile::Lock();
+}
+
+//when the file closes, it locks the blockfiles, but it calls this so we can
check if it has been saved before.
+void ODPCMAliasBlockFile::CloseLock()
+{
+ if(mHasBeenSaved)
+ PCMAliasBlockFile::Lock();
+}
+
+
+/// unlocks the blockfile only if it has a file that exists. This needs to be
done
+/// so that the unsaved ODPCMAliasBlockfiles are deleted upon exit
+void ODPCMAliasBlockFile::Unlock()
+{
+ if(IsSummaryAvailable() && IsLocked())
+ PCMAliasBlockFile::Unlock();
+}
+
/// Gets extreme values for the specified region
void ODPCMAliasBlockFile::GetMinMax(sampleCount start, sampleCount len,
@@ -147,8 +187,11 @@
{
BlockFile *newBlockFile;
-
- if(IsSummaryAvailable())
+ //If the file has been written AND it has been saved, we create a PCM alias
blockfile because for
+ //all intents and purposes, it is the same.
+ //However, if it hasn't been saved yet, we shouldn't create one because the
default behavior of the
+ //PCMAliasBlockFile is to lock on exit, and this will cause orphaned
blockfiles..
+ if(IsSummaryAvailable() && mHasBeenSaved)
{
newBlockFile = new PCMAliasBlockFile(newFileName,
mAliasedFileName,
mAliasStart,
@@ -158,12 +201,11 @@
}
else
{
- //Summary File doesn't exist in this case.
- //Also, this one needs to be scheduled for loading as well ... what to
do?
+ //Summary File might exist in this case, but it might not.
newBlockFile = new ODPCMAliasBlockFile(newFileName,
mAliasedFileName,
mAliasStart,
mLen, mAliasChannel,
- mMin, mMax, mRMS);
+ mMin, mMax,
mRMS,IsSummaryAvailable());
//The client code will need to schedule this blockfile for OD
summarizing if it is going to a new track.
}
@@ -181,12 +223,16 @@
if(IsSummaryAvailable())
{
PCMAliasBlockFile::SaveXML(xmlFile);
+ mHasBeenSaved = true;
}
else
{
xmlFile.StartTag(wxT("odpcmaliasblockfile"));
+ mFileNameMutex.Lock();
xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
+ mFileNameMutex.Unlock();
+
xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
xmlFile.WriteAttr(wxT("aliasstart"), mAliasStart);
xmlFile.WriteAttr(wxT("aliaslen"), mLen);
@@ -201,7 +247,7 @@
}
/// Constructs a ODPCMAliasBlockFile from the xml output of WriteXML.
-/// Also schedules the ODPCMAliasBlockFile for OD loading.
+/// Does not schedule the ODPCMAliasBlockFile for OD loading. Client code
must do this.
BlockFile *ODPCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar
**attrs)
{
wxFileName summaryFileName;
@@ -304,25 +350,48 @@
mWriteSummaryMutex.Unlock();
}
+///sets the file name the summary info will be saved in. threadsafe.
+void ODPCMAliasBlockFile::SetFileName(wxFileName &name)
+{
+ mFileNameMutex.Lock();
+ mFileName=name;
+ delete [] mFileNameChar;
+ mFileNameChar = new
char[strlen(mFileName.GetFullPath().mb_str(wxConvUTF8))+1];
+ strcpy(mFileNameChar,mFileName.GetFullPath().mb_str(wxConvUTF8));
+ mFileNameMutex.Unlock();
+}
+
+///sets the file name the summary info will be saved in. threadsafe.
+wxFileName ODPCMAliasBlockFile::GetFileName()
+{
+ wxFileName name;
+ mFileNameMutex.Lock();
+ name = mFileName;
+ mFileNameMutex.Unlock();
+ return name;
+}
+
/// Write the summary to disk, using the derived ReadData() to get the data
void ODPCMAliasBlockFile::WriteSummary()
{
+ //the mFileName path may change, for example, when the project is saved.
+ //(it moves from /tmp/ to wherever it is saved to.
+ mFileNameMutex.Lock();
+ //wxFFile is not thread-safe - if any error occurs in fopen, it posts a
wxlog message which WILL crash
+ //audacity because it goes into the wx GUI. For this reason I left the
FILE* method commented out (mchinen)
+ //wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb"));
- //Below from BlockFile.cpp's method. We need to delete the data returned by
- //CalcSummary, because it uses local info. In the future we might do
something
- //smarter and thread-dependant like a static thread context.
- wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb"));
+ FILE* summaryFile=fopen(mFileNameChar, "wb");
- if( !summaryFile.IsOpened() ){
- // Never silence the Log w.r.t write errors; they always count
- // as new errors
+ if( !summaryFile){//.IsOpened() ){
+ // Never silence the Log w.r.t write errors; they always count
//however, this is going to be called from a non-main thread,
//and wxLog calls are not thread safe.
- printf("Unable to write summary data to file");// %s",
- // mFileName.GetFullPath().c_str());
- // If we can't write, there's nothing to do.
-
+ printf("Unable to write summary data to file: ");// %s",
+ printf("test..\n");
+ printf(" filename: %s\n",mFileNameChar);
+ mFileNameMutex.Unlock();
return;
}
@@ -333,15 +402,17 @@
void *summaryData = CalcSummary(sampleData, mLen,
floatSample);
- summaryFile.Write(summaryData, mSummaryInfo.totalSummaryBytes);
-
+
+ //summaryFile.Write(summaryData, mSummaryInfo.totalSummaryBytes);
+ fwrite(summaryData, 1, mSummaryInfo.totalSummaryBytes, summaryFile);
+ fclose(summaryFile);
DeleteSamples(sampleData);
delete [] (char *) summaryData;
-
- //above from BlockFiles.cpps method
+ mFileNameMutex.Unlock();
+ // printf("write successful. filename: %s\n",mFileNameChar);
mSummaryAvailableMutex.Lock();
mSummaryAvailable=true;
@@ -515,7 +586,10 @@
memset(&info, 0, sizeof(info));
- SNDFILE *sf=sf_open(OSFILENAME(mAliasedFileName.GetFullPath()),
+ wxString aliasPath = mAliasedFileName.GetFullPath();
+ //there are thread-unsafe crashes here - not sure why. sf_open may be
called on the same file
+ //from different threads, but this seems okay, unless it is implemented
strangely..
+ SNDFILE *sf=sf_open(OSFILENAME(aliasPath),
SFM_READ, &info);
if (!sf){
@@ -571,6 +645,8 @@
/// be at least mSummaryInfo.totalSummaryBytes long.
bool ODPCMAliasBlockFile::ReadSummary(void *data)
{
+
+ mFileNameMutex.Lock();
wxFFile summaryFile(mFileName.GetFullPath(), wxT("rb"));
if( !summaryFile.IsOpened() ){
@@ -583,6 +659,8 @@
// spewing at the user will complicate the user's ability to
// deal
mSilentLog=TRUE;
+
+ mFileNameMutex.Unlock();
return true;
}else mSilentLog=FALSE; // worked properly, any future error is new
@@ -591,6 +669,8 @@
FixSummary(data);
+
+ mFileNameMutex.Unlock();
return (read == mSummaryInfo.totalSummaryBytes);
}
Index: ODPCMAliasBlockFile.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/blockfile/ODPCMAliasBlockFile.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- ODPCMAliasBlockFile.h 5 Aug 2008 02:19:58 -0000 1.9
+++ ODPCMAliasBlockFile.h 10 Aug 2008 02:31:09 -0000 1.10
@@ -56,7 +56,7 @@
ODPCMAliasBlockFile(wxFileName existingFileName,
wxFileName aliasedFile, sampleCount aliasStart,
sampleCount aliasLen, int aliasChannel,
- float min, float max, float rms);
+ float min, float max, float rms, bool summaryAvailable);
virtual ~ODPCMAliasBlockFile();
//checks to see if summary data has been computed and written to disk yet.
Thread safe. Blocks if we are writing summary data.
@@ -98,6 +98,12 @@
///Gets the value that indicates where the first sample in this block
corresponds to the global sequence/clip. Only for display use.
sampleCount GetStart(){return mStart;}
+ /// Locks the blockfile only if it has a file that exists.
+ void Lock();
+
+ /// Unlocks the blockfile only if it has a file that exists.
+ void Unlock();
+
///sets the amount of samples the clip associated with this blockfile is
offset in the wavetrack (non effecting)
void SetClipOffset(sampleCount numSamples){mClipOffset= numSamples;}
@@ -112,21 +118,37 @@
/// Read the summary into a buffer
virtual bool ReadSummary(void *data);
-
+
+ ///sets the file name the summary info will be saved in. threadsafe.
+ virtual void SetFileName(wxFileName &name);
+ virtual wxFileName GetFileName();
+
+ //when the file closes, it locks the blockfiles, but it calls this so we
can check if it has been saved before.
+ virtual void CloseLock();
protected:
virtual void WriteSummary();
virtual void *CalcSummary(samplePtr buffer, sampleCount len,
sampleFormat format);
+
+ char* mFileNameChar;
+
ODLock mWriteSummaryMutex;
+ //need to protect this since it is changed from the main thread upon save.
+ ODLock mFileNameMutex;
+
+ ///Also need to protect the aliased file name.
+ ODLock mAliasedFileNameMutex;
+
//lock the read data - libsndfile can't handle two reads at once?
ODLock mReadDataMutex;
ODLock mSummaryAvailableMutex;
bool mSummaryAvailable;
bool mSummaryBeingComputed;
+ bool mHasBeenSaved;
///for reporting after task is complete. Only for display use.
sampleCount mStart;
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs