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

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

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

revision 3481 by schoenebeck, Fri Feb 22 12:12:50 2019 UTC revision 3922 by schoenebeck, Mon Jun 14 10:33:29 2021 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-2019 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2021 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 209  namespace DLS { Line 209  namespace DLS {
209          if (lart) {          if (lart) {
210              uint32_t artCkType = (lart->GetListType() == LIST_TYPE_LAR2) ? CHUNK_ID_ART2              uint32_t artCkType = (lart->GetListType() == LIST_TYPE_LAR2) ? CHUNK_ID_ART2
211                                                                           : CHUNK_ID_ARTL;                                                                           : CHUNK_ID_ARTL;
212              RIFF::Chunk* art = lart->GetFirstSubChunk();              size_t i = 0;
213              while (art) {              for (RIFF::Chunk* art = lart->GetSubChunkAt(i); art;
214                     art = lart->GetSubChunkAt(++i))
215                {
216                  if (art->GetChunkID() == artCkType) {                  if (art->GetChunkID() == artCkType) {
217                      if (!pArticulations) pArticulations = new ArticulationList;                      if (!pArticulations) pArticulations = new ArticulationList;
218                      pArticulations->push_back(new Articulation(art));                      pArticulations->push_back(new Articulation(art));
219                  }                  }
                 art = lart->GetNextSubChunk();  
220              }              }
221          }          }
222      }      }
# Line 556  namespace DLS { Line 557  namespace DLS {
557      }      }
558    
559      void Resource::GenerateDLSID(dlsid_t* pDLSID) {      void Resource::GenerateDLSID(dlsid_t* pDLSID) {
 #if defined(WIN32) || defined(__APPLE__) || defined(HAVE_UUID_GENERATE)  
560  #ifdef WIN32  #ifdef WIN32
561          UUID uuid;          UUID uuid;
562          UuidCreate(&uuid);          UuidCreate(&uuid);
# Line 581  namespace DLS { Line 581  namespace DLS {
581          pDLSID->abData[5] = uuid.byte13;          pDLSID->abData[5] = uuid.byte13;
582          pDLSID->abData[6] = uuid.byte14;          pDLSID->abData[6] = uuid.byte14;
583          pDLSID->abData[7] = uuid.byte15;          pDLSID->abData[7] = uuid.byte15;
584  #else  #elif defined(HAVE_UUID_GENERATE)
585          uuid_t uuid;          uuid_t uuid;
586          uuid_generate(uuid);          uuid_generate(uuid);
587          pDLSID->ulData1 = uuid[0] | uuid[1] << 8 | uuid[2] << 16 | uuid[3] << 24;          pDLSID->ulData1 = uuid[0] | uuid[1] << 8 | uuid[2] << 16 | uuid[3] << 24;
588          pDLSID->usData2 = uuid[4] | uuid[5] << 8;          pDLSID->usData2 = uuid[4] | uuid[5] << 8;
589          pDLSID->usData3 = uuid[6] | uuid[7] << 8;          pDLSID->usData3 = uuid[6] | uuid[7] << 8;
590          memcpy(pDLSID->abData, &uuid[8], 8);          memcpy(pDLSID->abData, &uuid[8], 8);
591  #endif  #else
592    # error "Missing support for uuid generation"
593  #endif  #endif
594      }      }
595            
# Line 1375  namespace DLS { Line 1376  namespace DLS {
1376          RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);          RIFF::List* lrgn = pCkInstrument->GetSubList(LIST_TYPE_LRGN);
1377          if (lrgn) {          if (lrgn) {
1378              uint32_t regionCkType = (lrgn->GetSubList(LIST_TYPE_RGN2)) ? LIST_TYPE_RGN2 : LIST_TYPE_RGN; // prefer regions level 2              uint32_t regionCkType = (lrgn->GetSubList(LIST_TYPE_RGN2)) ? LIST_TYPE_RGN2 : LIST_TYPE_RGN; // prefer regions level 2
1379              RIFF::List* rgn = lrgn->GetFirstSubList();              size_t i = 0;
1380              while (rgn) {              for (RIFF::List* rgn = lrgn->GetSubListAt(i); rgn;
1381                     rgn = lrgn->GetSubListAt(++i))
1382                {
1383                  if (rgn->GetListType() == regionCkType) {                  if (rgn->GetListType() == regionCkType) {
1384                      pRegions->push_back(new Region(this, rgn));                      pRegions->push_back(new Region(this, rgn));
1385                  }                  }
                 rgn = lrgn->GetNextSubList();  
1386              }              }
1387          }          }
1388      }      }
# Line 1445  namespace DLS { Line 1447  namespace DLS {
1447          RegionList::iterator iter = pRegions->begin();          RegionList::iterator iter = pRegions->begin();
1448          RegionList::iterator end  = pRegions->end();          RegionList::iterator end  = pRegions->end();
1449          for (int i = 0; iter != end; ++iter, ++i) {          for (int i = 0; iter != end; ++iter, ++i) {
1450              // divide local progress into subprogress              if (pProgress) {
1451              progress_t subprogress;                  // divide local progress into subprogress
1452              __divide_progress(pProgress, &subprogress, pRegions->size(), i);                  progress_t subprogress;
1453              // do the actual work                  __divide_progress(pProgress, &subprogress, pRegions->size(), i);
1454              (*iter)->UpdateChunks(&subprogress);                  // do the actual work
1455                    (*iter)->UpdateChunks(&subprogress);
1456                } else
1457                    (*iter)->UpdateChunks(NULL);
1458          }          }
1459          __notify_progress(pProgress, 1.0); // notify done          if (pProgress)
1460                __notify_progress(pProgress, 1.0); // notify done
1461      }      }
1462    
1463      /** @brief Destructor.      /** @brief Destructor.
# Line 1675  namespace DLS { Line 1681  namespace DLS {
1681          if (wvpl) {          if (wvpl) {
1682              file_offset_t wvplFileOffset = wvpl->GetFilePos() -              file_offset_t wvplFileOffset = wvpl->GetFilePos() -
1683                                             wvpl->GetPos(); // should be zero, but just to be sure                                             wvpl->GetPos(); // should be zero, but just to be sure
1684              RIFF::List* wave = wvpl->GetFirstSubList();              size_t i = 0;
1685              while (wave) {              for (RIFF::List* wave = wvpl->GetSubListAt(i); wave;
1686                     wave = wvpl->GetSubListAt(++i))
1687                {
1688                  if (wave->GetListType() == LIST_TYPE_WAVE) {                  if (wave->GetListType() == LIST_TYPE_WAVE) {
1689                      file_offset_t waveFileOffset = wave->GetFilePos() -                      file_offset_t waveFileOffset = wave->GetFilePos() -
1690                                                     wave->GetPos(); // should be zero, but just to be sure                                                     wave->GetPos(); // should be zero, but just to be sure
1691                      pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));                      pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
1692                  }                  }
                 wave = wvpl->GetNextSubList();  
1693              }              }
1694          }          }
1695          else { // Seen a dwpl list chunk instead of a wvpl list chunk in some file (officially not DLS compliant)          else { // Seen a dwpl list chunk instead of a wvpl list chunk in some file (officially not DLS compliant)
# Line 1690  namespace DLS { Line 1697  namespace DLS {
1697              if (dwpl) {              if (dwpl) {
1698                  file_offset_t dwplFileOffset = dwpl->GetFilePos() -                  file_offset_t dwplFileOffset = dwpl->GetFilePos() -
1699                                                 dwpl->GetPos(); // should be zero, but just to be sure                                                 dwpl->GetPos(); // should be zero, but just to be sure
1700                  RIFF::List* wave = dwpl->GetFirstSubList();                  size_t i = 0;
1701                  while (wave) {                  for (RIFF::List* wave = dwpl->GetSubListAt(i); wave;
1702                         wave = dwpl->GetSubListAt(++i))
1703                    {
1704                      if (wave->GetListType() == LIST_TYPE_WAVE) {                      if (wave->GetListType() == LIST_TYPE_WAVE) {
1705                          file_offset_t waveFileOffset = wave->GetFilePos() -                          file_offset_t waveFileOffset = wave->GetFilePos() -
1706                                                         wave->GetPos(); // should be zero, but just to be sure                                                         wave->GetPos(); // should be zero, but just to be sure
1707                          pSamples->push_back(new Sample(this, wave, waveFileOffset - dwplFileOffset));                          pSamples->push_back(new Sample(this, wave, waveFileOffset - dwplFileOffset));
1708                      }                      }
                     wave = dwpl->GetNextSubList();  
1709                  }                  }
1710              }              }
1711          }          }
# Line 1754  namespace DLS { Line 1762  namespace DLS {
1762          if (!pInstruments) pInstruments = new InstrumentList;          if (!pInstruments) pInstruments = new InstrumentList;
1763          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1764          if (lstInstruments) {          if (lstInstruments) {
1765              RIFF::List* lstInstr = lstInstruments->GetFirstSubList();              size_t i = 0;
1766              while (lstInstr) {              for (RIFF::List* lstInstr = lstInstruments->GetSubListAt(i);
1767                     lstInstr; lstInstr = lstInstruments->GetSubListAt(++i))
1768                {
1769                  if (lstInstr->GetListType() == LIST_TYPE_INS) {                  if (lstInstr->GetListType() == LIST_TYPE_INS) {
1770                      pInstruments->push_back(new Instrument(this, lstInstr));                      pInstruments->push_back(new Instrument(this, lstInstr));
1771                  }                  }
                 lstInstr = lstInstruments->GetNextSubList();  
1772              }              }
1773          }          }
1774      }      }
# Line 1878  namespace DLS { Line 1887  namespace DLS {
1887    
1888          // update instrument's chunks          // update instrument's chunks
1889          if (pInstruments) {          if (pInstruments) {
1890              // divide local progress into subprogress              if (pProgress) {
1891              progress_t subprogress;                  // divide local progress into subprogress
1892              __divide_progress(pProgress, &subprogress, 20.f, 0.f); // arbitrarily subdivided into 5% of total progress                  progress_t subprogress;
1893                    __divide_progress(pProgress, &subprogress, 20.f, 0.f); // arbitrarily subdivided into 5% of total progress
1894    
             // do the actual work  
             InstrumentList::iterator iter = pInstruments->begin();  
             InstrumentList::iterator end  = pInstruments->end();  
             for (int i = 0; iter != end; ++iter, ++i) {  
                 // divide subprogress into sub-subprogress  
                 progress_t subsubprogress;  
                 __divide_progress(&subprogress, &subsubprogress, pInstruments->size(), i);  
1895                  // do the actual work                  // do the actual work
1896                  (*iter)->UpdateChunks(&subsubprogress);                  InstrumentList::iterator iter = pInstruments->begin();
1897              }                  InstrumentList::iterator end  = pInstruments->end();
1898                    for (int i = 0; iter != end; ++iter, ++i) {
1899                        // divide subprogress into sub-subprogress
1900                        progress_t subsubprogress;
1901                        __divide_progress(&subprogress, &subsubprogress, pInstruments->size(), i);
1902                        // do the actual work
1903                        (*iter)->UpdateChunks(&subsubprogress);
1904                    }
1905    
1906              __notify_progress(&subprogress, 1.0); // notify subprogress done                  __notify_progress(&subprogress, 1.0); // notify subprogress done
1907                } else {
1908                    InstrumentList::iterator iter = pInstruments->begin();
1909                    InstrumentList::iterator end  = pInstruments->end();
1910                    for (int i = 0; iter != end; ++iter, ++i) {
1911                        (*iter)->UpdateChunks(NULL);
1912                    }
1913                }
1914          }          }
1915    
1916          // update 'ptbl' chunk          // update 'ptbl' chunk
# Line 1911  namespace DLS { Line 1928  namespace DLS {
1928    
1929          // update sample's chunks          // update sample's chunks
1930          if (pSamples) {          if (pSamples) {
1931              // divide local progress into subprogress              if (pProgress) {
1932              progress_t subprogress;                  // divide local progress into subprogress
1933              __divide_progress(pProgress, &subprogress, 20.f, 1.f); // arbitrarily subdivided into 95% of total progress                  progress_t subprogress;
1934                    __divide_progress(pProgress, &subprogress, 20.f, 1.f); // arbitrarily subdivided into 95% of total progress
1935    
             // do the actual work  
             SampleList::iterator iter = pSamples->begin();  
             SampleList::iterator end  = pSamples->end();  
             for (int i = 0; iter != end; ++iter, ++i) {  
                 // divide subprogress into sub-subprogress  
                 progress_t subsubprogress;  
                 __divide_progress(&subprogress, &subsubprogress, pSamples->size(), i);  
1936                  // do the actual work                  // do the actual work
1937                  (*iter)->UpdateChunks(&subsubprogress);                  SampleList::iterator iter = pSamples->begin();
1938              }                  SampleList::iterator end  = pSamples->end();
1939                    for (int i = 0; iter != end; ++iter, ++i) {
1940                        // divide subprogress into sub-subprogress
1941                        progress_t subsubprogress;
1942                        __divide_progress(&subprogress, &subsubprogress, pSamples->size(), i);
1943                        // do the actual work
1944                        (*iter)->UpdateChunks(&subsubprogress);
1945                    }
1946    
1947              __notify_progress(&subprogress, 1.0); // notify subprogress done                  __notify_progress(&subprogress, 1.0); // notify subprogress done
1948                } else {
1949                    SampleList::iterator iter = pSamples->begin();
1950                    SampleList::iterator end  = pSamples->end();
1951                    for (int i = 0; iter != end; ++iter, ++i) {
1952                        (*iter)->UpdateChunks(NULL);
1953                    }
1954                }
1955          }          }
1956    
1957          // if there are any extension files, gather which ones are regular          // if there are any extension files, gather which ones are regular
# Line 2062  namespace DLS { Line 2087  namespace DLS {
2087              ptbl->Resize(iPtblSize);              ptbl->Resize(iPtblSize);
2088          }          }
2089    
2090          __notify_progress(pProgress, 1.0); // notify done          if (pProgress)
2091                __notify_progress(pProgress, 1.0); // notify done
2092      }      }
2093    
2094      /** @brief Save changes to another file.      /** @brief Save changes to another file.
# Line 2087  namespace DLS { Line 2113  namespace DLS {
2113          // save extension files (if required)          // save extension files (if required)
2114          if (!ExtensionFiles.empty()) {          if (!ExtensionFiles.empty()) {
2115              // for assembling path of extension files to be saved to              // for assembling path of extension files to be saved to
             const std::string folder = parentPath(Path);  
2116              const std::string baseName = pathWithoutExtension(Path);              const std::string baseName = pathWithoutExtension(Path);
2117              // save the individual extension files              // save the individual extension files
2118              std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();              std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();
2119              for (int i = 0; it != ExtensionFiles.end(); ++i, ++it) {              for (int i = 0; it != ExtensionFiles.end(); ++i, ++it) {
                 // divide local progress into subprogress  
                 progress_t subprogress;  
                 __divide_progress(pProgress, &subprogress, tasks, 0.f + i); // subdivided into amount of extension files  
2120                  //FIXME: the .gx99 file is always used by GSt for convolution                  //FIXME: the .gx99 file is always used by GSt for convolution
2121                  // data (GigaPulse); so we should better detect by subchunk                  // data (GigaPulse); so we should better detect by subchunk
2122                  // whether the extension file is intended for convolution                  // whether the extension file is intended for convolution
# Line 2102  namespace DLS { Line 2124  namespace DLS {
2124                  // not work for saving new gigs created from scratch                  // not work for saving new gigs created from scratch
2125                  const std::string oldName = (*it)->GetFileName();                  const std::string oldName = (*it)->GetFileName();
2126                  const bool isGigaPulseFile = (extensionOfPath(oldName) == "gx99");                  const bool isGigaPulseFile = (extensionOfPath(oldName) == "gx99");
2127                  std::string ext = (isGigaPulseFile) ? ".gx99" : strPrint(".gx02d", i+1);                  std::string ext = (isGigaPulseFile) ? ".gx99" : strPrint(".gx%02d", i+1);
2128                  std::string newPath = concatPath(folder, baseName) + ext;                  std::string newPath = baseName + ext;
2129                  // save extension file to its new location                  // save extension file to its new location
2130                  (*it)->Save(newPath, &subprogress);                  if (pProgress) {
2131                         // divide local progress into subprogress
2132                        progress_t subprogress;
2133                        __divide_progress(pProgress, &subprogress, tasks, 0.f + i); // subdivided into amount of extension files
2134                        // do the actual work
2135                        (*it)->Save(newPath, &subprogress);
2136                    } else
2137                        (*it)->Save(newPath);
2138              }              }
2139          }          }
2140    
2141          {          if (pProgress) {
2142              // divide local progress into subprogress              // divide local progress into subprogress
2143              progress_t subprogress;              progress_t subprogress;
2144              __divide_progress(pProgress, &subprogress, tasks, 1.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)              __divide_progress(pProgress, &subprogress, tasks, 1.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)
2145              // do the actual work              // do the actual work
2146              UpdateChunks(&subprogress);              UpdateChunks(&subprogress);
2147          }          } else
2148          {              UpdateChunks(NULL);
2149    
2150            if (pProgress) {
2151              // divide local progress into subprogress              // divide local progress into subprogress
2152              progress_t subprogress;              progress_t subprogress;
2153              __divide_progress(pProgress, &subprogress, tasks, 2.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)              __divide_progress(pProgress, &subprogress, tasks, 2.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)
2154              // do the actual work              // do the actual work
2155              pRIFF->Save(Path, &subprogress);              pRIFF->Save(Path, &subprogress);
2156          }          } else
2157                pRIFF->Save(Path);
2158    
2159          UpdateFileOffsets();          UpdateFileOffsets();
2160          __notify_progress(pProgress, 1.0); // notify done  
2161            if (pProgress)
2162                __notify_progress(pProgress, 1.0); // notify done
2163      }      }
2164    
2165      /** @brief Save changes to same file.      /** @brief Save changes to same file.
# Line 2146  namespace DLS { Line 2181  namespace DLS {
2181          if (!ExtensionFiles.empty()) {          if (!ExtensionFiles.empty()) {
2182              std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();              std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();
2183              for (int i = 0; it != ExtensionFiles.end(); ++i, ++it) {              for (int i = 0; it != ExtensionFiles.end(); ++i, ++it) {
                 // divide local progress into subprogress  
                 progress_t subprogress;  
                 __divide_progress(pProgress, &subprogress, tasks, 0.f + i); // subdivided into amount of extension files  
2184                  // save extension file                  // save extension file
2185                  (*it)->Save(&subprogress);                  if (pProgress) {
2186                        // divide local progress into subprogress
2187                        progress_t subprogress;
2188                        __divide_progress(pProgress, &subprogress, tasks, 0.f + i); // subdivided into amount of extension files
2189                        // do the actual work
2190                        (*it)->Save(&subprogress);
2191                    } else
2192                        (*it)->Save();
2193              }              }
2194          }          }
2195    
2196          {          if (pProgress) {
2197              // divide local progress into subprogress              // divide local progress into subprogress
2198              progress_t subprogress;              progress_t subprogress;
2199              __divide_progress(pProgress, &subprogress, tasks, 1.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)              __divide_progress(pProgress, &subprogress, tasks, 1.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)
2200              // do the actual work              // do the actual work
2201              UpdateChunks(&subprogress);              UpdateChunks(&subprogress);
2202          }          } else
2203          {              UpdateChunks(NULL);
2204    
2205            if (pProgress) {
2206              // divide local progress into subprogress              // divide local progress into subprogress
2207              progress_t subprogress;              progress_t subprogress;
2208              __divide_progress(pProgress, &subprogress, tasks, 2.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)              __divide_progress(pProgress, &subprogress, tasks, 2.f + nExtFiles); // arbitrarily subdivided into 50% (minus extension files progress)
2209              // do the actual work              // do the actual work
2210              pRIFF->Save(&subprogress);              pRIFF->Save(&subprogress);
2211          }          } else
2212                pRIFF->Save();
2213    
2214          UpdateFileOffsets();          UpdateFileOffsets();
2215          __notify_progress(pProgress, 1.0); // notify done  
2216            if (pProgress)
2217                __notify_progress(pProgress, 1.0); // notify done
2218      }      }
2219    
2220      /** @brief Updates all file offsets stored all over the file.      /** @brief Updates all file offsets stored all over the file.

Legend:
Removed from v.3481  
changed lines
  Added in v.3922

  ViewVC Help
Powered by ViewVC