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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2205 - (show annotations) (download)
Mon Jul 11 17:52:01 2011 UTC (12 years, 9 months ago) by iliev
File size: 7927 byte(s)
* Introduced Signal Units and Signal Unit Racks, which hopefully will meet
  the demands of the new engines for flexible signal processing.
* sf2: Initial implementation of vibrato LFO, fixes in modulation EG and
  and volume EG (work in progress)

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 "SF2SignalUnitRack.h"
24 #include "Voice.h"
25
26 namespace LinuxSampler { namespace sf2 {
27
28 void EGUnit::EnterReleaseStage() {
29 update(EG::event_release, pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
30 }
31
32 void EGUnit::CancelRelease() {
33 update(EG::event_cancel_release, pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
34 }
35
36
37 void VolEGUnit::Trigger() {
38 // set the delay trigger
39 double d = pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
40 uiDelayTrigger = pOwner->pRegion->GetEG1PreAttackDelay(pOwner->pPresetRegion) * d;
41 ////////////
42
43 trigger (
44 0, // should be in permille
45 pOwner->pRegion->GetEG1Attack(pOwner->pPresetRegion),
46 pOwner->pRegion->GetEG1Hold(pOwner->pPresetRegion),
47 pOwner->pRegion->GetEG1Decay(pOwner->pPresetRegion),
48 uint(pOwner->pRegion->GetEG1Sustain(pOwner->pPresetRegion)),
49 pOwner->pRegion->GetEG1Release(pOwner->pPresetRegion),
50 pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE
51 );
52 }
53
54 void VolEGUnit::Increment() {
55 if (DelayStage()) return;
56
57 EGUnit::Increment();
58 if (!active()) return;
59
60 switch (getSegmentType()) {
61 case EG::segment_lin:
62 processLin();
63 break;
64 case EG::segment_exp:
65 processExp();
66 break;
67 case EG::segment_end:
68 getLevel();
69 break; // noop
70 case EG::segment_pow:
71 processPow();
72 break;
73 }
74
75 if (active()) {
76
77 // if sample has a loop and loop start has been reached in this subfragment, send a special event to EG1 to let it finish the attack hold stage
78 /*if (pOwner->SmplInfo.HasLoops && pOwner->Pos <= pOwner->SmplInfo.LoopStart && pOwner->SmplInfo.LoopStart < newPos) {
79 update(EG::event_hold_end, pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
80 }*/
81 // TODO: ^^^
82
83 increment(1);
84 if (!toStageEndLeft()) update(EG::event_stage_end, pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
85 }
86 }
87
88 void ModEGUnit::Trigger() {
89 double d = pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
90 uiDelayTrigger = pOwner->pRegion->GetEG2PreAttackDelay(pOwner->pPresetRegion) * d;
91
92 trigger (
93 0, // should be in permille
94 pOwner->pRegion->GetEG2Attack(pOwner->pPresetRegion),
95 pOwner->pRegion->GetEG2Hold(pOwner->pPresetRegion),
96 pOwner->pRegion->GetEG2Decay(pOwner->pPresetRegion),
97 uint(pOwner->pRegion->GetEG2Sustain(pOwner->pPresetRegion)),
98 pOwner->pRegion->GetEG2Release(pOwner->pPresetRegion),
99 pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE
100 );
101 }
102
103 void ModEGUnit::Increment() {
104 if (DelayStage()) return;
105
106 EGUnit::Increment();
107 if (!active()) return;
108
109 switch (getSegmentType()) {
110 case EG::segment_lin:
111 processLin();
112 break;
113 case EG::segment_exp:
114 processExp();
115 break;
116 case EG::segment_end:
117 getLevel();
118 break; // noop
119 case EG::segment_pow:
120 processPow();
121 break;
122 }
123
124 if (active()) {
125 increment(1);
126 if (!toStageEndLeft()) update(EG::event_stage_end, pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE);
127 }
128 }
129
130
131 void VibLfoUnit::Trigger() {
132 // set the delay trigger
133 double samplerate = pOwner->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
134 uiDelayTrigger = pOwner->pRegion->GetDelayVibLfo(pOwner->pPresetRegion) * samplerate;
135 ////////////
136
137 trigger (
138 pOwner->pRegion->GetFreqVibLfo(pOwner->pPresetRegion),
139 start_level_min,
140 pOwner->pRegion->GetVibLfoToPitch(pOwner->pPresetRegion),
141 0, false, samplerate
142 );
143 update(0);
144 }
145 void VibLfoUnit::Increment() {
146 if (DelayStage()) return;
147
148 SignalUnitBase<Voice>::Increment();
149
150 Level = render();
151 }
152
153
154 void EndpointUnit::Trigger() {
155
156 }
157
158 bool EndpointUnit::Active() {
159 if (Params.size() < 1) return false;
160 return Params[0].pUnit->Active(); // volEGUnit
161 }
162
163 float EndpointUnit::GetVolume() {
164 if (Params.size() < 1) return 0;
165 return Params[0].pUnit->Active() ? Params[0].GetFinalValue() : 0;
166 }
167
168 float EndpointUnit::GetFilterCutoff() {
169 return 1;
170 }
171
172 float EndpointUnit::GetPitch() {
173 if (Params.size() < 3) return 0;
174 double eg = Params[1].pUnit->Active() ? RTMath::CentsToFreqRatio(Params[1].GetFinalValue()) : 1;
175 double lfo = Params[2].pUnit->Active() ? RTMath::CentsToFreqRatio(Params[2].GetFinalValue()) : 1;
176
177 return eg * lfo;
178 }
179
180 float EndpointUnit::GetResonance() {
181 return 1;
182 }
183
184 SF2SignalUnitRack::SF2SignalUnitRack(Voice* pVoice): SignalUnitRackBase<Voice>(pVoice) {
185 Units.add(&suVolEG);
186 Units.add(&suModEG);
187 Units.add(&suVibLfo);
188 Units.add(&suEndpoint);
189
190 // Volume envelope
191 suEndpoint.Params.add(SignalUnit::Parameter(&suVolEG));
192 // Modulation envelope
193 suEndpoint.Params.add(SignalUnit::Parameter(&suModEG));
194 // Vibrato LFO
195 suEndpoint.Params.add(SignalUnit::Parameter(&suVibLfo));
196 }
197
198 void SF2SignalUnitRack::Trigger() {
199 // The region settings are available after the voice is triggered
200
201 // Modulation envelope
202 int pitch = pOwner->pRegion->GetModEnvToPitch(pOwner->pPresetRegion);
203 suEndpoint.Params[1].Coeff = pitch;
204 ///////
205
206 SignalUnitRackBase<Voice>::Trigger();
207 }
208
209 EndpointSignalUnit* SF2SignalUnitRack::GetEndpointUnit() {
210 return static_cast<EndpointSignalUnit*> (&suEndpoint);
211 }
212
213 }} // namespace LinuxSampler::sf2

  ViewVC Help
Powered by ViewVC