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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 iliev 2218 /***************************************************************************
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 iliev 2219
55 iliev 2218
56 iliev 2219 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 iliev 2218
83 iliev 2219
84 iliev 2218 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 iliev 2219 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 iliev 2218 }
132    
133     float EndpointUnit::GetPitch() {
134     return 1;
135     }
136    
137     float EndpointUnit::GetResonance() {
138 iliev 2219 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 iliev 2218 }
149    
150 iliev 2219 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 iliev 2218
166 iliev 2219
167 iliev 2218 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
168     : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this),
169 iliev 2219 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount),
170     LFOs(maxLfoCount), filLFOs(maxLfoCount), resLFOs(maxLfoCount), panLFOs(maxLfoCount)
171 iliev 2218 {
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 iliev 2219
179     for (int i = 0; i < LFOs.capacity(); i++) {
180     LFOs[i] = new LFOv2Unit(this);
181     LFOs[i]->pVoice = voice;
182     }
183 iliev 2218 }
184    
185     SfzSignalUnitRack::~SfzSignalUnitRack() {
186 iliev 2219 for (int i = 0; i < EGs.capacity(); i++) {
187 iliev 2218 delete EGs[i]; EGs[i] = NULL;
188     }
189 iliev 2219
190     for (int i = 0; i < LFOs.capacity(); i++) {
191     delete LFOs[i]; LFOs[i] = NULL;
192     }
193 iliev 2218 }
194    
195     void SfzSignalUnitRack::Trigger() {
196     EGs.clear();
197     volEGs.clear();
198     pitchEGs.clear();
199    
200 iliev 2219 LFOs.clear();
201     filLFOs.clear();
202     resLFOs.clear();
203     panLFOs.clear();
204    
205 iliev 2218 ::sfz::Region* const pRegion = pVoice->pRegion;
206    
207 iliev 2219 for (int i = 0; i < pRegion->eg.size(); i++) {
208 iliev 2218 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 iliev 2219 // 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 iliev 2218 Units.clear();
254    
255     Units.add(&suVolEG);
256    
257 iliev 2219 for (int i = 0; i < EGs.size(); i++) {
258 iliev 2218 Units.add(EGs[i]);
259     }
260    
261 iliev 2219 for (int i = 0; i < LFOs.size(); i++) {
262     Units.add(LFOs[i]);
263     }
264    
265 iliev 2218 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