/[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 2115 by persson, Thu Aug 12 15:36:15 2010 UTC revision 3082 by schoenebeck, Mon Jan 9 18:39:35 2017 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-2010 Grigor Iliev                                  *   *   Copyright (C) 2009-2012 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 24  Line 24 
24    
25  #include "Engine.h"  #include "Engine.h"
26  #include "EngineChannel.h"  #include "EngineChannel.h"
27    #include "InstrumentScriptVM.h"
28    
29  namespace LinuxSampler { namespace sfz {  namespace LinuxSampler { namespace sfz {
30      Engine::Format Engine::GetEngineFormat() { return SFZ; }      Engine::Format Engine::GetEngineFormat() { return SFZ; }
31    
32        void Engine::CreateInstrumentScriptVM() {
33            dmsg(2,("sfz::Engine created SFZ format scriptvm\n"));
34            if (pScriptVM) return;
35            pScriptVM = new InstrumentScriptVM; // sfz format specific extended script runner
36        }
37        
38        Engine::Engine() {
39            pCCPool = new Pool<CCSignalUnit::CC>(GLOBAL_MAX_VOICES * MaxCCPerVoice);
40            pSmootherPool = new Pool<Smoother>(GLOBAL_MAX_VOICES * MaxCCPerVoice);
41            for (VoiceIterator iterVoice = GetVoicePool()->allocAppend(); iterVoice == GetVoicePool()->last(); iterVoice = GetVoicePool()->allocAppend()) {
42                (static_cast<SfzSignalUnitRack*>(iterVoice->pSignalUnitRack))->InitRTLists();
43            }
44            GetVoicePool()->clear();
45        }
46        
47        Engine::~Engine() {
48            if (pCCPool) {
49                pCCPool->clear();
50                delete pCCPool;
51            }
52            
53            if (pSmootherPool) {
54                pSmootherPool->clear();
55                delete pSmootherPool;
56            }
57        }
58        
59        void Engine::PostSetMaxVoices(int iVoices) {
60            pCCPool->resizePool(iVoices * MaxCCPerVoice);
61            pSmootherPool->resizePool(iVoices * MaxCCPerVoice);
62            
63            for (VoiceIterator iterVoice = GetVoicePool()->allocAppend(); iterVoice == GetVoicePool()->last(); iterVoice = GetVoicePool()->allocAppend()) {
64                (static_cast<SfzSignalUnitRack*>(iterVoice->pSignalUnitRack))->InitRTLists();
65            }
66            GetVoicePool()->clear();
67        }
68    
69      /**      /**
70       *  Reacts on supported control change commands (e.g. pitch bend wheel,       *  Reacts on supported control change commands (e.g. pitch bend wheel,
71       *  modulation wheel, aftertouch).       *  modulation wheel, aftertouch).
# Line 57  namespace LinuxSampler { namespace sfz { Line 95  namespace LinuxSampler { namespace sfz {
95          if (pChannel->pInstrument && cc < 128) {          if (pChannel->pInstrument && cc < 128) {
96    
97              ::sfz::Query q;              ::sfz::Query q;
98              q.chan        = pChannel->MidiChannel();              q.chan        = itControlChangeEvent->Param.CC.Channel + 1;
99              q.key         = 60;              q.key         = 60;
100              q.vel         = 127;              q.vel         = 127;
101              q.bend        = pChannel->Pitch;              q.bend        = pChannel->Pitch;
# Line 75  namespace LinuxSampler { namespace sfz { Line 113  namespace LinuxSampler { namespace sfz {
113    
114              q.search(pChannel->pInstrument, cc);              q.search(pChannel->pInstrument, cc);
115    
116                NoteIterator itNewNote;
117    
118              int i = 0;              int i = 0;
119              while (::sfz::Region* region = q.next()) {              while (::sfz::Region* region = q.next()) {
120                  if (!RegionSuspended(region)) {                  if (!RegionSuspended(region)) {
121                      itControlChangeEvent->Param.Note.Key = 60;                      itControlChangeEvent->Param.Note.Key = 60;
122                      itControlChangeEvent->Param.Note.Velocity = 127;                      itControlChangeEvent->Param.Note.Velocity = 127;
123                      itControlChangeEvent->Param.Note.pRegion = region;                      itControlChangeEvent->Param.Note.pRegion = region;
124                      LaunchVoice(pChannel, itControlChangeEvent, i, false, false, true);                      if (!itNewNote) {
125                            const note_id_t noteID = LaunchNewNote(pEngineChannel, &*itControlChangeEvent);
126                            itNewNote = GetNotePool()->fromID(noteID);
127                            if (!itNewNote) {
128                                dmsg(1,("sfz::Engine: Note pool empty!\n"));
129                                return;
130                            }
131                        }
132                        VoiceIterator itNewVoice =
133                            LaunchVoice(pChannel, itControlChangeEvent, i, false, false, true);
134                        if (itNewVoice)
135                            itNewVoice.moveToEndOf(itNewNote->pActiveVoices);
136                  }                  }
137                  i++;                  i++;
138              }              }
139          }          }
140      }      }
141    
142        void Engine::ProcessChannelPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itChannelPressureEvent) {
143            // forward this to the CC routine, so it updates the current aftertouch value
144            ProcessControlChange(pEngineChannel, itChannelPressureEvent);
145    
146            // if required: engine global aftertouch handling (apart from the per voice handling)
147        }
148    
149        void Engine::ProcessPolyphonicKeyPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNotePressureEvent) {
150            // if required: engine global aftertouch handling (apart from the per voice handling)
151        }
152    
153      DiskThread* Engine::CreateDiskThread() {      DiskThread* Engine::CreateDiskThread() {
154          return new DiskThread (          return new DiskThread (
155              iMaxDiskStreams,              iMaxDiskStreams,
# Line 102  namespace LinuxSampler { namespace sfz { Line 164  namespace LinuxSampler { namespace sfz {
164          bool                         HandleKeyGroupConflicts          bool                         HandleKeyGroupConflicts
165      ) {      ) {
166          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
167            //MidiKey* pKey = &pChannel->pMIDIKeyInfo[itNoteOnEvent->Param.Note.Key];
168          ::sfz::Query q;          ::sfz::Query q;
169          q.chan        = pChannel->MidiChannel();          q.chan        = itNoteOnEvent->Param.Note.Channel + 1;
170          q.key         = itNoteOnEvent->Param.Note.Key;          q.key         = itNoteOnEvent->Param.Note.Key;
171          q.vel         = itNoteOnEvent->Param.Note.Velocity;          q.vel         = itNoteOnEvent->Param.Note.Velocity;
172          q.bend        = pChannel->Pitch;          q.bend        = pChannel->Pitch;
# Line 125  namespace LinuxSampler { namespace sfz { Line 188  namespace LinuxSampler { namespace sfz {
188    
189          q.search(pChannel->pInstrument);          q.search(pChannel->pInstrument);
190    
191            NoteIterator itNote = GetNotePool()->fromID(itNoteOnEvent->Param.Note.ID);
192            if (!itNote) {
193                dmsg(1,("sfz::Engine: No Note object for triggering new voices!\n"));
194                return;
195            }
196    
197          int i = 0;          int i = 0;
198          while (::sfz::Region* region = q.next()) {          while (::sfz::Region* region = q.next()) {
199              if (!RegionSuspended(region)) {              if (!RegionSuspended(region)) {
200                  itNoteOnEvent->Param.Note.pRegion = region;                  itNoteOnEvent->Param.Note.pRegion = region;
201                  LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);                  VoiceIterator itNewVoice =
202                        LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);
203                    if (itNewVoice)
204                        itNewVoice.moveToEndOf(itNote->pActiveVoices);
205              }              }
206              i++;              i++;
207          }          }
# Line 141  namespace LinuxSampler { namespace sfz { Line 213  namespace LinuxSampler { namespace sfz {
213      ) {      ) {
214          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
215          ::sfz::Query q;          ::sfz::Query q;
216          q.chan        = pChannel->MidiChannel();          q.chan        = itNoteOffEvent->Param.Note.Channel + 1;
217          q.key         = itNoteOffEvent->Param.Note.Key;          q.key         = itNoteOffEvent->Param.Note.Key;
218    
219          // MIDI note-on velocity is used instead of note-off velocity          // MIDI note-on velocity is used instead of note-off velocity
# Line 163  namespace LinuxSampler { namespace sfz { Line 235  namespace LinuxSampler { namespace sfz {
235    
236          q.search(pChannel->pInstrument);          q.search(pChannel->pInstrument);
237    
238            NoteIterator itNote = GetNotePool()->fromID(itNoteOffEvent->Param.Note.ID);
239            if (!itNote) {
240                dmsg(1,("sfz::Engine: No Note object for triggering new release voices!\n"));
241                return;
242            }
243    
244          // now launch the required amount of voices          // now launch the required amount of voices
245          int i = 0;          int i = 0;
246          while (::sfz::Region* region = q.next()) {          while (::sfz::Region* region = q.next()) {
247              itNoteOffEvent->Param.Note.pRegion = region;              itNoteOffEvent->Param.Note.pRegion = region;
248              LaunchVoice(pChannel, itNoteOffEvent, i, true, false, true); //FIXME: for the moment we don't perform voice stealing for release triggered samples              VoiceIterator itNewVoice =
249                    LaunchVoice(pChannel, itNoteOffEvent, i, true, false, true); //FIXME: for the moment we don't perform voice stealing for release triggered samples
250                if (itNewVoice)
251                    itNewVoice.moveToEndOf(itNote->pActiveVoices);
252              i++;              i++;
253          }          }
254      }      }
# Line 181  namespace LinuxSampler { namespace sfz { Line 262  namespace LinuxSampler { namespace sfz {
262          bool                          HandleKeyGroupConflicts          bool                          HandleKeyGroupConflicts
263      ) {      ) {
264          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);          EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
265          int key = itNoteOnEvent->Param.Note.Key;          //int key = itNoteOnEvent->Param.Note.Key;
266          EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];          //EngineChannel::MidiKey* pKey  = &pChannel->pMIDIKeyInfo[key];
267          ::sfz::Region* pRgn = static_cast< ::sfz::Region*>(itNoteOnEvent->Param.Note.pRegion);          ::sfz::Region* pRgn = static_cast< ::sfz::Region*>(itNoteOnEvent->Param.Note.pRegion);
268    
269          Voice::type_t VoiceType =          Voice::type_t VoiceType =
# Line 194  namespace LinuxSampler { namespace sfz { Line 275  namespace LinuxSampler { namespace sfz {
275    
276          Pool<Voice>::Iterator itNewVoice;          Pool<Voice>::Iterator itNewVoice;
277    
         // no need to process if sample is silent  
         if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();  
   
278          if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(pRgn->group, itNoteOnEvent);          if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(pRgn->group, itNoteOnEvent);
279    
280            // no need to process if sample is silent
281            if (!pRgn->GetSample(false) || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
282    
283          // allocate a new voice for the key          // allocate a new voice for the key
284          itNewVoice = pKey->pActiveVoices->allocAppend();          itNewVoice = GetVoicePool()->allocAppend();
285          int res = InitNewVoice (          int res = InitNewVoice (
286                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,                  pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
287                  pRgn->off_by, ReleaseTriggerVoice, VoiceStealing, itNewVoice                  pRgn->off_by, ReleaseTriggerVoice, VoiceStealing, itNewVoice
# Line 224  namespace LinuxSampler { namespace sfz { Line 305  namespace LinuxSampler { namespace sfz {
305      }      }
306    
307      String Engine::Version() {      String Engine::Version() {
308          String s = "$Revision: 1.11 $";          String s = "$Revision$";
309          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
310      }      }
311    

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

  ViewVC Help
Powered by ViewVC