--- linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.h 2011/07/28 15:47:51 2220 +++ linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.h 2011/08/10 19:40:39 2235 @@ -27,6 +27,9 @@ #include "EG.h" #include "EGADSR.h" #include "../common/AbstractVoice.h" +#include "../common/PulseLFO.h" +#include "../common/SawLFO.h" +#include "../common/SineLFO.h" namespace LinuxSampler { namespace sfz { const int MaxUnitCount = 1000; @@ -50,8 +53,51 @@ } double GetSampleRate(); + float GetInfluence(ArrayList< ::sfz::CC>& cc); }; + + class CCUnit: public CCSignalUnit { + public: + Voice* pVoice; + + CCUnit(SfzSignalUnitRack* rack, Listener* l = NULL); + + virtual void Trigger(); + + void SetCCs(::sfz::Array& pCC); + void SetCCs(ArrayList< ::sfz::CC>& cc); + + virtual void AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth); + + inline int GetCurveCount(); + inline ::sfz::Curve* GetCurve(int idx); + + double GetSampleRate(); + }; + + class CurveCCUnit: public CCUnit { + public: + CurveCCUnit(SfzSignalUnitRack* rack, Listener* l = NULL): CCUnit(rack, l) { } + + virtual float Normalize(uint8_t val, short int curve = -1) { + if (curve == -1) return val / 127.0f; + return GetCurve(curve)->v[val]; + } + }; + + + + class SmoothCCUnit: public CurveCCUnit { + protected: + Smoother Smoothers[128]; + public: + SmoothCCUnit(SfzSignalUnitRack* rack, Listener* l = NULL): CurveCCUnit(rack, l) { } + + virtual void AddSmoothCC(uint8_t Controller, float Influence, short int Curve, float Smooth); + }; + + template class EGUnit: public SfzSignalUnit { public: @@ -106,12 +152,19 @@ public: int depth; EGv1Unit(SfzSignalUnitRack* rack): EGUnit(rack), depth(0) { } - virtual void Trigger(); }; class EGv2Unit: public EGUnit< ::LinuxSampler::sfz::EG> { + protected: + ::sfz::EG egInfo; public: - EGv2Unit(SfzSignalUnitRack* rack): EGUnit< ::LinuxSampler::sfz::EG>(rack) { } + CCUnit suAmpOnCC; + CCUnit suVolOnCC; + CCUnit suPitchOnCC; + CCUnit suCutoffOnCC; + CCUnit suResOnCC; + + EGv2Unit(SfzSignalUnitRack* rack); virtual void Trigger(); }; @@ -121,37 +174,147 @@ virtual void Trigger(); }; - class LFOUnit: public SfzSignalUnit { + class FilEGUnit: public EGv1Unit { + public: + FilEGUnit(SfzSignalUnitRack* rack): EGv1Unit(rack) { } + virtual void Trigger(); + }; + + class AmpEGUnit: public EGv1Unit { + public: + AmpEGUnit(SfzSignalUnitRack* rack): EGv1Unit(rack) { } + virtual void Trigger(); + }; + + class AbstractLfo { + public: + virtual float Render() = 0; + virtual void Update(const uint16_t& ExtControlValue) = 0; + virtual void Trigger(float Frequency, start_level_t StartLevel, uint16_t InternalDepth, uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate) = 0; + virtual void SetPhase(float phase) = 0; + virtual void SetFrequency(float Frequency, unsigned int SampleRate) = 0; + }; + + template + class LfoBase: public AbstractLfo, public T { public: - ::sfz::LFO* pLfoInfo; - LFOSigned lfo; + LfoBase(float Max): T(Max) { } + virtual float Render() { return T::render(); } + + virtual void Update(const uint16_t& ExtControlValue) { T::update(ExtControlValue); } - LFOUnit(SfzSignalUnitRack* rack): SfzSignalUnit(rack), pLfoInfo(NULL), lfo(1200.0f) { } - LFOUnit(const LFOUnit& Unit): SfzSignalUnit(Unit), lfo(1200.0f) { Copy(Unit); } + virtual void Trigger ( + float Frequency, start_level_t StartLevel, uint16_t InternalDepth, + uint16_t ExtControlDepth, bool FlipPhase, unsigned int SampleRate + ) { + T::trigger(Frequency, StartLevel, InternalDepth, ExtControlDepth, FlipPhase, SampleRate); + } + + virtual void SetPhase(float phase) { T::setPhase(phase); } + + virtual void SetFrequency(float Frequency, unsigned int SampleRate) { + T::setFrequency(Frequency, SampleRate); + } + }; + + class LFOUnit; + + class FadeEGUnit: public EGUnit { + public: + FadeEGUnit(SfzSignalUnitRack* rack): EGUnit(rack) { } + virtual void Trigger() { } + virtual void EnterReleaseStage() { } + virtual void CancelRelease() { } + + friend class LFOUnit; + }; + + class LFOUnit: public SfzSignalUnit, public CCSignalUnit::Listener { + public: + ::sfz::LFO* pLfoInfo; + AbstractLfo* pLFO; + FadeEGUnit suFadeEG; + SmoothCCUnit suDepthOnCC; + SmoothCCUnit suFreqOnCC; + + LFOUnit(SfzSignalUnitRack* rack); + LFOUnit(const LFOUnit& Unit); void operator=(const LFOUnit& Unit) { Copy(Unit); } void Copy(const LFOUnit& Unit) { - pLfoInfo = Unit.pLfoInfo; + pLfoInfo = Unit.pLfoInfo; + suFadeEG = Unit.suFadeEG; SfzSignalUnit::Copy(Unit); } - virtual bool Active() { return true; } + virtual bool Active() { return pLfoInfo->freq > 0; } virtual void Trigger(); virtual void Increment(); virtual float GetLevel() { return Level; } + virtual void ValueChanged(CCSignalUnit* pUnit); + }; + + class LFOv1Unit: public LFOUnit { + public: + ::sfz::LFO lfoInfo; + LfoBase lfo; + + LFOv1Unit(SfzSignalUnitRack* rack): LFOUnit(rack), lfo(1200.0f) { + pLfoInfo = &lfoInfo; pLFO = &lfo; + } + + virtual void Trigger(); }; class LFOv2Unit: public LFOUnit { + protected: + FixedArray lfos; + LfoBase lfo0; // triangle + LfoBase > lfo1; // sine + LfoBase > lfo2; // pulse 75% + LfoBase > lfo3; // square + LfoBase > lfo4; // pulse 25% + LfoBase > lfo5; // pulse 12,5% + LfoBase > lfo6; // saw up + LfoBase > lfo7; // saw down + + + public: + SmoothCCUnit suVolOnCC; + SmoothCCUnit suPitchOnCC; + SmoothCCUnit suPanOnCC; + SmoothCCUnit suCutoffOnCC; + SmoothCCUnit suResOnCC; + + LFOv2Unit(SfzSignalUnitRack* rack); + + virtual void Trigger(); + }; + + class AmpLFOUnit: public LFOv1Unit { public: - LFOv2Unit(SfzSignalUnitRack* rack): LFOUnit(rack) { } + AmpLFOUnit(SfzSignalUnitRack* rack): LFOv1Unit(rack) { } virtual void Trigger(); }; + class PitchLFOUnit: public LFOv1Unit { + public: + PitchLFOUnit(SfzSignalUnitRack* rack): LFOv1Unit(rack) { } + + virtual void Trigger(); + }; + class FilLFOUnit: public LFOv1Unit { + public: + FilLFOUnit(SfzSignalUnitRack* rack): LFOv1Unit(rack) { } + + virtual void Trigger(); + }; - class EndpointUnit : public EndpointSignalUnit { + + class EndpointUnit: public EndpointSignalUnit { public: Voice* pVoice; @@ -173,15 +336,26 @@ virtual float CalculateResonance(float res) { return GetResonance() + res; } + + virtual float CalculateFilterCutoff(float cutoff); }; class SfzSignalUnitRack : public SignalUnitRack { private: EndpointUnit suEndpoint; - EGv1Unit suVolEG; + AmpEGUnit suVolEG; + FilEGUnit suFilEG; PitchEGUnit suPitchEG; + AmpLFOUnit suAmpLFO; + PitchLFOUnit suPitchLFO; + FilLFOUnit suFilLFO; + + // SFZ v2 + + SmoothCCUnit suVolOnCC; + FixedArray EGs; // used for optimization - contains only the ones that are modulating volume @@ -190,9 +364,21 @@ // used for optimization - contains only the ones that are modulating pitch FixedArray pitchEGs; + // used for optimization - contains only the ones that are modulating filter cutoff + FixedArray filEGs; + + // used for optimization - contains only the ones that are modulating filter cutoff + FixedArray resEGs; + FixedArray LFOs; + // used for optimization - contains only the ones that are modulating volume + FixedArray volLFOs; + + // used for optimization - contains only the ones that are modulating pitch + FixedArray pitchLFOs; + // used for optimization - contains only the ones that are modulating filter cutoff FixedArray filLFOs;