--- linuxsampler/trunk/src/engines/sfz/sfz.h 2011/08/03 17:11:40 2227 +++ linuxsampler/trunk/src/engines/sfz/sfz.h 2011/08/20 15:54:07 2253 @@ -48,13 +48,35 @@ class Instrument; class File; class LookupTable; + class SampleManager; class Sample : public LinuxSampler::SampleFileBase { + private: + int End; + long TotalFrames; + public: - Sample(String File, bool DontClose = false, uint offset = 0): LinuxSampler::SampleFileBase(File, DontClose) { + Sample(String File, bool DontClose = false, uint offset = 0, int end = -2 /* -2 means unspecified */) + : LinuxSampler::SampleFileBase(File, DontClose) + { Offset = offset; + End = end; + + long tfc = LinuxSampler::SampleFileBase::GetTotalFrameCount(); + if (Offset >= tfc) { + std::cerr << "Offset for file '" << this->GetFile() << "' too long (" << Offset << ")" << std::endl; + Offset = 0; + } + + if (End == -2 || End > tfc) TotalFrames = tfc; + else if (End == -1 || End < Offset) TotalFrames = 0; + else TotalFrames = End; } virtual ~Sample() { } + + virtual long GetTotalFrameCount() { return TotalFrames; } + + friend class SampleManager; }; // Enumerations @@ -72,7 +94,7 @@ class SampleManager : public LinuxSampler::SampleManager { public: - Sample* FindSample(std::string samplePath, int offset); + Sample* FindSample(std::string samplePath, uint offset, int end); protected: virtual void OnSampleInUse(Sample* pSample) { @@ -86,14 +108,16 @@ class CC { public: - uint8_t Controller; ///< MIDI controller number. - float Influence; ///< Controller Value. + uint8_t Controller; ///< MIDI controller number. + short int Curve; + float Influence; ///< Controller Value. + float Smooth; ///< The speed of parameter change in milliseconds - CC() { CC(0, 0.0f); } - - CC(uint8_t Controller, float Influence) { + CC(uint8_t Controller = 0, float Influence = 0.0f, short int Curve = -1, float Smooth = 0) { this->Controller = Controller; - this->Influence = Influence; + this->Influence = Influence; + this->Curve = Curve; + this->Smooth = Smooth; } CC(const CC& cc) { Copy(cc); } @@ -101,7 +125,9 @@ void Copy(const CC& cc) { Controller = cc.Controller; - Influence = cc.Influence; + Influence = cc.Influence; + Curve = cc.Curve; + Smooth = cc.Smooth; } }; @@ -246,7 +272,13 @@ float level; float shape; float curve; + LinuxSampler::ArrayList time_oncc; + LinuxSampler::ArrayList level_oncc; + EGNode(); + EGNode(const EGNode& egNode) { Copy(egNode); } + void operator=(const EGNode& egNode) { Copy(egNode); } + void Copy(const EGNode& egNode); }; class EG @@ -257,8 +289,25 @@ int loop; int loop_count; float amplitude; + float volume; float cutoff; + int pitch; // -9600 to 9600 cents + float resonance; // 0 to 40 dB + float pan; // -100 to 100 % + int pan_curve; + + LinuxSampler::ArrayList amplitude_oncc; + LinuxSampler::ArrayList volume_oncc; + LinuxSampler::ArrayList cutoff_oncc; // -9600 to 9600 cents + LinuxSampler::ArrayList pitch_oncc; + LinuxSampler::ArrayList resonance_oncc; // 0 to 40 dB + LinuxSampler::ArrayList pan_oncc; // -100 to 100 % + LinuxSampler::ArrayList pan_curvecc; // used only as temporary buffer during the parsing - values are then moved to pan_oncc + EG(); + EG(const EG& eg) { Copy(eg); } + void operator=(const EG& eg) { Copy(eg); } + void Copy(const EG& eg); }; class LFO @@ -275,12 +324,26 @@ float resonance; // 0 to 40 dB float pan; // -100 to 100 % + LinuxSampler::ArrayList delay_oncc; // 0 to 100 seconds LinuxSampler::ArrayList freq_oncc; // 0 to 20 Hz + LinuxSampler::ArrayList freq_smoothcc; // 0 to ? milliseconds LinuxSampler::ArrayList fade_oncc; // 0 to 100 seconds LinuxSampler::ArrayList phase_oncc; // 0 to 360 degrees + LinuxSampler::ArrayList volume_oncc; // -144 to 6 dB + LinuxSampler::ArrayList volume_smoothcc; // 0 to ? milliseconds LinuxSampler::ArrayList pitch_oncc; + LinuxSampler::ArrayList pitch_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList pan_oncc; // -100 to 100 % + LinuxSampler::ArrayList pan_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList cutoff_oncc; // -9600 to 9600 cents + LinuxSampler::ArrayList cutoff_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList resonance_oncc; // 0 to 40 dB + LinuxSampler::ArrayList resonance_smoothcc; // 0 to ? milliseconds LFO(); + LFO(const LFO& lfo) { Copy(lfo); } + void operator=(const LFO& lfo) { Copy(lfo); } + void Copy(const LFO& lfo); }; // Fixed size array with copy-on-write semantics @@ -378,7 +441,7 @@ optional delay_samples; Array > delay_samples_oncc; optional end; optional loop_crossfade; - optional offset; optional offset_random; Array > offset_oncc; + optional offset; optional offset_random; Array > offset_oncc; loop_mode_t loop_mode; optional loop_start; optional loop_end; optional sync_beats; @@ -411,19 +474,17 @@ // filter filter_t fil_type; filter_t fil2_type; optional cutoff; optional cutoff2; - Array cutoff_oncc; Array cutoff2_oncc; - int cutoff_cc; // TODO: this is just a temporary fix to avoid - // looping through the cutoff_oncc array - Array cutoff_smoothcc; Array cutoff2_smoothcc; + LinuxSampler::ArrayList cutoff_oncc, cutoff2_oncc; + LinuxSampler::ArrayList cutoff_smoothcc, cutoff2_smoothcc; Array cutoff_stepcc; Array cutoff2_stepcc; - Array cutoff_curvecc; Array cutoff2_curvecc; + LinuxSampler::ArrayList cutoff_curvecc, cutoff2_curvecc; int cutoff_chanaft; int cutoff2_chanaft; int cutoff_polyaft; int cutoff2_polyaft; float resonance; float resonance2; - Array resonance_oncc; Array resonance2_oncc; - Array resonance_smoothcc; Array resonance2_smoothcc; + LinuxSampler::ArrayList resonance_oncc, resonance2_oncc; + LinuxSampler::ArrayList resonance_smoothcc, resonance2_smoothcc; Array resonance_stepcc; Array resonance2_stepcc; - Array resonance_curvecc; Array resonance2_curvecc; + LinuxSampler::ArrayList resonance_curvecc, resonance2_curvecc; int fil_keytrack; int fil2_keytrack; int fil_keycenter; int fil2_keycenter; int fil_veltrack; int fil2_veltrack; @@ -442,26 +503,48 @@ //Deprecated (from version 1) float ampeg_delay, ampeg_start, ampeg_attack, ampeg_hold, ampeg_decay, ampeg_sustain, ampeg_release; float ampeg_vel2delay, ampeg_vel2attack, ampeg_vel2hold, ampeg_vel2decay, ampeg_vel2sustain, ampeg_vel2release; + LinuxSampler::ArrayList ampeg_delaycc, ampeg_startcc, ampeg_attackcc, ampeg_holdcc; + LinuxSampler::ArrayList ampeg_decaycc, ampeg_sustaincc, ampeg_releasecc; float fileg_delay, fileg_start, fileg_attack, fileg_hold, fileg_decay, fileg_sustain, fileg_release; float fileg_vel2delay, fileg_vel2attack, fileg_vel2hold, fileg_vel2decay, fileg_vel2sustain, fileg_vel2release; + LinuxSampler::ArrayList fileg_delay_oncc, fileg_start_oncc, fileg_attack_oncc, fileg_hold_oncc; + LinuxSampler::ArrayList fileg_decay_oncc, fileg_sustain_oncc, fileg_release_oncc, fileg_depth_oncc; float pitcheg_delay, pitcheg_start, pitcheg_attack, pitcheg_hold, pitcheg_decay, pitcheg_sustain, pitcheg_release; float pitcheg_vel2delay, pitcheg_vel2attack, pitcheg_vel2hold, pitcheg_vel2decay, pitcheg_vel2sustain, pitcheg_vel2release; int fileg_depth, pitcheg_depth; + LinuxSampler::ArrayList pitcheg_delay_oncc, pitcheg_start_oncc, pitcheg_attack_oncc, pitcheg_hold_oncc; + LinuxSampler::ArrayList pitcheg_decay_oncc, pitcheg_sustain_oncc, pitcheg_release_oncc, pitcheg_depth_oncc; float amplfo_delay, amplfo_fade, amplfo_freq, amplfo_depth; float fillfo_delay, fillfo_fade, fillfo_freq, fillfo_depth; float pitchlfo_delay, pitchlfo_fade, pitchlfo_freq; int pitchlfo_depth; - Array pitchlfo_depthcc; + LinuxSampler::ArrayList pitchlfo_delay_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList pitchlfo_fade_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList pitchlfo_depthcc; // -1200 to 1200 cents LinuxSampler::ArrayList pitchlfo_freqcc; // 0 to 20 Hz - LinuxSampler::ArrayList fillfo_freqcc; // 0 to 20 Hz - LinuxSampler::ArrayList amplfo_freqcc; // 0 to 20 Hz + LinuxSampler::ArrayList fillfo_delay_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList fillfo_fade_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList fillfo_depthcc; // -1200 to 1200 cents + LinuxSampler::ArrayList fillfo_freqcc; // 0 to 20 Hz + LinuxSampler::ArrayList amplfo_delay_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList amplfo_fade_oncc; // 0 to 100 seconds + LinuxSampler::ArrayList amplfo_depthcc; // -10 to 10 dB + LinuxSampler::ArrayList amplfo_freqcc; // 0 to 20 Hz // envelope generators LinuxSampler::ArrayList eg; // low frequency oscillators LinuxSampler::ArrayList lfos; + + LinuxSampler::ArrayList volume_oncc; + LinuxSampler::ArrayList volume_curvecc; // used only as temporary buffer during the parsing - values are then moved to volume_oncc + LinuxSampler::ArrayList volume_smoothcc; // used only as temporary buffer during the parsing - values are then moved to volume_oncc + + LinuxSampler::ArrayList pan_oncc; // -100 to 100 % + LinuxSampler::ArrayList pan_curvecc; // used only as temporary buffer during the parsing - values are then moved to pan_oncc + LinuxSampler::ArrayList pan_smoothcc; // used only as temporary buffer during the parsing - values are then moved to pan_oncc }; class Query { @@ -528,11 +611,20 @@ Instrument* pInstrument; int seq_counter; }; + + class Curve { + public: + float v[128]; + Curve() { for (int i = 0; i < 128; i++) v[i] = 0; } + Curve(const Curve& curve) { Copy(curve); } + void operator=(const Curve& curve) { Copy(curve); } + void Copy(const Curve& curve) { for (int i = 0; i < 128; i++) v[i] = curve.v[i]; } + }; ///////////////////////////////////////////////////////////// // class Instrument - /// Provides all neccessary information for the synthesis of an Instrument + /// Provides all necessary information for the synthesis of an Instrument class Instrument : public SampleManager { public: @@ -548,6 +640,7 @@ /// List of Regions belonging to this Instrument std::vector regions; + ::LinuxSampler::ArrayList curves; friend class File; friend class Query; @@ -604,16 +697,23 @@ EG& eg(int x); EGNode& egnode(int x, int y); LFO& lfo(int x); + void copyCurves(LinuxSampler::ArrayList& curves, LinuxSampler::ArrayList& dest); + void copySmoothValues(LinuxSampler::ArrayList& smooths, LinuxSampler::ArrayList& dest); + + int ToInt(const std::string& s) throw(LinuxSampler::Exception); + float ToFloat(const std::string& s) throw(LinuxSampler::Exception); + int currentLine; std::string currentDir; /// Pointer to the Instrument belonging to this file Instrument* _instrument; // state variables - enum section_t { UNKNOWN, GROUP, REGION, CONTROL }; + enum section_t { UNKNOWN, GROUP, REGION, CONTROL, CURVE }; section_t _current_section; Region* _current_region; Group* _current_group; + Curve* _current_curve; Definition* pCurDef; // control header directives