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

Contents of /linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2219 - (show annotations) (download)
Thu Jul 28 12:35:49 2011 UTC (12 years, 8 months ago) by iliev
File size: 9747 byte(s)
* sfz engine: implemented opcodes lfoN_delay,
  lfoN_freq, lfoN_pan, lfoN_cutoff, lfoN_resonance

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "SfzSignalUnitRack.h"
24 #include "Voice.h"
25
26 namespace LinuxSampler { namespace sfz {
27
28 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
29
30 }
31
32 double SfzSignalUnit::GetSampleRate() {
33 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
34 }
35
36
37 void EGv1Unit::Trigger() {
38 ::sfz::Region* const pRegion = pVoice->pRegion;
39 // the length of the decay and release curves are dependent on the velocity
40 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
41
42 EG.trigger(uint(pRegion->ampeg_start * 10),
43 std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),
44 std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),
45 std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),
46 uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),
47 std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),
48 GetSampleRate());
49 }
50
51 void EGv2Unit::Trigger() {
52 EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);
53 }
54
55
56 void LFOUnit::Increment() {
57 if (DelayStage()) return;
58
59 SignalUnit::Increment();
60
61 Level = lfo.render();
62 }
63
64 void LFOUnit::Trigger() {
65 //reset
66 Level = 0;
67
68 // set the delay trigger
69 uiDelayTrigger = pLfoInfo->delay * GetSampleRate();
70 }
71
72 void LFOv2Unit::Trigger() {
73 LFOUnit::Trigger();
74
75 lfo.trigger (
76 pLfoInfo->freq,
77 start_level_mid,
78 1, 0, false, GetSampleRate()
79 );
80 lfo.update(0);
81 }
82
83
84 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {
85
86 }
87
88 SfzSignalUnitRack* const EndpointUnit::GetRack() {
89 return static_cast<SfzSignalUnitRack* const>(pRack);
90 }
91
92 void EndpointUnit::Trigger() {
93
94 }
95
96 bool EndpointUnit::Active() {
97 if (GetRack()->suVolEG.Active()) return true;
98
99 bool b = false;
100 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
101 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
102 }
103
104 return b;
105 }
106
107 float EndpointUnit::GetVolume() {
108 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
109
110 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
111 EGv2Unit* eg = GetRack()->volEGs[i];
112 if (!eg->Active()) continue;
113 vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);
114 }
115
116 return vol;
117 }
118
119 float EndpointUnit::GetFilterCutoff() {
120 float val = 1;
121
122 for (int i = 0; i < GetRack()->filLFOs.size(); i++) {
123 LFOv2Unit* lfo = GetRack()->filLFOs[i];
124 if (!lfo->Active()) continue;
125
126 float f = lfo->GetLevel() * lfo->pLfoInfo->cutoff;
127 val *= RTMath::CentsToFreqRatioUnlimited(f);
128 }
129
130 return val;
131 }
132
133 float EndpointUnit::GetPitch() {
134 return 1;
135 }
136
137 float EndpointUnit::GetResonance() {
138 float val = 0;
139
140 for (int i = 0; i < GetRack()->resLFOs.size(); i++) {
141 LFOv2Unit* lfo = GetRack()->resLFOs[i];
142 if (!lfo->Active()) continue;
143
144 val += lfo->GetLevel() * lfo->pLfoInfo->resonance;
145 }
146
147 return val;
148 }
149
150 float EndpointUnit::GetPan() {
151 float pan = 0;
152
153 for (int i = 0; i < GetRack()->panLFOs.size(); i++) {
154 LFOv2Unit* lfo = GetRack()->panLFOs[i];
155 if (!lfo->Active()) continue;
156
157 pan += lfo->GetLevel() * lfo->pLfoInfo->pan;
158 }
159
160 if(pan < -100) return -100;
161 if(pan > 100) return 100;
162
163 return pan;
164 }
165
166
167 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
168 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this),
169 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),
170 LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
171 {
172 suEndpoint.pVoice = suVolEG.pVoice = voice;
173
174 for (int i = 0; i < EGs.capacity(); i++) {
175 EGs[i] = new EGv2Unit(this);
176 EGs[i]->pVoice = voice;
177 }
178
179 for (int i = 0; i < LFOs.capacity(); i++) {
180 LFOs[i] = new LFOv2Unit(this);
181 LFOs[i]->pVoice = voice;
182 }
183 }
184
185 SfzSignalUnitRack::~SfzSignalUnitRack() {
186 for (int i = 0; i < EGs.capacity(); i++) {
187 delete EGs[i]; EGs[i] = NULL;
188 }
189
190 for (int i = 0; i < LFOs.capacity(); i++) {
191 delete LFOs[i]; LFOs[i] = NULL;
192 }
193 }
194
195 void SfzSignalUnitRack::Trigger() {
196 EGs.clear();
197 volEGs.clear();
198 pitchEGs.clear();
199
200 LFOs.clear();
201 filLFOs.clear();
202 resLFOs.clear();
203 panLFOs.clear();
204
205 ::sfz::Region* const pRegion = pVoice->pRegion;
206
207 for (int i = 0; i < pRegion->eg.size(); i++) {
208 if (pRegion->eg[i].node.size() == 0) continue;
209
210 if(EGs.size() < EGs.capacity()) {
211 EGv2Unit eg(this);
212 eg.pEGInfo = &(pRegion->eg[i]);
213 EGs.increment()->Copy(eg);
214 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
215
216 if (pRegion->eg[i].amplitude > 0) {
217 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
218 else std::cerr << "Maximum number of EGs reached!" << std::endl;
219 }
220 }
221
222 if (pRegion->ampeg_sustain == -1) {
223 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
224 else pRegion->ampeg_sustain = 100;
225 }
226
227 // LFO
228 for (int i = 0; i < pRegion->lfos.size(); i++) {
229 if (pRegion->lfos[i].freq == -1) continue; // Not initialized
230
231 if(LFOs.size() < LFOs.capacity()) {
232 LFOv2Unit lfo(this);
233 lfo.pLfoInfo = &(pRegion->lfos[i]);
234 LFOs.increment()->Copy(lfo);
235 } else { std::cerr << "Maximum number of LFOs reached!" << std::endl; break; }
236
237 if (pRegion->lfos[i].cutoff != 0) {
238 if(filLFOs.size() < filLFOs.capacity()) filLFOs.add(LFOs[LFOs.size() - 1]);
239 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
240 }
241
242 if (pRegion->lfos[i].resonance != 0) {
243 if(resLFOs.size() < resLFOs.capacity()) resLFOs.add(LFOs[LFOs.size() - 1]);
244 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
245 }
246
247 if (pRegion->lfos[i].pan != 0) {
248 if(panLFOs.size() < panLFOs.capacity()) panLFOs.add(LFOs[LFOs.size() - 1]);
249 else std::cerr << "Maximum number of LFOs reached!" << std::endl;
250 }
251 }
252
253 Units.clear();
254
255 Units.add(&suVolEG);
256
257 for (int i = 0; i < EGs.size(); i++) {
258 Units.add(EGs[i]);
259 }
260
261 for (int i = 0; i < LFOs.size(); i++) {
262 Units.add(LFOs[i]);
263 }
264
265 Units.add(&suEndpoint);
266
267 SignalUnitRack::Trigger();
268 }
269
270 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
271 return &suEndpoint;
272 }
273
274 void SfzSignalUnitRack::EnterFadeOutStage() {
275 suVolEG.EG.enterFadeOutStage();
276
277 for (int i = 0; i < volEGs.size(); i++) {
278 volEGs[i]->EG.enterFadeOutStage();
279 }
280 }
281
282 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC