/[svn]/linuxsampler/trunk/src/engines/InstrumentManagerBase.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/InstrumentManagerBase.h

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 Grigor Iliev                                       *   *   Copyright (C) 2009 - 2012 Christian Schoenebeck and Grigor Iliev      *
8   *                                                                         *   *                                                                         *
9   *   This library is free software; you can redistribute it and/or modify  *   *   This library 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 37  Line 37 
37  // how much initial sample points we need to cache into RAM. If the given  // how much initial sample points we need to cache into RAM. If the given
38  // sampler channel does not have an audio output device assigned yet  // sampler channel does not have an audio output device assigned yet
39  // though, we simply use this default value.  // though, we simply use this default value.
40  #define GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE     128  #define RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE     128
41    
42  namespace LinuxSampler {  namespace LinuxSampler {
43    
44      template <class F /* Instrument File */, class I /* Instrument */, class R /* Regions */, class S /*Sample */>      template <class F /* Instrument File */, class I /* Instrument */, class R /* Regions */, class S /*Sample */>
45      class InstrumentManagerBase : virtual public InstrumentManager, virtual public ResourceManager<InstrumentManager::instrument_id_t, I> {      class InstrumentManagerBase : public InstrumentManager, public ResourceManager<InstrumentManager::instrument_id_t, I> {
46          public:          public:
47              struct region_info_t {              struct region_info_t {
48                  int    refCount;                  int    refCount;
# Line 128  namespace LinuxSampler { Line 128  namespace LinuxSampler {
128                  dmsg(2,("InstrumentManagerBase: setting mode for %s (Index=%d) to %d\n",ID.FileName.c_str(),ID.Index,Mode));                  dmsg(2,("InstrumentManagerBase: setting mode for %s (Index=%d) to %d\n",ID.FileName.c_str(),ID.Index,Mode));
129                  SetAvailabilityMode(ID, static_cast<typename ResourceManager<instrument_id_t, I>::mode_t>(Mode));                  SetAvailabilityMode(ID, static_cast<typename ResourceManager<instrument_id_t, I>::mode_t>(Mode));
130              }              }
131                
132        protected:
133                // data stored as long as an instrument resource exists
134                struct instr_entry_t {
135                    InstrumentManager::instrument_id_t ID;
136                    F*                                 pFile;
137                    uint                               MaxSamplesPerCycle; ///< if some engine requests an already allocated instrument with a higher value, we have to reallocate the instrument
138                };
139    
140    
141              /**              /**
142               * Used by the implementing instrument manager descendents in case               * Used by the implementing instrument manager descendents in case
143               * they don't have a reference to a sampler channel, which in turn               * they don't have a reference to a sampler channel, which in turn
# Line 155  namespace LinuxSampler { Line 164  namespace LinuxSampler {
164                      if (pDevice->MaxSamplesPerCycle() > samples)                      if (pDevice->MaxSamplesPerCycle() > samples)
165                          samples = pDevice->MaxSamplesPerCycle();                          samples = pDevice->MaxSamplesPerCycle();
166                  }                  }
167                  return (samples != 0) ? samples : 128 /* some fallback default value*/;                  return (samples != 0) ? samples : RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;
168                }
169    
170                uint GetMaxSamplesPerCycle(InstrumentConsumer* pConsumer) {
171                    // try to resolve the audio device context
172                    AbstractEngineChannel* pEngineChannel = dynamic_cast<AbstractEngineChannel*>(pConsumer);
173                    AudioOutputDevice* pDevice = pEngineChannel ? pEngineChannel->GetAudioOutputDeviceSafe() : 0;
174                    return pDevice ? pDevice->MaxSamplesPerCycle() : DefaultMaxSamplesPerCycle();
175              }              }
176    
         protected:  
177              Mutex RegionInfoMutex; ///< protects the RegionInfo and SampleRefCount maps from concurrent access by the instrument loader and disk threads              Mutex RegionInfoMutex; ///< protects the RegionInfo and SampleRefCount maps from concurrent access by the instrument loader and disk threads
178              std::map< R*, region_info_t> RegionInfo; ///< contains dimension regions that are still in use but belong to released instrument              std::map< R*, region_info_t> RegionInfo; ///< contains dimension regions that are still in use but belong to released instrument
179              std::map< S*, int> SampleRefCount; ///< contains samples that are still in use but belong to a released instrument              std::map< S*, int> SampleRefCount; ///< contains samples that are still in use but belong to a released instrument
180    
             /**  
              *  Caches a certain size at the beginning of the given sample in RAM. If the  
              *  sample is very short, the whole sample will be loaded into RAM and thus  
              *  no disk streaming is needed for this sample. Caching an initial part of  
              *  samples is needed to compensate disk reading latency.  
              *  
              *  @param pSample - points to the sample to be cached  
              *  @param pEngine - pointer to Engine which caused this call  
              *                   (may be NULL, in this case default amount of samples  
              *                   will be cached)  
              */  
             virtual void CacheInitialSamples(S* pSample, AbstractEngine* pEngine) = 0;  
   
181              virtual void DeleteRegionIfNotUsed(R* pRegion, region_info_t* pRegInfo) = 0;              virtual void DeleteRegionIfNotUsed(R* pRegion, region_info_t* pRegInfo) = 0;
182              virtual void DeleteSampleIfNotUsed(S* pSample, region_info_t* pRegInfo) = 0;              virtual void DeleteSampleIfNotUsed(S* pSample, region_info_t* pRegInfo) = 0;
183    
# Line 189  namespace LinuxSampler { Line 191  namespace LinuxSampler {
191                  for (int i = low; i <= high; i++) bindingsArray[i] = 1;                  for (int i = low; i <= high; i++) bindingsArray[i] = 1;
192              }              }
193    
194      };              /**
195                 *  Caches a certain size at the beginning of the given sample in RAM. If the
196      template <class F /* Instrument File */, class I /* Instrument */, class R /* Region */, class S /* Sample */>               *  sample is very short, the whole sample will be loaded into RAM and thus
197      class InstrumentManagerDefaultImpl : public InstrumentManagerBase<F, I, R, S> {               *  no disk streaming is needed for this sample. Caching an initial part of
198          public:               *  samples is needed to compensate disk reading latency.
199              InstrumentManagerDefaultImpl() { }               *
200              virtual ~InstrumentManagerDefaultImpl() { }               *  @param pSample - points to the sample to be cached
201          protected:               *  @param maxSamplesPerCycle - max samples per cycle
202              virtual void CacheInitialSamples(S* pSample, AbstractEngine* pEngine)  {               */
203                void CacheInitialSamples(S* pSample, uint maxSamplesPerCycle)  {
204                  if (!pSample) {                  if (!pSample) {
205                      dmsg(4,("InstrumentManagerBase: Skipping sample (pSample == NULL)\n"));                      dmsg(4,("InstrumentManagerBase: Skipping sample (pSample == NULL)\n"));
206                      return;                      return;
# Line 210  namespace LinuxSampler { Line 213  namespace LinuxSampler {
213                      // number of '0' samples (silence samples) behind the official buffer                      // number of '0' samples (silence samples) behind the official buffer
214                      // 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
215                      // the sample.                      // the sample.
                     const uint maxSamplesPerCycle =  
                         (pEngine) ? pEngine->pAudioOutputDevice->MaxSamplesPerCycle()  
                                   : GIG_RESOURCE_MANAGER_DEFAULT_MAX_SAMPLES_PER_CYCLE;  
216                      const uint neededSilenceSamples = (maxSamplesPerCycle << CONFIG_MAX_PITCH) + 3;                      const uint neededSilenceSamples = (maxSamplesPerCycle << CONFIG_MAX_PITCH) + 3;
217                      const uint currentlyCachedSilenceSamples = pSample->GetCache().NullExtensionSize / pSample->GetFrameSize();                      const uint currentlyCachedSilenceSamples = pSample->GetCache().NullExtensionSize / pSample->GetFrameSize();
218                      if (currentlyCachedSilenceSamples < neededSilenceSamples) {                      if (currentlyCachedSilenceSamples < neededSilenceSamples) {
# Line 228  namespace LinuxSampler { Line 228  namespace LinuxSampler {
228                  if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;                  if (!pSample->GetCache().Size) std::cerr << "Unable to cache sample - maybe memory full!" << std::endl << std::flush;
229              }              }
230    
231              /**              // implementation of derived abstract methods from 'InstrumentManager'
232               * Just a wrapper around the other @c CacheInitialSamples() method.              std::vector<instrument_id_t> Instruments() {
233               *                  return ResourceManager<InstrumentManager::instrument_id_t, I>::Entries();
234               *  @param pSample - points to the sample to be cached              }
235               *  @param pEngine - pointer to Gig Engine Channel which caused this call  
236               *                   (may be NULL, in this case default amount of samples              // implementation of derived abstract methods from 'ResourceManager'
237               *                   will be cached)              void OnBorrow(I* pResource, InstrumentConsumer* pConsumer, void*& pArg) {
238               */                  instr_entry_t* pEntry = static_cast<instr_entry_t*>(pArg);
239              virtual void CacheInitialSamples(S* pSample, EngineChannel* pEngineChannel) {          
240                   AbstractEngine* pEngine =                  uint maxSamplesPerCycle = GetMaxSamplesPerCycle(pConsumer);
241                      (pEngineChannel && pEngineChannel->GetEngine()) ?  
242                          dynamic_cast<AbstractEngine*>(pEngineChannel->GetEngine()) : NULL;                  if (pEntry->MaxSamplesPerCycle < maxSamplesPerCycle) {
243                  CacheInitialSamples(pSample, pEngine);                      dmsg(1,("Completely reloading instrument due to insufficient precached samples ...\n"));
244                        Update(pResource, pConsumer);
245                    }
246              }              }
247      };      };
248    

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

  ViewVC Help
Powered by ViewVC