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

Diff of /linuxsampler/trunk/src/engines/AbstractEngine.cpp

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

revision 2121 by schoenebeck, Tue Sep 14 17:09:08 2010 UTC revision 2606 by persson, Sun Jun 8 05:42:56 2014 UTC
# Line 4  Line 4 
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-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev        *
8     *   Copyright (C) 2013-2014 Christian Schoenebeck and Andreas Persson     *
9   *                                                                         *   *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   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 26  Line 27 
27  #include "AbstractEngineChannel.h"  #include "AbstractEngineChannel.h"
28  #include "EngineFactory.h"  #include "EngineFactory.h"
29  #include "../common/global_private.h"  #include "../common/global_private.h"
30    #include "../effects/EffectFactory.h"
31    
32  namespace LinuxSampler {  namespace LinuxSampler {
33    
# Line 33  namespace LinuxSampler { Line 35  namespace LinuxSampler {
35    
36      std::map<AbstractEngine::Format, std::map<AudioOutputDevice*,AbstractEngine*> > AbstractEngine::engines;      std::map<AbstractEngine::Format, std::map<AudioOutputDevice*,AbstractEngine*> > AbstractEngine::engines;
37    
38        VMParserContext* AbstractEngine::ScriptResourceManager::Create(String Key, ScriptConsumer* pConsumer, void*& pArg) {
39            return parent->pScriptVM->loadScript(Key);
40        }
41    
42        void AbstractEngine::ScriptResourceManager::Destroy(VMParserContext* pResource, void* pArg) {
43            delete pResource;
44        }
45    
46      /**      /**
47       * Get an AbstractEngine object for the given AbstractEngineChannel and the       * Get an AbstractEngine object for the given AbstractEngineChannel and the
48       * given AudioOutputDevice. All engine channels which are connected to       * given AudioOutputDevice. All engine channels which are connected to
# Line 70  namespace LinuxSampler { Line 80  namespace LinuxSampler {
80          return pEngine;          return pEngine;
81      }      }
82    
83      AbstractEngine::AbstractEngine() {      AbstractEngine::AbstractEngine() : scripts(this) {
84          pAudioOutputDevice = NULL;          pAudioOutputDevice = NULL;
85          pEventGenerator    = NULL;          pEventGenerator    = NULL;
86          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);          pSysexBuffer       = new RingBuffer<uint8_t,false>(CONFIG_SYSEX_BUFFER_SIZE, 0);
# Line 80  namespace LinuxSampler { Line 90  namespace LinuxSampler {
90          FrameTime          = 0;          FrameTime          = 0;
91          RandomSeed         = 0;          RandomSeed         = 0;
92          pDedicatedVoiceChannelLeft = pDedicatedVoiceChannelRight = NULL;          pDedicatedVoiceChannelLeft = pDedicatedVoiceChannelRight = NULL;
93            pScriptVM          = CreateInstrumentScriptVM();
94      }      }
95    
96      AbstractEngine::~AbstractEngine() {      AbstractEngine::~AbstractEngine() {
# Line 90  namespace LinuxSampler { Line 101  namespace LinuxSampler {
101          if (pSysexBuffer) delete pSysexBuffer;          if (pSysexBuffer) delete pSysexBuffer;
102          if (pDedicatedVoiceChannelLeft) delete pDedicatedVoiceChannelLeft;          if (pDedicatedVoiceChannelLeft) delete pDedicatedVoiceChannelLeft;
103          if (pDedicatedVoiceChannelRight) delete pDedicatedVoiceChannelRight;          if (pDedicatedVoiceChannelRight) delete pDedicatedVoiceChannelRight;
104            if (pScriptVM) delete pScriptVM;
105          Unregister();          Unregister();
106      }      }
107    
108      /**      /**
109         * Allocates a sampler format independent real-time instrument script
110         * runner. This method is overriden by sampler engines in case they have
111         * their own implementation of the script VM, with script feature extensions
112         * required for their sampler format.
113         */
114        InstrumentScriptVM* AbstractEngine::CreateInstrumentScriptVM() {
115            return new InstrumentScriptVM; // format independent script runner
116        }
117    
118        /**
119       * Once an engine channel is disconnected from an audio output device,       * Once an engine channel is disconnected from an audio output device,
120       * it will immediately call this method to unregister itself from the       * it will immediately call this method to unregister itself from the
121       * engine instance and if that engine instance is not used by any other       * engine instance and if that engine instance is not used by any other
# Line 164  namespace LinuxSampler { Line 186  namespace LinuxSampler {
186       */       */
187      void AbstractEngine::ResetScaleTuning() {      void AbstractEngine::ResetScaleTuning() {
188          memset(&ScaleTuning[0], 0x00, 12);          memset(&ScaleTuning[0], 0x00, 12);
189            ScaleTuningChanged.raise();
190      }      }
191    
192      /**      /**
# Line 305  namespace LinuxSampler { Line 328  namespace LinuxSampler {
328                  return false; // error                  return false; // error
329              }              }
330              AudioChannel* pDstChan = NULL;              AudioChannel* pDstChan = NULL;
331              if (pFxSend->DestinationMasterEffectChain() >= 0) { // fx send routed to an internal master effect              if (pFxSend->DestinationEffectChain() >= 0) { // fx send routed to an internal send effect
332                  EffectChain* pEffectChain =                  EffectChain* pEffectChain =
333                      pAudioOutputDevice->MasterEffectChain(                      pAudioOutputDevice->SendEffectChainByID(
334                          pFxSend->DestinationMasterEffectChain()                          pFxSend->DestinationEffectChain()
335                      );                      );
336                  if (!pEffectChain) {                  if (!pEffectChain) {
337                      dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffectChain()));                      dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationEffectChain()));
338                      return false; // error                      return false; // error
339                  }                  }
340                  Effect* pEffect =                  Effect* pEffect =
341                      pEffectChain->GetEffect(                      pEffectChain->GetEffect(
342                          pFxSend->DestinationMasterEffect()                          pFxSend->DestinationEffectChainPosition()
343                      );                      );
344                  if (!pEffect) {                  if (!pEffect) {
345                      dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect %d of effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationMasterEffect(), pFxSend->DestinationMasterEffectChain()));                      dmsg(1,("Engine::RouteAudio() Error: invalid FX send (%s) destination effect %d of effect chain %d", ((iChan) ? "R" : "L"), pFxSend->DestinationEffectChainPosition(), pFxSend->DestinationEffectChain()));
346                      return false; // error                      return false; // error
347                  }                  }
348                  pDstChan = pEffect->InputChannel(iDstChan);                  pDstChan = pEffect->InputChannel(iDstChan);
# Line 345  namespace LinuxSampler { Line 368  namespace LinuxSampler {
368       */       */
369      uint8_t AbstractEngine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {      uint8_t AbstractEngine::GSCheckSum(const RingBuffer<uint8_t,false>::NonVolatileReader AddrReader, uint DataSize) {
370          RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;          RingBuffer<uint8_t,false>::NonVolatileReader reader = AddrReader;
371          uint bytes = 3 /*addr*/ + DataSize;          uint bytes = 3 /*addr*/ + DataSize;        
         uint8_t addr_and_data[bytes];  
         reader.read(&addr_and_data[0], bytes);  
372          uint8_t sum = 0;          uint8_t sum = 0;
373          for (uint i = 0; i < bytes; i++) sum += addr_and_data[i];          uint8_t c;
374            for (uint i = 0; i < bytes; ++i) {
375                if (!reader.pop(&c)) break;
376                sum += c;
377            }
378          return 128 - sum % 128;          return 128 - sum % 128;
379      }      }
380    
# Line 358  namespace LinuxSampler { Line 383  namespace LinuxSampler {
383       *       *
384       * @param ScaleTunes - detuning of all twelve semitones (in cents)       * @param ScaleTunes - detuning of all twelve semitones (in cents)
385       */       */
386      void AbstractEngine::AdjustScale(int8_t ScaleTunes[12]) {      void AbstractEngine::AdjustScaleTuning(const int8_t ScaleTunes[12]) {
387          memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12); //TODO: currently not sample accurate          memcpy(&this->ScaleTuning[0], &ScaleTunes[0], 12);
388            ScaleTuningChanged.raise();
389        }
390        
391        void AbstractEngine::GetScaleTuning(int8_t* pScaleTunes) {
392            memcpy(pScaleTunes, &this->ScaleTuning[0], 12);
393      }      }
394    
395      uint AbstractEngine::VoiceCount() {      uint AbstractEngine::VoiceCount() {
# Line 375  namespace LinuxSampler { Line 405  namespace LinuxSampler {
405      }      }
406    
407      /**      /**
408       *  Moves pitchbend event from the general (input) event list to the engine       *  Stores the latest pitchbend event as current pitchbend scalar value.
      *  channel's event list. It will actually processed later by the  
      *  respective voice.  
409       *       *
410       *  @param pEngineChannel - engine channel on which this event occured on       *  @param pEngineChannel - engine channel on which this event occured on
411       *  @param itPitchbendEvent - absolute pitch value and time stamp of the event       *  @param itPitchbendEvent - absolute pitch value and time stamp of the event
# Line 414  namespace LinuxSampler { Line 442  namespace LinuxSampler {
442          Event event             = pEventGenerator->CreateEvent();          Event event             = pEventGenerator->CreateEvent();
443          event.Type              = Event::type_sysex;          event.Type              = Event::type_sysex;
444          event.Param.Sysex.Size  = Size;          event.Param.Sysex.Size  = Size;
445            memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
446          event.pEngineChannel    = NULL; // as Engine global event          event.pEngineChannel    = NULL; // as Engine global event
447          event.pMidiInputPort    = pSender;          event.pMidiInputPort    = pSender;
448          if (pEventQueue->write_space() > 0) {          if (pEventQueue->write_space() > 0) {
# Line 506  namespace LinuxSampler { Line 535  namespace LinuxSampler {
535                          for (int i = 0; i < engineChannels.size(); ++i) {                          for (int i = 0; i < engineChannels.size(); ++i) {
536                              AbstractEngineChannel* pEngineChannel                              AbstractEngineChannel* pEngineChannel
537                                  = static_cast<AbstractEngineChannel*>(engineChannels[i]);                                  = static_cast<AbstractEngineChannel*>(engineChannels[i]);
538                              if (pEngineChannel->GetMidiInputPort() == itSysexEvent->pMidiInputPort) {                              Sync< ArrayList<MidiInputPort*> > midiInputs = pEngineChannel->midiInputs.front();
539                                  KillAllVoices(pEngineChannel, itSysexEvent);                              for (int k = 0; k < midiInputs->size(); ++k) {
540                                  pEngineChannel->ResetControllers();                                  if ((*midiInputs)[k] == itSysexEvent->pMidiInputPort) {
541                                        KillAllVoices(pEngineChannel, itSysexEvent);
542                                        pEngineChannel->ResetControllers();
543                                        break;
544                                    }
545                              }                              }
546                          }                          }
547                      }                      }
# Line 529  namespace LinuxSampler { Line 562  namespace LinuxSampler {
562                              if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;                              if (GSCheckSum(checksum_reader, 12)) goto free_sysex_data;
563                              #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM                              #endif // CONFIG_ASSERT_GS_SYSEX_CHECKSUM
564                              for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;                              for (int i = 0; i < 12; i++) scale_tunes[i] -= 64;
565                              AdjustScale((int8_t*) scale_tunes);                              AdjustScaleTuning((int8_t*) scale_tunes);
566                              dmsg(3,("\t\t\tNew scale applied.\n"));                              dmsg(3,("\t\t\tNew scale applied.\n"));
567                              break;                              break;
568                          }                          }
# Line 541  namespace LinuxSampler { Line 574  namespace LinuxSampler {
574                              for (int i = 0; i < engineChannels.size(); ++i) {                              for (int i = 0; i < engineChannels.size(); ++i) {
575                                  AbstractEngineChannel* pEngineChannel                                  AbstractEngineChannel* pEngineChannel
576                                      = static_cast<AbstractEngineChannel*>(engineChannels[i]);                                      = static_cast<AbstractEngineChannel*>(engineChannels[i]);
577                                  if (                                  if (pEngineChannel->midiChannel == part ||
578                                      (pEngineChannel->midiChannel == part ||                                      pEngineChannel->midiChannel == midi_chan_all)
579                                       pEngineChannel->midiChannel == midi_chan_all) &&                                  {  
580                                       pEngineChannel->GetMidiInputPort() == itSysexEvent->pMidiInputPort                                      Sync< ArrayList<MidiInputPort*> > midiInputs = pEngineChannel->midiInputs.front();
581                                  ) {                                      for (int k = 0; k < midiInputs->size(); ++k) {
582                                      try {                                          if ((*midiInputs)[k] == itSysexEvent->pMidiInputPort) {
583                                          pEngineChannel->SetMidiInstrumentMap(map);                                              try {
584                                      } catch (Exception e) {                                                  pEngineChannel->SetMidiInstrumentMap(map);
585                                          dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d: %s\n", map, part, e.Message().c_str()));                                              } catch (Exception e) {
586                                          goto free_sysex_data;                                                  dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d: %s\n", map, part, e.Message().c_str()));
587                                      } catch (...) {                                                  goto free_sysex_data;
588                                          dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d (unknown exception)\n", map, part));                                              } catch (...) {
589                                          goto free_sysex_data;                                                  dmsg(2,("\t\t\tCould not apply MIDI instrument map %d to part %d (unknown exception)\n", map, part));
590                                                    goto free_sysex_data;
591                                                }
592                                                break;
593                                            }
594                                      }                                      }
595                                  }                                  }
596                              }                              }

Legend:
Removed from v.2121  
changed lines
  Added in v.2606

  ViewVC Help
Powered by ViewVC