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

Reply via email to