2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file access library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2014 by Christian Schoenebeck * |
* Copyright (C) 2003-2015 by Christian Schoenebeck * |
6 |
* <cuse@users.sourceforge.net> * |
* <cuse@users.sourceforge.net> * |
7 |
* * |
* * |
8 |
* This library is free software; you can redistribute it and/or modify * |
* This library is free software; you can redistribute it and/or modify * |
25 |
#define __GIG_H__ |
#define __GIG_H__ |
26 |
|
|
27 |
#include "DLS.h" |
#include "DLS.h" |
28 |
|
#include <vector> |
29 |
|
|
30 |
#if WORDS_BIGENDIAN |
#if WORDS_BIGENDIAN |
31 |
# define LIST_TYPE_3PRG 0x33707267 |
# define LIST_TYPE_3PRG 0x33707267 |
32 |
# define LIST_TYPE_3EWL 0x3365776C |
# define LIST_TYPE_3EWL 0x3365776C |
33 |
# define LIST_TYPE_3GRI 0x33677269 |
# define LIST_TYPE_3GRI 0x33677269 |
34 |
# define LIST_TYPE_3GNL 0x33676E6C |
# define LIST_TYPE_3GNL 0x33676E6C |
35 |
|
# define LIST_TYPE_3LS 0x334c5320 // own gig format extension |
36 |
|
# define LIST_TYPE_RTIS 0x52544953 // own gig format extension |
37 |
# define CHUNK_ID_3GIX 0x33676978 |
# define CHUNK_ID_3GIX 0x33676978 |
38 |
# define CHUNK_ID_3EWA 0x33657761 |
# define CHUNK_ID_3EWA 0x33657761 |
39 |
# define CHUNK_ID_3LNK 0x336C6E6B |
# define CHUNK_ID_3LNK 0x336C6E6B |
42 |
# define CHUNK_ID_3GNM 0x33676E6D |
# define CHUNK_ID_3GNM 0x33676E6D |
43 |
# define CHUNK_ID_EINF 0x65696E66 |
# define CHUNK_ID_EINF 0x65696E66 |
44 |
# define CHUNK_ID_3CRC 0x33637263 |
# define CHUNK_ID_3CRC 0x33637263 |
45 |
|
# define CHUNK_ID_SCRI 0x53637269 // own gig format extension |
46 |
|
# define CHUNK_ID_LSNM 0x4c534e4d // own gig format extension |
47 |
|
# define CHUNK_ID_SCSL 0x5343534c // own gig format extension |
48 |
#else // little endian |
#else // little endian |
49 |
# define LIST_TYPE_3PRG 0x67727033 |
# define LIST_TYPE_3PRG 0x67727033 |
50 |
# define LIST_TYPE_3EWL 0x6C776533 |
# define LIST_TYPE_3EWL 0x6C776533 |
51 |
# define LIST_TYPE_3GRI 0x69726733 |
# define LIST_TYPE_3GRI 0x69726733 |
52 |
# define LIST_TYPE_3GNL 0x6C6E6733 |
# define LIST_TYPE_3GNL 0x6C6E6733 |
53 |
|
# define LIST_TYPE_3LS 0x20534c33 // own gig format extension |
54 |
|
# define LIST_TYPE_RTIS 0x53495452 // own gig format extension |
55 |
# define CHUNK_ID_3GIX 0x78696733 |
# define CHUNK_ID_3GIX 0x78696733 |
56 |
# define CHUNK_ID_3EWA 0x61776533 |
# define CHUNK_ID_3EWA 0x61776533 |
57 |
# define CHUNK_ID_3LNK 0x6B6E6C33 |
# define CHUNK_ID_3LNK 0x6B6E6C33 |
60 |
# define CHUNK_ID_3GNM 0x6D6E6733 |
# define CHUNK_ID_3GNM 0x6D6E6733 |
61 |
# define CHUNK_ID_EINF 0x666E6965 |
# define CHUNK_ID_EINF 0x666E6965 |
62 |
# define CHUNK_ID_3CRC 0x63726333 |
# define CHUNK_ID_3CRC 0x63726333 |
63 |
|
# define CHUNK_ID_SCRI 0x69726353 // own gig format extension |
64 |
|
# define CHUNK_ID_LSNM 0x4d4e534c // own gig format extension |
65 |
|
# define CHUNK_ID_SCSL 0x4c534353 // own gig format extension |
66 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
67 |
|
|
68 |
/** Gigasampler specific classes and definitions */ |
/** Gigasampler/GigaStudio specific classes and definitions */ |
69 |
namespace gig { |
namespace gig { |
70 |
|
|
71 |
typedef std::string String; |
typedef std::string String; |
72 |
|
typedef RIFF::progress_t progress_t; |
73 |
|
|
74 |
/** Lower and upper limit of a range. */ |
/** Lower and upper limit of a range. */ |
75 |
struct range_t { |
struct range_t { |
312 |
unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
313 |
}; |
}; |
314 |
|
|
|
/** |
|
|
* @brief Used for indicating the progress of a certain task. |
|
|
* |
|
|
* The function pointer argument has to be supplied with a valid |
|
|
* function of the given signature which will then be called on |
|
|
* progress changes. An equivalent progress_t structure will be passed |
|
|
* back as argument to the callback function on each progress change. |
|
|
* The factor field of the supplied progress_t structure will then |
|
|
* reflect the current progress as value between 0.0 and 1.0. You might |
|
|
* want to use the custom field for data needed in your callback |
|
|
* function. |
|
|
*/ |
|
|
struct progress_t { |
|
|
void (*callback)(progress_t*); ///< Callback function pointer which has to be assigned to a function for progress notification. |
|
|
float factor; ///< Reflects current progress as value between 0.0 and 1.0. |
|
|
void* custom; ///< This pointer can be used for arbitrary data. |
|
|
float __range_min; ///< Only for internal usage, do not modify! |
|
|
float __range_max; ///< Only for internal usage, do not modify! |
|
|
progress_t(); |
|
|
}; |
|
|
|
|
315 |
// just symbol prototyping |
// just symbol prototyping |
316 |
class File; |
class File; |
317 |
class Instrument; |
class Instrument; |
318 |
class Sample; |
class Sample; |
319 |
class Region; |
class Region; |
320 |
class Group; |
class Group; |
321 |
|
class Script; |
322 |
|
class ScriptGroup; |
323 |
|
|
324 |
/** @brief Encapsulates articulation information of a dimension region. |
/** @brief Encapsulates articulation informations of a dimension region. |
325 |
|
* |
326 |
|
* This is the most important data object of the Gigasampler / GigaStudio |
327 |
|
* format. A DimensionRegion provides the link to the sample to be played |
328 |
|
* and all required articulation informations to be interpreted for playing |
329 |
|
* back the sample and processing it appropriately by the sampler software. |
330 |
|
* Every Region of a Gigasampler Instrument has at least one dimension |
331 |
|
* region (exactly then when the Region has no dimension defined). Many |
332 |
|
* Regions though provide more than one DimensionRegion, which reflect |
333 |
|
* different playing "cases". For example a different sample might be played |
334 |
|
* if a certain pedal is pressed down, or if the note was triggered with |
335 |
|
* different velocity. |
336 |
* |
* |
337 |
* Every Gigasampler Instrument has at least one dimension region |
* One instance of a DimensionRegion reflects exactly one particular case |
338 |
* (exactly then when it has no dimension defined). |
* while playing an instrument (for instance "note between C3 and E3 was |
339 |
|
* triggered AND note on velocity was between 20 and 42 AND modulation wheel |
340 |
|
* controller is between 80 and 127). The DimensionRegion defines what to do |
341 |
|
* under that one particular case, that is which sample to play back and how |
342 |
|
* to play that sample back exactly and how to process it. So a |
343 |
|
* DimensionRegion object is always linked to exactly one sample. It may |
344 |
|
* however also link to no sample at all, for defining a "silence" case |
345 |
|
* where nothing shall be played (for example when note on velocity was |
346 |
|
* below 6). |
347 |
* |
* |
348 |
* Gigasampler provides three Envelope Generators and Low Frequency |
* Note that a DimensionRegion object only defines "what to do", but it does |
349 |
* Oscillators: |
* not define "when to do it". To actually resolve which DimensionRegion to |
350 |
|
* pick under which situation, you need to refer to the DimensionRegions' |
351 |
|
* parent Region object. The Region object contains the necessary |
352 |
|
* "Dimension" definitions, which in turn define which DimensionRegion is |
353 |
|
* associated with which playing case exactly. |
354 |
|
* |
355 |
|
* The Gigasampler/GigaStudio format defines 3 Envelope Generators and 3 |
356 |
|
* Low Frequency Oscillators: |
357 |
* |
* |
358 |
* - EG1 and LFO1, both controlling sample amplitude |
* - EG1 and LFO1, both controlling sample amplitude |
359 |
* - EG2 and LFO2, both controlling filter cutoff frequency |
* - EG2 and LFO2, both controlling filter cutoff frequency |
360 |
* - EG3 and LFO3, both controlling sample pitch |
* - EG3 and LFO3, both controlling sample pitch |
361 |
|
* |
362 |
|
* Since the gig format was designed as extension to the DLS file format, |
363 |
|
* this class is derived from the DLS::Sampler class. So also refer to |
364 |
|
* DLS::Sampler for additional informations, class attributes and methods. |
365 |
*/ |
*/ |
366 |
class DimensionRegion : protected DLS::Sampler { |
class DimensionRegion : protected DLS::Sampler { |
367 |
public: |
public: |
477 |
using DLS::Sampler::DeleteSampleLoop; |
using DLS::Sampler::DeleteSampleLoop; |
478 |
// overridden methods |
// overridden methods |
479 |
virtual void SetGain(int32_t gain); |
virtual void SetGain(int32_t gain); |
480 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
481 |
virtual void CopyAssign(const DimensionRegion* orig); |
virtual void CopyAssign(const DimensionRegion* orig); |
482 |
protected: |
protected: |
483 |
uint8_t* VelocityTable; ///< For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity MIDI value to dimension bit number. |
uint8_t* VelocityTable; ///< For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity MIDI value to dimension bit number. |
603 |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
604 |
}; |
}; |
605 |
|
|
606 |
/** @brief Encapsulates sample waves used for playback. |
/** @brief Encapsulates sample waves of Gigasampler/GigaStudio files used for playback. |
607 |
|
* |
608 |
|
* This class provides access to the actual audio sample data of a |
609 |
|
* Gigasampler/GigaStudio file. Along to the actual sample data, it also |
610 |
|
* provides access to the sample's meta informations like bit depth, |
611 |
|
* sample rate, encoding type, but also loop informations. The latter may be |
612 |
|
* used by instruments for resembling sounds with arbitary note lengths. |
613 |
* |
* |
614 |
* In case you created a new sample with File::AddSample(), you should |
* In case you created a new sample with File::AddSample(), you should |
615 |
* first update all attributes with the desired meta informations |
* first update all attributes with the desired meta informations |
623 |
* retrieved from the respective DimensionRegon instead from the Sample |
* retrieved from the respective DimensionRegon instead from the Sample |
624 |
* itself. This was made for allowing different loop definitions for the |
* itself. This was made for allowing different loop definitions for the |
625 |
* same sample under different conditions. |
* same sample under different conditions. |
626 |
|
* |
627 |
|
* Since the gig format was designed as extension to the DLS file format, |
628 |
|
* this class is derived from the DLS::Sample class. So also refer to |
629 |
|
* DLS::Sample for additional informations, class attributes and methods. |
630 |
*/ |
*/ |
631 |
class Sample : public DLS::Sample { |
class Sample : public DLS::Sample { |
632 |
public: |
public: |
667 |
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL); |
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL); |
668 |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
669 |
Group* GetGroup() const; |
Group* GetGroup() const; |
670 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
671 |
void CopyAssignMeta(const Sample* orig); |
void CopyAssignMeta(const Sample* orig); |
672 |
void CopyAssignWave(const Sample* orig); |
void CopyAssignWave(const Sample* orig); |
673 |
protected: |
protected: |
718 |
}; |
}; |
719 |
|
|
720 |
// TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions) |
// TODO: <3dnl> list not used yet - not important though (just contains optional descriptions for the dimensions) |
721 |
/** @brief Defines Region information of an Instrument. |
/** @brief Defines Region information of a Gigasampler/GigaStudio instrument. |
722 |
* |
* |
723 |
* A Region reflects a consecutive area on the keyboard. The individual |
* A Region reflects a consecutive area (key range) on the keyboard. The |
724 |
* regions in the gig format may not overlap with other regions (of the same |
* individual regions in the gig format may not overlap with other regions |
725 |
* instrument). Further, in the gig format a Region is merely a container |
* (of the same instrument that is). Further, in the gig format a Region is |
726 |
* for DimensionRegions (a.k.a. "Cases"). The Region itself does not provide |
* merely a container for DimensionRegions (a.k.a. "Cases"). The Region |
727 |
* the sample mapping or articulation informations used, even though the |
* itself does not provide the sample mapping or articulation informations |
728 |
* data structures indeed provide such informations. The latter is however |
* used, even though the data structures of regions indeed provide such |
729 |
* just of historical nature, because the gig format was derived from the |
* informations. The latter is however just of historical nature, because |
730 |
* DLS format. |
* the gig file format was derived from the DLS file format. |
731 |
* |
* |
732 |
* Each Region consists of at least one or more DimensionRegions. The actual |
* Each Region consists of at least one or more DimensionRegions. The actual |
733 |
* amount of DimensionRegions depends on which kind of "dimensions" are |
* amount of DimensionRegions depends on which kind of "dimensions" are |
734 |
* defined for this region, and on the split / zone amount for each of those |
* defined for this region, and on the split / zone amount for each of those |
735 |
* dimensions. |
* dimensions. |
736 |
|
* |
737 |
|
* Since the gig format was designed as extension to the DLS file format, |
738 |
|
* this class is derived from the DLS::Region class. So also refer to |
739 |
|
* DLS::Region for additional informations, class attributes and methods. |
740 |
*/ |
*/ |
741 |
class Region : public DLS::Region { |
class Region : public DLS::Region { |
742 |
public: |
public: |
749 |
// own methods |
// own methods |
750 |
DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]); |
DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]); |
751 |
DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]); |
DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]); |
752 |
|
int GetDimensionRegionIndexByValue(const uint DimValues[8]); |
753 |
Sample* GetSample(); |
Sample* GetSample(); |
754 |
void AddDimension(dimension_def_t* pDimDef); |
void AddDimension(dimension_def_t* pDimDef); |
755 |
void DeleteDimension(dimension_def_t* pDimDef); |
void DeleteDimension(dimension_def_t* pDimDef); |
756 |
dimension_def_t* GetDimensionDefinition(dimension_t type); |
dimension_def_t* GetDimensionDefinition(dimension_t type); |
757 |
|
void DeleteDimensionZone(dimension_t type, int zone); |
758 |
|
void SplitDimensionZone(dimension_t type, int zone); |
759 |
|
void SetDimensionType(dimension_t oldType, dimension_t newType); |
760 |
// overridden methods |
// overridden methods |
761 |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
762 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
763 |
virtual void CopyAssign(const Region* orig); |
virtual void CopyAssign(const Region* orig); |
764 |
protected: |
protected: |
765 |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
767 |
void UpdateVelocityTable(); |
void UpdateVelocityTable(); |
768 |
Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL); |
Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL); |
769 |
void CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples); |
void CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples); |
770 |
|
DimensionRegion* GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase); |
771 |
~Region(); |
~Region(); |
772 |
friend class Instrument; |
friend class Instrument; |
773 |
}; |
}; |
774 |
|
|
775 |
/** Abstract base class for all MIDI rules. */ |
/** @brief Abstract base class for all MIDI rules. |
776 |
|
* |
777 |
|
* Note: Instead of using MIDI rules, we recommend you using real-time |
778 |
|
* instrument scripts instead. Read about the reasons below. |
779 |
|
* |
780 |
|
* MIDI Rules (also called "iMIDI rules" or "intelligent MIDI rules") were |
781 |
|
* introduced with GigaStudio 4 as an attempt to increase the power of |
782 |
|
* potential user controls over sounds. At that point other samplers already |
783 |
|
* supported certain powerful user control features, which were not possible |
784 |
|
* with GigaStudio yet. For example triggering new notes by MIDI CC |
785 |
|
* controller. |
786 |
|
* |
787 |
|
* Such extended features however were usually implemented by other samplers |
788 |
|
* by requiring the sound designer to write an instrument script which the |
789 |
|
* designer would then bundle with the respective instrument file. Such |
790 |
|
* scripts are essentially text files, using a very specific programming |
791 |
|
* language for the purpose of controlling the sampler in real-time. Since |
792 |
|
* however musicians are not typically keen to writing such cumbersome |
793 |
|
* script files, the GigaStudio designers decided to implement such extended |
794 |
|
* features completely without instrument scripts. Instead they created a |
795 |
|
* set of rules, which could be defined and altered conveniently by mouse |
796 |
|
* clicks in GSt's instrument editor application. The downside of this |
797 |
|
* overall approach however, was that those MIDI rules were very limited in |
798 |
|
* practice. As sound designer you easily came across the possiblities such |
799 |
|
* MIDI rules were able to offer. |
800 |
|
* |
801 |
|
* Due to such severe use case constraints, support for MIDI rules is quite |
802 |
|
* limited in libgig. At the moment only the "Control Trigger", "Alternator" |
803 |
|
* and the "Legato" MIDI rules are supported by libgig. Consequently the |
804 |
|
* graphical instrument editor application gigedit just supports the |
805 |
|
* "Control Trigger" and "Legato" MIDI rules, and LinuxSampler even does not |
806 |
|
* support any MIDI rule type at all and LinuxSampler probably will not |
807 |
|
* support MIDI rules in future either. |
808 |
|
* |
809 |
|
* Instead of using MIDI rules, we introduced real-time instrument scripts |
810 |
|
* as extension to the original GigaStudio file format. This script based |
811 |
|
* solution is much more powerful than MIDI rules and is already supported |
812 |
|
* by libgig, gigedit and LinuxSampler. |
813 |
|
* |
814 |
|
* @deprecated Just provided for backward compatiblity, use Script for new |
815 |
|
* instruments instead. |
816 |
|
*/ |
817 |
class MidiRule { |
class MidiRule { |
818 |
public: |
public: |
819 |
virtual ~MidiRule() { } |
virtual ~MidiRule() { } |
822 |
friend class Instrument; |
friend class Instrument; |
823 |
}; |
}; |
824 |
|
|
825 |
/** MIDI rule for triggering notes by control change events. */ |
/** @brief MIDI rule for triggering notes by control change events. |
826 |
|
* |
827 |
|
* A "Control Trigger MIDI rule" allows to trigger new notes by sending MIDI |
828 |
|
* control change events to the sampler. |
829 |
|
* |
830 |
|
* Note: "Control Trigger" MIDI rules are only supported by gigedit, but not |
831 |
|
* by LinuxSampler. We recommend you using real-time instrument scripts |
832 |
|
* instead. Read more about the details and reasons for this in the |
833 |
|
* description of the MidiRule base class. |
834 |
|
* |
835 |
|
* @deprecated Just provided for backward compatiblity, use Script for new |
836 |
|
* instruments instead. See description of MidiRule for details. |
837 |
|
*/ |
838 |
class MidiRuleCtrlTrigger : public MidiRule { |
class MidiRuleCtrlTrigger : public MidiRule { |
839 |
public: |
public: |
840 |
uint8_t ControllerNumber; ///< MIDI controller number. |
uint8_t ControllerNumber; ///< MIDI controller number. |
856 |
friend class Instrument; |
friend class Instrument; |
857 |
}; |
}; |
858 |
|
|
859 |
/** MIDI rule for instruments with legato samples. */ |
/** @brief MIDI rule for instruments with legato samples. |
860 |
|
* |
861 |
|
* A "Legato MIDI rule" allows playing instruments resembling the legato |
862 |
|
* playing technique. In the past such legato articulations were tried to be |
863 |
|
* simulated by pitching the samples of the instrument. However since |
864 |
|
* usually a high amount of pitch is needed for legatos, this always sounded |
865 |
|
* very artificial and unrealistic. The "Legato MIDI rule" thus uses another |
866 |
|
* approach. Instead of pitching the samples, it allows the sound designer |
867 |
|
* to bundle separate, additional samples for the individual legato |
868 |
|
* situations and the legato rules defined which samples to be played in |
869 |
|
* which situation. |
870 |
|
* |
871 |
|
* Note: "Legato MIDI rules" are only supported by gigedit, but not |
872 |
|
* by LinuxSampler. We recommend you using real-time instrument scripts |
873 |
|
* instead. Read more about the details and reasons for this in the |
874 |
|
* description of the MidiRule base class. |
875 |
|
* |
876 |
|
* @deprecated Just provided for backward compatiblity, use Script for new |
877 |
|
* instruments instead. See description of MidiRule for details. |
878 |
|
*/ |
879 |
class MidiRuleLegato : public MidiRule { |
class MidiRuleLegato : public MidiRule { |
880 |
public: |
public: |
881 |
uint8_t LegatoSamples; ///< Number of legato samples per key in each direction (always 12) |
uint8_t LegatoSamples; ///< Number of legato samples per key in each direction (always 12) |
896 |
friend class Instrument; |
friend class Instrument; |
897 |
}; |
}; |
898 |
|
|
899 |
/** MIDI rule to automatically cycle through specified sequences of different articulations. The instrument must be using the smartmidi dimension. */ |
/** @brief MIDI rule to automatically cycle through specified sequences of different articulations. |
900 |
|
* |
901 |
|
* The instrument must be using the smartmidi dimension. |
902 |
|
* |
903 |
|
* Note: "Alternator" MIDI rules are neither supported by gigedit nor by |
904 |
|
* LinuxSampler. We recommend you using real-time instrument scripts |
905 |
|
* instead. Read more about the details and reasons for this in the |
906 |
|
* description of the MidiRule base class. |
907 |
|
* |
908 |
|
* @deprecated Just provided for backward compatiblity, use Script for new |
909 |
|
* instruments instead. See description of MidiRule for details. |
910 |
|
*/ |
911 |
class MidiRuleAlternator : public MidiRule { |
class MidiRuleAlternator : public MidiRule { |
912 |
public: |
public: |
913 |
uint8_t Articulations; ///< Number of articulations in the instrument |
uint8_t Articulations; ///< Number of articulations in the instrument |
948 |
friend class Instrument; |
friend class Instrument; |
949 |
}; |
}; |
950 |
|
|
951 |
/** A MIDI rule not yet implemented by libgig. */ |
/** @brief A MIDI rule not yet implemented by libgig. |
952 |
|
* |
953 |
|
* This class is currently used as a place holder by libgig for MIDI rule |
954 |
|
* types which are not supported by libgig yet. |
955 |
|
* |
956 |
|
* Note: Support for missing MIDI rule types are probably never added to |
957 |
|
* libgig. We recommend you using real-time instrument scripts instead. |
958 |
|
* Read more about the details and reasons for this in the description of |
959 |
|
* the MidiRule base class. |
960 |
|
* |
961 |
|
* @deprecated Just provided for backward compatiblity, use Script for new |
962 |
|
* instruments instead. See description of MidiRule for details. |
963 |
|
*/ |
964 |
class MidiRuleUnknown : public MidiRule { |
class MidiRuleUnknown : public MidiRule { |
965 |
protected: |
protected: |
966 |
MidiRuleUnknown() { } |
MidiRuleUnknown() { } |
968 |
friend class Instrument; |
friend class Instrument; |
969 |
}; |
}; |
970 |
|
|
971 |
/** Provides all neccessary information for the synthesis of an <i>Instrument</i>. */ |
/** @brief Real-time instrument script (gig format extension). |
972 |
|
* |
973 |
|
* Real-time instrument scripts are user supplied small programs which can |
974 |
|
* be used by instrument designers to create custom behaviors and features |
975 |
|
* not available in the stock sampler engine. Features which might be very |
976 |
|
* exotic or specific for the respective instrument. |
977 |
|
* |
978 |
|
* This is an extension of the GigaStudio format, thus a feature which was |
979 |
|
* not available in the GigaStudio 4 software. It is currently only |
980 |
|
* supported by LinuxSampler and gigedit. Scripts will not load with the |
981 |
|
* original GigaStudio software. |
982 |
|
*/ |
983 |
|
class Script { |
984 |
|
public: |
985 |
|
enum Encoding_t { |
986 |
|
ENCODING_ASCII = 0 ///< Standard 8 bit US ASCII character encoding (default). |
987 |
|
}; |
988 |
|
enum Compression_t { |
989 |
|
COMPRESSION_NONE = 0 ///< Is not compressed at all (default). |
990 |
|
}; |
991 |
|
enum Language_t { |
992 |
|
LANGUAGE_NKSP = 0 ///< NKSP stands for "Is Not KSP" (default). |
993 |
|
}; |
994 |
|
|
995 |
|
String Name; ///< Arbitrary name of the script, which may be displayed i.e. in an instrument editor. |
996 |
|
Compression_t Compression; ///< Whether the script was/should be compressed, and if so, which compression algorithm shall be used. |
997 |
|
Encoding_t Encoding; ///< Format the script's source code text is encoded with. |
998 |
|
Language_t Language; ///< Programming language and dialect the script is written in. |
999 |
|
bool Bypass; ///< Global bypass: if enabled, this script shall not be executed by the sampler for any instrument. |
1000 |
|
|
1001 |
|
String GetScriptAsText(); |
1002 |
|
void SetScriptAsText(const String& text); |
1003 |
|
void SetGroup(ScriptGroup* pGroup); |
1004 |
|
ScriptGroup* GetGroup() const; |
1005 |
|
protected: |
1006 |
|
Script(ScriptGroup* group, RIFF::Chunk* ckScri); |
1007 |
|
virtual ~Script(); |
1008 |
|
void UpdateChunks(progress_t* pProgress); |
1009 |
|
void RemoveAllScriptReferences(); |
1010 |
|
friend class ScriptGroup; |
1011 |
|
friend class Instrument; |
1012 |
|
private: |
1013 |
|
ScriptGroup* pGroup; |
1014 |
|
RIFF::Chunk* pChunk; ///< 'Scri' chunk |
1015 |
|
std::vector<uint8_t> data; |
1016 |
|
uint32_t crc; ///< CRC-32 checksum of the raw script data |
1017 |
|
}; |
1018 |
|
|
1019 |
|
/** @brief Group of instrument scripts (gig format extension). |
1020 |
|
* |
1021 |
|
* This class is simply used to sort a bunch of real-time instrument scripts |
1022 |
|
* into individual groups. This allows instrument designers and script |
1023 |
|
* developers to keep scripts in a certain order while working with a larger |
1024 |
|
* amount of scripts in an instrument editor. |
1025 |
|
* |
1026 |
|
* This is an extension of the GigaStudio format, thus a feature which was |
1027 |
|
* not available in the GigaStudio 4 software. It is currently only |
1028 |
|
* supported by LinuxSampler and gigedit. |
1029 |
|
*/ |
1030 |
|
class ScriptGroup { |
1031 |
|
public: |
1032 |
|
String Name; ///< Name of this script group. For example to be displayed in an instrument editor. |
1033 |
|
|
1034 |
|
Script* GetScript(uint index); |
1035 |
|
Script* AddScript(); |
1036 |
|
void DeleteScript(Script* pScript); |
1037 |
|
protected: |
1038 |
|
ScriptGroup(File* file, RIFF::List* lstRTIS); |
1039 |
|
virtual ~ScriptGroup(); |
1040 |
|
void LoadScripts(); |
1041 |
|
void UpdateChunks(progress_t* pProgress); |
1042 |
|
friend class Script; |
1043 |
|
friend class File; |
1044 |
|
private: |
1045 |
|
File* pFile; |
1046 |
|
RIFF::List* pList; ///< 'RTIS' list chunk |
1047 |
|
std::list<Script*>* pScripts; |
1048 |
|
}; |
1049 |
|
|
1050 |
|
/** @brief Provides access to a Gigasampler/GigaStudio instrument. |
1051 |
|
* |
1052 |
|
* This class provides access to Gigasampler/GigaStudio instruments |
1053 |
|
* contained in .gig files. A gig instrument is merely a set of keyboard |
1054 |
|
* ranges (called Region), plus some additional global informations about |
1055 |
|
* the instrument. The major part of the actual instrument definition used |
1056 |
|
* for the synthesis of the instrument is contained in the respective Region |
1057 |
|
* object (or actually in the respective DimensionRegion object being, see |
1058 |
|
* description of Region for details). |
1059 |
|
* |
1060 |
|
* Since the gig format was designed as extension to the DLS file format, |
1061 |
|
* this class is derived from the DLS::Instrument class. So also refer to |
1062 |
|
* DLS::Instrument for additional informations, class attributes and |
1063 |
|
* methods. |
1064 |
|
*/ |
1065 |
class Instrument : protected DLS::Instrument { |
class Instrument : protected DLS::Instrument { |
1066 |
public: |
public: |
1067 |
// derived attributes from DLS::Resource |
// derived attributes from DLS::Resource |
1090 |
Region* GetNextRegion(); |
Region* GetNextRegion(); |
1091 |
Region* AddRegion(); |
Region* AddRegion(); |
1092 |
void DeleteRegion(Region* pRegion); |
void DeleteRegion(Region* pRegion); |
1093 |
virtual void UpdateChunks(); |
void MoveTo(Instrument* dst); |
1094 |
|
virtual void UpdateChunks(progress_t* pProgress); |
1095 |
virtual void CopyAssign(const Instrument* orig); |
virtual void CopyAssign(const Instrument* orig); |
1096 |
// own methods |
// own methods |
1097 |
Region* GetRegion(unsigned int Key); |
Region* GetRegion(unsigned int Key); |
1100 |
MidiRuleLegato* AddMidiRuleLegato(); |
MidiRuleLegato* AddMidiRuleLegato(); |
1101 |
MidiRuleAlternator* AddMidiRuleAlternator(); |
MidiRuleAlternator* AddMidiRuleAlternator(); |
1102 |
void DeleteMidiRule(int i); |
void DeleteMidiRule(int i); |
1103 |
|
// real-time instrument script methods |
1104 |
|
Script* GetScriptOfSlot(uint index); |
1105 |
|
void AddScriptSlot(Script* pScript, bool bypass = false); |
1106 |
|
void SwapScriptSlots(uint index1, uint index2); |
1107 |
|
void RemoveScriptSlot(uint index); |
1108 |
|
void RemoveScript(Script* pScript); |
1109 |
|
uint ScriptSlotCount() const; |
1110 |
|
bool IsScriptSlotBypassed(uint index); |
1111 |
|
void SetScriptSlotBypassed(uint index, bool bBypass); |
1112 |
protected: |
protected: |
1113 |
Region* RegionKeyTable[128]; ///< fast lookup for the corresponding Region of a MIDI key |
Region* RegionKeyTable[128]; ///< fast lookup for the corresponding Region of a MIDI key |
1114 |
|
|
1116 |
~Instrument(); |
~Instrument(); |
1117 |
void CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples); |
void CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples); |
1118 |
void UpdateRegionKeyTable(); |
void UpdateRegionKeyTable(); |
1119 |
|
void LoadScripts(); |
1120 |
|
void UpdateScriptFileOffsets(); |
1121 |
friend class File; |
friend class File; |
1122 |
friend class Region; // so Region can call UpdateRegionKeyTable() |
friend class Region; // so Region can call UpdateRegionKeyTable() |
1123 |
private: |
private: |
1124 |
|
struct _ScriptPooolEntry { |
1125 |
|
uint32_t fileOffset; |
1126 |
|
bool bypass; |
1127 |
|
}; |
1128 |
|
struct _ScriptPooolRef { |
1129 |
|
Script* script; |
1130 |
|
bool bypass; |
1131 |
|
}; |
1132 |
MidiRule** pMidiRules; |
MidiRule** pMidiRules; |
1133 |
|
std::vector<_ScriptPooolEntry> scriptPoolFileOffsets; |
1134 |
|
std::vector<_ScriptPooolRef>* pScriptRefs; |
1135 |
}; |
}; |
1136 |
|
|
1137 |
/** @brief Group of Gigasampler objects |
/** @brief Group of Gigasampler samples |
1138 |
* |
* |
1139 |
* Groups help to organize a huge collection of Gigasampler objects. |
* Groups help to organize a huge collection of Gigasampler samples. |
1140 |
* Groups are not concerned at all for the synthesis, but they help |
* Groups are not concerned at all for the synthesis, but they help |
1141 |
* sound library developers when working on complex instruments with an |
* sound library developers when working on complex instruments with an |
1142 |
* instrument editor (as long as that instrument editor supports it ;-). |
* instrument editor (as long as that instrument editor supports it ;-). |
1143 |
* |
* |
|
* At the moment, it seems as only samples can be grouped together in |
|
|
* the Gigasampler format yet. If this is false in the meantime, please |
|
|
* tell us ! |
|
|
* |
|
1144 |
* A sample is always assigned to exactly one Group. This also means |
* A sample is always assigned to exactly one Group. This also means |
1145 |
* there is always at least one Group in a .gig file, no matter if you |
* there is always at least one Group in a .gig file, no matter if you |
1146 |
* created one yet or not. |
* created one yet or not. |
1155 |
protected: |
protected: |
1156 |
Group(File* file, RIFF::Chunk* ck3gnm); |
Group(File* file, RIFF::Chunk* ck3gnm); |
1157 |
virtual ~Group(); |
virtual ~Group(); |
1158 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
1159 |
void MoveAll(); |
void MoveAll(); |
1160 |
friend class File; |
friend class File; |
1161 |
private: |
private: |
1163 |
RIFF::Chunk* pNameChunk; ///< '3gnm' chunk |
RIFF::Chunk* pNameChunk; ///< '3gnm' chunk |
1164 |
}; |
}; |
1165 |
|
|
1166 |
/** Parses Gigasampler files and provides abstract access to the data. */ |
/** @brief Provides convenient access to Gigasampler/GigaStudio .gig files. |
1167 |
|
* |
1168 |
|
* This is the entry class for accesing a Gigasampler/GigaStudio (.gig) file |
1169 |
|
* with libgig. It allows you to open existing .gig files, modifying them |
1170 |
|
* and saving them persistently either under the same file name or under a |
1171 |
|
* different location. |
1172 |
|
* |
1173 |
|
* A .gig file is merely a monolithic file. That means samples and the |
1174 |
|
* defintion of the virtual instruments are contained in the same file. A |
1175 |
|
* .gig file contains an arbitrary amount of samples, and an arbitrary |
1176 |
|
* amount of instruments which are referencing those samples. It is also |
1177 |
|
* possible to store samples in .gig files not being referenced by any |
1178 |
|
* instrument. This is not an error from the file format's point of view and |
1179 |
|
* it is actually often used in practice during the design phase of new gig |
1180 |
|
* instruments. |
1181 |
|
* |
1182 |
|
* So on toplevel of the gig file format you have: |
1183 |
|
* |
1184 |
|
* - A set of samples (see Sample). |
1185 |
|
* - A set of virtual instruments (see Instrument). |
1186 |
|
* |
1187 |
|
* And as extension to the original GigaStudio format, we added: |
1188 |
|
* |
1189 |
|
* - Real-time instrument scripts (see Script). |
1190 |
|
* |
1191 |
|
* Note that the latter however is only supported by libgig, gigedit and |
1192 |
|
* LinuxSampler. Scripts are not supported by the original GigaStudio |
1193 |
|
* software. |
1194 |
|
* |
1195 |
|
* All released Gigasampler/GigaStudio file format versions are supported |
1196 |
|
* (so from first Gigasampler version up to including GigaStudio 4). |
1197 |
|
* |
1198 |
|
* Since the gig format was designed as extension to the DLS file format, |
1199 |
|
* this class is derived from the DLS::File class. So also refer to |
1200 |
|
* DLS::File for additional informations, class attributes and methods. |
1201 |
|
*/ |
1202 |
class File : protected DLS::File { |
class File : protected DLS::File { |
1203 |
public: |
public: |
1204 |
static const DLS::version_t VERSION_2; |
static const DLS::version_t VERSION_2; |
1241 |
void SetAutoLoad(bool b); |
void SetAutoLoad(bool b); |
1242 |
bool GetAutoLoad(); |
bool GetAutoLoad(); |
1243 |
void AddContentOf(File* pFile); |
void AddContentOf(File* pFile); |
1244 |
|
ScriptGroup* GetScriptGroup(uint index); |
1245 |
|
ScriptGroup* GetScriptGroup(const String& name); |
1246 |
|
ScriptGroup* AddScriptGroup(); |
1247 |
|
void DeleteScriptGroup(ScriptGroup* pGroup); |
1248 |
virtual ~File(); |
virtual ~File(); |
1249 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(progress_t* pProgress); |
1250 |
protected: |
protected: |
1251 |
// overridden protected methods from DLS::File |
// overridden protected methods from DLS::File |
1252 |
virtual void LoadSamples(); |
virtual void LoadSamples(); |
1253 |
virtual void LoadInstruments(); |
virtual void LoadInstruments(); |
1254 |
virtual void LoadGroups(); |
virtual void LoadGroups(); |
1255 |
|
virtual void UpdateFileOffsets(); |
1256 |
// own protected methods |
// own protected methods |
1257 |
virtual void LoadSamples(progress_t* pProgress); |
virtual void LoadSamples(progress_t* pProgress); |
1258 |
virtual void LoadInstruments(progress_t* pProgress); |
virtual void LoadInstruments(progress_t* pProgress); |
1259 |
|
virtual void LoadScriptGroups(); |
1260 |
void SetSampleChecksum(Sample* pSample, uint32_t crc); |
void SetSampleChecksum(Sample* pSample, uint32_t crc); |
1261 |
friend class Region; |
friend class Region; |
1262 |
friend class Sample; |
friend class Sample; |
1263 |
|
friend class Instrument; |
1264 |
friend class Group; // so Group can access protected member pRIFF |
friend class Group; // so Group can access protected member pRIFF |
1265 |
|
friend class ScriptGroup; // so ScriptGroup can access protected member pRIFF |
1266 |
private: |
private: |
1267 |
std::list<Group*>* pGroups; |
std::list<Group*>* pGroups; |
1268 |
std::list<Group*>::iterator GroupsIterator; |
std::list<Group*>::iterator GroupsIterator; |
1269 |
bool bAutoLoad; |
bool bAutoLoad; |
1270 |
|
std::list<ScriptGroup*>* pScriptGroups; |
1271 |
}; |
}; |
1272 |
|
|
1273 |
/** |
/** |