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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3219 - (show annotations) (download)
Thu May 25 21:49:40 2017 UTC (6 years, 10 months ago) by schoenebeck
File size: 8724 byte(s)
* NKSP Fix: built-in script function "change_note()" did not
  (re)select the correct expected region.
* NKSP Fix: built-in script function "change_velo()" did not
  (re)select the correct subregion/dimension region
  (whatever term you are using for the sampler format of
   your choice).
* Bumped version (2.0.0.svn51).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005-2009 Christian Schoenebeck *
7 * Copyright (C) 2009-2010 Grigor Iliev *
8 * *
9 * 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 *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #include "Engine.h"
26 #include "EngineChannel.h"
27
28 namespace LinuxSampler { namespace sf2 {
29 Engine::Format Engine::GetEngineFormat() { return SF2; }
30
31 /**
32 * Reacts on supported control change commands (e.g. pitch bend wheel,
33 * modulation wheel, aftertouch).
34 *
35 * @param pEngineChannel - engine channel on which this event occured on
36 * @param itControlChangeEvent - controller, value and time stamp of the event
37 */
38 void Engine::ProcessControlChange (
39 LinuxSampler::EngineChannel* pEngineChannel,
40 Pool<Event>::Iterator& itControlChangeEvent
41 ) {
42 dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
43
44 EngineChannel* pChannel = dynamic_cast<EngineChannel*>(pEngineChannel);
45 // handle the "control triggered" MIDI rule: a control change
46 // event can trigger a new note on or note off event
47 if (pChannel->pInstrument) {
48
49 // TODO:
50 }
51
52 // update controller value in the engine channel's controller table
53 pChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
54
55 ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);
56
57 // handle FX send controllers
58 ProcessFxSendControllers(pChannel, itControlChangeEvent);
59 }
60
61 void Engine::ProcessChannelPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itChannelPressureEvent) {
62 // forward this to the CC routine, so it updates the current aftertouch value
63 ProcessControlChange(pEngineChannel, itChannelPressureEvent);
64
65 // if required: engine global aftertouch handling (apart from the per voice handling)
66 }
67
68 void Engine::ProcessPolyphonicKeyPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNotePressureEvent) {
69 // if required: engine global aftertouch handling (apart from the per voice handling)
70 }
71
72 DiskThread* Engine::CreateDiskThread() {
73 return new DiskThread (
74 iMaxDiskStreams,
75 ((pAudioOutputDevice->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
76 &instruments
77 );
78 }
79
80 void Engine::TriggerNewVoices (
81 LinuxSampler::EngineChannel* pEngineChannel,
82 RTList<Event>::Iterator& itNoteOnEvent,
83 bool HandleKeyGroupConflicts
84 ) {
85 NoteIterator itNote = GetNotePool()->fromID(itNoteOnEvent->Param.Note.ID);
86 if (!itNote) {
87 dmsg(1,("sf2::Engine: No Note object for triggering new voices!\n"));
88 return;
89 }
90 EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
91
92 //uint8_t chan = pChannel->MidiChannel();
93 int key = itNote->cause.Param.Note.Key; //itNoteOnEvent->Param.Note.Key; <- using note object instead, since note nr might been modified by script
94 uint8_t vel = itNote->cause.Param.Note.Velocity; //itNoteOnEvent->Param.Note.Velocity; <- using note object instead, since velocity might been modified by script
95 //int bend = pChannel->Pitch;
96 //uint8_t chanaft = pChannel->ControllerTable[128];
97 //uint8_t* cc = pChannel->ControllerTable;
98
99 int layer = 0;
100 ::sf2::Query query(*pChannel->pInstrument);
101 query.key = key;
102 query.vel = vel;
103 while (::sf2::Region* region = query.next()) {
104 // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner. In
105 // other words, PGEN generators increase or decrease the value of an IGEN generator.
106 ::sf2::Query subQuery(*region->pInstrument);
107 subQuery.key = key;
108 subQuery.vel = vel;
109 while (::sf2::Region* r = subQuery.next()) {
110 //std::cout << r->GetSample()->GetName();
111 //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;
112 if (!RegionSuspended(r)) {
113 itNoteOnEvent->Param.Note.pRegion = r;
114 VoiceIterator itNewVoice =
115 LaunchVoice(pChannel, itNoteOnEvent, layer, false, true, HandleKeyGroupConflicts);
116 if (itNewVoice)
117 itNewVoice.moveToEndOf(itNote->pActiveVoices);
118 }
119 layer++;
120 }
121 }
122 }
123
124 void Engine::TriggerReleaseVoices (
125 LinuxSampler::EngineChannel* pEngineChannel,
126 RTList<Event>::Iterator& itNoteOffEvent
127 ) {
128
129 }
130
131 Pool<Voice>::Iterator Engine::LaunchVoice (
132 LinuxSampler::EngineChannel* pEngineChannel,
133 Pool<Event>::Iterator& itNoteOnEvent,
134 int iLayer,
135 bool ReleaseTriggerVoice,
136 bool VoiceStealing,
137 bool HandleKeyGroupConflicts
138 ) {
139 EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
140 //int key = itNoteOnEvent->Param.Note.Key;
141 //EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key];
142
143 Voice::type_t VoiceType = Voice::type_normal;
144
145 Pool<Voice>::Iterator itNewVoice;
146 ::sf2::Region* pRgn = static_cast< ::sf2::Region*>(itNoteOnEvent->Param.Note.pRegion);
147
148 // no need to process if sample is silent
149 if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
150
151 int iKeyGroup = pRgn->exclusiveClass;
152 if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
153
154 // allocate a new voice for the key
155 itNewVoice = GetVoicePool()->allocAppend();
156 int res = InitNewVoice (
157 pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
158 iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
159 );
160 if (!res) return itNewVoice;
161
162 // return if this is a release triggered voice and there is no
163 // releasetrigger dimension (could happen if an instrument
164 // change has occured between note on and off)
165 //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
166
167 return Pool<Voice>::Iterator(); // no free voice or error
168 }
169
170 bool Engine::DiskStreamSupported() {
171 return true;
172 }
173
174 String Engine::Description() {
175 return "SoundFont Format Engine";
176 }
177
178 String Engine::Version() {
179 String s = "$Revision$";
180 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
181 }
182
183 }} // namespace LinuxSampler::sf2

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC