/[svn]/linuxsampler/trunk/src/engines/gig/InstrumentResourceManager.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/InstrumentResourceManager.cpp

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

revision 420 by schoenebeck, Thu Mar 3 03:25:17 2005 UTC revision 517 by schoenebeck, Sun May 8 00:26:21 2005 UTC
# Line 34  Line 34 
34    
35  namespace LinuxSampler { namespace gig {  namespace LinuxSampler { namespace gig {
36    
37        // some data needed for the libgig callback function
38        struct progress_callback_arg_t {
39            InstrumentResourceManager* pManager;
40            instrument_id_t*           pInstrumentKey;
41        };
42    
43        /**
44         * Callback function which will be called by libgig during loading of
45         * instruments to inform about the current progress. Or to be more
46         * specific; it will be called during the GetInstrument() call.
47         *
48         * @param pProgress - contains current progress value, pointer to the
49         *                    InstrumentResourceManager instance and
50         *                    instrument ID
51         */
52        void InstrumentResourceManager::OnInstrumentLoadingProgress(::gig::progress_t* pProgress) {
53            dmsg(7,("gig::InstrumentResourceManager: progress %f%", pProgress->factor));
54            progress_callback_arg_t* pArg = static_cast<progress_callback_arg_t*>(pProgress->custom);
55            // we randomly schedule 90% for the .gig file loading and the remaining 10% later for sample caching
56            const float localProgress = 0.9f * pProgress->factor;
57            pArg->pManager->DispatchResourceProgressEvent(*pArg->pInstrumentKey, localProgress);
58        }
59    
60      ::gig::Instrument* InstrumentResourceManager::Create(instrument_id_t Key, InstrumentConsumer* pConsumer, void*& pArg) {      ::gig::Instrument* InstrumentResourceManager::Create(instrument_id_t Key, InstrumentConsumer* pConsumer, void*& pArg) {
61          // get gig file from inernal gig file manager          // get gig file from inernal gig file manager
62          ::gig::File* pGig = Gigs.Borrow(Key.FileName, (GigConsumer*) Key.iInstrument); // conversion kinda hackish :/          ::gig::File* pGig = Gigs.Borrow(Key.FileName, (GigConsumer*) Key.iInstrument); // conversion kinda hackish :/
63    
64            // we pass this to the progress callback mechanism of libgig
65            progress_callback_arg_t callbackArg;
66            callbackArg.pManager       = this;
67            callbackArg.pInstrumentKey = &Key;
68    
69            ::gig::progress_t progress;
70            progress.callback = OnInstrumentLoadingProgress;
71            progress.custom   = &callbackArg;
72    
73          dmsg(1,("Loading gig instrument..."));          dmsg(1,("Loading gig instrument..."));
74          ::gig::Instrument* pInstrument = pGig->GetInstrument(Key.iInstrument);          ::gig::Instrument* pInstrument = pGig->GetInstrument(Key.iInstrument, &progress);
75          if (!pInstrument) {          if (!pInstrument) {
76              std::stringstream msg;              std::stringstream msg;
77              msg << "There's no instrument with index " << Key.iInstrument << ".";              msg << "There's no instrument with index " << Key.iInstrument << ".";
# Line 50  namespace LinuxSampler { namespace gig { Line 82  namespace LinuxSampler { namespace gig {
82    
83          // cache initial samples points (for actually needed samples)          // cache initial samples points (for actually needed samples)
84          dmsg(1,("Caching initial samples..."));          dmsg(1,("Caching initial samples..."));
85            uint iRegion = 0; // just for progress calculation
86          ::gig::Region* pRgn = pInstrument->GetFirstRegion();          ::gig::Region* pRgn = pInstrument->GetFirstRegion();
87          while (pRgn) {          while (pRgn) {
88                // we randomly schedule 90% for the .gig file loading and the remaining 10% now for sample caching
89                const float localProgress = 0.9f + 0.1f * (float) iRegion / (float) pInstrument->Regions;
90                DispatchResourceProgressEvent(Key, localProgress);            
91                
92              if (pRgn->GetSample() && !pRgn->GetSample()->GetCache().Size) {              if (pRgn->GetSample() && !pRgn->GetSample()->GetCache().Size) {
93                  dmsg(2,("C"));                  dmsg(2,("C"));
94                  CacheInitialSamples(pRgn->GetSample(), dynamic_cast<gig::EngineChannel*>(pConsumer));                  CacheInitialSamples(pRgn->GetSample(), dynamic_cast<gig::EngineChannel*>(pConsumer));
# Line 61  namespace LinuxSampler { namespace gig { Line 98  namespace LinuxSampler { namespace gig {
98              }              }
99    
100              pRgn = pInstrument->GetNextRegion();              pRgn = pInstrument->GetNextRegion();
101                iRegion++;
102          }          }
103          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
104            DispatchResourceProgressEvent(Key, 1.0f); // done; notify all consumers about progress 100%
105    
106          // we need the following for destruction later          // we need the following for destruction later
107          instr_entry_t* pEntry = new instr_entry_t;          instr_entry_t* pEntry = new instr_entry_t;
108          pEntry->iInstrument   = Key.iInstrument;          pEntry->iInstrument   = Key.iInstrument;
109          pEntry->pGig          = pGig;          pEntry->pGig          = pGig;
110            
111          gig::EngineChannel* pEngineChannel = dynamic_cast<gig::EngineChannel*>(pConsumer);          gig::EngineChannel* pEngineChannel = dynamic_cast<gig::EngineChannel*>(pConsumer);
112          // and we save this to check if we need to reallocate for a engine with higher value of 'MaxSamplesPerSecond'          // and we save this to check if we need to reallocate for a engine with higher value of 'MaxSamplesPerSecond'
113          pEntry->MaxSamplesPerCycle =          pEntry->MaxSamplesPerCycle =
# Line 105  namespace LinuxSampler { namespace gig { Line 144  namespace LinuxSampler { namespace gig {
144       *  @param pSample - points to the sample to be cached       *  @param pSample - points to the sample to be cached
145       *  @param pEngineChannel - pointer to Gig Engine Channel which caused this call       *  @param pEngineChannel - pointer to Gig Engine Channel which caused this call
146       */       */
147      void InstrumentResourceManager::CacheInitialSamples(::gig::Sample* pSample, gig::EngineChannel* pEngineChannel) {              void InstrumentResourceManager::CacheInitialSamples(::gig::Sample* pSample, gig::EngineChannel* pEngineChannel) {
148          if (!pSample) {          if (!pSample) {
149              dmsg(1,("gig::InstrumentResourceManager: Warning, skipping sample (pSample == NULL)\n"));              dmsg(4,("gig::InstrumentResourceManager: Skipping sample (pSample == NULL)\n"));
150              return;              return;
151          }          }
152          if (!pSample->SamplesTotal) return; // skip zero size samples          if (!pSample->SamplesTotal) return; // skip zero size samples
153            
154          if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {          if (pSample->SamplesTotal <= NUM_RAM_PRELOAD_SAMPLES) {
155              // Sample is too short for disk streaming, so we load the whole              // Sample is too short for disk streaming, so we load the whole
156              // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'              // sample into RAM and place 'pAudioIO->FragmentSize << MAX_PITCH'
157              // number of '0' samples (silence samples) behind the official buffer              // number of '0' samples (silence samples) behind the official buffer
158              // border, to allow the interpolator do it's work even at the end of              // border, to allow the interpolator do it's work even at the end of
159              // the sample.                          // the sample.
160              const uint maxSamplesPerCycle =              const uint maxSamplesPerCycle =
161                  (pEngineChannel->GetEngine()) ? dynamic_cast<gig::Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice->MaxSamplesPerCycle()                  (pEngineChannel->GetEngine()) ? dynamic_cast<gig::Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice->MaxSamplesPerCycle()
162                                                : GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;                                                : GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;

Legend:
Removed from v.420  
changed lines
  Added in v.517

  ViewVC Help
Powered by ViewVC