--- libgig/trunk/src/gig.h 2009/07/30 08:16:02 1953 +++ libgig/trunk/src/gig.h 2013/09/08 16:25:42 2467 @@ -2,7 +2,7 @@ * * * libgig - C++ cross-platform Gigasampler format file access library * * * - * Copyright (C) 2003-2009 by Christian Schoenebeck * + * Copyright (C) 2003-2013 by Christian Schoenebeck * * * * * * This library is free software; you can redistribute it and/or modify * @@ -31,7 +31,6 @@ # define LIST_TYPE_3EWL 0x3365776C # define LIST_TYPE_3GRI 0x33677269 # define LIST_TYPE_3GNL 0x33676E6C -# define CHUNK_ID_SMPL 0x736D706C # define CHUNK_ID_3GIX 0x33676978 # define CHUNK_ID_3EWA 0x33657761 # define CHUNK_ID_3LNK 0x336C6E6B @@ -45,7 +44,6 @@ # define LIST_TYPE_3EWL 0x6C776533 # define LIST_TYPE_3GRI 0x69726733 # define LIST_TYPE_3GNL 0x6C6E6733 -# define CHUNK_ID_SMPL 0x6C706D73 # define CHUNK_ID_3GIX 0x78696733 # define CHUNK_ID_3EWA 0x61776533 # define CHUNK_ID_3LNK 0x6B6E6C33 @@ -431,11 +429,11 @@ uint8_t DimensionUpperLimits[8]; ///< gig3: defines the upper limit of the dimension values for this dimension region // derived attributes from DLS::Sampler - DLS::Sampler::UnityNote; - DLS::Sampler::FineTune; - DLS::Sampler::Gain; - DLS::Sampler::SampleLoops; - DLS::Sampler::pSampleLoops; + using DLS::Sampler::UnityNote; + using DLS::Sampler::FineTune; + using DLS::Sampler::Gain; + using DLS::Sampler::SampleLoops; + using DLS::Sampler::pSampleLoops; // own methods double GetVelocityAttenuation(uint8_t MIDIKeyVelocity); @@ -452,11 +450,12 @@ void SetVCFVelocityScale(uint8_t scaling); Region* GetParent() const; // derived methods - DLS::Sampler::AddSampleLoop; - DLS::Sampler::DeleteSampleLoop; + using DLS::Sampler::AddSampleLoop; + using DLS::Sampler::DeleteSampleLoop; // overridden methods virtual void SetGain(int32_t gain); virtual void UpdateChunks(); + virtual void CopyAssign(const DimensionRegion* orig); protected: uint8_t* VelocityTable; ///< For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity MIDI value to dimension bit number. DimensionRegion(Region* pParent, RIFF::List* _3ewl); @@ -630,6 +629,7 @@ // overridden methods virtual void SetKeyRange(uint16_t Low, uint16_t High); virtual void UpdateChunks(); + virtual void CopyAssign(const Region* orig); protected: Region(Instrument* pInstrument, RIFF::List* rgnList); void LoadDimensionRegions(RIFF::List* rgn); @@ -643,6 +643,9 @@ class MidiRule { public: virtual ~MidiRule() { } + protected: + virtual void UpdateChunks(uint8_t* pData) const = 0; + friend class Instrument; }; /** MIDI rule for triggering notes by control change events. */ @@ -662,6 +665,78 @@ protected: MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg); + MidiRuleCtrlTrigger(); + void UpdateChunks(uint8_t* pData) const; + friend class Instrument; + }; + + /** MIDI rule for instruments with legato samples. */ + class MidiRuleLegato : public MidiRule { + public: + uint8_t LegatoSamples; ///< Number of legato samples per key in each direction (always 12) + bool BypassUseController; ///< If a controller should be used to bypass the sustain note + uint8_t BypassKey; ///< Key to be used to bypass the sustain note + uint8_t BypassController; ///< Controller to be used to bypass the sustain note + uint16_t ThresholdTime; ///< Maximum time (ms) between two notes that should be played legato + uint16_t ReleaseTime; ///< Release time + range_t KeyRange; ///< Key range for legato notes + uint8_t ReleaseTriggerKey; ///< Key triggering release samples + uint8_t AltSustain1Key; ///< Key triggering alternate sustain samples + uint8_t AltSustain2Key; ///< Key triggering a second set of alternate sustain samples + + protected: + MidiRuleLegato(RIFF::Chunk* _3ewg); + MidiRuleLegato(); + void UpdateChunks(uint8_t* pData) const; + friend class Instrument; + }; + + /** MIDI rule to automatically cycle through specified sequences of different articulations. The instrument must be using the smartmidi dimension. */ + class MidiRuleAlternator : public MidiRule { + public: + uint8_t Articulations; ///< Number of articulations in the instrument + String pArticulations[32]; ///< Names of the articulations + + range_t PlayRange; ///< Key range of the playable keys in the instrument + + uint8_t Patterns; ///< Number of alternator patterns + struct pattern_t { + String Name; ///< Name of the pattern + int Size; ///< Number of steps in the pattern + const uint8_t& operator[](int i) const { /// Articulation to play + return data[i]; + } + uint8_t& operator[](int i) { + return data[i]; + } + private: + uint8_t data[32]; + } pPatterns[32]; ///< A pattern is a sequence of articulation numbers + + typedef enum { + selector_none, + selector_key_switch, + selector_controller + } selector_t; + selector_t Selector; ///< Method by which pattern is chosen + range_t KeySwitchRange; ///< Key range for key switch selector + uint8_t Controller; ///< CC number for controller selector + + bool Polyphonic; ///< If alternator should step forward only when all notes are off + bool Chained; ///< If all patterns should be chained together + + protected: + MidiRuleAlternator(RIFF::Chunk* _3ewg); + MidiRuleAlternator(); + void UpdateChunks(uint8_t* pData) const; + friend class Instrument; + }; + + /** A MIDI rule not yet implemented by libgig. */ + class MidiRuleUnknown : public MidiRule { + protected: + MidiRuleUnknown() { } + void UpdateChunks(uint8_t* pData) const { } friend class Instrument; }; @@ -669,15 +744,15 @@ class Instrument : protected DLS::Instrument { public: // derived attributes from DLS::Resource - DLS::Resource::pInfo; - DLS::Resource::pDLSID; + using DLS::Resource::pInfo; + using DLS::Resource::pDLSID; // derived attributes from DLS::Instrument - DLS::Instrument::IsDrum; - DLS::Instrument::MIDIBank; - DLS::Instrument::MIDIBankCoarse; - DLS::Instrument::MIDIBankFine; - DLS::Instrument::MIDIProgram; - DLS::Instrument::Regions; + using DLS::Instrument::IsDrum; + using DLS::Instrument::MIDIBank; + using DLS::Instrument::MIDIBankCoarse; + using DLS::Instrument::MIDIBankFine; + using DLS::Instrument::MIDIProgram; + using DLS::Instrument::Regions; // own attributes int32_t Attenuation; ///< in dB uint16_t EffectSend; @@ -688,16 +763,21 @@ // derived methods from DLS::Resource - DLS::Resource::GetParent; + using DLS::Resource::GetParent; // overridden methods Region* GetFirstRegion(); Region* GetNextRegion(); Region* AddRegion(); void DeleteRegion(Region* pRegion); virtual void UpdateChunks(); + virtual void CopyAssign(const Instrument* orig); // own methods Region* GetRegion(unsigned int Key); MidiRule* GetMidiRule(int i); + MidiRuleCtrlTrigger* AddMidiRuleCtrlTrigger(); + MidiRuleLegato* AddMidiRuleLegato(); + MidiRuleAlternator* AddMidiRuleAlternator(); + void DeleteMidiRule(int i); protected: Region* RegionKeyTable[128]; ///< fast lookup for the corresponding Region of a MIDI key @@ -740,7 +820,7 @@ friend class File; private: File* pFile; - RIFF::Chunk* pNameChunk; + RIFF::Chunk* pNameChunk; ///< '3gnm' chunk }; /** Parses Gigasampler files and provides abstract access to the data. */ @@ -750,16 +830,17 @@ static const DLS::version_t VERSION_3; // derived attributes from DLS::Resource - DLS::Resource::pInfo; - DLS::Resource::pDLSID; + using DLS::Resource::pInfo; + using DLS::Resource::pDLSID; // derived attributes from DLS::File - DLS::File::pVersion; - DLS::File::Instruments; + using DLS::File::pVersion; + using DLS::File::Instruments; // derived methods from DLS::Resource - DLS::Resource::GetParent; + using DLS::Resource::GetParent; // derived methods from DLS::File - DLS::File::Save; + using DLS::File::Save; + using DLS::File::GetFileName; // overridden methods File(); File(RIFF::File* pRIFF); @@ -771,6 +852,7 @@ 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); 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.