/[svn]/libgig/trunk/src/gig.cpp
ViewVC logotype

Diff of /libgig/trunk/src/gig.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2912 by schoenebeck, Tue May 17 14:30:10 2016 UTC revision 2913 by schoenebeck, Tue May 17 15:19:33 2016 UTC
# Line 3850  namespace { Line 3850  namespace {
3850          if ((int32_t)WavePoolTableIndex == -1) return NULL;          if ((int32_t)WavePoolTableIndex == -1) return NULL;
3851          File* file = (File*) GetParent()->GetParent();          File* file = (File*) GetParent()->GetParent();
3852          if (!file->pWavePoolTable) return NULL;          if (!file->pWavePoolTable) return NULL;
3853          if (file->HasMonolithicLargeFilePolicy()) {          // for new files or files >= 2 GB use 64 bit wave pool offsets
3854            if (file->pRIFF->IsNew() || (file->pRIFF->GetCurrentFileSize() >> 31)) {
3855                // use 64 bit wave pool offsets (treating this as large file)
3856              uint64_t soughtoffset =              uint64_t soughtoffset =
3857                  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |                  uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
3858                  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;                  uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
# Line 3861  namespace { Line 3863  namespace {
3863                  sample = file->GetNextSample();                  sample = file->GetNextSample();
3864              }              }
3865          } else {          } else {
3866                // use extension files and 32 bit wave pool offsets
3867              file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];              file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
3868              file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];              file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
3869              Sample* sample = file->GetFirstSample(pProgress);              Sample* sample = file->GetFirstSample(pProgress);
# Line 5348  namespace { Line 5351  namespace {
5351          int iTotalSamples = WavePoolCount;          int iTotalSamples = WavePoolCount;
5352    
5353          // check if samples should be loaded from extension files          // check if samples should be loaded from extension files
5354            // (only for old gig files < 2 GB)
5355          int lastFileNo = 0;          int lastFileNo = 0;
5356          if (!HasMonolithicLargeFilePolicy()) {          if (!file->IsNew() && !(file->GetCurrentFileSize() >> 31)) {
5357              for (int i = 0 ; i < WavePoolCount ; i++) {              for (int i = 0 ; i < WavePoolCount ; i++) {
5358                  if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];                  if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
5359              }              }
# Line 5841  namespace { Line 5845  namespace {
5845          }          }
5846      }      }
5847    
     /** @brief Returns the version number of libgig's Giga file format extension.  
      *  
      * libgig added several new features which were not available with the  
      * original GigaStudio software. For those purposes libgig's own custom RIFF  
      * chunks were added to the Giga file format.  
      *  
      * This method returns the version number of the Giga file format extension  
      * used in this Giga file. Currently there are 3 possible values that might  
      * be returned by this method:  
      *  
      * - @c 0: This gig file is not using any libgig specific file format  
      *         extension at all.  
      * - @c 1: This gig file uses the RT instrument script format extension.  
      * - @c 2: This gig file additionally provides support for monolithic  
      *         large gig files (larger than 2 GB).  
      *  
      * @note This method is currently protected and shall not be used as public  
      * API method, since its method signature might change in future.  
      */  
     uint File::GetFormatExtensionVersion() const {  
         RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);  
         if (!lst3LS) return 0; // is not using custom Giga format extensions at all  
         RIFF::Chunk* ckFFmt = lst3LS->GetSubChunk(CHUNK_ID_FFMT);  
         if (!ckFFmt) return 1; // uses custom Giga format extension(s) but had no format version saved  
         uint8_t* pData = (uint8_t*) ckFFmt->LoadChunkData();  
         return load32(pData);  
     }  
   
     /** @brief Returns true in case this file is stored as one, single monolithic gig file.  
      *  
      * To avoid issues with operating systems which did not support large files  
      * (larger than 2 GB) the original Giga file format avoided to ever save gig  
      * files larger than 2 GB, instead such large Giga files were splitted into  
      * several files, each one not being larger than 2 GB. It used a predefined  
      * file name scheme for them like this:  
      * @code  
      * foo.gig  
      * foo.gx01  
      * foo.gx02  
      * foo.gx03  
      * ...  
      * @endcode  
      * So when like in this example foo.gig was loaded, all other files  
      * (foo.gx01, ...) were automatically loaded as well to make up the overall  
      * large gig file (provided they were located at the same directory). Such  
      * additional .gxYY files were called "extension files".  
      *  
      * Since nowadays all modern systems support large files, libgig always  
      * saves large gig files as one single monolithic gig file instead, that  
      * is libgig won't split such a large gig file into separate files like the  
      * original GigaStudio software did. It uses a custom Giga file format  
      * extension for this feature.  
      *  
      * For still being able though to load old splitted gig files and the new  
      * large monolithic ones, this method is used to determine which loading  
      * policy must be used for this gig file.  
      *  
      * @note This method is currently protected and shall not be used as public  
      * API method, since its method signature might change in future and since  
      * this method should not be directly relevant for applications based on  
      * libgig.  
      */  
     bool File::HasMonolithicLargeFilePolicy() const {  
         RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);  
         if (!lst3LS) return false;  
         RIFF::Chunk* ckFFmt = lst3LS->GetSubChunk(CHUNK_ID_FFMT);  
         if (!ckFFmt) return false;  
         uint8_t* pData = (uint8_t*) ckFFmt->LoadChunkData();  
         uint32_t formatBitField = load32(&pData[4]);  
         return formatBitField & 1;  
     }  
   
