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

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

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

revision 2325 by schoenebeck, Mon Sep 19 21:48:45 2011 UTC revision 2326 by persson, Thu Mar 8 19:40:14 2012 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2011 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2008 Christian Schoenebeck                       *
7   *   Copyright (C) 2009 - 2011 Grigor Iliev                                *   *   Copyright (C) 2009 - 2012 Christian Schoenebeck and Grigor Iliev      *
8   *                                                                         *   *                                                                         *
9   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
10   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 35  Line 35 
35    
36  namespace LinuxSampler { namespace sf2 {  namespace LinuxSampler { namespace sf2 {
37    
     // data stored as long as an instrument resource exists  
     struct instr_entry_t {  
         InstrumentManager::instrument_id_t ID;  
         ::sf2::File*                       pSf2;  
         uint                               MaxSamplesPerCycle; ///< if some engine requests an already allocated instrument with a higher value, we have to reallocate the instrument  
     };  
   
     // some data needed for the libgig callback function  
     struct progress_callback_arg_t {  
         InstrumentResourceManager*          pManager;  
         InstrumentManager::instrument_id_t* pInstrumentKey;  
     };  
   
     std::vector<InstrumentResourceManager::instrument_id_t> InstrumentResourceManager::Instruments() {  
         return Entries();  
     }  
   
38      String InstrumentResourceManager::GetInstrumentName(instrument_id_t ID) {      String InstrumentResourceManager::GetInstrumentName(instrument_id_t ID) {
39          Lock();          Lock();
40          ::sf2::Preset* pInstrument = Resource(ID, false);          ::sf2::Preset* pInstrument = Resource(ID, false);
# Line 96  namespace LinuxSampler { namespace sf2 { Line 79  namespace LinuxSampler { namespace sf2 {
79          ::RIFF::File* riff = NULL;          ::RIFF::File* riff = NULL;
80          ::sf2::File*  sf2  = NULL;          ::sf2::File*  sf2  = NULL;
81          try {          try {
82              if(!loaded) {              if (!loaded) {
83                  riff = new ::RIFF::File(ID.FileName);                  riff = new ::RIFF::File(ID.FileName);
84                  sf2 = new ::sf2::File(riff);                  sf2 = new ::sf2::File(riff);
85                  pInstrument = GetSfInstrument(sf2, ID.Index);                  pInstrument = GetSfInstrument(sf2, ID.Index);
# Line 157  namespace LinuxSampler { namespace sf2 { Line 140  namespace LinuxSampler { namespace sf2 {
140          // cache initial samples points (for actually needed samples)          // cache initial samples points (for actually needed samples)
141          dmsg(1,("Caching initial samples..."));          dmsg(1,("Caching initial samples..."));
142          float regTotal = 0, regCurrent = 0;          float regTotal = 0, regCurrent = 0;
143          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {          for (int i = 0 ; i < pInstrument->GetRegionCount() ; i++) {
144              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;
145              if(sf2Instr) regTotal += sf2Instr->GetRegionCount();              if (sf2Instr) regTotal += sf2Instr->GetRegionCount();
146          }          }
147          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {          uint maxSamplesPerCycle = GetMaxSamplesPerCycle(pConsumer);
148            for (int i = 0 ; i < pInstrument->GetRegionCount() ; i++) {
149              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;
150              if(sf2Instr != NULL) {              if (sf2Instr) {
151                  // pInstrument is ::sf2::Preset                  // pInstrument is ::sf2::Preset
152                  for(int j = 0; j < sf2Instr->GetRegionCount(); j++) {                  for (int j = 0 ; j < sf2Instr->GetRegionCount() ; j++) {
153                      const float localProgress = regCurrent++ / regTotal;                      float localProgress = regCurrent++ / regTotal;
154                      DispatchResourceProgressEvent(Key, localProgress);                      DispatchResourceProgressEvent(Key, localProgress);
155                      CacheInitialSamples(sf2Instr->GetRegion(j)->GetSample(), dynamic_cast<AbstractEngineChannel*>(pConsumer));                      CacheInitialSamples(sf2Instr->GetRegion(j)->GetSample(), maxSamplesPerCycle);
156                  }                  }
157              }              }
158          }          }
# Line 179  namespace LinuxSampler { namespace sf2 { Line 163  namespace LinuxSampler { namespace sf2 {
163          instr_entry_t* pEntry = new instr_entry_t;          instr_entry_t* pEntry = new instr_entry_t;
164          pEntry->ID.FileName   = Key.FileName;          pEntry->ID.FileName   = Key.FileName;
165          pEntry->ID.Index      = Key.Index;          pEntry->ID.Index      = Key.Index;
166          pEntry->pSf2          = pSf2;          pEntry->pFile         = pSf2;
167    
168          // (try to resolve the audio device context)          // and we save this to check if we need to reallocate for an engine with higher value of 'MaxSamplesPerSecond'
169          EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);          pEntry->MaxSamplesPerCycle = maxSamplesPerCycle;
         AudioOutputDevice* pDevice =  
             (pEngineChannel) ? dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice : NULL;  
           
         // and we save this to check if we need to reallocate for a engine with higher value of 'MaxSamplesPerSecond'  
         pEntry->MaxSamplesPerCycle =  
             (pDevice) ? pDevice->MaxSamplesPerCycle() : DefaultMaxSamplesPerCycle();  
170    
171          pArg = pEntry;          pArg = pEntry;
172    
173          return pInstrument;          return pInstrument;
174      }      }
175    
176      void InstrumentResourceManager::Destroy( ::sf2::Preset* pResource, void* pArg) {      void InstrumentResourceManager::Destroy(::sf2::Preset* pResource, void* pArg) {
177          instr_entry_t* pEntry = (instr_entry_t*) pArg;          instr_entry_t* pEntry = (instr_entry_t*) pArg;
178          // we don't need the .sf2 file here anymore          // we don't need the .sf2 file here anymore
179          Sf2s.HandBack(pEntry->pSf2, reinterpret_cast<Sf2Consumer*>(pEntry->ID.Index)); // conversion kinda hackish :/          Sf2s.HandBack(pEntry->pFile, reinterpret_cast<Sf2Consumer*>(pEntry->ID.Index)); // conversion kinda hackish :/
180          delete pEntry;          delete pEntry;
181      }      }
182    
     void InstrumentResourceManager::OnBorrow(::sf2::Preset* pResource, InstrumentConsumer* pConsumer, void*& pArg) {  
         instr_entry_t* pEntry = (instr_entry_t*) pArg;  
           
         // (try to resolve the audio device context)  
         EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);  
         AudioOutputDevice* pDevice =  
             (pEngineChannel) ? dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice : NULL;  
   
         uint maxSamplesPerCycle =  
             (pDevice) ? pDevice->MaxSamplesPerCycle() : DefaultMaxSamplesPerCycle();  
   
         if (pEntry->MaxSamplesPerCycle < maxSamplesPerCycle) {  
             dmsg(1,("Completely reloading instrument due to insufficient precached samples ...\n"));  
             Update(pResource, pConsumer);  
         }  
     }  
   
183      void InstrumentResourceManager::DeleteRegionIfNotUsed(::sf2::Region* pRegion, region_info_t* pRegInfo) {      void InstrumentResourceManager::DeleteRegionIfNotUsed(::sf2::Region* pRegion, region_info_t* pRegInfo) {
184          // TODO: we could delete Region and Instrument here if they have become unused          // TODO: we could delete Region and Instrument here if they have become unused
185      }      }

Legend:
Removed from v.2325  
changed lines
  Added in v.2326

  ViewVC Help
Powered by ViewVC