/[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 2559 - (show annotations) (download)
Sun May 18 17:38:25 2014 UTC (9 years, 11 months ago) by schoenebeck
File size: 7966 byte(s)
* Aftertouch: extended API to explicitly handle channel pressure and
  polyphonic key pressure events (so far polyphonic pressure was not
  supported at all, and channel pressure was rerouted as CC128 but not
  used so far).
* Gig Engine: Fixed support for 'aftertouch' attenuation controller.
* Bumped version (1.0.0.svn39).

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 // if required: engine global aftertouch handling (apart from the per voice handling)
63 }
64
65 void Engine::ProcessPolyphonicKeyPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNotePressureEvent) {
66 // if required: engine global aftertouch handling (apart from the per voice handling)
67 }
68
69 DiskThread* Engine::CreateDiskThread() {
70 return new DiskThread (
71 iMaxDiskStreams,
72 ((pAudioOutputDevice->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
73 &instruments
74 );
75 }
76
77 void Engine::TriggerNewVoices (
78 LinuxSampler::EngineChannel* pEngineChannel,
79 RTList<Event>::Iterator& itNoteOnEvent,
80 bool HandleKeyGroupConflicts
81 ) {
82 EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
83
84 uint8_t chan = pChannel->MidiChannel();
85 int key = itNoteOnEvent->Param.Note.Key;
86 uint8_t vel = itNoteOnEvent->Param.Note.Velocity;
87 int bend = pChannel->Pitch;
88 uint8_t chanaft = pChannel->ControllerTable[128];
89 uint8_t* cc = pChannel->ControllerTable;
90
91 int layer = 0;
92 ::sf2::Query query(*pChannel->pInstrument);
93 query.key = key;
94 query.vel = vel;
95 while (::sf2::Region* region = query.next()) {
96 // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner. In
97 // other words, PGEN generators increase or decrease the value of an IGEN generator.
98 ::sf2::Query subQuery(*region->pInstrument);
99 subQuery.key = key;
100 subQuery.vel = vel;
101 while (::sf2::Region* r = subQuery.next()) {
102 //std::cout << r->GetSample()->GetName();
103 //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;
104 if (!RegionSuspended(r)) {
105 itNoteOnEvent->Param.Note.pRegion = r;
106 LaunchVoice(pChannel, itNoteOnEvent, layer, false, true, HandleKeyGroupConflicts);
107 }
108 layer++;
109 }
110 }
111 }
112
113 void Engine::TriggerReleaseVoices (
114 LinuxSampler::EngineChannel* pEngineChannel,
115 RTList<Event>::Iterator& itNoteOffEvent
116 ) {
117
118 }
119
120 Pool<Voice>::Iterator Engine::LaunchVoice (
121 LinuxSampler::EngineChannel* pEngineChannel,
122 Pool<Event>::Iterator& itNoteOnEvent,
123 int iLayer,
124 bool ReleaseTriggerVoice,
125 bool VoiceStealing,
126 bool HandleKeyGroupConflicts
127 ) {
128 EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
129 int key = itNoteOnEvent->Param.Note.Key;
130 EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key];
131
132 Voice::type_t VoiceType = Voice::type_normal;
133
134 Pool<Voice>::Iterator itNewVoice;
135 ::sf2::Region* pRgn = static_cast< ::sf2::Region*>(itNoteOnEvent->Param.Note.pRegion);
136
137 // no need to process if sample is silent
138 if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
139
140 int iKeyGroup = pRgn->exclusiveClass;
141 if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
142
143 // allocate a new voice for the key
144 itNewVoice = pKey->pActiveVoices->allocAppend();
145 int res = InitNewVoice (
146 pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
147 iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
148 );
149 if (!res) return itNewVoice;
150
151 // return if this is a release triggered voice and there is no
152 // releasetrigger dimension (could happen if an instrument
153 // change has occured between note on and off)
154 //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
155
156 return Pool<Voice>::Iterator(); // no free voice or error
157 }
158
159 bool Engine::DiskStreamSupported() {
160 return true;
161 }
162
163 String Engine::Description() {
164 return "SoundFont Format Engine";
165 }
166
167 String Engine::Version() {
168 String s = "$Revision$";
169 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
170 }
171
172 }} // namespace LinuxSampler::sf2

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC