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

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

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

revision 2012 by iliev, Fri Oct 23 17:53:17 2009 UTC revision 2101 by persson, Sun May 30 11:40:31 2010 UTC
# Line 46  namespace LinuxSampler { namespace sf2 { Line 46  namespace LinuxSampler { namespace sf2 {
46          // event can trigger a new note on or note off event          // event can trigger a new note on or note off event
47          if (pChannel->pInstrument) {          if (pChannel->pInstrument) {
48    
49              // TODO:              // TODO:
50          }          }
51    
52          // update controller value in the engine channel's controller table          // update controller value in the engine channel's controller table
# Line 80  namespace LinuxSampler { namespace sf2 { Line 80  namespace LinuxSampler { namespace sf2 {
80          uint8_t  chanaft  = pChannel->ControllerTable[128];          uint8_t  chanaft  = pChannel->ControllerTable[128];
81          uint8_t* cc       = pChannel->ControllerTable;          uint8_t* cc       = pChannel->ControllerTable;
82    
83          std::vector< ::sf2::Region*> regs = pChannel->pInstrument->GetRegionsOnKey (          int layer = 0;
84              key, vel          ::sf2::Query query(*pChannel->pInstrument);
85          );          query.key = key;
86            query.vel = vel;
87          pChannel->regionsTemp.clear();          while (::sf2::Region* region = query.next()) {
88                // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner.  In
89          bool preset = (dynamic_cast< ::sf2::Preset*>(pChannel->pInstrument)) != NULL;              // other words, PGEN generators increase or decrease the value of an IGEN generator.
90                ::sf2::Query subQuery(*region->pInstrument);
91          if (preset) {              subQuery.key = key;
92              for (int i = 0; i < regs.size(); i++) {              subQuery.vel = vel;
93                  // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner.  In              while (::sf2::Region* r = subQuery.next()) {
94                  // other words, PGEN generators increase or decrease the value of an IGEN generator.                  //std::cout << r->GetSample()->GetName();
95                  ::sf2::Instrument* sfInstr = regs[i]->pInstrument;                  //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;
96                    if (!RegionSuspended(r)) {
97                  std::vector< ::sf2::Region*> subRegs = sfInstr->GetRegionsOnKey (                      itNoteOnEvent->Param.Note.pRegion = r;
98                      key, vel                      LaunchVoice(pChannel, itNoteOnEvent, layer, false, true, HandleKeyGroupConflicts);
                 );  
                 for (int j = 0; j < subRegs.size(); j++) {  
                     pChannel->regionsTemp.push_back(subRegs[j]);  
99                  }                  }
100              }                  layer++;
         } else {  
             pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (  
                 key, vel  
             );  
         }  
           
         for (int i = 0; i < pChannel->regionsTemp.size(); i++) {  
             ::sf2::Region* r = pChannel->regionsTemp[i];  
             //std::cout << r->GetSample()->GetName();  
             //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;  
             if (!RegionSuspended(pChannel->regionsTemp[i])) {  
                 LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);  
101              }              }
102          }          }
103      }      }
# Line 121  namespace LinuxSampler { namespace sf2 { Line 106  namespace LinuxSampler { namespace sf2 {
106          LinuxSampler::EngineChannel*  pEngineChannel,          LinuxSampler::EngineChannel*  pEngineChannel,
107          RTList<Event>::Iterator&      itNoteOffEvent          RTList<Event>::Iterator&      itNoteOffEvent
108      ) {      ) {
109            
110      }      }
111    
112      Pool<Voice>::Iterator Engine::LaunchVoice (      Pool<Voice>::Iterator Engine::LaunchVoice (
# Line 134  namespace LinuxSampler { namespace sf2 { Line 119  namespace LinuxSampler { namespace sf2 {
119      ) {      ) {
120          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
121          int key = itNoteOnEvent->Param.Note.Key;          int key = itNoteOnEvent->Param.Note.Key;
122          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];          EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key];
         /*::gig::Region* pRegion = pChannel->pInstrument->GetRegion(MIDIKey);  
   
         // if nothing defined for this key  
         if (!pRegion) return Pool<Voice>::Iterator(); // nothing to do  
   
         // only mark the first voice of a layered voice (group) to be in a  
         // key group, so the layered voices won't kill each other  
         int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRegion->KeyGroup : 0;  
   
         // handle key group (a.k.a. exclusive group) conflicts  
         if (HandleKeyGroupConflicts) {  
             if (iKeyGroup) { // if this voice / key belongs to a key group  
                 uint** ppKeyGroup = &pChannel->ActiveKeyGroups[iKeyGroup];  
                 if (*ppKeyGroup) { // if there's already an active key in that key group  
                     EngineChannel::MidiKey* pOtherKey = &pChannel->pMIDIKeyInfo[**ppKeyGroup];  
                     // kill all voices on the (other) key  
                     RTList<Voice>::Iterator itVoiceToBeKilled = pOtherKey->pActiveVoices->first();  
                     RTList<Voice>::Iterator end               = pOtherKey->pActiveVoices->end();  
                     for (; itVoiceToBeKilled != end; ++itVoiceToBeKilled) {  
                         if (itVoiceToBeKilled->Type != Voice::type_release_trigger) {  
                             itVoiceToBeKilled->Kill(itNoteOnEvent);  
                             --VoiceSpawnsLeft; //FIXME: just a hack, we should better check in StealVoice() if the voice was killed due to key conflict  
                         }  
                     }  
                 }  
             }  
         }*/ // TODO: ^^^  
