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

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

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

revision 2086 by persson, Sun Apr 25 12:51:30 2010 UTC revision 2244 by iliev, Thu Aug 18 11:32:33 2011 UTC
# Line 27  Line 27 
27    
28  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
29      Engine::Format Engine::GetEngineFormat() { return SFZ; }      Engine::Format Engine::GetEngineFormat() { return SFZ; }
30        
31        Engine::Engine() {
32            pCCPool = new Pool<CCSignalUnit::CC>(GLOBAL_MAX_VOICES * MaxCCPerVoice);
33            pSmootherPool = new Pool<Smoother>(GLOBAL_MAX_VOICES * MaxCCPerVoice);
34            for (VoiceIterator iterVoice = GetVoicePool()->allocAppend(); iterVoice == GetVoicePool()->last(); iterVoice = GetVoicePool()->allocAppend()) {
35                (static_cast<SfzSignalUnitRack*>(iterVoice->pSignalUnitRack))->InitRTLists();
36            }
37            GetVoicePool()->clear();
38        }
39        
40        Engine::~Engine() {
41            if (pCCPool) {
42                pCCPool->clear();
43                delete pCCPool;
44            }
45            
46            if (pSmootherPool) {
47                pSmootherPool->clear();
48                delete pSmootherPool;
49            }
50        }
51        
52        void Engine::PostSetMaxVoices(int iVoices) {
53            pCCPool->resizePool(iVoices * MaxCCPerVoice);
54            pSmootherPool->resizePool(iVoices * MaxCCPerVoice);
55            
56            for (VoiceIterator iterVoice = GetVoicePool()->allocAppend(); iterVoice == GetVoicePool()->last(); iterVoice = GetVoicePool()->allocAppend()) {
57                (static_cast<SfzSignalUnitRack*>(iterVoice->pSignalUnitRack))->InitRTLists();
58            }
59            GetVoicePool()->clear();
60        }
61    
62      /**      /**
63       *  Reacts on supported control change commands (e.g. pitch bend wheel,       *  Reacts on supported control change commands (e.g. pitch bend wheel,
# Line 39  namespace LinuxSampler { namespace sfz { Line 70  namespace LinuxSampler { namespace sfz {
70          LinuxSampler::EngineChannel*  pEngineChannel,          LinuxSampler::EngineChannel*  pEngineChannel,
71          Pool<Event>::Iterator&        itControlChangeEvent          Pool<Event>::Iterator&        itControlChangeEvent
72      ) {      ) {
73          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));          uint8_t cc = itControlChangeEvent->Param.CC.Controller;
74            dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", cc, itControlChangeEvent->Param.CC.Value));
         EngineChannel* pChannel = dynamic_cast<EngineChannel*>(pEngineChannel);  
         // handle the "control triggered" MIDI rule: a control change  
         // event can trigger a new note on or note off event  
         if (pChannel->pInstrument) {  
75    
76              // TODO:          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
         }  
77    
78          // update controller value in the engine channel's controller table          // update controller value in the engine channel's controller table
79          pChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;          pChannel->ControllerTable[cc] = itControlChangeEvent->Param.CC.Value;
80    
81          ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);          ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);
82    
83          // handle FX send controllers          // handle FX send controllers
84          ProcessFxSendControllers(pChannel, itControlChangeEvent);          ProcessFxSendControllers(pChannel, itControlChangeEvent);
85    
86            // handle control triggered regions: a control change event
87            // can trigger a new voice
88            if (pChannel->pInstrument && cc < 128) {
89    
90                ::sfz::Query q;
91                q.chan        = pChannel->MidiChannel();
92                q.key         = 60;
93                q.vel         = 127;
94                q.bend        = pChannel->Pitch;
95                q.bpm         = 0;
96                q.chanaft     = pChannel->ControllerTable[128];
97                q.polyaft     = 0;
98                q.prog        = 0;
99                q.rand        = Random();
100                q.cc          = pChannel->ControllerTable;
101                q.timer       = 0;
102                q.sw          = pChannel->PressedKeys;
103                q.last_sw_key = pChannel->LastKeySwitch;
104                q.prev_sw_key = pChannel->LastKey;
105                q.trig        = TRIGGER_ATTACK | TRIGGER_FIRST;
106    
107                q.search(pChannel->pInstrument, cc);
108    
109                int i = 0;
110                while (::sfz::Region* region = q.next()) {
111                    if (!RegionSuspended(region)) {
112                        itControlChangeEvent->Param.Note.Key = 60;
113                        itControlChangeEvent->Param.Note.Velocity = 127;
114                        itControlChangeEvent->Param.Note.pRegion = region;
115                        LaunchVoice(pChannel, itControlChangeEvent, i, false, false, true);
116                    }
117                    i++;
118                }
119            }
120      }      }
121    
122      DiskThread* Engine::CreateDiskThread() {      DiskThread* Engine::CreateDiskThread() {
# Line 72  namespace LinuxSampler { namespace sfz { Line 133  namespace LinuxSampler { namespace sfz {
133          bool                         HandleKeyGroupConflicts          bool                         HandleKeyGroupConflicts
134      ) {      ) {
135          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
136            ::sfz::Query q;
137          uint8_t  chan     = pChannel->MidiChannel();          q.chan        = pChannel->MidiChannel();
138          int      key      = itNoteOnEvent->Param.Note.Key;          q.key         = itNoteOnEvent->Param.Note.Key;
139          uint8_t  vel      = itNoteOnEvent->Param.Note.Velocity;          q.vel         = itNoteOnEvent->Param.Note.Velocity;
140          int      bend     = pChannel->Pitch;          q.bend        = pChannel->Pitch;
141          uint8_t  chanaft  = pChannel->ControllerTable[128];          q.bpm         = 0;
142          uint8_t* cc       = pChannel->ControllerTable;          q.chanaft     = pChannel->ControllerTable[128];
143          ::sfz::trigger_t trig = TRIGGER_ATTACK |          q.polyaft     = 0;
144                ((pChannel->LastKey != -1 &&          q.prog        = 0;
145                  pChannel->PressedKeys[pChannel->LastKey] &&          q.rand        = Random();
146                  pChannel->LastKey != key) ?          q.cc          = pChannel->ControllerTable;
147                 TRIGGER_LEGATO : TRIGGER_FIRST);          q.timer       = 0;
148            q.sw          = pChannel->PressedKeys;
149          pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (          q.last_sw_key = pChannel->LastKeySwitch;
150              chan, key, vel, bend, 0, chanaft, 0, 0, Random(), trig, cc,          q.prev_sw_key = pChannel->LastKey;
151              0.0f, pChannel->PressedKeys, pChannel->LastKeySwitch, pChannel->LastKey          q.trig        = TRIGGER_ATTACK |
152          );              ((pChannel->LastKey != -1 &&
153                  pChannel->PressedKeys[pChannel->LastKey] &&
154          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {                pChannel->LastKey != q.key) ?
155              if (!RegionSuspended(pChannel->regionsTemp[i])) {               TRIGGER_LEGATO : TRIGGER_FIRST);
156    
157            q.search(pChannel->pInstrument);
158    
159            int i = 0;
160            while (::sfz::Region* region = q.next()) {
161                if (!RegionSuspended(region)) {
162                    itNoteOnEvent->Param.Note.pRegion = region;
163                  LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);                  LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);
164              }              }
165                i++;
166          }          }
167      }      }
168    
# Line 102  namespace LinuxSampler { namespace sfz { Line 171  namespace LinuxSampler { namespace sfz {
171          RTList<Event>::Iterator&      itNoteOffEvent          RTList<Event>::Iterator&      itNoteOffEvent
172      ) {      ) {
173          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
174          uint8_t  chan     = pChannel->MidiChannel();          ::sfz::Query q;
175          int      key      = itNoteOffEvent->Param.Note.Key;          q.chan        = pChannel->MidiChannel();
176            q.key         = itNoteOffEvent->Param.Note.Key;
177    
178          // MIDI note-on velocity is used instead of note-off velocity          // MIDI note-on velocity is used instead of note-off velocity
179          uint8_t  vel      = pChannel->pMIDIKeyInfo[key].Velocity;          q.vel         = pChannel->pMIDIKeyInfo[q.key].Velocity;
180          itNoteOffEvent->Param.Note.Velocity = vel;          itNoteOffEvent->Param.Note.Velocity = q.vel;
181    
182          int      bend     = pChannel->Pitch;          q.bend        = pChannel->Pitch;
183          uint8_t  chanaft  = pChannel->ControllerTable[128];          q.bpm         = 0;
184          uint8_t* cc       = pChannel->ControllerTable;          q.chanaft     = pChannel->ControllerTable[128];
185          ::sfz::trigger_t trig = TRIGGER_RELEASE;          q.polyaft     = 0;
186            q.prog        = 0;
187          pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (          q.rand        = Random();
188              chan, key, vel, bend, 0, chanaft, 0, 0, Random(), trig, cc,          q.cc          = pChannel->ControllerTable;
189              0.0f, pChannel->PressedKeys, pChannel->LastKeySwitch, pChannel->LastKey          q.timer       = 0;
190          );          q.sw          = pChannel->PressedKeys;
191            q.last_sw_key = pChannel->LastKeySwitch;
192            q.prev_sw_key = pChannel->LastKey;
193            q.trig        = TRIGGER_RELEASE;
194    
195            q.search(pChannel->pInstrument);
196    
197          // now launch the required amount of voices          // now launch the required amount of voices
198          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {          int i = 0;
199              LaunchVoice(pChannel, itNoteOffEvent, i, true, false, false); //FIXME: for the moment we don't perform voice stealing for release triggered samples          while (::sfz::Region* region = q.next()) {
200                itNoteOffEvent->Param.Note.pRegion = region;
201                LaunchVoice(pChannel, itNoteOffEvent, i, true, false, true); //FIXME: for the moment we don't perform voice stealing for release triggered samples
202                i++;
203          }          }
204      }      }
205    
# Line 136  namespace LinuxSampler { namespace sfz { Line 214  namespace LinuxSampler { namespace sfz {
214          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
215          int key = itNoteOnEvent->Param.Note.Key;          int key = itNoteOnEvent->Param.Note.Key;
216          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];
217          Voice::type_t VoiceType = (ReleaseTriggerVoice) ? Voice::type_release_trigger : (!iLayer) ? Voice::type_release_trigger_required : Voice::type_normal;          ::sfz::Region* pRgn = static_cast< ::sfz::Region*>(itNoteOnEvent->Param.Note.pRegion);
218    
219            Voice::type_t VoiceType =
220                itNoteOnEvent->Type == Event::type_control_change ? Voice::type_controller_triggered :
221                ReleaseTriggerVoice ? Voice::type_release_trigger :
222                iLayer == 0 ? Voice::type_release_trigger_required :
223                Voice::type_normal;
224            if (pRgn->loop_mode == ::sfz::ONE_SHOT) VoiceType |= Voice::type_one_shot;
225    
226          Pool<Voice>::Iterator itNewVoice;          Pool<Voice>::Iterator itNewVoice;
         ::sfz::Region* pRgn = pChannel->regionsTemp[iLayer];  
227    
228          // no need to process if sample is silent          // no need to process if sample is silent
229          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
230    
231          // only mark the first voice of a layered voice (group) to be in a          if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(pRgn->group, itNoteOnEvent);
         // key group, so the layered voices won't kill each other  
         int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRgn->group : 0;  
         if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent, pRgn->off_mode == ::sfz::OFF_NORMAL);  
232    
233          // allocate a new voice for the key          // allocate a new voice for the key
234          itNewVoice = pKey->pActiveVoices->allocAppend();          itNewVoice = pKey->pActiveVoices->allocAppend();
235          int res = InitNewVoice (          int res = InitNewVoice (
236                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
237                  iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice                  pRgn->off_by, ReleaseTriggerVoice, VoiceStealing, itNewVoice
238          );          );
239          if (!res) return itNewVoice;          if (!res) return itNewVoice;
240    
# Line 174  namespace LinuxSampler { namespace sfz { Line 255  namespace LinuxSampler { namespace sfz {
255      }      }
256    
257      String Engine::Version() {      String Engine::Version() {
258          String s = "$Revision: 1.7 $";          String s = "$Revision: 1.11 $";
259          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
260      }      }
261    

Legend:
Removed from v.2086  
changed lines
  Added in v.2244

  ViewVC Help
Powered by ViewVC