--- libgig/trunk/src/gig.h 2017/05/10 21:17:10 3169 +++ libgig/trunk/src/gig.h 2017/07/20 22:09:54 3323 @@ -39,6 +39,8 @@ #endif #if HAVE_RTTI # include +#else +# warning No RTTI available! #endif #if WORDS_BIGENDIAN @@ -59,6 +61,7 @@ # define CHUNK_ID_SCRI 0x53637269 // own gig format extension # define CHUNK_ID_LSNM 0x4c534e4d // own gig format extension # define CHUNK_ID_SCSL 0x5343534c // own gig format extension +# define CHUNK_ID_LSDE 0x4c534445 // own gig format extension #else // little endian # define LIST_TYPE_3PRG 0x67727033 # define LIST_TYPE_3EWL 0x6C776533 @@ -77,6 +80,7 @@ # define CHUNK_ID_SCRI 0x69726353 // own gig format extension # define CHUNK_ID_LSNM 0x4d4e534c // own gig format extension # define CHUNK_ID_SCSL 0x4c534353 // own gig format extension +# define CHUNK_ID_LSDE 0x4544534c // own gig format extension #endif // WORDS_BIGENDIAN #ifndef GIG_DECLARE_ENUM @@ -113,7 +117,7 @@ /** Standard types of sample loops. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(loop_type_t, loop_type_normal = 0x00000000, ///< Loop forward (normal) @@ -123,7 +127,7 @@ /** Society of Motion Pictures and Television E time format. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(smpte_format_t, smpte_format_no_offset = 0x00000000, ///< no SMPTE offset @@ -135,7 +139,7 @@ /** Defines the shape of a function graph. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(curve_type_t, curve_type_nonlinear = 0, @@ -146,7 +150,7 @@ /** Dimensions allow to bypass one of the following controllers. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(dim_bypass_ctrl_t, dim_bypass_ctrl_none, @@ -156,7 +160,7 @@ /** Defines how LFO3 is controlled by. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo3_ctrl_t, lfo3_ctrl_internal = 0x00, ///< Only internally controlled. @@ -168,7 +172,7 @@ /** Defines how LFO2 is controlled by. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo2_ctrl_t, lfo2_ctrl_internal = 0x00, ///< Only internally controlled. @@ -180,7 +184,7 @@ /** Defines how LFO1 is controlled by. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo1_ctrl_t, lfo1_ctrl_internal = 0x00, ///< Only internally controlled. @@ -192,7 +196,7 @@ /** Defines how the filter cutoff frequency is controlled by. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_cutoff_ctrl_t, vcf_cutoff_ctrl_none = 0x00, @@ -211,7 +215,7 @@ /** Defines how the filter resonance is controlled by. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_res_ctrl_t, vcf_res_ctrl_none = 0xffffffff, @@ -232,7 +236,7 @@ struct leverage_ctrl_t { /** Defines possible controllers. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(type_t, type_none = 0x00, ///< No controller defined @@ -275,7 +279,7 @@ * to 32 zones (except the layer dimension with only up to 8 zones and * the samplechannel dimension which currently allows only 2 zones). * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(dimension_t, dimension_none = 0x00, ///< Dimension not in use. @@ -318,7 +322,7 @@ * Intended for internal usage: will be used to convert a dimension value * into the corresponding dimension bit number. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(split_type_t, split_type_normal, ///< dimension value between 0-127 @@ -336,7 +340,7 @@ /** Defines which frequencies are filtered by the VCF. * - * @see countEnum(), enumKey(), enumKeys(), enumValue() + * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_type_t, vcf_type_lowpass = 0x00, @@ -376,6 +380,39 @@ file_offset_t loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. }; + /** + * Defines behavior options for envelope generators. + * + * These options allow to override the precise default behavior of the + * envelope generators' state machines. + * + * @b Note: These EG options are an extension to the original gig file + * format, so these options are not available with the original + * Gigasampler/GigaStudio software! Currently only LinuxSampler and gigedit + * support these EG options! + * + * Adding these options to the original gig file format was necessary, + * because the precise state machine behavior of envelope generators of the + * gig format (and thus the default EG behavior if not explicitly overridden + * here) deviates from common, expected behavior of envelope generators in + * general, if i.e. compared with EGs of hardware synthesizers. For example + * with the gig format, the attack and decay stages will be aborted as soon + * as a note-off is received. Most other EG implementations in the industry + * however always run the attack and decay stages to their full duration, + * even if an early note-off arrives. The latter behavior is intentionally + * implemented in most other products, because it is required to resemble + * percussive sounds in a realistic manner. + */ + struct eg_opt_t { + bool AttackCancel; ///< Whether the "attack" stage is cancelled when receiving a note-off (default: @c true). + bool AttackHoldCancel; ///< Whether the "attack hold" stage is cancelled when receiving a note-off (default: @c true). + bool DecayCancel; ///< Whether the "decay" stage is cancelled when receiving a note-off (default: @c true). + bool ReleaseCancel; ///< Whether the "release" stage is cancelled when receiving a note-on (default: @c true). + + eg_opt_t(); + void serialize(Serialization::Archive* archive); + }; + // just symbol prototyping class File; class Instrument; @@ -514,6 +551,7 @@ uint16_t SampleStartOffset; ///< Number of samples the sample start should be moved (0 - 2000). double SampleAttenuation; ///< Sample volume (calculated from DLS::Sampler::Gain) uint8_t DimensionUpperLimits[8]; ///< gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered why this is defined on DimensionRegion level and not on Region level: the zone sizes (upper limits) of the velocity dimension can indeed differ in the individual dimension regions, depending on which zones of the other dimension types are currently selected. So this is exceptional for the velocity dimension only. All other dimension types have the same dimension zone sizes for every single DimensionRegion (of the sample Region). + eg_opt_t EGOptions; ///< [gig extension]: Behavior options which should be used for all 3 envelope generators. // derived attributes from DLS::Sampler using DLS::Sampler::UnityNote; @@ -1363,21 +1401,24 @@ */ class Exception : public DLS::Exception { public: - Exception(String Message); + Exception(String format, ...); + Exception(String format, va_list arg); void PrintMessage(); + protected: + Exception(); }; #if HAVE_RTTI - size_t countEnum(const std::type_info& type); - size_t countEnum(String typeName); + size_t enumCount(const std::type_info& type); const char* enumKey(const std::type_info& type, size_t value); - const char* enumKey(String typeName, size_t value); bool enumKey(const std::type_info& type, String key); - bool enumKey(String typeName, String key); const char** enumKeys(const std::type_info& type); +#endif // HAVE_RTTI + size_t enumCount(String typeName); + const char* enumKey(String typeName, size_t value); + bool enumKey(String typeName, String key); const char** enumKeys(String typeName); size_t enumValue(String key); -#endif // HAVE_RTTI String libraryName(); String libraryVersion();