/[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 2061 by persson, Tue Feb 23 18:32:31 2010 UTC revision 2115 by persson, Thu Aug 12 15:36:15 2010 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-2009 Christian Schoenebeck                         *   *   Copyright (C) 2005-2009 Christian Schoenebeck                         *
7   *   Copyright (C) 2009 Grigor Iliev                                       *   *   Copyright (C) 2009-2010 Grigor Iliev                                  *
8   *                                                                         *   *                                                                         *
9   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
10   *   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 39  namespace LinuxSampler { namespace sfz { Line 39  namespace LinuxSampler { namespace sfz {
39          LinuxSampler::EngineChannel*  pEngineChannel,          LinuxSampler::EngineChannel*  pEngineChannel,
40          Pool<Event>::Iterator&        itControlChangeEvent          Pool<Event>::Iterator&        itControlChangeEvent
41      ) {      ) {
42          dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));          uint8_t cc = itControlChangeEvent->Param.CC.Controller;
43            dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", cc, itControlChangeEvent->Param.CC.Value));
44    
45          EngineChannel* pChannel = dynamic_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_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) {  
   
             // TODO:  
         }  
46    
47          // update controller value in the engine channel's controller table          // update controller value in the engine channel's controller table
48          pChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;          pChannel->ControllerTable[cc] = itControlChangeEvent->Param.CC.Value;
49    
50          ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);          ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);
51    
52          // handle FX send controllers          // handle FX send controllers
53          ProcessFxSendControllers(pChannel, itControlChangeEvent);          ProcessFxSendControllers(pChannel, itControlChangeEvent);
54    
55            // handle control triggered regions: a control change event
56            // can trigger a new voice
57            if (pChannel->pInstrument && cc < 128) {
58    
59                ::sfz::Query q;
60                q.chan        = pChannel->MidiChannel();
61                q.key         = 60;
62                q.vel         = 127;
63                q.bend        = pChannel->Pitch;
64                q.bpm         = 0;
65                q.chanaft     = pChannel->ControllerTable[128];
66                q.polyaft     = 0;
67                q.prog        = 0;
68                q.rand        = Random();
69                q.cc          = pChannel->ControllerTable;
70                q.timer       = 0;
71                q.sw          = pChannel->PressedKeys;
72                q.last_sw_key = pChannel->LastKeySwitch;
73                q.prev_sw_key = pChannel->LastKey;
74                q.trig        = TRIGGER_ATTACK | TRIGGER_FIRST;
75    
76                q.search(pChannel->pInstrument, cc);
77    
78                int i = 0;
79                while (::sfz::Region* region = q.next()) {
80                    if (!RegionSuspended(region)) {
81                        itControlChangeEvent->Param.Note.Key = 60;
82                        itControlChangeEvent->Param.Note.Velocity = 127;
83                        itControlChangeEvent->Param.Note.pRegion = region;
84                        LaunchVoice(pChannel, itControlChangeEvent, i, false, false, true);
85                    }
86                    i++;
87                }
88            }
89      }      }
90    
91      DiskThread* Engine::CreateDiskThread() {      DiskThread* Engine::CreateDiskThread() {
# Line 72  namespace LinuxSampler { namespace sfz { Line 102  namespace LinuxSampler { namespace sfz {
102          bool                         HandleKeyGroupConflicts          bool                         HandleKeyGroupConflicts
103      ) {      ) {
104          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
105            ::sfz::Query q;
106          uint8_t  chan     = pChannel->MidiChannel();          q.chan        = pChannel->MidiChannel();
107          int      key      = itNoteOnEvent->Param.Note.Key;          q.key         = itNoteOnEvent->Param.Note.Key;
108          uint8_t  vel      = itNoteOnEvent->Param.Note.Velocity;          q.vel         = itNoteOnEvent->Param.Note.Velocity;
109          int      bend     = pChannel->Pitch;          q.bend        = pChannel->Pitch;
110          uint8_t  chanaft  = pChannel->ControllerTable[128];          q.bpm         = 0;
111          uint8_t* cc       = pChannel->ControllerTable;          q.chanaft     = pChannel->ControllerTable[128];
112          ::sfz::trigger_t trig = TRIGGER_ATTACK |          q.polyaft     = 0;
113                ((pChannel->LastKey != -1 &&          q.prog        = 0;
114                  pChannel->PressedKeys[pChannel->LastKey] &&          q.rand        = Random();
115                  pChannel->LastKey != key) ?          q.cc          = pChannel->ControllerTable;
116                 TRIGGER_LEGATO : TRIGGER_FIRST);          q.timer       = 0;
117            q.sw          = pChannel->PressedKeys;
118          pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (          q.last_sw_key = pChannel->LastKeySwitch;
119              chan, key, vel, bend, 0, chanaft, 0, 0, 0, trig, cc,          q.prev_sw_key = pChannel->LastKey;
120              0.0f, 1, pChannel->PressedKeys, pChannel->LastKeySwitch, pChannel->LastKey          q.trig        = TRIGGER_ATTACK |
121          );              ((pChannel->LastKey != -1 &&
122                  pChannel->PressedKeys[pChannel->LastKey] &&
123          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {                pChannel->LastKey != q.key) ?
124              if (!RegionSuspended(pChannel->regionsTemp[i])) {               TRIGGER_LEGATO : TRIGGER_FIRST);
125    
126            q.search(pChannel->pInstrument);
127    
128            int i = 0;
129            while (::sfz::Region* region = q.next()) {
130                if (!RegionSuspended(region)) {
131                    itNoteOnEvent->Param.Note.pRegion = region;
132                  LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);                  LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);
133              }              }
134                i++;
135          }          }
136      }      }
137    
# Line 102  namespace LinuxSampler { namespace sfz { Line 140  namespace LinuxSampler { namespace sfz {
140          RTList<Event>::Iterator&      itNoteOffEvent          RTList<Event>::Iterator&      itNoteOffEvent
141      ) {      ) {
142          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
143          uint8_t  chan     = pChannel->MidiChannel();          ::sfz::Query q;
144          int      key      = itNoteOffEvent->Param.Note.Key;          q.chan        = pChannel->MidiChannel();
145            q.key         = itNoteOffEvent->Param.Note.Key;
146    
147          // MIDI note-on velocity is used instead of note-off velocity          // MIDI note-on velocity is used instead of note-off velocity
148          uint8_t  vel      = pChannel->pMIDIKeyInfo[key].Velocity;          q.vel         = pChannel->pMIDIKeyInfo[q.key].Velocity;
149          itNoteOffEvent->Param.Note.Velocity = vel;          itNoteOffEvent->Param.Note.Velocity = q.vel;
150    
151          int      bend     = pChannel->Pitch;          q.bend        = pChannel->Pitch;
152          uint8_t  chanaft  = pChannel->ControllerTable[128];          q.bpm         = 0;
153          uint8_t* cc       = pChannel->ControllerTable;          q.chanaft     = pChannel->ControllerTable[128];
154          ::sfz::trigger_t trig = TRIGGER_RELEASE;          q.polyaft     = 0;
155            q.prog        = 0;
156            q.rand        = Random();
157            q.cc          = pChannel->ControllerTable;
158            q.timer       = 0;
159            q.sw          = pChannel->PressedKeys;
160            q.last_sw_key = pChannel->LastKeySwitch;
161            q.prev_sw_key = pChannel->LastKey;
162            q.trig        = TRIGGER_RELEASE;
163    
164          pChannel->regionsTemp = pChannel->pInstrument->GetRegionsOnKey (          q.search(pChannel->pInstrument);
             chan, key, vel, bend, 0, chanaft, 0, 0, 0, trig, cc, 0.0f, 1, NULL, 0, 0  
         );  
165    
166          // now launch the required amount of voices          // now launch the required amount of voices
167          for (int i = 0; i < pChannel->regionsTemp.size(); i++) {          int i = 0;
168              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()) {
169                itNoteOffEvent->Param.Note.pRegion = region;
170                LaunchVoice(pChannel, itNoteOffEvent, i, true, false, true); //FIXME: for the moment we don't perform voice stealing for release triggered samples
171                i++;
172          }          }
173      }      }
174    
# Line 135  namespace LinuxSampler { namespace sfz { Line 183  namespace LinuxSampler { namespace sfz {
183          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
184          int key = itNoteOnEvent->Param.Note.Key;          int key = itNoteOnEvent->Param.Note.Key;
185          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];
186          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);
187    
188            Voice::type_t VoiceType =
189                itNoteOnEvent->Type == Event::type_control_change ? Voice::type_controller_triggered :
190                ReleaseTriggerVoice ? Voice::type_release_trigger :
191                iLayer == 0 ? Voice::type_release_trigger_required :
192                Voice::type_normal;
193            if (pRgn->loop_mode == ::sfz::ONE_SHOT) VoiceType |= Voice::type_one_shot;
194    
195          Pool<Voice>::Iterator itNewVoice;          Pool<Voice>::Iterator itNewVoice;
         ::sfz::Region* pRgn = pChannel->regionsTemp[iLayer];  
196    
197          // no need to process if sample is silent          // no need to process if sample is silent
198          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();          if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
199    
200          // 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);  
201    
202          // allocate a new voice for the key          // allocate a new voice for the key
203          itNewVoice = pKey->pActiveVoices->allocAppend();          itNewVoice = pKey->pActiveVoices->allocAppend();
204          int res = InitNewVoice (          int res = InitNewVoice (
205                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
206                  iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice                  pRgn->off_by, ReleaseTriggerVoice, VoiceStealing, itNewVoice
207          );          );
208          if (!res) return itNewVoice;          if (!res) return itNewVoice;
209    
# Line 173  namespace LinuxSampler { namespace sfz { Line 224  namespace LinuxSampler { namespace sfz {
224      }      }
225    
226      String Engine::Version() {      String Engine::Version() {
227          String s = "$Revision: 1.4 $";          String s = "$Revision: 1.11 $";
228          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
229      }      }
230    

Legend:
Removed from v.2061  
changed lines
  Added in v.2115

  ViewVC Help
Powered by ViewVC