28 |
|
|
29 |
namespace LinuxSampler { |
namespace LinuxSampler { |
30 |
|
|
31 |
|
class SignalUnitRack; |
32 |
|
|
33 |
/** |
/** |
34 |
* A signal unit consist of internal signal generator (like envelope generator, |
* A signal unit consist of internal signal generator (like envelope generator, |
35 |
* low frequency oscillator, etc) with a number of generator parameters which |
* low frequency oscillator, etc) with a number of generator parameters which |
83 |
Parameter(const Parameter& Prm) { Copy(Prm); } |
Parameter(const Parameter& Prm) { Copy(Prm); } |
84 |
void operator=(const Parameter& Prm) { Copy(Prm); } |
void operator=(const Parameter& Prm) { Copy(Prm); } |
85 |
|
|
86 |
virtual void Copy(const Parameter& Prm) { |
void Copy(const Parameter& Prm) { |
87 |
if (this == &Prm) return; |
if (this == &Prm) return; |
88 |
|
|
89 |
pUnit = Prm.pUnit; |
pUnit = Prm.pUnit; |
117 |
public: |
public: |
118 |
ArrayList<SignalUnit::Parameter> Params; // The list of parameters which are modulating the signal unit |
ArrayList<SignalUnit::Parameter> Params; // The list of parameters which are modulating the signal unit |
119 |
|
|
120 |
SignalUnit() : bActive(false), Level(0.0f), bCalculating(false), uiDelayTrigger(0) { } |
SignalUnit(SignalUnitRack* rack): pRack(rack), bActive(false), Level(0.0f), bCalculating(false), uiDelayTrigger(0) { } |
121 |
SignalUnit(const SignalUnit& Unit) { Copy(Unit); } |
SignalUnit(const SignalUnit& Unit): pRack(Unit.pRack) { Copy(Unit); } |
122 |
void operator=(const SignalUnit& Unit) { Copy(Unit); } |
void operator=(const SignalUnit& Unit) { Copy(Unit); } |
123 |
|
|
124 |
virtual void Copy(const SignalUnit& Unit) { |
void Copy(const SignalUnit& Unit) { |
125 |
if (this == &Unit) return; |
if (this == &Unit) return; |
126 |
|
|
127 |
bActive = Unit.bActive; |
bActive = Unit.bActive; |
202 |
*/ |
*/ |
203 |
virtual uint DelayTrigger() { return uiDelayTrigger; } |
virtual uint DelayTrigger() { return uiDelayTrigger; } |
204 |
|
|
205 |
|
/** |
206 |
|
* A helper method which checks whether the delay |
207 |
|
* stage is finished. |
208 |
|
*/ |
209 |
|
bool DelayStage(); |
210 |
|
|
211 |
protected: |
protected: |
212 |
|
SignalUnitRack* const pRack; |
213 |
|
|
214 |
bool bActive; /* Don't use it to check the active state of the unit!!! |
bool bActive; /* Don't use it to check the active state of the unit!!! |
215 |
* Use Active() instead! */ |
* Use Active() instead! */ |
216 |
float Level; |
float Level; |
223 |
|
|
224 |
}; |
}; |
225 |
|
|
226 |
class EndpointSignalUnit: virtual public SignalUnit { |
class EndpointSignalUnit: public SignalUnit { |
227 |
public: |
public: |
228 |
|
EndpointSignalUnit(SignalUnitRack* rack): SignalUnit(rack) { } |
229 |
|
|
230 |
/** |
/** |
231 |
* Gets the volume modulation value |
* Gets the volume modulation value |
232 |
* for the current time step (sample point). |
* for the current time step (sample point). |
251 |
*/ |
*/ |
252 |
virtual float GetResonance() = 0; |
virtual float GetResonance() = 0; |
253 |
|
|
254 |
virtual float CalculateFilterCutoff(float cutoff) = 0; |
/** Should return value in the range [-100, 100] (L <-> R) */ |
255 |
|
virtual float GetPan() = 0; |
|
virtual float CalculatePitch(float pitch) = 0; |
|
|
|
|
|
virtual float CalculateResonance(float res) = 0; |
|
|
}; |
|
|
|
|
|
|
|
|
class SignalUnitRack; |
|
|
|
|
|
template <class O /* The signal unit's owner */> |
|
|
class SignalUnitBase: virtual public SignalUnit { |
|
|
public: |
|
|
SignalUnitBase() : pOwner(NULL) { } |
|
|
SignalUnitBase(const SignalUnitBase& Unit) { Copy(Unit); } |
|
|
void operator=(const SignalUnitBase& Unit) { Copy(Unit); } |
|
256 |
|
|
257 |
virtual void Copy(const SignalUnitBase& Unit) { |
virtual float CalculateFilterCutoff(float cutoff) { |
258 |
if (this == &Unit) return; |
cutoff *= GetFilterCutoff(); |
259 |
|
return cutoff > 13500 ? 13500 : cutoff; |
|
pOwner = Unit.pOwner; |
|
|
SignalUnit::Copy(Unit); |
|
260 |
} |
} |
|
|
|
|
protected: |
|
|
O* pOwner; // The owner to which this rack belongs. |
|
|
|
|
|
SignalUnitRack* GetSignalUnitRack() { return pOwner->GetSignalUnitRack(); } |
|
|
|
|
|
public: |
|
261 |
|
|
262 |
|
virtual float CalculatePitch(float pitch) { |
263 |
|
return GetPitch() * pitch; |
264 |
|
} |
265 |
|
|
266 |
/** |
virtual float CalculateResonance(float res) { |
267 |
* The owner of the unit is set by the rack |
return GetResonance() * res; |
268 |
* just before the call to the unit's trigger method. |
} |
|
*/ |
|
|
void SetOwner(O* Owner) { pOwner = Owner; } |
|
269 |
|
|
270 |
/** |
/** Should return value in the range [0, 127] (L <-> R) */ |
271 |
* A helper method which checks whether the delay |
virtual uint8_t CaluclatePan(uint8_t pan) { |
272 |
* stage is finished. |
int p = pan + GetPan() * 0.63; |
273 |
*/ |
if (p < 0) return 0; |
274 |
bool DelayStage() { |
if (p > 127) return 127; |
275 |
return (DelayTrigger() >= GetSignalUnitRack()->GetCurrentStep()); |
return p; |
276 |
} |
} |
277 |
}; |
}; |
278 |
|
|
281 |
* The level of this unit corresponds to the controller changes |
* The level of this unit corresponds to the controller changes |
282 |
* and is normalized to be in the range from -1 to +1. |
* and is normalized to be in the range from -1 to +1. |
283 |
*/ |
*/ |
284 |
template<class O> |
class CCSignalUnit: public SignalUnit { |
|
class CCSignalUnit: public SignalUnitBase<O> { |
|
285 |
private: |
private: |
286 |
uint8_t Ctrl; // The number of the MIDI controller which modulates this signal unit. |
uint8_t Ctrl; // The number of the MIDI controller which modulates this signal unit. |
287 |
|
|
288 |
public: |
public: |
289 |
CCSignalUnit(uint8_t Controller) { |
CCSignalUnit(SignalUnitRack* rack, uint8_t Controller): SignalUnit(rack) { |
290 |
Ctrl = Controller; |
Ctrl = Controller; |
291 |
} |
} |
292 |
|
|
293 |
CCSignalUnit(const CCSignalUnit& Unit) { Copy(Unit); } |
CCSignalUnit(const CCSignalUnit& Unit): SignalUnit(Unit.pRack) { Copy(Unit); } |
294 |
void operator=(const CCSignalUnit& Unit) { Copy(Unit); } |
void operator=(const CCSignalUnit& Unit) { Copy(Unit); } |
295 |
|
|
296 |
virtual void Copy(const CCSignalUnit& Unit) { |
void Copy(const CCSignalUnit& Unit) { |
|
SignalUnitBase<O>::Copy(Unit); |
|
297 |
Ctrl = Unit.Ctrl; |
Ctrl = Unit.Ctrl; |
298 |
|
SignalUnit::Copy(Unit); |
299 |
} |
} |
300 |
|
|
301 |
virtual void Increment() { } |
virtual void Increment() { } |
304 |
if (Controller != Ctrl) return; |
if (Controller != Ctrl) return; |
305 |
|
|
306 |
// Normalize the value so it belongs to the interval [-1, +1] |
// Normalize the value so it belongs to the interval [-1, +1] |
307 |
SignalUnitBase<O>::Level = 2 * Value; |
Level = 2 * Value; |
308 |
SignalUnitBase<O>::Level = SignalUnitBase<O>::Level/127.0f - 1.0f; |
Level = Level/127.0f - 1.0f; |
309 |
|
|
310 |
if (!SignalUnitBase<O>::bActive) SignalUnitBase<O>::bActive = true; |
if (!bActive) bActive = true; |
|
} |
|
|
}; |
|
|
|
|
|
/** |
|
|
* Endpoint signal unit. |
|
|
*/ |
|
|
template<class O> |
|
|
class EndpointSignalUnitBase : public SignalUnitBase<O>, public EndpointSignalUnit { |
|
|
public: |
|
|
|
|
|
virtual float CalculateFilterCutoff(float cutoff) { |
|
|
cutoff *= GetFilterCutoff(); |
|
|
return cutoff > 13500 ? 13500 : cutoff; |
|
|
} |
|
|
|
|
|
virtual float CalculatePitch(float pitch) { |
|
|
return GetPitch() * pitch; |
|
|
} |
|
|
|
|
|
virtual float CalculateResonance(float res) { |
|
|
return GetResonance() * res; |
|
311 |
} |
} |
312 |
}; |
}; |
313 |
|
|