/// If the summary has been computed,
/// 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(wxFileName newFileName)
{
   BlockFile *newBlockFile;
   
   //mAliasedFile can change so we lock readdatamutex, which is responsible for it.
   LockRead();
   if(IsSummaryAvailable())
   {
      //create a simpleblockfile, because once it has the summary it is a simpleblockfile for all intents an purposes
      newBlockFile  = SimpleBlockFile::Copy(newFileName) ; 
   }
   else
   {
      //Summary File might exist in this case, but it probably (99.999% of the time) won't.
      newBlockFile  = new ODDecodeBlockFile(newFileName,
                                                   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.
   }
   
   UnlockRead();
   
   return newBlockFile;
}
Пример #2
0
/// If the summary has been computed,
/// 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(wxFileName newFileName)
{
   BlockFile *newBlockFile;
   
   //mAliasedFile can change so we lock readdatamutex, which is responsible for it.
   mReadDataMutex.Lock();
   //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,
                                                   mLen, mAliasChannel,
                                                   mMin, mMax, mRMS);

   }
   else
   {
      //Summary File might exist in this case, but it might not.
      newBlockFile  = new ODPCMAliasBlockFile(newFileName,
                                                   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.
   }
   
   mReadDataMutex.Unlock();
   
   return newBlockFile;
}
/// Writes the xml as a SimpleBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODDecodeBlockFile::SaveXML(XMLWriter &xmlFile)
{
   LockRead();
   if(IsSummaryAvailable())
   {
      SimpleBlockFile::SaveXML(xmlFile);
   }
   else
   {
      xmlFile.StartTag(wxT("oddecodeblockfile"));
       //unlock to prevent deadlock and resume lock after.
      UnlockRead();
      mFileNameMutex.Lock();
      xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      mFileNameMutex.Unlock();
      LockRead();
      xmlFile.WriteAttr(wxT("audiofile"), mAudioFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"), mAliasStart);
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
      xmlFile.WriteAttr(wxT("decodetype"), (size_t)mType);

      xmlFile.EndTag(wxT("oddecodeblockfile"));
   }
   UnlockRead();
}
Пример #4
0
/// Writes the xml as a PCMAliasBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODPCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
{
   //we lock this so that mAliasedFileName doesn't change.
   LockRead();
   if(IsSummaryAvailable())
   {
      PCMAliasBlockFile::SaveXML(xmlFile);
      mHasBeenSaved = true;
   }
   else
   {
      xmlFile.StartTag(wxT("odpcmaliasblockfile"));

      //unlock to prevent deadlock and resume lock after.
      UnlockRead();
      mFileNameMutex.Lock();
      xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      mFileNameMutex.Unlock();
      LockRead();

      xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"), mAliasStart);
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);

      xmlFile.EndTag(wxT("odpcmaliasblockfile"));
   }

   UnlockRead();
}
Пример #5
0
/// If the summary has been computed,
/// 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(wxFileName newFileName)
{
    BlockFile *newBlockFile;


    if(IsSummaryAvailable())
    {
        //create a simpleblockfile, because once it has the summary it is a simpleblockfile for all intents an purposes
        newBlockFile  = SimpleBlockFile::Copy(newFileName) ;
    }
    else
    {
        //TODO:do the correct constructor thingthing for this one.
        //Also, this one needs to be scheduled for loading as well ... what to do?
        newBlockFile  = NULL; // new ODPCMAliasBlockFile(newFileName,
        //                     mAliasedFileName, mAliasStart,
        //                   mLen, mAliasChannel,
        //                 mMin, mMax, mRMS);
        //TODO:add to the ODManager Task list so this one loads itself.  It's wasteful to do this twice, but lets be simple and naieve
        //just this once,.
    }


    return newBlockFile;
}
Пример #6
0
void ODDecodeBlockFile::Recover(void)
{
    if(IsSummaryAvailable())
    {
        WriteODDecodeBlockFile();
    }
}
Пример #7
0
/// Writes the xml as a SimpleBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODDecodeBlockFile::SaveXML(XMLWriter &xmlFile)
// may throw
{
   auto locker = LockForRead();
   if(IsSummaryAvailable())
   {
      SimpleBlockFile::SaveXML(xmlFile);
   }
   else
   {
      xmlFile.StartTag(wxT("oddecodeblockfile"));
      {
         //unlock to prevent deadlock and resume lock after.
         auto suspension = locker.Suspend();
         ODLocker locker2{ &mFileNameMutex };
         xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      }
      xmlFile.WriteAttr(wxT("audiofile"), mAudioFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"),
                        mAliasStart.as_long_long());
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
      xmlFile.WriteAttr(wxT("decodetype"), (size_t)mType);

      xmlFile.EndTag(wxT("oddecodeblockfile"));
   }
}
Пример #8
0
/// Writes the xml as a PCMAliasBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODPCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
{
   //we lock this so that mAliasedFileName doesn't change.
   mReadDataMutex.Lock();
   if(IsSummaryAvailable())
   {
      PCMAliasBlockFile::SaveXML(xmlFile);
      mHasBeenSaved = true;
   }
   else
   {
      xmlFile.StartTag(wxT("odpcmaliasblockfile"));

      //unlock to prevent deadlock and resume lock after.
      mReadDataMutex.Unlock();
      mFileNameMutex.Lock();
      xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      mFileNameMutex.Unlock();
      mReadDataMutex.Lock();
      
      xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"), mAliasStart);
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
      //these have not been computed yet.
      //xmlFile.WriteAttr(wxT("min"), mMin);
      //xmlFile.WriteAttr(wxT("max"), mMax);
     // xmlFile.WriteAttr(wxT("rms"), mRMS);

      xmlFile.EndTag(wxT("odpcmaliasblockfile"));
   }
   
   mReadDataMutex.Unlock();
}
Пример #9
0
/// If the summary has been computed,
/// 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(wxFileName newFileName)
{
   BlockFile *newBlockFile;
   
   
   if(IsSummaryAvailable())
   {
      newBlockFile  = new PCMAliasBlockFile(newFileName,
                                                   mAliasedFileName, mAliasStart,
                                                   mLen, mAliasChannel,
                                                   mMin, mMax, mRMS);

   }
   else
   {
      //TODO: does it make sense to create a copy of ODPCMAliasBF?  Summary File doesn't exist in this case.
      //Also, this one needs to be scheduled for loading as well ... what to do?
      newBlockFile  = new ODPCMAliasBlockFile(newFileName,
                                                   mAliasedFileName, mAliasStart,
                                                   mLen, mAliasChannel,
                                                   mMin, mMax, mRMS);
      //TODO:add to the ODManager Task list so this one loads itself.  It's wasteful to do this twice, but lets be simple and naieve
      //just this once,.
   }
   
   
   return newBlockFile;
}
Пример #10
0
void ODPCMAliasBlockFile::Recover(void)
{
   if(IsSummaryAvailable())
   {
      WriteSummary();
   }
}
Пример #11
0
/// Writes the xml as a PCMAliasBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet exist, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODPCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
// may throw
{
   //we lock this so that mAliasedFileName doesn't change.
   auto locker = LockForRead();
   if(IsSummaryAvailable())
   {
      PCMAliasBlockFile::SaveXML(xmlFile);
      mHasBeenSaved = true;
   }
   else
   {
      xmlFile.StartTag(wxT("odpcmaliasblockfile"));

      //unlock to prevent deadlock and resume lock after.
      {
         auto suspension = locker.Suspend();
         ODLocker locker2 { &mFileNameMutex };
         xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      }

      xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"),
                        mAliasStart.as_long_long());
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);

      xmlFile.EndTag(wxT("odpcmaliasblockfile"));
   }
}
Пример #12
0
///Calls write summary, and makes sure it is only done once in a thread-safe fasion.
void ODPCMAliasBlockFile::DoWriteSummary()
{
   mWriteSummaryMutex.Lock();
   if(!IsSummaryAvailable())
      WriteSummary();
   mWriteSummaryMutex.Unlock();
}
/// Read the summary of this alias block from disk.  Since the audio data
/// is elsewhere, this consists of reading the entire summary file.
///
/// @param *data The buffer where the summary data will be stored.  It must
///              be at least mSummaryInfo.totalSummaryBytes long.
bool ODDecodeBlockFile::ReadSummary(void *data)
{
   //I dont think we need to add a mutex here because only the main thread changes filenames and calls ReadSummarz
   if(IsSummaryAvailable())
      return SimpleBlockFile::ReadSummary(data);
   
   memset(data, 0, (size_t)mSummaryInfo.totalSummaryBytes);
   return true;
}
Пример #14
0
/// Read the summary of this alias block from disk.  Since the audio data
/// is elsewhere, this consists of reading the entire summary file.
/// Fill with zeroes and return false if data are unavailable for any reason.
///
/// @param *data The buffer where the summary data will be stored.  It must
///              be at least mSummaryInfo.totalSummaryBytes long.
bool ODDecodeBlockFile::ReadSummary(ArrayOf<char> &data)
{
   //I dont think we need to add a mutex here because only the main thread changes filenames and calls ReadSummary
   if(IsSummaryAvailable())
      return SimpleBlockFile::ReadSummary(data);

   data.reinit( mSummaryInfo.totalSummaryBytes );
   memset(data.get(), 0, mSummaryInfo.totalSummaryBytes);
   return false;
}
Пример #15
0
/// Reads the specified data from the aliased file, using libsndfile,
/// and converts it to the given sample format.
///
/// @param data   The buffer to read the sample data into.
/// @param format The format to convert the data into
/// @param start  The offset within the block to begin reading
/// @param len    The number of samples to read
int ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
                                sampleCount start, sampleCount len)
{

    if(IsSummaryAvailable())
        return SimpleBlockFile::ReadData(data,format,start,len);
    else
        return 0; //TODO: do we need to zero out the data?  It would be more efficient if the client code checked
    //ISSummaryAvailable first.
}
Пример #16
0
/// Returns the 64K summary data block
/// Fill with zeroes and return false if data are unavailable for any reason.
bool ODDecodeBlockFile::Read64K(float *buffer, size_t start, size_t len)
{
   if(IsSummaryAvailable())
   {
      return SimpleBlockFile::Read64K(buffer,start,len);
   }
   else
   {
      ClearSamples((samplePtr)buffer, floatSample, 0, len);
      return false;
   }
}
Пример #17
0
/// Returns the 64K summary data block
bool ODDecodeBlockFile::Read64K(float *buffer, sampleCount start, sampleCount len)
{
    if(IsSummaryAvailable())
    {
        return SimpleBlockFile::Read64K(buffer,start,len);
    }
    else
    {
        //TODO: put some dummy value?  should we make a fake one?
        return true;
    }
}
Пример #18
0
//Check to see if we have the file for these calls.
wxLongLong ODDecodeBlockFile::GetSpaceUsage()
{
    if(IsSummaryAvailable())
    {
        wxFFile summaryFile(mFileName.GetFullPath());
        return summaryFile.Length();
    }
    else
    {
        return 0;
    }
}
/// Returns the 64K summary data block
bool ODDecodeBlockFile::Read64K(float *buffer, sampleCount start, sampleCount len)
{
   if(IsSummaryAvailable())
   {
      return SimpleBlockFile::Read64K(buffer,start,len);
   }
   else
   {
      //this should not be reached (client should check IsSummaryAvailable()==true before this.
      return true;
   }
}
Пример #20
0
/// Returns the 64K summary data block.
/// Fill with zeroes and return false if data are unavailable for any reason.
bool ODPCMAliasBlockFile::Read64K(float *buffer, size_t start, size_t len)
{
   if(IsSummaryAvailable())
   {
      return PCMAliasBlockFile::Read64K(buffer,start,len);
   }
   else
   {
      //return nothing - it hasn't been calculated yet
      ClearSamples((samplePtr)buffer, floatSample, 0, len);
      return false;
   }
}
Пример #21
0
/// Returns the 256 byte summary data block.
/// Fill with zeroes and return false if data are unavailable for any reason.
bool ODPCMAliasBlockFile::Read256(float *buffer, size_t start, size_t len)
{
   if(IsSummaryAvailable())
   {
      return PCMAliasBlockFile::Read256(buffer,start,len);
   }
   else
   {
      //return nothing.
      ClearSamples((samplePtr)buffer, floatSample, 0, len);
      return false;
   }
}
Пример #22
0
/// Returns the 256 byte summary data block
bool ODPCMAliasBlockFile::Read256(float *buffer, sampleCount start, sampleCount len)
{
   if(IsSummaryAvailable())
   {
      return PCMAliasBlockFile::Read256(buffer,start,len);
   }
   else
   {
      //TODO: put some dummy value?  should we make a fake one?
      buffer = NULL;
      return true;
   }
}
Пример #23
0
/// Returns the 64K summary data block. Clients should check to see if the summary is available before trying to read it with this call.
bool ODPCMAliasBlockFile::Read64K(float *buffer, sampleCount start, sampleCount len)
{
   if(IsSummaryAvailable())
   {
      return PCMAliasBlockFile::Read64K(buffer,start,len);
   }
   else
   {
      //return nothing - it hasn't been calculated yet
      buffer = NULL;
      return true;
   }
}
Пример #24
0
/// Returns the 256 byte summary data block.  Clients should check to see if the summary is available before trying to read it with this call.
bool ODPCMAliasBlockFile::Read256(float *buffer, sampleCount start, sampleCount len)
{
   if(IsSummaryAvailable())
   {
      return PCMAliasBlockFile::Read256(buffer,start,len);
   }
   else
   {
      //return nothing.  
      buffer = NULL;
      return true;
   }
}
Пример #25
0
/// Gets extreme values for the entire block
void ODPCMAliasBlockFile::GetMinMax(float *outMin, float *outMax, float *outRMS)
{
  if(IsSummaryAvailable())
   {
      PCMAliasBlockFile::GetMinMax(outMin,outMax,outRMS);
   }
   else
   {
      //fake values.  These values are used usually for normalization and amplifying, so we want 
      //the max to be maximal and the min to be minimal
      *outMin = -1.0*JUST_BELOW_MAX_AUDIO;
      *outMax = 1.0*JUST_BELOW_MAX_AUDIO;
      *outRMS = (float)0.707;//sin with amp of 1 rms
   }
}
Пример #26
0
/// Gets extreme values for the specified region
void ODDecodeBlockFile::GetMinMax(sampleCount start, sampleCount len,
                                  float *outMin, float *outMax, float *outRMS)
{
    if(IsSummaryAvailable())
    {
        SimpleBlockFile::GetMinMax(start,len,outMin,outMax,outRMS);
    }
    else
    {
        //fake values.  These values are used usually for normalization and amplifying, so we want
        //the max to be maximal and the min to be minimal
        *outMin = -1.0;
        *outMax = 1.0;
        *outRMS = (float)0.707;//sin with amp of 1 rms
    }
}
Пример #27
0
//Check to see if we have the file for these calls.
wxLongLong ODPCMAliasBlockFile::GetSpaceUsage()
{ 
   if(IsSummaryAvailable())
   {
      wxLongLong ret;
      mFileNameMutex.Lock();
      wxFFile summaryFile(mFileName.GetFullPath());
      ret= summaryFile.Length();
      mFileNameMutex.Unlock();
      return ret;
   }
   else
   {
      return 0;
   }
}
Пример #28
0
/// Reads the specified data from the aliased file, using libsndfile,
/// and converts it to the given sample format.
///
/// @param data   The buffer to read the sample data into.
/// @param format The format to convert the data into
/// @param start  The offset within the block to begin reading
/// @param len    The number of samples to read
size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
                                size_t start, size_t len, bool mayThrow) const
{
   auto locker = LockForRead();
   if(IsSummaryAvailable())
      return SimpleBlockFile::ReadData(data, format, start, len, mayThrow);
   else
   {
      if (mayThrow)
         throw NotYetAvailableException{ mAudioFileName };

      //we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile
      //ReadData.
      ClearSamples(data, format, 0, len);
      return 0;
   }
}
/// Reads the specified data from the aliased file, using libsndfile,
/// and converts it to the given sample format.
///
/// @param data   The buffer to read the sample data into.
/// @param format The format to convert the data into
/// @param start  The offset within the block to begin reading
/// @param len    The number of samples to read
int ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format,
                                sampleCount start, sampleCount len)
{
   int ret;
   LockRead();
   if(IsSummaryAvailable())
      ret= SimpleBlockFile::ReadData(data,format,start,len);
   else
   {
      //we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFIle
      //ReadData.
      ClearSamples(data, format, 0, len);
      ret= len;
   }
   UnlockRead();
   return ret;
}
Пример #30
0
/// Writes the xml as a PCMAliasBlockFile if we can (if we have a summary file)
/// Otherwise writes XML as a subset of attributes with 'odpcmaliasblockfile as the start tag.
/// Most notably, the summaryfile attribute refers to a file that does not yet, so when the project file is read back in
/// and this object reconstructed, it needs to avoid trying to open it as well as schedule itself for OD loading
void ODPCMAliasBlockFile::SaveXML(XMLWriter &xmlFile)
{
   if(IsSummaryAvailable())
   {
      PCMAliasBlockFile::SaveXML(xmlFile);
   }
   else
   {
      xmlFile.StartTag(wxT("odpcmaliasblockfile"));

      xmlFile.WriteAttr(wxT("summaryfile"), mFileName.GetFullName());
      xmlFile.WriteAttr(wxT("aliasfile"), mAliasedFileName.GetFullPath());
      xmlFile.WriteAttr(wxT("aliasstart"), mAliasStart);
      xmlFile.WriteAttr(wxT("aliaslen"), mLen);
      xmlFile.WriteAttr(wxT("aliaschannel"), mAliasChannel);
      //these have not been computed yet.
      //xmlFile.WriteAttr(wxT("min"), mMin);
      //xmlFile.WriteAttr(wxT("max"), mMax);
     // xmlFile.WriteAttr(wxT("rms"), mRMS);

      xmlFile.EndTag(wxT("odpcmaliasblockfile"));
   }
}