--- libgig/trunk/src/gig.h 2017/05/21 12:46:05 3198 +++ libgig/trunk/src/gig.h 2018/12/23 21:47:26 3446 @@ -2,7 +2,7 @@ * * * libgig - C++ cross-platform Gigasampler format file access library * * * - * Copyright (C) 2003-2017 by Christian Schoenebeck * + * Copyright (C) 2003-2018 by Christian Schoenebeck * * * * * * This library is free software; you can redistribute it and/or modify * @@ -61,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 @@ -79,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 @@ -118,9 +120,9 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(loop_type_t, - loop_type_normal = 0x00000000, ///< Loop forward (normal) - loop_type_bidirectional = 0x00000001, ///< Alternating loop (forward/backward, also known as Ping Pong) - loop_type_backward = 0x00000002 ///< Loop backward (reverse) + loop_type_normal = 0x00000000, /**< Loop forward (normal) */ + loop_type_bidirectional = 0x00000001, /**< Alternating loop (forward/backward, also known as Ping Pong) */ + loop_type_backward = 0x00000002 /**< Loop backward (reverse) */ ); /** Society of Motion Pictures and Television E time format. @@ -128,11 +130,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(smpte_format_t, - smpte_format_no_offset = 0x00000000, ///< no SMPTE offset - smpte_format_24_frames = 0x00000018, ///< 24 frames per second - smpte_format_25_frames = 0x00000019, ///< 25 frames per second - smpte_format_30_frames_dropping = 0x0000001D, ///< 30 frames per second with frame dropping (30 drop) - smpte_format_30_frames = 0x0000001E ///< 30 frames per second + smpte_format_no_offset = 0x00000000, /**< no SMPTE offset */ + smpte_format_24_frames = 0x00000018, /**< 24 frames per second */ + smpte_format_25_frames = 0x00000019, /**< 25 frames per second */ + smpte_format_30_frames_dropping = 0x0000001D, /**< 30 frames per second with frame dropping (30 drop) */ + smpte_format_30_frames = 0x0000001E /**< 30 frames per second */ ); /** Defines the shape of a function graph. @@ -140,10 +142,10 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(curve_type_t, - curve_type_nonlinear = 0, - curve_type_linear = 1, - curve_type_special = 2, - curve_type_unknown = 0xffffffff + curve_type_nonlinear = 0, /**< Non-linear curve type. */ + curve_type_linear = 1, /**< Linear curve type. */ + curve_type_special = 2, /**< Special curve type. */ + curve_type_unknown = 0xffffffff /**< Unknown curve type. */ ); /** Dimensions allow to bypass one of the following controllers. @@ -151,9 +153,9 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(dim_bypass_ctrl_t, - dim_bypass_ctrl_none, - dim_bypass_ctrl_94, ///< Effect 4 Depth (MIDI Controller 94) - dim_bypass_ctrl_95 ///< Effect 5 Depth (MIDI Controller 95) + dim_bypass_ctrl_none, /**< No controller bypass. */ + dim_bypass_ctrl_94, /**< Effect 4 Depth (MIDI Controller 94) */ + dim_bypass_ctrl_95 /**< Effect 5 Depth (MIDI Controller 95) */ ); /** Defines how LFO3 is controlled by. @@ -161,11 +163,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo3_ctrl_t, - lfo3_ctrl_internal = 0x00, ///< Only internally controlled. - lfo3_ctrl_modwheel = 0x01, ///< Only controlled by external modulation wheel. - lfo3_ctrl_aftertouch = 0x02, ///< Only controlled by aftertouch controller. - lfo3_ctrl_internal_modwheel = 0x03, ///< Controlled internally and by external modulation wheel. - lfo3_ctrl_internal_aftertouch = 0x04 ///< Controlled internally and by aftertouch controller. + lfo3_ctrl_internal = 0x00, /**< Only internally controlled. */ + lfo3_ctrl_modwheel = 0x01, /**< Only controlled by external modulation wheel. */ + lfo3_ctrl_aftertouch = 0x02, /**< Only controlled by aftertouch controller. */ + lfo3_ctrl_internal_modwheel = 0x03, /**< Controlled internally and by external modulation wheel. */ + lfo3_ctrl_internal_aftertouch = 0x04 /**< Controlled internally and by aftertouch controller. */ ); /** Defines how LFO2 is controlled by. @@ -173,11 +175,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo2_ctrl_t, - lfo2_ctrl_internal = 0x00, ///< Only internally controlled. - lfo2_ctrl_modwheel = 0x01, ///< Only controlled by external modulation wheel. - lfo2_ctrl_foot = 0x02, ///< Only controlled by external foot controller. - lfo2_ctrl_internal_modwheel = 0x03, ///< Controlled internally and by external modulation wheel. - lfo2_ctrl_internal_foot = 0x04 ///< Controlled internally and by external foot controller. + lfo2_ctrl_internal = 0x00, /**< Only internally controlled. */ + lfo2_ctrl_modwheel = 0x01, /**< Only controlled by external modulation wheel. */ + lfo2_ctrl_foot = 0x02, /**< Only controlled by external foot controller. */ + lfo2_ctrl_internal_modwheel = 0x03, /**< Controlled internally and by external modulation wheel. */ + lfo2_ctrl_internal_foot = 0x04 /**< Controlled internally and by external foot controller. */ ); /** Defines how LFO1 is controlled by. @@ -185,11 +187,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(lfo1_ctrl_t, - lfo1_ctrl_internal = 0x00, ///< Only internally controlled. - lfo1_ctrl_modwheel = 0x01, ///< Only controlled by external modulation wheel. - lfo1_ctrl_breath = 0x02, ///< Only controlled by external breath controller. - lfo1_ctrl_internal_modwheel = 0x03, ///< Controlled internally and by external modulation wheel. - lfo1_ctrl_internal_breath = 0x04 ///< Controlled internally and by external breath controller. + lfo1_ctrl_internal = 0x00, /**< Only internally controlled. */ + lfo1_ctrl_modwheel = 0x01, /**< Only controlled by external modulation wheel. */ + lfo1_ctrl_breath = 0x02, /**< Only controlled by external breath controller. */ + lfo1_ctrl_internal_modwheel = 0x03, /**< Controlled internally and by external modulation wheel. */ + lfo1_ctrl_internal_breath = 0x04 /**< Controlled internally and by external breath controller. */ ); /** Defines how the filter cutoff frequency is controlled by. @@ -197,18 +199,18 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_cutoff_ctrl_t, - vcf_cutoff_ctrl_none = 0x00, - vcf_cutoff_ctrl_none2 = 0x01, ///< The difference between none and none2 is unknown - vcf_cutoff_ctrl_modwheel = 0x81, ///< Modulation Wheel (MIDI Controller 1) - vcf_cutoff_ctrl_effect1 = 0x8c, ///< Effect Controller 1 (Coarse, MIDI Controller 12) - vcf_cutoff_ctrl_effect2 = 0x8d, ///< Effect Controller 2 (Coarse, MIDI Controller 13) - vcf_cutoff_ctrl_breath = 0x82, ///< Breath Controller (Coarse, MIDI Controller 2) - vcf_cutoff_ctrl_foot = 0x84, ///< Foot Pedal (Coarse, MIDI Controller 4) - vcf_cutoff_ctrl_sustainpedal = 0xc0, ///< Sustain Pedal (MIDI Controller 64) - vcf_cutoff_ctrl_softpedal = 0xc3, ///< Soft Pedal (MIDI Controller 67) - vcf_cutoff_ctrl_genpurpose7 = 0xd2, ///< General Purpose Controller 7 (Button, MIDI Controller 82) - vcf_cutoff_ctrl_genpurpose8 = 0xd3, ///< General Purpose Controller 8 (Button, MIDI Controller 83) - vcf_cutoff_ctrl_aftertouch = 0x80 ///< Key Pressure + vcf_cutoff_ctrl_none = 0x00, /**< No MIDI controller assigned for filter cutoff frequency. */ + vcf_cutoff_ctrl_none2 = 0x01, /**< The difference between none and none2 is unknown */ + vcf_cutoff_ctrl_modwheel = 0x81, /**< Modulation Wheel (MIDI Controller 1) */ + vcf_cutoff_ctrl_effect1 = 0x8c, /**< Effect Controller 1 (Coarse, MIDI Controller 12) */ + vcf_cutoff_ctrl_effect2 = 0x8d, /**< Effect Controller 2 (Coarse, MIDI Controller 13) */ + vcf_cutoff_ctrl_breath = 0x82, /**< Breath Controller (Coarse, MIDI Controller 2) */ + vcf_cutoff_ctrl_foot = 0x84, /**< Foot Pedal (Coarse, MIDI Controller 4) */ + vcf_cutoff_ctrl_sustainpedal = 0xc0, /**< Sustain Pedal (MIDI Controller 64) */ + vcf_cutoff_ctrl_softpedal = 0xc3, /**< Soft Pedal (MIDI Controller 67) */ + vcf_cutoff_ctrl_genpurpose7 = 0xd2, /**< General Purpose Controller 7 (Button, MIDI Controller 82) */ + vcf_cutoff_ctrl_genpurpose8 = 0xd3, /**< General Purpose Controller 8 (Button, MIDI Controller 83) */ + vcf_cutoff_ctrl_aftertouch = 0x80 /**< Key Pressure */ ); /** Defines how the filter resonance is controlled by. @@ -216,11 +218,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_res_ctrl_t, - vcf_res_ctrl_none = 0xffffffff, - vcf_res_ctrl_genpurpose3 = 0, ///< General Purpose Controller 3 (Slider, MIDI Controller 18) - vcf_res_ctrl_genpurpose4 = 1, ///< General Purpose Controller 4 (Slider, MIDI Controller 19) - vcf_res_ctrl_genpurpose5 = 2, ///< General Purpose Controller 5 (Button, MIDI Controller 80) - vcf_res_ctrl_genpurpose6 = 3 ///< General Purpose Controller 6 (Button, MIDI Controller 81) + vcf_res_ctrl_none = 0xffffffff, /**< No MIDI controller assigned for filter resonance. */ + vcf_res_ctrl_genpurpose3 = 0, /**< General Purpose Controller 3 (Slider, MIDI Controller 18) */ + vcf_res_ctrl_genpurpose4 = 1, /**< General Purpose Controller 4 (Slider, MIDI Controller 19) */ + vcf_res_ctrl_genpurpose5 = 2, /**< General Purpose Controller 5 (Button, MIDI Controller 80) */ + vcf_res_ctrl_genpurpose6 = 3 /**< General Purpose Controller 6 (Button, MIDI Controller 81) */ ); /** @@ -237,10 +239,10 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(type_t, - type_none = 0x00, ///< No controller defined - type_channelaftertouch = 0x2f, ///< Channel Key Pressure - type_velocity = 0xff, ///< Key Velocity - type_controlchange = 0xfe ///< Ordinary MIDI control change controller, see field 'controller_number' + type_none = 0x00, /**< No controller defined */ + type_channelaftertouch = 0x2f, /**< Channel Key Pressure */ + type_velocity = 0xff, /**< Key Velocity */ + type_controlchange = 0xfe /**< Ordinary MIDI control change controller, see field 'controller_number' */ ); type_t type; ///< Controller type @@ -280,40 +282,40 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(dimension_t, - dimension_none = 0x00, ///< Dimension not in use. - dimension_samplechannel = 0x80, ///< If used sample has more than one channel (thus is not mono). - dimension_layer = 0x81, ///< For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers). - dimension_velocity = 0x82, ///< Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined). - dimension_channelaftertouch = 0x83, ///< Channel Key Pressure - dimension_releasetrigger = 0x84, ///< Special dimension for triggering samples on releasing a key. - dimension_keyboard = 0x85, ///< Dimension for keyswitching - dimension_roundrobin = 0x86, ///< Different samples triggered each time a note is played, dimension regions selected in sequence - dimension_random = 0x87, ///< Different samples triggered each time a note is played, random order - dimension_smartmidi = 0x88, ///< For MIDI tools like legato and repetition mode - dimension_roundrobinkeyboard = 0x89, ///< Different samples triggered each time a note is played, any key advances the counter - dimension_modwheel = 0x01, ///< Modulation Wheel (MIDI Controller 1) - dimension_breath = 0x02, ///< Breath Controller (Coarse, MIDI Controller 2) - dimension_foot = 0x04, ///< Foot Pedal (Coarse, MIDI Controller 4) - dimension_portamentotime = 0x05, ///< Portamento Time (Coarse, MIDI Controller 5) - dimension_effect1 = 0x0c, ///< Effect Controller 1 (Coarse, MIDI Controller 12) - dimension_effect2 = 0x0d, ///< Effect Controller 2 (Coarse, MIDI Controller 13) - dimension_genpurpose1 = 0x10, ///< General Purpose Controller 1 (Slider, MIDI Controller 16) - dimension_genpurpose2 = 0x11, ///< General Purpose Controller 2 (Slider, MIDI Controller 17) - dimension_genpurpose3 = 0x12, ///< General Purpose Controller 3 (Slider, MIDI Controller 18) - dimension_genpurpose4 = 0x13, ///< General Purpose Controller 4 (Slider, MIDI Controller 19) - dimension_sustainpedal = 0x40, ///< Sustain Pedal (MIDI Controller 64) - dimension_portamento = 0x41, ///< Portamento (MIDI Controller 65) - dimension_sostenutopedal = 0x42, ///< Sostenuto Pedal (MIDI Controller 66) - dimension_softpedal = 0x43, ///< Soft Pedal (MIDI Controller 67) - dimension_genpurpose5 = 0x30, ///< General Purpose Controller 5 (Button, MIDI Controller 80) - dimension_genpurpose6 = 0x31, ///< General Purpose Controller 6 (Button, MIDI Controller 81) - dimension_genpurpose7 = 0x32, ///< General Purpose Controller 7 (Button, MIDI Controller 82) - dimension_genpurpose8 = 0x33, ///< General Purpose Controller 8 (Button, MIDI Controller 83) - dimension_effect1depth = 0x5b, ///< Effect 1 Depth (MIDI Controller 91) - dimension_effect2depth = 0x5c, ///< Effect 2 Depth (MIDI Controller 92) - dimension_effect3depth = 0x5d, ///< Effect 3 Depth (MIDI Controller 93) - dimension_effect4depth = 0x5e, ///< Effect 4 Depth (MIDI Controller 94) - dimension_effect5depth = 0x5f ///< Effect 5 Depth (MIDI Controller 95) + dimension_none = 0x00, /**< Dimension not in use. */ + dimension_samplechannel = 0x80, /**< If used sample has more than one channel (thus is not mono). */ + dimension_layer = 0x81, /**< For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers). */ + dimension_velocity = 0x82, /**< Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined). */ + dimension_channelaftertouch = 0x83, /**< Channel Key Pressure */ + dimension_releasetrigger = 0x84, /**< Special dimension for triggering samples on releasing a key. */ + dimension_keyboard = 0x85, /**< Dimension for keyswitching */ + dimension_roundrobin = 0x86, /**< Different samples triggered each time a note is played, dimension regions selected in sequence */ + dimension_random = 0x87, /**< Different samples triggered each time a note is played, random order */ + dimension_smartmidi = 0x88, /**< For MIDI tools like legato and repetition mode */ + dimension_roundrobinkeyboard = 0x89, /**< Different samples triggered each time a note is played, any key advances the counter */ + dimension_modwheel = 0x01, /**< Modulation Wheel (MIDI Controller 1) */ + dimension_breath = 0x02, /**< Breath Controller (Coarse, MIDI Controller 2) */ + dimension_foot = 0x04, /**< Foot Pedal (Coarse, MIDI Controller 4) */ + dimension_portamentotime = 0x05, /**< Portamento Time (Coarse, MIDI Controller 5) */ + dimension_effect1 = 0x0c, /**< Effect Controller 1 (Coarse, MIDI Controller 12) */ + dimension_effect2 = 0x0d, /**< Effect Controller 2 (Coarse, MIDI Controller 13) */ + dimension_genpurpose1 = 0x10, /**< General Purpose Controller 1 (Slider, MIDI Controller 16) */ + dimension_genpurpose2 = 0x11, /**< General Purpose Controller 2 (Slider, MIDI Controller 17) */ + dimension_genpurpose3 = 0x12, /**< General Purpose Controller 3 (Slider, MIDI Controller 18) */ + dimension_genpurpose4 = 0x13, /**< General Purpose Controller 4 (Slider, MIDI Controller 19) */ + dimension_sustainpedal = 0x40, /**< Sustain Pedal (MIDI Controller 64) */ + dimension_portamento = 0x41, /**< Portamento (MIDI Controller 65) */ + dimension_sostenutopedal = 0x42, /**< Sostenuto Pedal (MIDI Controller 66) */ + dimension_softpedal = 0x43, /**< Soft Pedal (MIDI Controller 67) */ + dimension_genpurpose5 = 0x30, /**< General Purpose Controller 5 (Button, MIDI Controller 80) */ + dimension_genpurpose6 = 0x31, /**< General Purpose Controller 6 (Button, MIDI Controller 81) */ + dimension_genpurpose7 = 0x32, /**< General Purpose Controller 7 (Button, MIDI Controller 82) */ + dimension_genpurpose8 = 0x33, /**< General Purpose Controller 8 (Button, MIDI Controller 83) */ + dimension_effect1depth = 0x5b, /**< Effect 1 Depth (MIDI Controller 91) */ + dimension_effect2depth = 0x5c, /**< Effect 2 Depth (MIDI Controller 92) */ + dimension_effect3depth = 0x5d, /**< Effect 3 Depth (MIDI Controller 93) */ + dimension_effect4depth = 0x5e, /**< Effect 4 Depth (MIDI Controller 94) */ + dimension_effect5depth = 0x5f /**< Effect 5 Depth (MIDI Controller 95) */ ); /** @@ -323,8 +325,8 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(split_type_t, - split_type_normal, ///< dimension value between 0-127 - split_type_bit ///< dimension values are already the sought bit number + split_type_normal, /**< dimension value between 0-127 */ + split_type_bit /**< dimension values are already the sought bit number */ ); /** General dimension definition. */ @@ -341,11 +343,11 @@ * @see enumCount(), enumKey(), enumKeys(), enumValue() */ GIG_DECLARE_ENUM(vcf_type_t, - vcf_type_lowpass = 0x00, - vcf_type_lowpassturbo = 0xff, ///< More poles than normal lowpass - vcf_type_bandpass = 0x01, - vcf_type_highpass = 0x02, - vcf_type_bandreject = 0x03 + vcf_type_lowpass = 0x00, /**< Standard lowpass filter type. */ + vcf_type_lowpassturbo = 0xff, /**< More poles than normal lowpass. */ + vcf_type_bandpass = 0x01, /**< Bandpass filter type. */ + vcf_type_highpass = 0x02, /**< Highpass filter type. */ + vcf_type_bandreject = 0x03 /**< Band reject filter type. */ ); /** @@ -378,6 +380,62 @@ 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 (gig format extension). + * + * 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 Decay1Cancel; ///< Whether the "decay 1" stage is cancelled when receiving a note-off (default: @c true). + bool Decay2Cancel; ///< Whether the "decay 2" 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); + }; + + /** @brief Defines behaviour of release triggered sample(s) on sustain pedal up event. + * + * This option defines whether a sustain pedal up event (CC#64) would cause + * release triggered samples to be played (if any). + * + * @b Note: This option is an extension to the original gig file format, + * so this option is not available with the original Gigasampler/GigaStudio + * software! Currently only LinuxSampler and gigedit support this option! + * + * By default (which equals the original Gigasampler/GigaStudio behaviour) + * no release triggered samples are played if the sustain pedal is released. + * So usually in the gig format release triggered samples are only played + * on MIDI note-off events. + * + * @see enumCount(), enumKey(), enumKeys(), enumValue() + */ + GIG_DECLARE_ENUM(sust_rel_trg_t, + sust_rel_trg_none = 0x00, /**< No release triggered sample(s) are played on sustain pedal up (default). */ + sust_rel_trg_maxvelocity = 0x01, /**< Play release trigger sample(s) on sustain pedal up, and simply use 127 as MIDI velocity for playback. */ + sust_rel_trg_keyvelocity = 0x02 /**< Play release trigger sample(s) on sustain pedal up, and use the key's last MIDI note-on velocity for playback. */ + ); + // just symbol prototyping class File; class Instrument; @@ -516,6 +574,10 @@ 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 EG1Options; ///< [gig extension]: Behavior options which should be used for envelope generator 1 (volume amplitude EG). + eg_opt_t EG2Options; ///< [gig extension]: Behavior options which should be used for envelope generator 2 (filter cutoff EG). + sust_rel_trg_t SustainReleaseTrigger; ///< [gig extension]: Whether a sustain pedal up event shall play release trigger sample. + bool NoNoteOffReleaseTrigger; ///< [gig extension]: If @c true then don't play a release trigger sample on MIDI note-off events. // derived attributes from DLS::Sampler using DLS::Sampler::UnityNote; @@ -1283,6 +1345,7 @@ public: static const DLS::version_t VERSION_2; static const DLS::version_t VERSION_3; + static const DLS::version_t VERSION_4; // derived attributes from DLS::Resource using DLS::Resource::pInfo; @@ -1304,12 +1367,14 @@ Sample* GetNextSample(); ///< Returns a pointer to the next Sample object of the file, NULL otherwise. Sample* GetSample(uint index); Sample* AddSample(); + size_t CountSamples(); void DeleteSample(Sample* pSample); Instrument* GetFirstInstrument(); ///< Returns a pointer to the first Instrument object of the file, NULL otherwise. Instrument* GetNextInstrument(); ///< Returns a pointer to the next Instrument object of the file, NULL otherwise. Instrument* GetInstrument(uint index, progress_t* pProgress = NULL); Instrument* AddInstrument(); Instrument* AddDuplicateInstrument(const Instrument* orig); + size_t CountInstruments(); void DeleteInstrument(Instrument* pInstrument); Group* GetFirstGroup(); ///< Returns a pointer to the first Group object of the file, NULL otherwise. Group* GetNextGroup(); ///< Returns a pointer to the next Group object of the file, NULL otherwise.