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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2205 - (hide 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 iliev 2205 /***************************************************************************
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