/[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 2026 by iliev, Fri Oct 23 17:53:17 2009 UTC revision 2027 by iliev, Tue Nov 3 19:27:42 2009 UTC
# Line 86  namespace LinuxSampler { namespace sf2 { Line 86  namespace LinuxSampler { namespace sf2 {
86    
87          pChannel->regionsTemp.clear();          pChannel->regionsTemp.clear();
88    
89          bool preset = (dynamic_cast< ::sf2::Preset*>(pChannel->pInstrument)) != NULL;          for (int i = 0; i < regs.size(); i++) {
90                // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner.  In
91                // other words, PGEN generators increase or decrease the value of an IGEN generator.
92                ::sf2::Instrument* sfInstr = regs[i]->pInstrument;
93    
94          if (preset) {              std::vector< ::sf2::Region*> subRegs = sfInstr->GetRegionsOnKey (
             for (int i = 0; i < regs.size(); i++) {  
                 // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner.  In  
                 // other words, PGEN generators increase or decrease the value of an IGEN generator.  
                 ::sf2::Instrument* sfInstr = regs[i]->pInstrument;  
   
                 std::vector< ::sf2::Region*> subRegs = sfInstr->GetRegionsOnKey (  
                     key, vel  
                 );  
                 for (int j = 0; j < subRegs.size(); j++) {  
                     pChannel->regionsTemp.push_back(subRegs[j]);  
                 }  
             }  
         } else {  
             pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (  
95                  key, vel                  key, vel
96              );              );
97                for (int j = 0; j < subRegs.size(); j++) {
98                    pChannel->regionsTemp.push_back(subRegs[j]);
99                }
100          }          }
101                    
102          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {
# Line 134  namespace LinuxSampler { namespace sf2 { Line 126  namespace LinuxSampler { namespace sf2 {
126      ) {      ) {
127          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
128          int key = itNoteOnEvent->Param.Note.Key;          int key = itNoteOnEvent->Param.Note.Key;
129          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: ^^^  
130    
131          Voice::type_t VoiceType = Voice::type_normal;          Voice::type_t VoiceType = Voice::type_normal;
132    
# Line 169  namespace LinuxSampler { namespace sf2 { Line 134  namespace LinuxSampler { namespace sf2 {
134          ::sf2::Region* pRgn = pChannel->regionsTemp[iLayer];          ::sf2::Region* pRgn = pChannel->regionsTemp[iLayer];
135    
136          // no need to process if sample is silent          // no need to process if sample is silent
137          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) itNewVoice; // TODO:          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
138    
139            // only mark the first voice of a layered voice (group) to be in a
140            // key group, so the layered voices won't kill each other
141            int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRgn->exclusiveClass : 0;
142            if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
143    
144          // allocate a new voice for the key          // allocate a new voice for the key
145          itNewVoice = pKey->pActiveVoices->allocAppend();          itNewVoice = pKey->pActiveVoices->allocAppend();
146          if (itNewVoice) {          int res = InitNewVoice (
147              // launch the new voice                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
148              if (itNewVoice->Trigger(pChannel, itNoteOnEvent, pChannel->Pitch, pRgn, VoiceType, 0 /* iKeyGroup */) < 0) {                  iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
149                  dmsg(4,("Voice not triggered\n"));          );
150                  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"));  
             }  
         }  
151    
152          // return if this is a release triggered voice and there is no          // return if this is a release triggered voice and there is no
153          // releasetrigger dimension (could happen if an instrument          // releasetrigger dimension (could happen if an instrument
154          // change has occured between note on and off)          // change has occured between note on and off)
155          //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();          //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
156    
157                    return Pool<Voice>::Iterator(); // no free voice or error
   
         return itNewVoice;  
158      }      }
159    
160      bool Engine::DiskStreamSupported() {      bool Engine::DiskStreamSupported() {
# Line 229  namespace LinuxSampler { namespace sf2 { Line 166  namespace LinuxSampler { namespace sf2 {
166      }      }
167    
168      String Engine::Version() {      String Engine::Version() {
169          String s = "$Revision: 1.1 $";          String s = "$Revision: 1.2 $";
170          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
171      }      }
172    

Legend:
Removed from v.2026  
changed lines
  Added in v.2027

  ViewVC Help
Powered by ViewVC