/[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 2018 by iliev, Tue Oct 27 19:04:57 2009 UTC revision 2275 by schoenebeck, Mon Sep 19 21:48:45 2011 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 - 2009 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2011 Christian Schoenebeck                       *
7   *   Copyright (C) 2009 Grigor Iliev                                       *   *   Copyright (C) 2009 - 2011 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 54  namespace LinuxSampler { namespace sf2 { Line 54  namespace LinuxSampler { namespace sf2 {
54    
55      String InstrumentResourceManager::GetInstrumentName(instrument_id_t ID) {      String InstrumentResourceManager::GetInstrumentName(instrument_id_t ID) {
56          Lock();          Lock();
57          ::sf2::InstrumentBase* pInstrument = Resource(ID, false);          ::sf2::Preset* pInstrument = Resource(ID, false);
58          String res = (pInstrument) ? pInstrument->GetName() : "";          String res = (pInstrument) ? pInstrument->GetName() : "";
59          Unlock();          Unlock();
60          return res;          return res;
# Line 89  namespace LinuxSampler { namespace sf2 { Line 89  namespace LinuxSampler { namespace sf2 {
89    
90      InstrumentResourceManager::instrument_info_t InstrumentResourceManager::GetInstrumentInfo(instrument_id_t ID) throw (InstrumentManagerException) {      InstrumentResourceManager::instrument_info_t InstrumentResourceManager::GetInstrumentInfo(instrument_id_t ID) throw (InstrumentManagerException) {
91          Lock();          Lock();
92          ::sf2::InstrumentBase* pInstrument = Resource(ID, false);          ::sf2::Preset* pInstrument = Resource(ID, false);
93          bool loaded = (pInstrument != NULL);          bool loaded = (pInstrument != NULL);
94          if (!loaded) Unlock();          if (!loaded) Unlock();
95    
# Line 116  namespace LinuxSampler { namespace sf2 { Line 116  namespace LinuxSampler { namespace sf2 {
116              for (int i = 0; i < pInstrument->GetRegionCount(); i++) {              for (int i = 0; i < pInstrument->GetRegionCount(); i++) {
117                  int low = pInstrument->GetRegion(i)->loKey;                  int low = pInstrument->GetRegion(i)->loKey;
118                  int high = pInstrument->GetRegion(i)->hiKey;                  int high = pInstrument->GetRegion(i)->hiKey;
119                  if (low < 0 || low > 127 || high < 0 || high > 127 || low > high) {                  if (low == ::sf2::NONE || high == ::sf2::NONE) {
120                      std::cerr << "Invalid key range: " << low << " - " << high << std::endl;                      ::sf2::Instrument* layer = pInstrument->GetRegion(i)->pInstrument;
121                        for (int j = 0; j < layer->GetRegionCount(); j++) {
122                            int lo = layer->GetRegion(j)->loKey;
123                            int hi = layer->GetRegion(j)->hiKey;
124                            SetKeyBindings(info.KeyBindings, lo, hi, ::sf2::NONE);
125                        }
126                  } else {                  } else {
127                      for (int i = low; i <= high; i++) info.KeyBindings[i] = 1;                      SetKeyBindings(info.KeyBindings, low, high, ::sf2::NONE);
128                  }                  }
129              }              }
130    
# Line 141  namespace LinuxSampler { namespace sf2 { Line 146  namespace LinuxSampler { namespace sf2 {
146          }          }
147      }      }
148    
149      ::sf2::InstrumentBase* InstrumentResourceManager::Create(instrument_id_t Key, InstrumentConsumer* pConsumer, void*& pArg) {      ::sf2::Preset* InstrumentResourceManager::Create(instrument_id_t Key, InstrumentConsumer* pConsumer, void*& pArg) {
150          // get sfz file from internal sfz file manager          // get sfz file from internal sfz file manager
151          ::sf2::File* pSf2 = Sf2s.Borrow(Key.FileName, (Sf2Consumer*) Key.Index); // conversion kinda hackish :/          ::sf2::File* pSf2 = Sf2s.Borrow(Key.FileName, reinterpret_cast<Sf2Consumer*>(Key.Index)); // conversion kinda hackish :/
152    
153          dmsg(1,("Loading sf2 instrument ('%s',%d)...",Key.FileName.c_str(),Key.Index));          dmsg(1,("Loading sf2 instrument ('%s',%d)...",Key.FileName.c_str(),Key.Index));
154          ::sf2::InstrumentBase* pInstrument = GetSfInstrument(pSf2, Key.Index);          ::sf2::Preset* pInstrument = GetSfInstrument(pSf2, Key.Index);
155          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
156    
157          // cache initial samples points (for actually needed samples)          // cache initial samples points (for actually needed samples)
# Line 155  namespace LinuxSampler { namespace sf2 { Line 160  namespace LinuxSampler { namespace sf2 {
160          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {
161              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;
162              if(sf2Instr) regTotal += sf2Instr->GetRegionCount();              if(sf2Instr) regTotal += sf2Instr->GetRegionCount();
             else regTotal++; // if sf2Instr is null, than pInstrument is not a preset  
163          }          }
164          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {          for(int i = 0 ; i < pInstrument->GetRegionCount(); i++) {
165              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;              ::sf2::Instrument* sf2Instr = pInstrument->GetRegion(i)->pInstrument;
             ::sf2::Sample* sf2Sample = pInstrument->GetRegion(i)->GetSample();  
166              if(sf2Instr != NULL) {              if(sf2Instr != NULL) {
167                  // pInstrument is ::sf2::Preset                  // pInstrument is ::sf2::Preset
168                  for(int j = 0; j < sf2Instr->GetRegionCount(); j++) {                  for(int j = 0; j < sf2Instr->GetRegionCount(); j++) {
# Line 167  namespace LinuxSampler { namespace sf2 { Line 170  namespace LinuxSampler { namespace sf2 {
170                      DispatchResourceProgressEvent(Key, localProgress);                      DispatchResourceProgressEvent(Key, localProgress);
171                      CacheInitialSamples(sf2Instr->GetRegion(j)->GetSample(), dynamic_cast<AbstractEngineChannel*>(pConsumer));                      CacheInitialSamples(sf2Instr->GetRegion(j)->GetSample(), dynamic_cast<AbstractEngineChannel*>(pConsumer));
172                  }                  }
             } else if(sf2Sample != NULL) {  
                 // pInstrument is ::sf2::Instrument  
                 CacheInitialSamples(sf2Sample, dynamic_cast<AbstractEngineChannel*>(pConsumer));  
173              }              }
174          }          }
175          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
# Line 181  namespace LinuxSampler { namespace sf2 { Line 181  namespace LinuxSampler { namespace sf2 {
181          pEntry->ID.Index      = Key.Index;          pEntry->ID.Index      = Key.Index;
182          pEntry->pSf2          = pSf2;          pEntry->pSf2          = pSf2;
183    
184            // (try to resolve the audio device context)
185          EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);          EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);
186            AudioOutputDevice* pDevice =
187                (pEngineChannel) ? dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice : NULL;
188            
189          // 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'
190          pEntry->MaxSamplesPerCycle =          pEntry->MaxSamplesPerCycle =
191              (!pEngineChannel) ? 0 /* don't care for instrument editors */ :              (pDevice) ? pDevice->MaxSamplesPerCycle() : DefaultMaxSamplesPerCycle();
192                  (pEngineChannel->GetEngine()) ?  
                     dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice->MaxSamplesPerCycle()  
                     : GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;  
193          pArg = pEntry;          pArg = pEntry;
194    
195          return pInstrument;          return pInstrument;
196      }      }
197    
198      void InstrumentResourceManager::Destroy( ::sf2::InstrumentBase* pResource, void* pArg) {      void InstrumentResourceManager::Destroy( ::sf2::Preset* pResource, void* pArg) {
199          instr_entry_t* pEntry = (instr_entry_t*) pArg;          instr_entry_t* pEntry = (instr_entry_t*) pArg;
200          // we don't need the .sf2 file here anymore          // we don't need the .sf2 file here anymore
201          Sf2s.HandBack(pEntry->pSf2, (Sf2Consumer*) pEntry->ID.Index); // conversion kinda hackish :/          Sf2s.HandBack(pEntry->pSf2, reinterpret_cast<Sf2Consumer*>(pEntry->ID.Index)); // conversion kinda hackish :/
202          delete pEntry;          delete pEntry;
203      }      }
204    
205      void InstrumentResourceManager::OnBorrow(::sf2::InstrumentBase* pResource, InstrumentConsumer* pConsumer, void*& pArg) {      void InstrumentResourceManager::OnBorrow(::sf2::Preset* pResource, InstrumentConsumer* pConsumer, void*& pArg) {
206          instr_entry_t* pEntry = (instr_entry_t*) pArg;          instr_entry_t* pEntry = (instr_entry_t*) pArg;
207            
208            // (try to resolve the audio device context)
209          EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);          EngineChannel* pEngineChannel = dynamic_cast<EngineChannel*>(pConsumer);
210            AudioOutputDevice* pDevice =
211                (pEngineChannel) ? dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice : NULL;
212    
213          uint maxSamplesPerCycle =          uint maxSamplesPerCycle =
214              (pEngineChannel && pEngineChannel->GetEngine()) ? dynamic_cast<Engine*>(pEngineChannel->GetEngine())->pAudioOutputDevice->MaxSamplesPerCycle()              (pDevice) ? pDevice->MaxSamplesPerCycle() : DefaultMaxSamplesPerCycle();
215                                            : GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;  
216          if (pEntry->MaxSamplesPerCycle < maxSamplesPerCycle) {          if (pEntry->MaxSamplesPerCycle < maxSamplesPerCycle) {
217                dmsg(1,("Completely reloading instrument due to insufficient precached samples ...\n"));
218              Update(pResource, pConsumer);              Update(pResource, pConsumer);
219          }          }
220      }      }
# Line 244  namespace LinuxSampler { namespace sf2 { Line 252  namespace LinuxSampler { namespace sf2 {
252      void InstrumentResourceManager::Sf2ResourceManager::Destroy(::sf2::File* pResource, void* pArg) {      void InstrumentResourceManager::Sf2ResourceManager::Destroy(::sf2::File* pResource, void* pArg) {
253          dmsg(1,("Freeing sf2 file from memory..."));          dmsg(1,("Freeing sf2 file from memory..."));
254    
255        /*  // Delete as much as possible of the sfz file. Some of the          // Delete as much as possible of the sf2 file. Some of the
256          // regions and samples may still be in use - these          // regions and samples may still be in use - these
257          // will be deleted later by the HandBackRegion function.          // will be deleted later by the HandBackRegion function.
258          bool deleteInstrument = true;          bool deleteFile = true;
         ::sf2::Instrument* pInstr = pResource->GetInstrument();  
259    
260          for (int i = pInstr->regions.size() - 1; i >= 0 ; i--) {          for (int i = pResource->GetInstrumentCount() - 1; i >= 0; i--) {
261              ::sfz::Region* pRegion = pInstr->regions[i];              ::sf2::Instrument* pInstr = pResource->GetInstrument(i);
262              std::map< ::sfz::Region*, region_info_t>::iterator iter = parent->RegionInfo.find(pRegion);              bool deleteInstrument = true;
263              if (iter != parent->RegionInfo.end()) {  
264                  region_info_t& regInfo = (*iter).second;              for (int j = pInstr->GetRegionCount() - 1; j >= 0 ; j--) {
265                  regInfo.file = pResource;                  ::sf2::Region* pRegion = pInstr->GetRegion(j);
266                  deleteInstrument = false;                  std::map< ::sf2::Region*, region_info_t>::iterator iter = parent->RegionInfo.find(pRegion);
267              } else {                  if (iter != parent->RegionInfo.end()) {
268                  SampleFile* sf = pRegion->GetSample(false);                      region_info_t& regInfo = (*iter).second;
269                  if (sf != NULL) pInstr->GetSampleManager()->RemoveSampleConsumer(sf, pRegion);                      regInfo.file = pResource;
270                  if (sf == NULL || !pInstr->GetSampleManager()->HasSampleConsumers(sf)) pInstr->DestroyRegion(pRegion);                      deleteFile = deleteInstrument = false;
271                    } else {
272                        pInstr->DeleteRegion(pRegion);
273                    }
274              }              }
275    
276                if (deleteInstrument) pResource->DeleteInstrument(pInstr);
277          }          }
278    
279          if(deleteInstrument) delete pResource;          if (deleteFile) {
280          else dmsg(2,("keeping some samples that are in use..."));*/              delete pResource;
281                delete (::RIFF::File*) pArg;
282            } else {
283                dmsg(2,("keeping some samples that are in use..."));
284                for (int i = pResource->GetSampleCount() - 1; i >= 0; i--) {
285                    ::sf2::Sample* sample = pResource->GetSample(i);
286                    if (parent->SampleRefCount.find(sample) == parent->SampleRefCount.end()) {
287                        pResource->DeleteSample(sample);
288                    }
289                }
290            }
291    
292          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
293      }      }
294    
295      int InstrumentResourceManager::GetSfInstrumentCount(::sf2::File* pFile) {      int InstrumentResourceManager::GetSfInstrumentCount(::sf2::File* pFile) {
296          return pFile->GetInstrumentCount() + pFile->GetPresetCount();          return pFile->GetPresetCount();
297      }      }
298    
299      ::sf2::InstrumentBase* InstrumentResourceManager::GetSfInstrument(::sf2::File* pFile, int idx) {      ::sf2::Preset* InstrumentResourceManager::GetSfInstrument(::sf2::File* pFile, int idx) {
300          if (idx >= pFile->GetInstrumentCount() + pFile->GetPresetCount()) {          if (idx >= pFile->GetPresetCount()) {
301              throw InstrumentManagerException("There is no instrument with index " + ToString(idx));              throw InstrumentManagerException("There is no instrument with index " + ToString(idx));
302          }          }
303            return pFile->GetPreset(idx);
         if (idx < pFile->GetInstrumentCount()) {  
             return pFile->GetInstrument(idx);  
         }  
           
         int presetIdx = idx - pFile->GetInstrumentCount();  
         return pFile->GetPreset(presetIdx);  
304      }      }
305    
306  }} // namespace LinuxSampler::sfz  }} // namespace LinuxSampler::sfz

Legend:
Removed from v.2018  
changed lines
  Added in v.2275

  ViewVC Help
Powered by ViewVC