/[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 53 by schoenebeck, Mon Apr 26 17:15:51 2004 UTC revision 233 by schoenebeck, Tue Sep 7 09:32:21 2004 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck         *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
8   *   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 59  namespace LinuxSampler { namespace gig { Line 59  namespace LinuxSampler { namespace gig {
59          pVoicePool->clear();          pVoicePool->clear();
60    
61          pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected          pSynthesisParameters[0] = NULL; // we allocate when an audio device is connected
62            pBasicFilterParameters  = NULL;
63            pMainFilterParameters   = NULL;
64    
65            InstrumentIdx = -1;
66            InstrumentStat = -1;
67    
68            AudioDeviceChannelLeft  = -1;
69            AudioDeviceChannelRight = -1;
70    
71          ResetInternal();          ResetInternal();
72      }      }
# Line 85  namespace LinuxSampler { namespace gig { Line 93  namespace LinuxSampler { namespace gig {
93          if (pVoicePool)  delete pVoicePool;          if (pVoicePool)  delete pVoicePool;
94          if (pActiveKeys) delete pActiveKeys;          if (pActiveKeys) delete pActiveKeys;
95          if (pEventGenerator) delete pEventGenerator;          if (pEventGenerator) delete pEventGenerator;
96            if (pMainFilterParameters) delete[] pMainFilterParameters;
97            if (pBasicFilterParameters) delete[] pBasicFilterParameters;
98          if (pSynthesisParameters[0]) delete[] pSynthesisParameters[0];          if (pSynthesisParameters[0]) delete[] pSynthesisParameters[0];
99      }      }
100    
101      void Engine::Enable() {      void Engine::Enable() {
102          dmsg(3,("gig::Engine: enabling\n"));          dmsg(3,("gig::Engine: enabling\n"));
103          EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)          EngineDisabled.PushAndUnlock(false, 2); // set condition object 'EngineDisabled' to false (wait max. 2s)
104          dmsg(1,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));          dmsg(3,("gig::Engine: enabled (val=%d)\n", EngineDisabled.GetUnsafe()));
105      }      }
106    
107      void Engine::Disable() {      void Engine::Disable() {
# Line 142  namespace LinuxSampler { namespace gig { Line 152  namespace LinuxSampler { namespace gig {
152          SustainPedal        = false;          SustainPedal        = false;
153          ActiveVoiceCount    = 0;          ActiveVoiceCount    = 0;
154          ActiveVoiceCountMax = 0;          ActiveVoiceCountMax = 0;
155            GlobalVolume        = 1.0;
156    
157          // set all MIDI controller values to zero          // set all MIDI controller values to zero
158          memset(ControllerTable, 0x00, 128);          memset(ControllerTable, 0x00, 128);
# Line 191  namespace LinuxSampler { namespace gig { Line 202  namespace LinuxSampler { namespace gig {
202              Instruments.HandBack(pInstrument, this);              Instruments.HandBack(pInstrument, this);
203          }          }
204    
205            InstrumentFile = FileName;
206            InstrumentIdx = Instrument;
207            InstrumentStat = 0;
208    
209          // request gig instrument from instrument manager          // request gig instrument from instrument manager
210          try {          try {
211              instrument_id_t instrid;              instrument_id_t instrid;
# Line 198  namespace LinuxSampler { namespace gig { Line 213  namespace LinuxSampler { namespace gig {
213              instrid.iInstrument = Instrument;              instrid.iInstrument = Instrument;
214              pInstrument = Instruments.Borrow(instrid, this);              pInstrument = Instruments.Borrow(instrid, this);
215              if (!pInstrument) {              if (!pInstrument) {
216                    InstrumentStat = -1;
217                  dmsg(1,("no instrument loaded!!!\n"));                  dmsg(1,("no instrument loaded!!!\n"));
218                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
219              }              }
220          }          }
221          catch (RIFF::Exception e) {          catch (RIFF::Exception e) {
222                InstrumentStat = -2;
223              String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message;              String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message;
224              throw LinuxSamplerException(msg);              throw LinuxSamplerException(msg);
225          }          }
226          catch (InstrumentResourceManagerException e) {          catch (InstrumentResourceManagerException e) {
227                InstrumentStat = -3;
228              String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message();              String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message();
229              throw LinuxSamplerException(msg);              throw LinuxSamplerException(msg);
230          }          }
231          catch (...) {          catch (...) {
232                InstrumentStat = -4;
233              throw LinuxSamplerException("gig::Engine error: Failed to load instrument, cause: Unknown exception while trying to parse gig file.");              throw LinuxSamplerException("gig::Engine error: Failed to load instrument, cause: Unknown exception while trying to parse gig file.");
234          }          }
235    
236            InstrumentStat = 100;
237    
238          // inform audio driver for the need of two channels          // inform audio driver for the need of two channels
239          try {          try {
240              if (pAudioOutputDevice) pAudioOutputDevice->AcquireChannels(2); // gig Engine only stereo              if (pAudioOutputDevice) pAudioOutputDevice->AcquireChannels(2); // gig Engine only stereo
# Line 261  namespace LinuxSampler { namespace gig { Line 282  namespace LinuxSampler { namespace gig {
282              throw LinuxSamplerException(msg);              throw LinuxSamplerException(msg);
283          }          }
284    
285            this->AudioDeviceChannelLeft  = 0;
286            this->AudioDeviceChannelRight = 1;
287            this->pOutputLeft             = pAudioOutputDevice->Channel(0)->Buffer();
288            this->pOutputRight            = pAudioOutputDevice->Channel(1)->Buffer();
289            this->MaxSamplesPerCycle      = pAudioOutputDevice->MaxSamplesPerCycle();
290            this->SampleRate              = pAudioOutputDevice->SampleRate();
291    
292          // (re)create disk thread          // (re)create disk thread
293          if (this->pDiskThread) {          if (this->pDiskThread) {
294              this->pDiskThread->StopThread();              this->pDiskThread->StopThread();
# Line 274  namespace LinuxSampler { namespace gig { Line 302  namespace LinuxSampler { namespace gig {
302    
303          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {          for (Voice* pVoice = pVoicePool->alloc(); pVoice; pVoice = pVoicePool->alloc()) {
304              pVoice->pDiskThread = this->pDiskThread;              pVoice->pDiskThread = this->pDiskThread;
             pVoice->SetOutput(pAudioOut);  
305              dmsg(3,("d"));              dmsg(3,("d"));
306          }          }
307          pVoicePool->clear();          pVoicePool->clear();
# Line 289  namespace LinuxSampler { namespace gig { Line 316  namespace LinuxSampler { namespace gig {
316          for (int dst = 1; dst < Event::destination_count; dst++)          for (int dst = 1; dst < Event::destination_count; dst++)
317              pSynthesisParameters[dst] = pSynthesisParameters[dst - 1] + pAudioOut->MaxSamplesPerCycle();              pSynthesisParameters[dst] = pSynthesisParameters[dst - 1] + pAudioOut->MaxSamplesPerCycle();
318    
319            // (re)allocate biquad filter parameter sequence
320            if (pBasicFilterParameters) delete[] pBasicFilterParameters;
321            if (pMainFilterParameters)  delete[] pMainFilterParameters;
322            pBasicFilterParameters = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
323            pMainFilterParameters  = new biquad_param_t[pAudioOut->MaxSamplesPerCycle()];
324    
325          dmsg(1,("Starting disk thread..."));          dmsg(1,("Starting disk thread..."));
326          pDiskThread->StartThread();          pDiskThread->StartThread();
327          dmsg(1,("OK\n"));          dmsg(1,("OK\n"));
# Line 306  namespace LinuxSampler { namespace gig { Line 339  namespace LinuxSampler { namespace gig {
339              AudioOutputDevice* olddevice = pAudioOutputDevice;              AudioOutputDevice* olddevice = pAudioOutputDevice;
340              pAudioOutputDevice = NULL;              pAudioOutputDevice = NULL;
341              olddevice->Disconnect(this);              olddevice->Disconnect(this);
342                AudioDeviceChannelLeft  = -1;
343                AudioDeviceChannelRight = -1;
344          }          }
345      }      }
346    
# Line 492  namespace LinuxSampler { namespace gig { Line 527  namespace LinuxSampler { namespace gig {
527              pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list              pEvents->move(pNoteOnEvent, pKey->pEvents); // move event to the key's own event list
528          }          }
529    
530          // allocate a new voice for the key          // allocate and trigger a new voice for the key
531          Voice* pNewVoice = pKey->pActiveVoices->alloc();          LaunchVoice(pNoteOnEvent);
         if (pNewVoice) {  
             // launch the new voice  
             if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument) < 0) {  
                 dmsg(1,("Triggering new voice failed!\n"));  
                 pKey->pActiveVoices->free(pNewVoice);  
             }  
             else if (!pKey->Active) { // mark as active key  
                 pKey->Active = true;  
                 pKey->pSelf  = pActiveKeys->alloc();  
                 *pKey->pSelf = pNoteOnEvent->Key;  
             }  
         }  
         else std::cerr << "No free voice!" << std::endl << std::flush;  