5848      /**      /**
5849       * Apply all the gig file's current instruments, samples, groups and settings       * Apply all the gig file's current instruments, samples, groups and settings
5850       * to the respective RIFF chunks. You have to call Save() to make changes       * to the respective RIFF chunks. You have to call Save() to make changes
# Line 5927  namespace { Line 5859  namespace {
5859      void File::UpdateChunks(progress_t* pProgress) {      void File::UpdateChunks(progress_t* pProgress) {
5860          bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;          bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL;
5861    
         b64BitWavePoolOffsets = pVersion && pVersion->major == 3;  
   
5862          // update own gig format extension chunks          // update own gig format extension chunks
5863          // (not part of the GigaStudio 4 format)          // (not part of the GigaStudio 4 format)
5864          RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);          RIFF::List* lst3LS = pRIFF->GetSubList(LIST_TYPE_3LS);
# Line 5936  namespace { Line 5866  namespace {
5866              lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);              lst3LS = pRIFF->AddSubList(LIST_TYPE_3LS);
5867          }          }
5868          // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise          // Make sure <3LS > chunk is placed before <ptbl> chunk. The precise
5869          // location of <3LS > is irrelevant, however it MUST BE located BEFORE          // location of <3LS > is irrelevant, however it should be located
5870          // the actual wave data, otherwise the <3LS > chunk becomes          // before  the actual wave data
         // inaccessible on gig files larger than 4GB !  
5871          RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);          RIFF::Chunk* ckPTBL = pRIFF->GetSubChunk(CHUNK_ID_PTBL);
5872          pRIFF->MoveSubChunk(lst3LS, ckPTBL);          pRIFF->MoveSubChunk(lst3LS, ckPTBL);
5873    
         // Update <FFmt> chunk with informations about our file format  
         // extensions. Currently this <FFmt> chunk has the following  
         // layout:  
         //  
         // <uint32> -> (libgig's) File Format Extension version  
         // <uint32> -> Format bit field:  
         //             bit 0: If flag is not set use separate .gx01  
         //                    extension files if file is larger than 2 GB  
         //                    like with the original Giga format, if flag  
         //                    is set use 64 bit sample references and keep  
         //                    everything as one single monolithic gig file.  
         RIFF::Chunk* ckFFmt = lst3LS->GetSubChunk(CHUNK_ID_FFMT);  
         if (!ckFFmt) {  
             const int iChunkSize = 2 * sizeof(uint32_t);  
             ckFFmt = lst3LS->AddSubChunk(CHUNK_ID_FFMT, iChunkSize);  
         }  
         {  
             uint8_t* pData = (uint8_t*) ckFFmt->LoadChunkData();  
             store32(&pData[0], GIG_FILE_EXT_VERSION);  
             // for now we always save gig files larger than 2 GB as one  
             // single monolithic file (saving those with extension files is  
             // currently not supported and probably also not desired anymore  
             // nowadays).  
             uint32_t formatBitfield = 1;  
             store32(&pData[4], formatBitfield);  
         }  
5874          // This must be performed before writing the chunks for instruments,          // This must be performed before writing the chunks for instruments,
5875          // because the instruments' script slots will write the file offsets          // because the instruments' script slots will write the file offsets
5876          // of the respective instrument script chunk as reference.          // of the respective instrument script chunk as reference.
# Line 5980  namespace { Line 5883  namespace {
5883              }              }
5884          }          }
5885    
5886            // in case no libgig custom format data was added, then remove the
5887            // custom "3LS " chunk again
5888            if (!lst3LS->CountSubChunks()) {
5889                pRIFF->DeleteSubChunk(lst3LS);
5890                lst3LS = NULL;
5891            }
5892    
5893          // first update base class's chunks          // first update base class's chunks
5894          DLS::File::UpdateChunks(pProgress);          DLS::File::UpdateChunks(pProgress);
5895    

Legend:
Removed from v.2912  
changed lines
  Added in v.2913

  ViewVC Help
Powered by ViewVC