/[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 437 by persson, Wed Mar 9 22:02:40 2005 UTC revision 518 by schoenebeck, Sun May 8 16:19:34 2005 UTC
# Line 25  Line 25 
25    
26  #include <iostream>  #include <iostream>
27    
28  namespace gig { namespace {  namespace gig {
29    
30    // *************** progress_t ***************
31    // *
32    
33        progress_t::progress_t() {
34            callback    = NULL;
35            custom      = NULL;
36            __range_min = 0.0f;
37            __range_max = 1.0f;
38        }
39    
40        // private helper function to convert progress of a subprocess into the global progress
41        static void __notify_progress(progress_t* pProgress, float subprogress) {
42            if (pProgress && pProgress->callback) {
43                const float totalrange    = pProgress->__range_max - pProgress->__range_min;
44                const float totalprogress = pProgress->__range_min + subprogress * totalrange;
45                pProgress->factor         = totalprogress;
46                pProgress->callback(pProgress); // now actually notify about the progress
47            }
48        }
49    
50        // private helper function to divide a progress into subprogresses
51        static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) {
52            if (pParentProgress && pParentProgress->callback) {
53                const float totalrange    = pParentProgress->__range_max - pParentProgress->__range_min;
54                pSubProgress->callback    = pParentProgress->callback;
55                pSubProgress->custom      = pParentProgress->custom;
56                pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks;
57                pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks;
58            }
59        }
60    
61    
62  // *************** Internal functions for sample decopmression ***************  // *************** Internal functions for sample decopmression ***************
63  // *  // *
64    
65    namespace {
66    
67      inline int get12lo(const unsigned char* pSrc)      inline int get12lo(const unsigned char* pSrc)
68      {      {
69          const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;          const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
# Line 1551  namespace gig { namespace { Line 1585  namespace gig { namespace {
1585          else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));          else         return static_cast<gig::Sample*>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
1586      }      }
1587    
1588      Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex) {      Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
1589          if ((int32_t)WavePoolTableIndex == -1) return NULL;          if ((int32_t)WavePoolTableIndex == -1) return NULL;
1590          File* file = (File*) GetParent()->GetParent();          File* file = (File*) GetParent()->GetParent();
1591          unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];          unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
1592          Sample* sample = file->GetFirstSample();          Sample* sample = file->GetFirstSample(pProgress);
1593          while (sample) {          while (sample) {
1594              if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);              if (sample->ulWavePoolOffset == soughtoffset) return static_cast<gig::Sample*>(pSample = sample);
1595              sample = file->GetNextSample();              sample = file->GetNextSample();
# Line 1568  namespace gig { namespace { Line 1602  namespace gig { namespace {
1602  // *************** Instrument ***************  // *************** Instrument ***************
1603  // *  // *
1604    
1605      Instrument::Instrument(File* pFile, RIFF::List* insList) : DLS::Instrument((DLS::File*)pFile, insList) {      Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
1606          // Initialization          // Initialization
1607          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;          for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
1608          RegionIndex = -1;          RegionIndex = -1;
# Line 1599  namespace gig { namespace { Line 1633  namespace gig { namespace {
1633          unsigned int iRegion = 0;          unsigned int iRegion = 0;
1634          while (rgn) {          while (rgn) {
1635              if (rgn->GetListType() == LIST_TYPE_RGN) {              if (rgn->GetListType() == LIST_TYPE_RGN) {
1636                    __notify_progress(pProgress, (float) iRegion / (float) Regions);
1637                  pRegions[iRegion] = new Region(this, rgn);                  pRegions[iRegion] = new Region(this, rgn);
1638                  iRegion++;                  iRegion++;
1639              }              }
# Line 1611  namespace gig { namespace { Line 1646  namespace gig { namespace {
1646                  RegionKeyTable[iKey] = pRegions[iReg];                  RegionKeyTable[iKey] = pRegions[iReg];
1647              }              }
1648          }          }
1649    
1650            __notify_progress(pProgress, 1.0f); // notify done
1651      }      }
1652    
1653      Instrument::~Instrument() {      Instrument::~Instrument() {
# Line 1699  namespace gig { namespace { Line 1736  namespace gig { namespace {
1736          }          }
1737      }      }
1738    
1739      Sample* File::GetFirstSample() {      Sample* File::GetFirstSample(progress_t* pProgress) {
1740          if (!pSamples) LoadSamples();          if (!pSamples) LoadSamples(pProgress);
1741          if (!pSamples) return NULL;          if (!pSamples) return NULL;
1742          SamplesIterator = pSamples->begin();          SamplesIterator = pSamples->begin();
1743          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
# Line 1712  namespace gig { namespace { Line 1749  namespace gig { namespace {
1749          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );          return static_cast<gig::Sample*>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
1750      }      }
1751    
1752      void File::LoadSamples() {      void File::LoadSamples(progress_t* pProgress) {
1753          RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);          RIFF::List* wvpl = pRIFF->GetSubList(LIST_TYPE_WVPL);
1754          if (wvpl) {          if (wvpl) {
1755                // just for progress calculation
1756                int iSampleIndex  = 0;
1757                int iTotalSamples = wvpl->CountSubLists(LIST_TYPE_WAVE);
1758    
1759              unsigned long wvplFileOffset = wvpl->GetFilePos();              unsigned long wvplFileOffset = wvpl->GetFilePos();
1760              RIFF::List* wave = wvpl->GetFirstSubList();              RIFF::List* wave = wvpl->GetFirstSubList();
1761              while (wave) {              while (wave) {
1762                  if (wave->GetListType() == LIST_TYPE_WAVE) {                  if (wave->GetListType() == LIST_TYPE_WAVE) {
1763                        // notify current progress
1764                        const float subprogress = (float) iSampleIndex / (float) iTotalSamples;
1765                        __notify_progress(pProgress, subprogress);
1766    
1767                      if (!pSamples) pSamples = new SampleList;                      if (!pSamples) pSamples = new SampleList;
1768                      unsigned long waveFileOffset = wave->GetFilePos();                      unsigned long waveFileOffset = wave->GetFilePos();
1769                      pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));                      pSamples->push_back(new Sample(this, wave, waveFileOffset - wvplFileOffset));
1770    
1771                        iSampleIndex++;
1772                  }                  }
1773                  wave = wvpl->GetNextSubList();                  wave = wvpl->GetNextSubList();
1774              }              }
1775                __notify_progress(pProgress, 1.0); // notify done
1776          }          }
1777          else throw gig::Exception("Mandatory <wvpl> chunk not found.");          else throw gig::Exception("Mandatory <wvpl> chunk not found.");
1778      }      }
# Line 1745  namespace gig { namespace { Line 1793  namespace gig { namespace {
1793      /**      /**
1794       * Returns the instrument with the given index.       * Returns the instrument with the given index.
1795       *       *
1796         * @param index     - number of the sought instrument (0..n)
1797         * @param pProgress - optional: callback function for progress notification
1798       * @returns  sought instrument or NULL if there's no such instrument       * @returns  sought instrument or NULL if there's no such instrument
1799       */       */
1800      Instrument* File::GetInstrument(uint index) {      Instrument* File::GetInstrument(uint index, progress_t* pProgress) {
1801          if (!pInstruments) LoadInstruments();          if (!pInstruments) {
1802                // TODO: hack - we simply load ALL samples here, it would have been done in the Region constructor anyway (ATM)
1803    
1804                // sample loading subtask
1805                progress_t subprogress;
1806                __divide_progress(pProgress, &subprogress, 3.0f, 0.0f); // randomly schedule 33% for this subtask
1807                __notify_progress(&subprogress, 0.0f);
1808                GetFirstSample(&subprogress); // now force all samples to be loaded
1809                __notify_progress(&subprogress, 1.0f);
1810    
1811                // instrument loading subtask
1812                if (pProgress && pProgress->callback) {
1813                    subprogress.__range_min = subprogress.__range_max;
1814                    subprogress.__range_max = pProgress->__range_max; // schedule remaining percentage for this subtask
1815                }
1816                __notify_progress(&subprogress, 0.0f);
1817                LoadInstruments(&subprogress);
1818                __notify_progress(&subprogress, 1.0f);
1819            }
1820          if (!pInstruments) return NULL;          if (!pInstruments) return NULL;
1821          InstrumentsIterator = pInstruments->begin();          InstrumentsIterator = pInstruments->begin();
1822          for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {          for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
# Line 1758  namespace gig { namespace { Line 1826  namespace gig { namespace {
1826          return NULL;          return NULL;
1827      }      }
1828    
1829      void File::LoadInstruments() {      void File::LoadInstruments(progress_t* pProgress) {
1830          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);          RIFF::List* lstInstruments = pRIFF->GetSubList(LIST_TYPE_LINS);
1831          if (lstInstruments) {          if (lstInstruments) {
1832                int iInstrumentIndex = 0;
1833              RIFF::List* lstInstr = lstInstruments->GetFirstSubList();              RIFF::List* lstInstr = lstInstruments->GetFirstSubList();
1834              while (lstInstr) {              while (lstInstr) {
1835                  if (lstInstr->GetListType() == LIST_TYPE_INS) {                  if (lstInstr->GetListType() == LIST_TYPE_INS) {
1836                        // notify current progress
1837                        const float localProgress = (float) iInstrumentIndex / (float) Instruments;
1838                        __notify_progress(pProgress, localProgress);
1839    
1840                        // divide local progress into subprogress for loading current Instrument
1841                        progress_t subprogress;
1842                        __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
1843    
1844                      if (!pInstruments) pInstruments = new InstrumentList;                      if (!pInstruments) pInstruments = new InstrumentList;
1845                      pInstruments->push_back(new Instrument(this, lstInstr));                      pInstruments->push_back(new Instrument(this, lstInstr, &subprogress));
1846    
1847                        iInstrumentIndex++;
1848                  }                  }
1849                  lstInstr = lstInstruments->GetNextSubList();                  lstInstr = lstInstruments->GetNextSubList();
1850              }              }
1851                __notify_progress(pProgress, 1.0); // notify done
1852          }          }
1853          else throw gig::Exception("Mandatory <lins> list chunk not found.");          else throw gig::Exception("Mandatory <lins> list chunk not found.");
1854      }      }
# Line 1785  namespace gig { namespace { Line 1865  namespace gig { namespace {
1865          std::cout << "gig::Exception: " << Message << std::endl;          std::cout << "gig::Exception: " << Message << std::endl;
1866      }      }
1867    
1868    
1869    // *************** functions ***************
1870    // *
1871    
1872        /**
1873         * Returns the name of this C++ library. This is usually "libgig" of
1874         * course. This call is equivalent to RIFF::libraryName() and
1875         * DLS::libraryName().
1876         */
1877        String libraryName() {
1878            return PACKAGE;
1879        }
1880    
1881        /**
1882         * Returns version of this C++ library. This call is equivalent to
1883         * RIFF::libraryVersion() and DLS::libraryVersion().
1884         */
1885        String libraryVersion() {
1886            return VERSION;
1887        }
1888    
1889  } // namespace gig  } // namespace gig

Legend:
Removed from v.437  
changed lines
  Added in v.518

  ViewVC Help
Powered by ViewVC