532      }      }
533    
534      /**      /**
# Line 541  namespace LinuxSampler { namespace gig { Line 563  namespace LinuxSampler { namespace gig {
563      }      }
564    
565      /**      /**
566         *  Allocates and triggers a new voice. This method will usually be
567         *  called by the ProcessNoteOn() method and by the voices itself
568         *  (e.g. to spawn further voices on the same key for layered sounds).
569         *
570         *  @param pNoteOnEvent - key, velocity and time stamp of the event
571         *  @param iLayer       - layer index for the new voice (optional - only
572         *                        in case of layered sounds of course)
573         */
574        void Engine::LaunchVoice(Event* pNoteOnEvent, int iLayer) {
575            midi_key_info_t* pKey = &pMIDIKeyInfo[pNoteOnEvent->Key];
576    
577            // allocate a new voice for the key
578            Voice* pNewVoice = pKey->pActiveVoices->alloc();
579            if (pNewVoice) {
580                // launch the new voice
581                if (pNewVoice->Trigger(pNoteOnEvent, this->Pitch, this->pInstrument, iLayer) < 0) {
582                    dmsg(1,("Triggering new voice failed!\n"));
583                    pKey->pActiveVoices->free(pNewVoice);
584                }
585                else if (!pKey->Active) { // mark as active key
586                    pKey->Active = true;
587                    pKey->pSelf  = pActiveKeys->alloc();
588                    *pKey->pSelf = pNoteOnEvent->Key;
589                }
590            }
591            else std::cerr << "No free voice!" << std::endl << std::flush;
592        }
593    
594        /**
595       *  Immediately kills the voice given with pVoice (no matter if sustain is       *  Immediately kills the voice given with pVoice (no matter if sustain is
596       *  pressed or not) and removes it from the MIDI key's list of active voice.       *  pressed or not) and removes it from the MIDI key's list of active voice.
597       *  This method will e.g. be called if a voice went inactive by itself.       *  This method will e.g. be called if a voice went inactive by itself.
# Line 635  namespace LinuxSampler { namespace gig { Line 686  namespace LinuxSampler { namespace gig {
686       */       */
687      void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {      void Engine::ResetSynthesisParameters(Event::destination_t dst, float val) {
688          int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();          int maxsamples = pAudioOutputDevice->MaxSamplesPerCycle();
689          for (int i = 0; i < maxsamples; i++) pSynthesisParameters[dst][i] = val;          float* m = &pSynthesisParameters[dst][0];
690            for (int i = 0; i < maxsamples; i += 4) {
691               m[i]   = val;
692               m[i+1] = val;
693               m[i+2] = val;
694               m[i+3] = val;
695            }
696      }      }
697    
698      float Engine::Volume() {      float Engine::Volume() {
# Line 646  namespace LinuxSampler { namespace gig { Line 703  namespace LinuxSampler { namespace gig {
703          GlobalVolume = f;          GlobalVolume = f;
704      }      }
705    
706        uint Engine::Channels() {
707            return 2;
708        }
709    
710        void Engine::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {
711            AudioChannel* pChannel = pAudioOutputDevice->Channel(AudioDeviceChannel);
712            if (!pChannel) throw AudioOutputException("Invalid audio output device channel " + ToString(AudioDeviceChannel));
713            switch (EngineAudioChannel) {
714                case 0: // left output channel
715                    pOutputLeft = pChannel->Buffer();
716                    AudioDeviceChannelLeft = AudioDeviceChannel;
717                    break;
718                case 1: // right output channel
719                    pOutputRight = pChannel->Buffer();
720                    AudioDeviceChannelRight = AudioDeviceChannel;
721                    break;
722                default:
723                    throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel));
724            }
725        }
726    
727        int Engine::OutputChannel(uint EngineAudioChannel) {
728            switch (EngineAudioChannel) {
729                case 0: // left channel
730                    return AudioDeviceChannelLeft;
731                case 1: // right channel
732                    return AudioDeviceChannelRight;
733                default:
734                    throw AudioOutputException("Invalid engine audio channel " + ToString(EngineAudioChannel));
735            }
736        }
737    
738      uint Engine::VoiceCount() {      uint Engine::VoiceCount() {
739          return ActiveVoiceCount;          return ActiveVoiceCount;
740      }      }
# Line 674  namespace LinuxSampler { namespace gig { Line 763  namespace LinuxSampler { namespace gig {
763          return pDiskThread->GetBufferFillPercentage();          return pDiskThread->GetBufferFillPercentage();
764      }      }
765    
766        String Engine::EngineName() {
767            return "GigEngine";
768        }
769    
770        String Engine::InstrumentFileName() {
771            return InstrumentFile;
772        }
773    
774        int Engine::InstrumentIndex() {
775            return InstrumentIdx;
776        }
777    
778        int Engine::InstrumentStatus() {
779            return InstrumentStat;
780        }
781    
782      String Engine::Description() {      String Engine::Description() {
783          return "Gigasampler Engine";          return "Gigasampler Engine";
784      }      }
785    
786      String Engine::Version() {      String Engine::Version() {
787          return "0.0.1-0cvs20040423";          String s = "$Revision: 1.9 $";
788            return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
789      }      }
790    
791  }} // namespace LinuxSampler::gig  }} // namespace LinuxSampler::gig

Legend:
Removed from v.53  
changed lines
  Added in v.233

  ViewVC Help
Powered by ViewVC