/[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 3442 by schoenebeck, Sat Dec 22 18:59:29 2018 UTC revision 3474 by schoenebeck, Wed Feb 20 16:04:19 2019 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   libgig - C++ cross-platform Gigasampler format file access library    *   *   libgig - C++ cross-platform Gigasampler format file access library    *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003-2018 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2019 by Christian Schoenebeck                      *
6   *                              <cuse@users.sourceforge.net>               *   *                              <cuse@users.sourceforge.net>               *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
# Line 1748  namespace { Line 1748  namespace {
1748          // format extension for sustain pedal up effect on release trigger samples          // format extension for sustain pedal up effect on release trigger samples
1749          if (lsde && lsde->GetSize() > 3) { // NOTE: we reserved the 3rd byte for a potential future EG3 option          if (lsde && lsde->GetSize() > 3) { // NOTE: we reserved the 3rd byte for a potential future EG3 option
1750              lsde->SetPos(3);              lsde->SetPos(3);
1751              SustainReleaseTrigger = static_cast<sust_rel_trg_t>(lsde->ReadUint8());              uint8_t byte = lsde->ReadUint8();
1752          } else SustainReleaseTrigger = sust_rel_trg_none;              SustainReleaseTrigger   = static_cast<sust_rel_trg_t>(byte & 0x03);
1753                NoNoteOffReleaseTrigger = byte >> 7;
1754            } else {
1755                SustainReleaseTrigger   = sust_rel_trg_none;
1756                NoNoteOffReleaseTrigger = false;
1757            }
1758    
1759          pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,          pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1760                                                       VelocityResponseDepth,                                                       VelocityResponseDepth,
# Line 1941  namespace { Line 1946  namespace {
1946          SRLZ(EG1Options);          SRLZ(EG1Options);
1947          SRLZ(EG2Options);          SRLZ(EG2Options);
1948          SRLZ(SustainReleaseTrigger);          SRLZ(SustainReleaseTrigger);
1949            SRLZ(NoNoteOffReleaseTrigger);
1950    
1951          // derived attributes from DLS::Sampler          // derived attributes from DLS::Sampler
1952          SRLZ(FineTune);          SRLZ(FineTune);
# Line 2253  namespace { Line 2259  namespace {
2259          RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);          RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2260          const int lsdeSize = 4; // NOTE: we reserved the 3rd byte for a potential future EG3 option          const int lsdeSize = 4; // NOTE: we reserved the 3rd byte for a potential future EG3 option
2261          if (!lsde) {          if (!lsde) {
2262              // only add this "LSDE" chunk if either EG options or sustain              // only add this "LSDE" chunk if either EG options or release
2263              // release trigger option deviate from their default behaviour              // trigger options deviate from their default behaviour
2264              eg_opt_t defaultOpt;              eg_opt_t defaultOpt;
2265              if (memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||              if (memcmp(&EG1Options, &defaultOpt, sizeof(eg_opt_t)) ||
2266                  memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)) ||                  memcmp(&EG2Options, &defaultOpt, sizeof(eg_opt_t)) ||
2267                  SustainReleaseTrigger)                  SustainReleaseTrigger || NoNoteOffReleaseTrigger)
2268              {              {
2269                  lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);                  lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2270                  // move LSDE chunk to the end of parent list                  // move LSDE chunk to the end of parent list
# Line 2279  namespace { Line 2285  namespace {
2285                      (pEGOpts[i]->Decay2Cancel     ? (1<<3) : 0) |                      (pEGOpts[i]->Decay2Cancel     ? (1<<3) : 0) |
2286                      (pEGOpts[i]->ReleaseCancel    ? (1<<4) : 0);                      (pEGOpts[i]->ReleaseCancel    ? (1<<4) : 0);
2287              }              }
2288              // format extension for effect of sustain pedal up event on release trigger samples              // format extension for release trigger options
2289              pData[3] = static_cast<uint8_t>(SustainReleaseTrigger);              pData[3] = static_cast<uint8_t>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 0);
2290          }          }
2291      }      }
2292    
# Line 5696  namespace { Line 5702  namespace {
5702          int iSampleIndex  = 0;          int iSampleIndex  = 0;
5703          int iTotalSamples = WavePoolCount;          int iTotalSamples = WavePoolCount;
5704    
5705          // check if samples should be loaded from extension files          // just for assembling path of optional extension files to be read
5706          // (only for old gig files < 2 GB)          const std::string folder = parentPath(pRIFF->GetFileName());
5707          int lastFileNo = 0;          const std::string baseName = pathWithoutExtension(pRIFF->GetFileName());
5708          if (!file->IsNew() && !(file->GetCurrentFileSize() >> 31)) {  
5709              for (int i = 0 ; i < WavePoolCount ; i++) {          // the main gig file and the extension files (.gx01, ... , .gx98) may
5710                  if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];          // contain wave data (wave pool)
5711              }          std::vector<RIFF::File*> poolFiles;
5712          }          poolFiles.push_back(pRIFF);
5713          String name(pRIFF->GetFileName());  
5714          int nameLen = (int) name.length();          // get info about all extension files
5715          char suffix[6];          RIFF::Chunk* ckXfil = pRIFF->GetSubChunk(CHUNK_ID_XFIL);
5716          if (nameLen > 4 && name.substr(nameLen - 4) == ".gig") nameLen -= 4;          if (ckXfil) { // there are extension files (.gx01, ... , .gx98) ...
5717                const uint32_t n = ckXfil->ReadInt32();
5718          for (int fileNo = 0 ; ; ) {              for (int i = 0; i < n; i++) {
5719                    // read the filename and load the extension file
5720                    std::string name;
5721                    ckXfil->ReadString(name, 128);
5722                    std::string path = concatPath(folder, name);
5723                    RIFF::File* pExtFile = new RIFF::File(path);
5724                    // check that the dlsids match
5725                    RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
5726                    if (ckDLSID) {
5727                        ::DLS::dlsid_t idExpected;
5728                        idExpected.ulData1 = ckXfil->ReadInt32();
5729                        idExpected.usData2 = ckXfil->ReadInt16();
5730                        idExpected.usData3 = ckXfil->ReadInt16();
5731                        ckXfil->Read(idExpected.abData, 8, 1);
5732                        ::DLS::dlsid_t idFound;
5733                        ckDLSID->Read(&idFound.ulData1, 1, 4);
5734                        ckDLSID->Read(&idFound.usData2, 1, 2);
5735                        ckDLSID->Read(&idFound.usData3, 1, 2);
5736                        ckDLSID->Read(idFound.abData, 8, 1);
5737                        if (memcmp(&idExpected, &idFound, 16) != 0)
5738                            throw gig::Exception("dlsid mismatch for extension file: %s", path.c_str());
5739                    }
5740                    poolFiles.push_back(pExtFile);
5741                    ExtensionFiles.push_back(pExtFile);
5742                }
5743            }
5744    
5745            // check if a .gx99 (GigaPulse) file exists
5746            RIFF::Chunk* ckDoxf = pRIFF->GetSubChunk(CHUNK_ID_DOXF);
5747            if (ckDoxf) { // there is a .gx99 (GigaPulse) file ...
5748                std::string path = baseName + ".gx99";
5749                RIFF::File* pExtFile = new RIFF::File(path);
5750    
5751                // skip unused int and filename
5752                ckDoxf->SetPos(132, RIFF::stream_whence_t::stream_curpos);
5753    
5754                // check that the dlsids match
5755                RIFF::Chunk* ckDLSID = pExtFile->GetSubChunk(CHUNK_ID_DLID);
5756                if (ckDLSID) {
5757                    ::DLS::dlsid_t idExpected;
5758                    idExpected.ulData1 = ckDoxf->ReadInt32();
5759                    idExpected.usData2 = ckDoxf->ReadInt16();
5760                    idExpected.usData3 = ckDoxf->ReadInt16();
5761                    ckDoxf->Read(idExpected.abData, 8, 1);
5762                    ::DLS::dlsid_t idFound;
5763                    ckDLSID->Read(&idFound.ulData1, 1, 4);
5764                    ckDLSID->Read(&idFound.usData2, 1, 2);
5765                    ckDLSID->Read(&idFound.usData3, 1, 2);
5766                    ckDLSID->Read(idFound.abData, 8, 1);
5767                    if (memcmp(&idExpected, &idFound, 16) != 0)
5768                        throw gig::Exception("dlsid mismatch for GigaPulse file: %s", path.c_str());
5769                }
5770                poolFiles.push_back(pExtFile);
5771                ExtensionFiles.push_back(pExtFile);
5772            }
5773    
5774            // load samples from extension files (if required)
5775            for (int i = 0; i < poolFiles.size(); i++) {
5776                RIFF::File* file = poolFiles[i];
5777              RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);              RIFF::List* wvpl = file->GetSubList(LIST_TYPE_WVPL);
5778              if (wvpl) {              if (wvpl) {
5779                  file_offset_t wvplFileOffset = wvpl->GetFilePos();                  file_offset_t wvplFileOffset = wvpl->GetFilePos();
# Line 5721  namespace { Line 5785  namespace {
5785                          __notify_progress(pProgress, subprogress);                          __notify_progress(pProgress, subprogress);
5786    
5787                          file_offset_t waveFileOffset = wave->GetFilePos();                          file_offset_t waveFileOffset = wave->GetFilePos();
5788                          pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, fileNo, iSampleIndex));                          pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset, i, iSampleIndex));
5789    
5790                          iSampleIndex++;                          iSampleIndex++;
5791                      }                      }
5792                      wave = wvpl->GetNextSubList();                      wave = wvpl->GetNextSubList();
5793                  }                  }
5794                }
                 if (fileNo == lastFileNo) break;  
   
                 // open extension file (*.gx01, *.gx02, ...)  
                 fileNo++;  
                 sprintf(suffix, ".gx%02d", fileNo);  
                 name.replace(nameLen, 5, suffix);  
                 file = new RIFF::File(name);  
                 ExtensionFiles.push_back(file);  
             } else break;  
5795          }          }
5796    
5797          __notify_progress(pProgress, 1.0); // notify done          __notify_progress(pProgress, 1.0); // notify done

Legend:
Removed from v.3442  
changed lines
  Added in v.3474

  ViewVC Help
Powered by ViewVC