--- linuxsampler/trunk/src/engines/sfz/sfz.h 2011/08/19 15:51:18 2248 +++ linuxsampler/trunk/src/engines/sfz/sfz.h 2016/01/06 10:02:40 2856 @@ -3,7 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2008 Anders Dahnielson * - * Copyright (C) 2009 - 2011 Anders Dahnielson and Grigor Iliev * + * Copyright (C) 2009 - 2016 Anders Dahnielson and Grigor Iliev * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -56,7 +57,7 @@ long TotalFrames; public: - Sample(String File, bool DontClose = false, uint offset = 0, int end = -2 /* -2 means unspecified */) + Sample(String File, bool DontClose = false, uint offset = 0, int end = 0 /* 0 means unspecified */) : LinuxSampler::SampleFileBase(File, DontClose) { Offset = offset; @@ -68,7 +69,7 @@ Offset = 0; } - if (End == -2 || End > tfc) TotalFrames = tfc; + if (End == 0 || End > tfc) TotalFrames = tfc; else if (End == -1 || End < Offset) TotalFrames = 0; else TotalFrames = End; } @@ -112,12 +113,20 @@ short int Curve; float Influence; ///< Controller Value. float Smooth; ///< The speed of parameter change in milliseconds + float Step; - CC(uint8_t Controller = 0, float Influence = 0.0f, short int Curve = -1, float Smooth = 0) { + CC ( + uint8_t Controller = 0, + float Influence = 0, + short int Curve = -1, + float Smooth = 0, + float Step = 0 + ) { this->Controller = Controller; this->Influence = Influence; this->Curve = Curve; this->Smooth = Smooth; + this->Step = Step; } CC(const CC& cc) { Copy(cc); } @@ -128,6 +137,7 @@ Influence = cc.Influence; Curve = cc.Curve; Smooth = cc.Smooth; + Step = cc.Step; } }; @@ -280,8 +290,60 @@ void operator=(const EGNode& egNode) { Copy(egNode); } void Copy(const EGNode& egNode); }; + + class EqImpl { + public: + float eq1freq, eq2freq, eq3freq; + float eq1bw, eq2bw, eq3bw; + float eq1gain, eq2gain, eq3gain; + LinuxSampler::ArrayList eq1freq_oncc; + LinuxSampler::ArrayList eq2freq_oncc; + LinuxSampler::ArrayList eq3freq_oncc; + LinuxSampler::ArrayList eq1bw_oncc; + LinuxSampler::ArrayList eq2bw_oncc; + LinuxSampler::ArrayList eq3bw_oncc; + LinuxSampler::ArrayList eq1gain_oncc; + LinuxSampler::ArrayList eq2gain_oncc; + LinuxSampler::ArrayList eq3gain_oncc; + + EqImpl(); + + EqImpl(const EqImpl& eq) { Copy(eq); } + void Copy(const EqImpl& eq); + bool HasEq(); + }; + + class EqSmoothStepImpl: public EqImpl { + public: + LinuxSampler::ArrayList eq1freq_smoothcc; + LinuxSampler::ArrayList eq2freq_smoothcc; + LinuxSampler::ArrayList eq3freq_smoothcc; + LinuxSampler::ArrayList eq1bw_smoothcc; + LinuxSampler::ArrayList eq2bw_smoothcc; + LinuxSampler::ArrayList eq3bw_smoothcc; + LinuxSampler::ArrayList eq1gain_smoothcc; + LinuxSampler::ArrayList eq2gain_smoothcc; + LinuxSampler::ArrayList eq3gain_smoothcc; + + LinuxSampler::ArrayList eq1freq_stepcc; + LinuxSampler::ArrayList eq2freq_stepcc; + LinuxSampler::ArrayList eq3freq_stepcc; + LinuxSampler::ArrayList eq1bw_stepcc; + LinuxSampler::ArrayList eq2bw_stepcc; + LinuxSampler::ArrayList eq3bw_stepcc; + LinuxSampler::ArrayList eq1gain_stepcc; + LinuxSampler::ArrayList eq2gain_stepcc; + LinuxSampler::ArrayList eq3gain_stepcc; + + EqSmoothStepImpl() { } + EqSmoothStepImpl(const EqSmoothStepImpl& eq) { Copy(eq); } + + void Copy(const EqSmoothStepImpl& eq); + void copySmoothValues(); + void copyStepValues(); + }; - class EG + class EG: public EqImpl { public: LinuxSampler::ArrayList node; @@ -310,7 +372,7 @@ void Copy(const EG& eg); }; - class LFO + class LFO: public EqSmoothStepImpl { public: float delay; // 0 to 100 seconds @@ -327,18 +389,24 @@ 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 freq_stepcc; 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 volume_stepcc; LinuxSampler::ArrayList pitch_oncc; LinuxSampler::ArrayList pitch_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList pitch_stepcc; LinuxSampler::ArrayList pan_oncc; // -100 to 100 % LinuxSampler::ArrayList pan_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList pan_stepcc; LinuxSampler::ArrayList cutoff_oncc; // -9600 to 9600 cents LinuxSampler::ArrayList cutoff_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList cutoff_stepcc; LinuxSampler::ArrayList resonance_oncc; // 0 to 40 dB LinuxSampler::ArrayList resonance_smoothcc; // 0 to ? milliseconds + LinuxSampler::ArrayList resonance_stepcc; // 0 to 40 dB LFO(); LFO(const LFO& lfo) { Copy(lfo); } @@ -439,7 +507,7 @@ optional delay; optional delay_random; Array > delay_oncc; optional delay_beats; optional stop_beats; optional delay_samples; Array > delay_samples_oncc; - optional end; + int end; optional loop_crossfade; optional offset; optional offset_random; Array > offset_oncc; loop_mode_t loop_mode; @@ -449,6 +517,7 @@ // amplifier float volume; + float amplitude; float pan; float width; float position; @@ -474,19 +543,19 @@ // 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; - Array cutoff_stepcc; Array cutoff2_stepcc; - Array cutoff_curvecc; Array cutoff2_curvecc; + LinuxSampler::ArrayList cutoff_oncc, cutoff2_oncc; + LinuxSampler::ArrayList cutoff_smoothcc, cutoff2_smoothcc; + LinuxSampler::ArrayList cutoff_stepcc, cutoff2_stepcc; + 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; - Array resonance_stepcc; Array resonance2_stepcc; - Array resonance_curvecc; Array resonance2_curvecc; + LinuxSampler::ArrayList resonance_oncc, resonance2_oncc; + LinuxSampler::ArrayList resonance_smoothcc, resonance2_smoothcc; + LinuxSampler::ArrayList resonance_stepcc, resonance2_stepcc; + LinuxSampler::ArrayList resonance_curvecc, resonance2_curvecc; + LinuxSampler::ArrayList pitch_oncc, pitch_stepcc; + LinuxSampler::ArrayList pitch_smoothcc, pitch_curvecc; int fil_keytrack; int fil2_keytrack; int fil_keycenter; int fil2_keycenter; int fil_veltrack; int fil2_veltrack; @@ -509,17 +578,21 @@ 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_delay_oncc; // 0 to 100 seconds LinuxSampler::ArrayList fillfo_fade_oncc; // 0 to 100 seconds @@ -539,10 +612,12 @@ 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 volume_stepcc; // 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 + LinuxSampler::ArrayList pan_stepcc; // used only as temporary buffer during the parsing - values are then moved to pan_oncc }; class Query { @@ -653,25 +728,25 @@ }; ///////////////////////////////////////////////////////////// - // class Group - - /// A Group act just as a template containing Region default values - class Group : + // class ContainerDefinition + + ///A ContainerDefinition is any section of the SFZ files that contains other Definitions (global, master, and group). + class ContainerDefinition : public Definition { public: - Group(); - virtual ~Group(); - - /// Reset Group to default values + enum section_type {GROUP = 0, MASTER, GLOBAL}; + + ContainerDefinition(section_type type); + virtual ~ContainerDefinition(); + + /// Reset all properties to default values void Reset(); - - /// Create a new Region - Region* RegionFactory(); - - // id counter - int id; - + + /// Copy all properties of this object to another Definition + void CopyValuesToDefinition(Definition* definition); + + section_type level; }; ///////////////////////////////////////////////////////////// @@ -681,8 +756,13 @@ class File { public: + static void copyCurves(LinuxSampler::ArrayList& curves, LinuxSampler::ArrayList& dest); + static void copySmoothValues(LinuxSampler::ArrayList& smooths, LinuxSampler::ArrayList& dest); + static void copyStepValues(LinuxSampler::ArrayList& steps, LinuxSampler::ArrayList& dest); + /// Load an existing SFZ file File(std::string file, SampleManager* pSampleManager = NULL); + void parseFile(std::string file, SampleManager* pSampleManager); virtual ~File(); /// Returns a pointer to the instrument object @@ -695,8 +775,6 @@ 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); @@ -707,12 +785,18 @@ Instrument* _instrument; // state variables - enum section_t { UNKNOWN, GROUP, REGION, CONTROL, CURVE }; + enum section_t { UNKNOWN, REGION, GROUP, MASTER, GLOBAL, CONTROL, CURVE }; section_t _current_section; Region* _current_region; - Group* _current_group; + std::stack _current_containers; + + static const std::string MACRO_NAME_CHARS; + static const std::string MACRO_VALUE_CHARS; + std::map _defined_macros; + Curve* _current_curve; Definition* pCurDef; + int id; // control header directives std::string default_path;