/[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 2609 by schoenebeck, Sun Jun 8 19:00:30 2014 UTC revision 2682 by schoenebeck, Mon Dec 29 16:25:51 2014 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-2013 by Christian Schoenebeck                      *   *   Copyright (C) 2003-2014 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 144  namespace DLS { Line 144  namespace DLS {
144      /**      /**
145       * Apply articulation connections to the respective RIFF chunks. You       * Apply articulation connections to the respective RIFF chunks. You
146       * have to call File::Save() to make changes persistent.       * have to call File::Save() to make changes persistent.
147         *
148         * @param pProgress - callback function for progress notification
149       */       */
150      void Articulation::UpdateChunks() {      void Articulation::UpdateChunks(progress_t* pProgress) {
151          const int iEntrySize = 12; // 12 bytes per connection block          const int iEntrySize = 12; // 12 bytes per connection block
152          pArticulationCk->Resize(HeaderSize + Connections * iEntrySize);          pArticulationCk->Resize(HeaderSize + Connections * iEntrySize);
153          uint8_t* pData = (uint8_t*) pArticulationCk->LoadChunkData();          uint8_t* pData = (uint8_t*) pArticulationCk->LoadChunkData();
# Line 217  namespace DLS { Line 219  namespace DLS {
219      /**      /**
220       * Apply all articulations to the respective RIFF chunks. You have to       * Apply all articulations to the respective RIFF chunks. You have to
221       * call File::Save() to make changes persistent.       * call File::Save() to make changes persistent.
222         *
223         * @param pProgress - callback function for progress notification
224       */       */
225      void Articulator::UpdateChunks() {      void Articulator::UpdateChunks(progress_t* pProgress) {
226          if (pArticulations) {          if (pArticulations) {
227              ArticulationList::iterator iter = pArticulations->begin();              ArticulationList::iterator iter = pArticulations->begin();
228              ArticulationList::iterator end  = pArticulations->end();              ArticulationList::iterator end  = pArticulations->end();
229              for (; iter != end; ++iter) {              for (; iter != end; ++iter) {
230                  (*iter)->UpdateChunks();                  (*iter)->UpdateChunks(pProgress);
231              }              }
232          }          }
233      }      }
# Line 336  namespace DLS { Line 340  namespace DLS {
340       *       *
341       * Apply current INFO field values to the respective INFO chunks. You       * Apply current INFO field values to the respective INFO chunks. You
342       * have to call File::Save() to make changes persistent.       * have to call File::Save() to make changes persistent.
343         *
344         * @param pProgress - callback function for progress notification
345       */       */
346      void Info::UpdateChunks() {      void Info::UpdateChunks(progress_t* pProgress) {
347          if (!pResourceListChunk) return;          if (!pResourceListChunk) return;
348    
349          // make sure INFO list chunk exists          // make sure INFO list chunk exists
# Line 464  namespace DLS { Line 470  namespace DLS {
470       * will not be applied at the moment (yet).       * will not be applied at the moment (yet).
471       *       *
472       * You have to call File::Save() to make changes persistent.       * You have to call File::Save() to make changes persistent.
473         *
474         * @param pProgress - callback function for progress notification
475       */       */
476      void Resource::UpdateChunks() {      void Resource::UpdateChunks(progress_t* pProgress) {
477          pInfo->UpdateChunks();          pInfo->UpdateChunks(pProgress);
478    
479          if (pDLSID) {          if (pDLSID) {
480              // make sure 'dlid' chunk exists              // make sure 'dlid' chunk exists
# Line 582  namespace DLS { Line 590  namespace DLS {
590      /**      /**
591       * Apply all sample player options to the respective RIFF chunk. You       * Apply all sample player options to the respective RIFF chunk. You
592       * have to call File::Save() to make changes persistent.       * have to call File::Save() to make changes persistent.
593         *
594         * @param pProgress - callback function for progress notification
595       */       */
596      void Sampler::UpdateChunks() {      void Sampler::UpdateChunks(progress_t* pProgress) {
597          // make sure 'wsmp' chunk exists          // make sure 'wsmp' chunk exists
598          RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);          RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
599          int wsmpSize = uiHeaderSize + SampleLoops * 16;          int wsmpSize = uiHeaderSize + SampleLoops * 16;
# Line 951  namespace DLS { Line 961  namespace DLS {
961       * Apply sample and its settings to the respective RIFF chunks. You have       * Apply sample and its settings to the respective RIFF chunks. You have
962       * to call File::Save() to make changes persistent.       * to call File::Save() to make changes persistent.
963       *       *
964         * @param pProgress - callback function for progress notification
965       * @throws Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data       * @throws Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data
966       *                   was provided yet       *                   was provided yet
967       */       */
968      void Sample::UpdateChunks() {      void Sample::UpdateChunks(progress_t* pProgress) {
969          if (FormatTag != DLS_WAVE_FORMAT_PCM)          if (FormatTag != DLS_WAVE_FORMAT_PCM)
970              throw Exception("Could not save sample, only PCM format is supported");              throw Exception("Could not save sample, only PCM format is supported");
971          // we refuse to do anything if not sample wave form was provided yet          // we refuse to do anything if not sample wave form was provided yet
972          if (!pCkData)          if (!pCkData)
973              throw Exception("Could not save sample, there is no sample data to save");              throw Exception("Could not save sample, there is no sample data to save");
974          // update chunks of base class as well          // update chunks of base class as well
975          Resource::UpdateChunks();          Resource::UpdateChunks(pProgress);
976          // make sure 'fmt' chunk exists          // make sure 'fmt' chunk exists
977          RIFF::Chunk* pCkFormat = pWaveList->GetSubChunk(CHUNK_ID_FMT);          RIFF::Chunk* pCkFormat = pWaveList->GetSubChunk(CHUNK_ID_FMT);
978          if (!pCkFormat) pCkFormat = pWaveList->AddSubChunk(CHUNK_ID_FMT, 16); // assumes PCM format          if (!pCkFormat) pCkFormat = pWaveList->AddSubChunk(CHUNK_ID_FMT, 16); // assumes PCM format
# Line 1094  namespace DLS { Line 1105  namespace DLS {
1105       * Apply Region settings to the respective RIFF chunks. You have to       * Apply Region settings to the respective RIFF chunks. You have to
1106       * call File::Save() to make changes persistent.       * call File::Save() to make changes persistent.
1107       *       *
1108         * @param pProgress - callback function for progress notification
1109       * @throws Exception - if the Region's sample could not be found       * @throws Exception - if the Region's sample could not be found
1110       */       */
1111      void Region::UpdateChunks() {      void Region::UpdateChunks(progress_t* pProgress) {
1112          // make sure 'rgnh' chunk exists          // make sure 'rgnh' chunk exists
1113          RIFF::Chunk* rgnh = pCkRegion->GetSubChunk(CHUNK_ID_RGNH);          RIFF::Chunk* rgnh = pCkRegion->GetSubChunk(CHUNK_ID_RGNH);
1114          if (!rgnh) rgnh = pCkRegion->AddSubChunk(CHUNK_ID_RGNH, Layer ? 14 : 12);          if (!rgnh) rgnh = pCkRegion->AddSubChunk(CHUNK_ID_RGNH, Layer ? 14 : 12);
# Line 1115  namespace DLS { Line 1127  namespace DLS {
1127    
1128          // update chunks of base classes as well (but skip Resource,          // update chunks of base classes as well (but skip Resource,
1129          // as a rgn doesn't seem to have dlid and INFO chunks)          // as a rgn doesn't seem to have dlid and INFO chunks)
1130          Articulator::UpdateChunks();          Articulator::UpdateChunks(pProgress);
1131          Sampler::UpdateChunks();          Sampler::UpdateChunks(pProgress);
1132    
1133          // make sure 'wlnk' chunk exists          // make sure 'wlnk' chunk exists
1134          RIFF::Chunk* wlnk = pCkRegion->GetSubChunk(CHUNK_ID_WLNK);          RIFF::Chunk* wlnk = pCkRegion->GetSubChunk(CHUNK_ID_WLNK);
# Line 1289  namespace DLS { Line 1301  namespace DLS {
1301       * Apply Instrument with all its Regions to the respective RIFF chunks.       * Apply Instrument with all its Regions to the respective RIFF chunks.
1302       * You have to call File::Save() to make changes persistent.       * You have to call File::Save() to make changes persistent.
1303       *       *
1304         * @param pProgress - callback function for progress notification
1305       * @throws Exception - on errors       * @throws Exception - on errors
1306       */       */
1307      void Instrument::UpdateChunks() {      void Instrument::UpdateChunks(progress_t* pProgress) {
1308          // first update base classes' chunks          // first update base classes' chunks
1309          Resource::UpdateChunks();          Resource::UpdateChunks(pProgress);
1310          Articulator::UpdateChunks();          Articulator::UpdateChunks(pProgress);
1311          // make sure 'insh' chunk exists          // make sure 'insh' chunk exists
1312          RIFF::Chunk* insh = pCkInstrument->GetSubChunk(CHUNK_ID_INSH);          RIFF::Chunk* insh = pCkInstrument->GetSubChunk(CHUNK_ID_INSH);
1313          if (!insh) insh = pCkInstrument->AddSubChunk(CHUNK_ID_INSH, 12);          if (!insh) insh = pCkInstrument->AddSubChunk(CHUNK_ID_INSH, 12);
# Line 1313  namespace DLS { Line 1326  namespace DLS {
1326          if (!pRegions) return;          if (!pRegions) return;
1327          RegionList::iterator iter = pRegions->begin();          RegionList::iterator iter = pRegions->begin();
1328          RegionList::iterator end  = pRegions->end();          RegionList::iterator end  = pRegions->end();
1329          for (; iter != end; ++iter) {          for (int i = 0; iter != end; ++iter, ++i) {
1330              (*iter)->UpdateChunks();              // divide local progress into subprogress
1331                progress_t subprogress;
1332                __divide_progress(pProgress, &subprogress, pRegions->size(), i);
1333                // do the actual work
1334                (*iter)->UpdateChunks(&subprogress);
1335          }          }
1336            __notify_progress(pProgress, 1.0); // notify done
1337      }      }
1338    
1339      /** @brief Destructor.      /** @brief Destructor.
# Line 1671  namespace DLS { Line 1689  namespace DLS {
1689       * the respective RIFF chunks. You have to call Save() to make changes       * the respective RIFF chunks. You have to call Save() to make changes
1690       * persistent.       * persistent.
1691       *       *
1692         * @param pProgress - callback function for progress notification
1693       * @throws Exception - on errors       * @throws Exception - on errors
1694       */       */
1695      void File::UpdateChunks() {      void File::UpdateChunks(progress_t* pProgress) {
1696          // first update base class's chunks          // first update base class's chunks
1697          Resource::UpdateChunks();          Resource::UpdateChunks(pProgress);
1698    
1699          // if version struct exists, update 'vers' chunk          // if version struct exists, update 'vers' chunk
1700          if (pVersion) {          if (pVersion) {
# Line 1697  namespace DLS { Line 1716  namespace DLS {
1716    
1717          // update instrument's chunks          // update instrument's chunks
1718          if (pInstruments) {          if (pInstruments) {
1719                // divide local progress into subprogress
1720                progress_t subprogress;
1721                __divide_progress(pProgress, &subprogress, 20.f, 0.f); // arbitrarily subdivided into 5% of total progress
1722    
1723                // do the actual work
1724              InstrumentList::iterator iter = pInstruments->begin();              InstrumentList::iterator iter = pInstruments->begin();
1725              InstrumentList::iterator end  = pInstruments->end();              InstrumentList::iterator end  = pInstruments->end();
1726              for (; iter != end; ++iter) {              for (int i = 0; iter != end; ++iter, ++i) {
1727                  (*iter)->UpdateChunks();                  // divide subprogress into sub-subprogress
1728                    progress_t subsubprogress;
1729                    __divide_progress(&subprogress, &subsubprogress, pInstruments->size(), i);
1730                    // do the actual work
1731                    (*iter)->UpdateChunks(&subsubprogress);
1732              }              }
1733    
1734                __notify_progress(&subprogress, 1.0); // notify subprogress done
1735          }          }
1736    
1737          // update 'ptbl' chunk          // update 'ptbl' chunk
# Line 1719  namespace DLS { Line 1749  namespace DLS {
1749    
1750          // update sample's chunks          // update sample's chunks
1751          if (pSamples) {          if (pSamples) {
1752                // divide local progress into subprogress
1753                progress_t subprogress;
1754                __divide_progress(pProgress, &subprogress, 20.f, 1.f); // arbitrarily subdivided into 95% of total progress
1755    
1756                // do the actual work
1757              SampleList::iterator iter = pSamples->begin();              SampleList::iterator iter = pSamples->begin();
1758              SampleList::iterator end  = pSamples->end();              SampleList::iterator end  = pSamples->end();
1759              for (; iter != end; ++iter) {              for (int i = 0; iter != end; ++iter, ++i) {
1760                  (*iter)->UpdateChunks();                  // divide subprogress into sub-subprogress
1761                    progress_t subsubprogress;
1762                    __divide_progress(&subprogress, &subsubprogress, pSamples->size(), i);
1763                    // do the actual work
1764                    (*iter)->UpdateChunks(&subsubprogress);
1765              }              }
1766    
1767                __notify_progress(&subprogress, 1.0); // notify subprogress done
1768          }          }
1769    
1770            __notify_progress(pProgress, 1.0); // notify done
1771      }      }
1772    
1773      /** @brief Save changes to another file.      /** @brief Save changes to another file.
# Line 1739  namespace DLS { Line 1782  namespace DLS {
1782       * the new file (given by \a Path) afterwards.       * the new file (given by \a Path) afterwards.
1783       *       *
1784       * @param Path - path and file name where everything should be written to       * @param Path - path and file name where everything should be written to
1785         * @param pProgress - optional: callback function for progress notification
1786       */       */
1787      void File::Save(const String& Path) {      void File::Save(const String& Path, progress_t* pProgress) {
1788          UpdateChunks();          {
1789          pRIFF->Save(Path);              // divide local progress into subprogress
1790                progress_t subprogress;
1791                __divide_progress(pProgress, &subprogress, 2.f, 0.f); // arbitrarily subdivided into 50% of total progress
1792                // do the actual work
1793                UpdateChunks(&subprogress);
1794                
1795            }
1796            {
1797                // divide local progress into subprogress
1798                progress_t subprogress;
1799                __divide_progress(pProgress, &subprogress, 2.f, 1.f); // arbitrarily subdivided into 50% of total progress
1800                // do the actual work
1801                pRIFF->Save(Path, &subprogress);
1802            }
1803          UpdateFileOffsets();          UpdateFileOffsets();
1804            __notify_progress(pProgress, 1.0); // notify done
1805      }      }
1806    
1807      /** @brief Save changes to same file.      /** @brief Save changes to same file.
# Line 1752  namespace DLS { Line 1810  namespace DLS {
1810       * file. The file might temporarily grow to a higher size than it will       * file. The file might temporarily grow to a higher size than it will
1811       * have at the end of the saving process.       * have at the end of the saving process.
1812       *       *
1813         * @param pProgress - optional: callback function for progress notification
1814       * @throws RIFF::Exception if any kind of IO error occured       * @throws RIFF::Exception if any kind of IO error occured
1815       * @throws DLS::Exception  if any kind of DLS specific error occured       * @throws DLS::Exception  if any kind of DLS specific error occured
1816       */       */
1817      void File::Save() {      void File::Save(progress_t* pProgress) {
1818          UpdateChunks();          {
1819          pRIFF->Save();              // divide local progress into subprogress
1820                progress_t subprogress;
1821                __divide_progress(pProgress, &subprogress, 2.f, 0.f); // arbitrarily subdivided into 50% of total progress
1822                // do the actual work
1823                UpdateChunks(&subprogress);
1824            }
1825            {
1826                // divide local progress into subprogress
1827                progress_t subprogress;
1828                __divide_progress(pProgress, &subprogress, 2.f, 1.f); // arbitrarily subdivided into 50% of total progress
1829                // do the actual work
1830                pRIFF->Save(&subprogress);
1831            }
1832          UpdateFileOffsets();          UpdateFileOffsets();
1833            __notify_progress(pProgress, 1.0); // notify done
1834      }      }
1835    
1836      /** @brief Updates all file offsets stored all over the file.      /** @brief Updates all file offsets stored all over the file.

Legend:
Removed from v.2609  
changed lines
  Added in v.2682

  ViewVC Help
Powered by ViewVC