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

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

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

revision 1789 by iliev, Sat Nov 1 19:01:27 2008 UTC revision 1933 by persson, Thu Jul 9 17:37:41 2009 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-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2009 Christian Schoenebeck                         *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   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 107  namespace LinuxSampler { namespace gig { Line 107  namespace LinuxSampler { namespace gig {
107          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);
108          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);          pEventQueue        = new RingBuffer<Event,false>(CONFIG_MAX_EVENTS_PER_FRAGMENT, 0);
109          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);          pEventPool         = new Pool<Event>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
110          pVoicePool         = new Pool<Voice>(CONFIG_MAX_VOICES);          pVoicePool         = new Pool<Voice>(GLOBAL_MAX_VOICES);
111          pDimRegionPool[0]  = new Pool< ::gig::DimensionRegion*>(CONFIG_MAX_VOICES);          pDimRegionPool[0]  = new Pool< ::gig::DimensionRegion*>(GLOBAL_MAX_VOICES);
112          pDimRegionPool[1]  = new Pool< ::gig::DimensionRegion*>(CONFIG_MAX_VOICES);          pDimRegionPool[1]  = new Pool< ::gig::DimensionRegion*>(GLOBAL_MAX_VOICES);
113          pVoiceStealingQueue = new RTList<Event>(pEventPool);          pVoiceStealingQueue = new RTList<Event>(pEventPool);
114          pGlobalEvents      = new RTList<Event>(pEventPool);          pGlobalEvents      = new RTList<Event>(pEventPool);
115            iMaxDiskStreams    = GLOBAL_MAX_STREAMS;
116            FrameTime          = 0;
117    
118          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {          for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
119              iterVoice->SetEngine(this);              iterVoice->SetEngine(this);
# Line 152  namespace LinuxSampler { namespace gig { Line 154  namespace LinuxSampler { namespace gig {
154    
155      void Engine::Enable() {      void Engine::Enable() {
156          dmsg(3,("gig::Engine: enabling\n"));          dmsg(3,("gig::Engine: enabling\n"));
157          EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)          EngineDisabled.PushAndUnlock(false, 2, 0, true); // set condition object 'EngineDisabled' to false (wait max. 2s)
158          dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));          dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));
159      }      }
160    
# Line 211  namespace LinuxSampler { namespace gig { Line 213  namespace LinuxSampler { namespace gig {
213                      if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream                      if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream
214                          iPendingStreamDeletions++;                          iPendingStreamDeletions++;
215                      }                      }
216                        // free the voice to the voice pool and update key info
217                        FreeVoice(pEngineChannel, itVoice);
218                  }                  }
219              }              }
220          }          }
# Line 342  namespace LinuxSampler { namespace gig { Line 346  namespace LinuxSampler { namespace gig {
346       * @param pAudioOut - audio output device to connect to       * @param pAudioOut - audio output device to connect to
347       */       */
348      void Engine::Connect(AudioOutputDevice* pAudioOut) {      void Engine::Connect(AudioOutputDevice* pAudioOut) {
349            // caution: don't ignore if connecting to the same device here,
350            // because otherwise SetMaxDiskStreams() implementation won't work anymore!
351    
352          pAudioOutputDevice = pAudioOut;          pAudioOutputDevice = pAudioOut;
353    
354          ResetInternal();          ResetInternal();
# Line 380  namespace LinuxSampler { namespace gig { Line 387  namespace LinuxSampler { namespace gig {
387              delete this->pDiskThread;              delete this->pDiskThread;
388              dmsg(1,("OK\n"));              dmsg(1,("OK\n"));
389          }          }
390          this->pDiskThread = new DiskThread(((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo          this->pDiskThread =
391                                             &instruments);              new DiskThread(
392                    iMaxDiskStreams,
393                    ((pAudioOut->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
394                    &instruments
395                );
396    
397          if (!pDiskThread) {          if (!pDiskThread) {
398              dmsg(0,("gig::Engine  new diskthread = NULL\n"));              dmsg(0,("gig::Engine  new diskthread = NULL\n"));
399              exit(EXIT_FAILURE);              exit(EXIT_FAILURE);
# Line 407  namespace LinuxSampler { namespace gig { Line 419  namespace LinuxSampler { namespace gig {
419                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
420              }              }
421          }          }
422            pVoicePool->clear();
423      }      }
424    
425      /**      /**
# Line 433  namespace LinuxSampler { namespace gig { Line 446  namespace LinuxSampler { namespace gig {
446                          if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream                          if (hStream != Stream::INVALID_HANDLE) { // voice actually used a stream
447                              iPendingStreamDeletions++;                              iPendingStreamDeletions++;
448                          }                          }
449                            //NOTE: maybe we should call FreeVoice() here, shouldn't cause a harm though I think, since the voices should be freed by RenderActiveVoices() in the render loop, they are probably just freed a bit later than they could/should be
450                      }                      }
451                  }                  }
452              }              }
# Line 584  namespace LinuxSampler { namespace gig { Line 598  namespace LinuxSampler { namespace gig {
598          // update time of start and end of this audio fragment (as events' time stamps relate to this)          // update time of start and end of this audio fragment (as events' time stamps relate to this)
599          pEventGenerator->UpdateFragmentTime(Samples);          pEventGenerator->UpdateFragmentTime(Samples);
600    
601          // We only allow a maximum of CONFIG_MAX_VOICES voices to be spawned          // We only allow the given maximum number of voices to be spawned
602          // in each audio fragment. All subsequent request for spawning new          // in each audio fragment. All subsequent request for spawning new
603          // voices in the same audio fragment will be ignored.          // voices in the same audio fragment will be ignored.
604          VoiceSpawnsLeft = CONFIG_MAX_VOICES;          VoiceSpawnsLeft = MaxVoices();
605    
606          // get all events from the engine's global input event queue which belong to the current fragment          // get all events from the engine's global input event queue which belong to the current fragment
607          // (these are usually just SysEx messages)          // (these are usually just SysEx messages)
# Line 1947  namespace LinuxSampler { namespace gig { Line 1961  namespace LinuxSampler { namespace gig {
1961                  if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;                  if (reader.read(&addr[0], 3) != 3) goto free_sysex_data;
1962                  if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters                  if (addr[0] == 0x40 && addr[1] == 0x00) { // System Parameters
1963                      dmsg(3,("\tSystem Parameter\n"));                      dmsg(3,("\tSystem Parameter\n"));
1964                        if (addr[2] == 0x7f) { // GS reset
1965                            for (int i = 0; i < engineChannels.size(); ++i) {
1966                                EngineChannel* pEngineChannel = engineChannels[i];
1967                                if (pEngineChannel->GetMidiInputPort() == itSysexEvent->pMidiInputPort) {
1968                                    KillAllVoices(pEngineChannel, itSysexEvent);
1969                                    pEngineChannel->ResetControllers();
1970                                }
1971                            }
1972                        }
1973                  }                  }
1974                  else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters                  else if (addr[0] == 0x40 && addr[1] == 0x01) { // Common Parameters
1975                      dmsg(3,("\tCommon Parameter\n"));                      dmsg(3,("\tCommon Parameter\n"));
# Line 2111  namespace LinuxSampler { namespace gig { Line 2134  namespace LinuxSampler { namespace gig {
2134          return ActiveVoiceCountMax;          return ActiveVoiceCountMax;
2135      }      }
2136    
2137        int Engine::MaxVoices() {
2138            return pVoicePool->poolSize();
2139        }
2140    
2141        void Engine::SetMaxVoices(int iVoices) throw (Exception) {
2142            if (iVoices < 1)
2143                throw Exception("Maximum voices for an engine cannot be set lower than 1");
2144    
2145            SuspendAll();
2146    
2147            // NOTE: we need to clear pDimRegionsInUse before deleting pDimRegionPool,
2148            // otherwise memory corruption will occur if there are active voices (see bug #118)
2149            for (int iChannel = 0; iChannel < engineChannels.size(); iChannel++) {
2150                engineChannels[iChannel]->ClearDimRegionsInUse();
2151            }
2152    
2153            if (pDimRegionPool[0]) delete pDimRegionPool[0];
2154            if (pDimRegionPool[1]) delete pDimRegionPool[1];
2155    
2156            pDimRegionPool[0] = new Pool< ::gig::DimensionRegion*>(iVoices);
2157            pDimRegionPool[1] = new Pool< ::gig::DimensionRegion*>(iVoices);
2158    
2159            for (int iChannel = 0; iChannel < engineChannels.size(); iChannel++) {
2160                engineChannels[iChannel]->ResetDimRegionsInUse();
2161            }
2162    
2163            try {
2164                pVoicePool->resizePool(iVoices);
2165            } catch (...) {
2166                throw Exception("FATAL: Could not resize voice pool!");
2167            }
2168    
2169            for (RTList<Voice>::Iterator iterVoice = pVoicePool->allocAppend(); iterVoice == pVoicePool->last(); iterVoice = pVoicePool->allocAppend()) {
2170                iterVoice->SetEngine(this);
2171                iterVoice->pDiskThread = this->pDiskThread;
2172            }
2173            pVoicePool->clear();
2174    
2175            ResumeAll();
2176        }
2177    
2178      bool Engine::DiskStreamSupported() {      bool Engine::DiskStreamSupported() {
2179          return true;          return true;
2180      }      }
# Line 2123  namespace LinuxSampler { namespace gig { Line 2187  namespace LinuxSampler { namespace gig {
2187          return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;          return (pDiskThread) ? pDiskThread->ActiveStreamCountMax : 0;
2188      }      }
2189    
2190        int Engine::MaxDiskStreams() {
2191            return iMaxDiskStreams;
2192        }
2193    
2194        void Engine::SetMaxDiskStreams(int iStreams) throw (Exception) {
2195            if (iStreams < 0)
2196                throw Exception("Maximum disk streams for an engine cannot be set lower than 0");
2197    
2198            SuspendAll();
2199    
2200            iMaxDiskStreams = iStreams;
2201    
2202            // reconnect to audio output device, because that will automatically
2203            // recreate the disk thread with the required amount of streams
2204            if (pAudioOutputDevice) Connect(pAudioOutputDevice);
2205    
2206            ResumeAll();
2207        }
2208    
2209      String Engine::DiskStreamBufferFillBytes() {      String Engine::DiskStreamBufferFillBytes() {
2210          return pDiskThread->GetBufferFillBytes();          return pDiskThread->GetBufferFillBytes();
2211      }      }
# Line 2140  namespace LinuxSampler { namespace gig { Line 2223  namespace LinuxSampler { namespace gig {
2223      }      }
2224    
2225      String Engine::Version() {      String Engine::Version() {
2226          String s = "$Revision: 1.98 $";          String s = "$Revision: 1.104 $";
2227          return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword          return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
2228      }      }
2229    

Legend:
Removed from v.1789  
changed lines
  Added in v.1933

  ViewVC Help
Powered by ViewVC