123    
124          Voice::type_t VoiceType = Voice::type_normal;          Voice::type_t VoiceType = Voice::type_normal;
125    
126          Pool<Voice>::Iterator itNewVoice;          Pool<Voice>::Iterator itNewVoice;
127          ::sf2::Region* pRgn = pChannel->regionsTemp[iLayer];          ::sf2::Region* pRgn = static_cast< ::sf2::Region*>(itNoteOnEvent->Param.Note.pRegion);
128    
129          // no need to process if sample is silent          // no need to process if sample is silent
130          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) itNewVoice; // TODO:          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
131    
132            // only mark the first voice of a layered voice (group) to be in a
133            // key group, so the layered voices won't kill each other
134            int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRgn->exclusiveClass : 0;
135            if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
136    
137          // allocate a new voice for the key          // allocate a new voice for the key
138          itNewVoice = pKey->pActiveVoices->allocAppend();          itNewVoice = pKey->pActiveVoices->allocAppend();
139          if (itNewVoice) {          int res = InitNewVoice (
140              // launch the new voice                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
141              if (itNewVoice->Trigger(pChannel, itNoteOnEvent, pChannel->Pitch, pRgn, VoiceType, 0 /* iKeyGroup */) < 0) {                  iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
142                  dmsg(4,("Voice not triggered\n"));          );
143                  pKey->pActiveVoices->free(itNewVoice);          if (!res) return itNewVoice;
             }  
             else { // on success  
                 --VoiceSpawnsLeft;  
                 if (!pKey->Active) { // mark as active key  
                     pKey->Active = true;  
                     pKey->itSelf = pChannel->pActiveKeys->allocAppend();  
                     *pKey->itSelf = itNoteOnEvent->Param.Note.Key;  
                 }  
                 if (itNewVoice->KeyGroup) {  
                     uint** ppKeyGroup = &pChannel->ActiveKeyGroups[itNewVoice->KeyGroup];  
                     *ppKeyGroup = &*pKey->itSelf; // put key as the (new) active key to its key group  
                 }  
                 if (itNewVoice->Type == Voice::type_release_trigger_required) pKey->ReleaseTrigger = true; // mark key for the need of release triggered voice(s)  
                 return itNewVoice; // success  
             }  
         }  
         else if (VoiceStealing) {  
             // try to steal one voice  
             int result = StealVoice(pChannel, itNoteOnEvent);  
             if (!result) { // voice stolen successfully  
                 // put note-on event into voice-stealing queue, so it will be reprocessed after killed voice died  
                 RTList<Event>::Iterator itStealEvent = pVoiceStealingQueue->allocAppend();  
                 if (itStealEvent) {  
                     *itStealEvent = *itNoteOnEvent; // copy event  
                     itStealEvent->Param.Note.Layer = iLayer;  
                     itStealEvent->Param.Note.ReleaseTrigger = ReleaseTriggerVoice;  
                     pKey->VoiceTheftsQueued++;  
                 }  
                 else dmsg(1,("Voice stealing queue full!\n"));  
             }  
         }  
144    
145          // return if this is a release triggered voice and there is no          // return if this is a release triggered voice and there is no
146          // releasetrigger dimension (could happen if an instrument          // releasetrigger dimension (could happen if an instrument
147          // change has occured between note on and off)          // change has occured between note on and off)
148          //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();          //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
149    
150                    return Pool<Voice>::Iterator(); // no free voice or error
   
         return itNewVoice;  
151      }      }
152    
153      bool Engine::DiskStreamSupported() {      bool Engine::DiskStreamSupported() {
# Line 229  namespace LinuxSampler { namespace sf2 { Line 159  namespace LinuxSampler { namespace sf2 {
159      }      }
160    
161      String Engine::Version() {      String Engine::Version() {
162          String s = "$Revision: 1.1 $";          String s = "$Revision: 1.3 $";
163          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
164      }      }
165    

Legend:
Removed from v.2012  
changed lines
  Added in v.2101

  ViewVC Help
Powered by ViewVC