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-2007 by Christian Schoenebeck * |
* Copyright (C) 2003-2013 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 * |
31 |
# define LIST_TYPE_3EWL 0x3365776C |
# define LIST_TYPE_3EWL 0x3365776C |
32 |
# define LIST_TYPE_3GRI 0x33677269 |
# define LIST_TYPE_3GRI 0x33677269 |
33 |
# define LIST_TYPE_3GNL 0x33676E6C |
# define LIST_TYPE_3GNL 0x33676E6C |
|
# define CHUNK_ID_SMPL 0x736D706C |
|
34 |
# define CHUNK_ID_3GIX 0x33676978 |
# define CHUNK_ID_3GIX 0x33676978 |
35 |
# define CHUNK_ID_3EWA 0x33657761 |
# define CHUNK_ID_3EWA 0x33657761 |
36 |
# define CHUNK_ID_3LNK 0x336C6E6B |
# define CHUNK_ID_3LNK 0x336C6E6B |
44 |
# define LIST_TYPE_3EWL 0x6C776533 |
# define LIST_TYPE_3EWL 0x6C776533 |
45 |
# define LIST_TYPE_3GRI 0x69726733 |
# define LIST_TYPE_3GRI 0x69726733 |
46 |
# define LIST_TYPE_3GNL 0x6C6E6733 |
# define LIST_TYPE_3GNL 0x6C6E6733 |
|
# define CHUNK_ID_SMPL 0x6C706D73 |
|
47 |
# define CHUNK_ID_3GIX 0x78696733 |
# define CHUNK_ID_3GIX 0x78696733 |
48 |
# define CHUNK_ID_3EWA 0x61776533 |
# define CHUNK_ID_3EWA 0x61776533 |
49 |
# define CHUNK_ID_3LNK 0x6B6E6C33 |
# define CHUNK_ID_3LNK 0x6B6E6C33 |
321 |
progress_t(); |
progress_t(); |
322 |
}; |
}; |
323 |
|
|
|
/** @brief CRC-32 checksum implementation |
|
|
* |
|
|
* This class is used to calculate checksums of the sample data in |
|
|
* a gig file. The checksums are stored in the 3crc chunk of the |
|
|
* gig file and automatically updated when a sample is written |
|
|
* with Sample::Write(). |
|
|
*/ |
|
|
class CRC { |
|
|
private: |
|
|
uint32_t value; |
|
|
static const uint32_t* table; |
|
|
static uint32_t* initTable(); |
|
|
public: |
|
|
CRC() { |
|
|
reset(); |
|
|
} |
|
|
void reset() { |
|
|
value = 0xffffffff; |
|
|
} |
|
|
void update(unsigned char* buf, int len) { |
|
|
for (int i = 0 ; i < len ; i++) { |
|
|
value = table[(value ^ buf[i]) & 0xff] ^ (value >> 8); |
|
|
} |
|
|
} |
|
|
uint32_t getValue() { |
|
|
return value ^ 0xffffffff; |
|
|
} |
|
|
}; |
|
|
|
|
324 |
// just symbol prototyping |
// just symbol prototyping |
325 |
class File; |
class File; |
326 |
class Instrument; |
class Instrument; |
394 |
// Filter |
// Filter |
395 |
bool VCFEnabled; ///< If filter should be used. |
bool VCFEnabled; ///< If filter should be used. |
396 |
vcf_type_t VCFType; ///< Defines the general filter characteristic (lowpass, highpass, bandpass, etc.). |
vcf_type_t VCFType; ///< Defines the general filter characteristic (lowpass, highpass, bandpass, etc.). |
397 |
vcf_cutoff_ctrl_t VCFCutoffController; ///< Specifies which external controller has influence on the filter cutoff frequency. |
vcf_cutoff_ctrl_t VCFCutoffController; ///< Specifies which external controller has influence on the filter cutoff frequency. @deprecated Don't alter directly, use SetVCFCutoffController() instead! |
398 |
bool VCFCutoffControllerInvert; ///< Inverts values coming from the defined cutoff controller |
bool VCFCutoffControllerInvert; ///< Inverts values coming from the defined cutoff controller |
399 |
uint8_t VCFCutoff; ///< Max. cutoff frequency. |
uint8_t VCFCutoff; ///< Max. cutoff frequency. |
400 |
curve_type_t VCFVelocityCurve; ///< Defines a transformation curve for the incoming velocity values, affecting the VCF. |
curve_type_t VCFVelocityCurve; ///< Defines a transformation curve for the incoming velocity values, affecting the VCF. @deprecated Don't alter directly, use SetVCFVelocityCurve() instead! |
401 |
uint8_t VCFVelocityScale; ///< (0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defined, otherwise this is the minimum cutoff). |
uint8_t VCFVelocityScale; ///< (0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defined, otherwise this is the minimum cutoff). @deprecated Don't alter directly, use SetVCFVelocityScale() instead! |
402 |
uint8_t VCFVelocityDynamicRange; ///< 0x04 = lowest, 0x00 = highest |
uint8_t VCFVelocityDynamicRange; ///< 0x04 = lowest, 0x00 = highest . @deprecated Don't alter directly, use SetVCFVelocityDynamicRange() instead! |
403 |
uint8_t VCFResonance; ///< Firm internal filter resonance weight. |
uint8_t VCFResonance; ///< Firm internal filter resonance weight. |
404 |
bool VCFResonanceDynamic; ///< If <i>true</i>: Increases the resonance Q according to changes of controllers that actually control the VCF cutoff frequency (EG2, ext. VCF MIDI controller). |
bool VCFResonanceDynamic; ///< If <i>true</i>: Increases the resonance Q according to changes of controllers that actually control the VCF cutoff frequency (EG2, ext. VCF MIDI controller). |
405 |
vcf_res_ctrl_t VCFResonanceController; ///< Specifies which external controller has influence on the filter resonance Q. |
vcf_res_ctrl_t VCFResonanceController; ///< Specifies which external controller has influence on the filter resonance Q. |
406 |
bool VCFKeyboardTracking; ///< If <i>true</i>: VCF cutoff frequence will be dependend to the note key position relative to the defined breakpoint value. |
bool VCFKeyboardTracking; ///< If <i>true</i>: VCF cutoff frequence will be dependend to the note key position relative to the defined breakpoint value. |
407 |
uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFKeyboardTracking (0 - 127). |
uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFKeyboardTracking (0 - 127). |
408 |
// Key Velocity Transformations |
// Key Velocity Transformations |
409 |
curve_type_t VelocityResponseCurve; ///< Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). |
curve_type_t VelocityResponseCurve; ///< Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). @deprecated Don't alter directly, use SetVelocityResponseCurve() instead! |
410 |
uint8_t VelocityResponseDepth; ///< Dynamic range of velocity affecting amplitude (0 - 4) (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). |
uint8_t VelocityResponseDepth; ///< Dynamic range of velocity affecting amplitude (0 - 4) (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). @deprecated Don't alter directly, use SetVelocityResponseDepth() instead! |
411 |
uint8_t VelocityResponseCurveScaling; ///< 0 - 127 (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead) |
uint8_t VelocityResponseCurveScaling; ///< 0 - 127 (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). @deprecated Don't alter directly, use SetVelocityResponseCurveScaling() instead! |
412 |
curve_type_t ReleaseVelocityResponseCurve; ///< Defines a transformation curve to the incoming release veloctiy values affecting envelope times. |
curve_type_t ReleaseVelocityResponseCurve; ///< Defines a transformation curve to the incoming release veloctiy values affecting envelope times. @deprecated Don't alter directly, use SetReleaseVelocityResponseCurve() instead! |
413 |
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic range of release velocity affecting envelope time (0 - 4). |
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic range of release velocity affecting envelope time (0 - 4). @deprecated Don't alter directly, use SetReleaseVelocityResponseDepth() instead! |
414 |
uint8_t ReleaseTriggerDecay; ///< 0 - 8 |
uint8_t ReleaseTriggerDecay; ///< 0 - 8 |
415 |
// Mix / Layer |
// Mix / Layer |
416 |
crossfade_t Crossfade; |
crossfade_t Crossfade; |
429 |
uint8_t DimensionUpperLimits[8]; ///< gig3: defines the upper limit of the dimension values for this dimension region |
uint8_t DimensionUpperLimits[8]; ///< gig3: defines the upper limit of the dimension values for this dimension region |
430 |
|
|
431 |
// derived attributes from DLS::Sampler |
// derived attributes from DLS::Sampler |
432 |
DLS::Sampler::UnityNote; |
using DLS::Sampler::UnityNote; |
433 |
DLS::Sampler::FineTune; |
using DLS::Sampler::FineTune; |
434 |
DLS::Sampler::Gain; |
using DLS::Sampler::Gain; |
435 |
DLS::Sampler::SampleLoops; |
using DLS::Sampler::SampleLoops; |
436 |
DLS::Sampler::pSampleLoops; |
using DLS::Sampler::pSampleLoops; |
437 |
|
|
438 |
// own methods |
// own methods |
439 |
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity); |
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity); |
440 |
double GetVelocityRelease(uint8_t MIDIKeyVelocity); |
double GetVelocityRelease(uint8_t MIDIKeyVelocity); |
441 |
double GetVelocityCutoff(uint8_t MIDIKeyVelocity); |
double GetVelocityCutoff(uint8_t MIDIKeyVelocity); |
442 |
|
void SetVelocityResponseCurve(curve_type_t curve); |
443 |
|
void SetVelocityResponseDepth(uint8_t depth); |
444 |
|
void SetVelocityResponseCurveScaling(uint8_t scaling); |
445 |
|
void SetReleaseVelocityResponseCurve(curve_type_t curve); |
446 |
|
void SetReleaseVelocityResponseDepth(uint8_t depth); |
447 |
|
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller); |
448 |
|
void SetVCFVelocityCurve(curve_type_t curve); |
449 |
|
void SetVCFVelocityDynamicRange(uint8_t range); |
450 |
|
void SetVCFVelocityScale(uint8_t scaling); |
451 |
|
Region* GetParent() const; |
452 |
// derived methods |
// derived methods |
453 |
DLS::Sampler::AddSampleLoop; |
using DLS::Sampler::AddSampleLoop; |
454 |
DLS::Sampler::DeleteSampleLoop; |
using DLS::Sampler::DeleteSampleLoop; |
455 |
// overridden methods |
// overridden methods |
456 |
|
virtual void SetGain(int32_t gain); |
457 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
458 |
|
virtual void CopyAssign(const DimensionRegion* orig); |
459 |
protected: |
protected: |
460 |
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. |
461 |
DimensionRegion(RIFF::List* _3ewl); |
DimensionRegion(Region* pParent, RIFF::List* _3ewl); |
462 |
|
DimensionRegion(RIFF::List* _3ewl, const DimensionRegion& src); |
463 |
~DimensionRegion(); |
~DimensionRegion(); |
464 |
|
void CopyAssign(const DimensionRegion* orig, const std::map<Sample*,Sample*>* mSamples); |
465 |
friend class Region; |
friend class Region; |
466 |
private: |
private: |
467 |
typedef enum { ///< Used to decode attenuation, EG1 and EG2 controller |
typedef enum { ///< Used to decode attenuation, EG1 and EG2 controller |
499 |
double* pVelocityAttenuationTable; ///< Points to the velocity table corresponding to the velocity parameters of this DimensionRegion. |
double* pVelocityAttenuationTable; ///< Points to the velocity table corresponding to the velocity parameters of this DimensionRegion. |
500 |
double* pVelocityReleaseTable; ///< Points to the velocity table corresponding to the release velocity parameters of this DimensionRegion |
double* pVelocityReleaseTable; ///< Points to the velocity table corresponding to the release velocity parameters of this DimensionRegion |
501 |
double* pVelocityCutoffTable; ///< Points to the velocity table corresponding to the filter velocity parameters of this DimensionRegion |
double* pVelocityCutoffTable; ///< Points to the velocity table corresponding to the filter velocity parameters of this DimensionRegion |
502 |
|
Region* pRegion; |
503 |
|
|
504 |
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController); |
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController); |
505 |
_lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController); |
_lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController); |
506 |
|
double* GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth); |
507 |
|
double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, uint8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t vcfCutoffController); |
508 |
double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
509 |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
510 |
}; |
}; |
558 |
void ReleaseSampleData(); |
void ReleaseSampleData(); |
559 |
void Resize(int iNewSize); |
void Resize(int iNewSize); |
560 |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
561 |
unsigned long GetPos(); |
unsigned long GetPos() const; |
562 |
unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL); |
unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL); |
563 |
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); |
564 |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
565 |
Group* GetGroup() const; |
Group* GetGroup() const; |
566 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
567 |
|
void CopyAssignMeta(const Sample* orig); |
568 |
|
void CopyAssignWave(const Sample* orig); |
569 |
protected: |
protected: |
570 |
static unsigned int Instances; ///< Number of instances of class Sample. |
static unsigned int Instances; ///< Number of instances of class Sample. |
571 |
static buffer_t InternalDecompressionBuffer; ///< Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples. |
static buffer_t InternalDecompressionBuffer; ///< Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples. |
580 |
unsigned long FileNo; ///< File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) |
unsigned long FileNo; ///< File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) |
581 |
RIFF::Chunk* pCk3gix; |
RIFF::Chunk* pCk3gix; |
582 |
RIFF::Chunk* pCkSmpl; |
RIFF::Chunk* pCkSmpl; |
583 |
CRC crc; ///< CRC-32 checksum of the raw sample data |
uint32_t crc; ///< CRC-32 checksum of the raw sample data |
584 |
|
|
585 |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0); |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0); |
586 |
~Sample(); |
~Sample(); |
623 |
DimensionRegion* pDimensionRegions[256]; ///< Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension regions not in use). Avoid to access the array directly and better use GetDimensionRegionByValue() instead, but of course in some cases it makes sense to use the array (e.g. iterating through all DimensionRegions). Use AddDimension() and DeleteDimension() to create a new dimension or delete an existing one (which will create or delete the respective dimension region(s) automatically). |
DimensionRegion* pDimensionRegions[256]; ///< Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension regions not in use). Avoid to access the array directly and better use GetDimensionRegionByValue() instead, but of course in some cases it makes sense to use the array (e.g. iterating through all DimensionRegions). Use AddDimension() and DeleteDimension() to create a new dimension or delete an existing one (which will create or delete the respective dimension region(s) automatically). |
624 |
unsigned int Layers; ///< Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there is Layer dimension. The same information can of course also be obtained by accessing pDimensionDefinitions. Do not alter this value! |
unsigned int Layers; ///< Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there is Layer dimension. The same information can of course also be obtained by accessing pDimensionDefinitions. Do not alter this value! |
625 |
|
|
626 |
|
// own methods |
627 |
DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]); |
DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]); |
628 |
DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]); |
DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]); |
629 |
Sample* GetSample(); |
Sample* GetSample(); |
630 |
void AddDimension(dimension_def_t* pDimDef); |
void AddDimension(dimension_def_t* pDimDef); |
631 |
void DeleteDimension(dimension_def_t* pDimDef); |
void DeleteDimension(dimension_def_t* pDimDef); |
632 |
|
// overridden methods |
633 |
|
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
634 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
635 |
|
virtual void CopyAssign(const Region* orig); |
636 |
protected: |
protected: |
637 |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
638 |
void LoadDimensionRegions(RIFF::List* rgn); |
void LoadDimensionRegions(RIFF::List* rgn); |
639 |
void UpdateVelocityTable(); |
void UpdateVelocityTable(); |
640 |
Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL); |
Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL); |
641 |
|
void CopyAssign(const Region* orig, const std::map<Sample*,Sample*>* mSamples); |
642 |
~Region(); |
~Region(); |
643 |
friend class Instrument; |
friend class Instrument; |
644 |
}; |
}; |
645 |
|
|
646 |
|
/** Abstract base class for all MIDI rules. */ |
647 |
|
class MidiRule { |
648 |
|
public: |
649 |
|
virtual ~MidiRule() { } |
650 |
|
protected: |
651 |
|
virtual void UpdateChunks(uint8_t* pData) const = 0; |
652 |
|
friend class Instrument; |
653 |
|
}; |
654 |
|
|
655 |
|
/** MIDI rule for triggering notes by control change events. */ |
656 |
|
class MidiRuleCtrlTrigger : public MidiRule { |
657 |
|
public: |
658 |
|
uint8_t ControllerNumber; ///< MIDI controller number. |
659 |
|
uint8_t Triggers; ///< Number of triggers. |
660 |
|
struct trigger_t { |
661 |
|
uint8_t TriggerPoint; ///< The CC value to pass for the note to be triggered. |
662 |
|
bool Descending; ///< If the change in CC value should be downwards. |
663 |
|
uint8_t VelSensitivity; ///< How sensitive the velocity should be to the speed of the controller change. |
664 |
|
uint8_t Key; ///< Key to trigger. |
665 |
|
bool NoteOff; ///< If a note off should be triggered instead of a note on. |
666 |
|
uint8_t Velocity; ///< Velocity of the note to trigger. 255 means that velocity should depend on the speed of the controller change. |
667 |
|
bool OverridePedal; ///< If a note off should be triggered even if the sustain pedal is down. |
668 |
|
} pTriggers[32]; |
669 |
|
|
670 |
|
protected: |
671 |
|
MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg); |
672 |
|
MidiRuleCtrlTrigger(); |
673 |
|
void UpdateChunks(uint8_t* pData) const; |
674 |
|
friend class Instrument; |
675 |
|
}; |
676 |
|
|
677 |
|
/** MIDI rule for instruments with legato samples. */ |
678 |
|
class MidiRuleLegato : public MidiRule { |
679 |
|
public: |
680 |
|
uint8_t LegatoSamples; ///< Number of legato samples per key in each direction (always 12) |
681 |
|
bool BypassUseController; ///< If a controller should be used to bypass the sustain note |
682 |
|
uint8_t BypassKey; ///< Key to be used to bypass the sustain note |
683 |
|
uint8_t BypassController; ///< Controller to be used to bypass the sustain note |
684 |
|
uint16_t ThresholdTime; ///< Maximum time (ms) between two notes that should be played legato |
685 |
|
uint16_t ReleaseTime; ///< Release time |
686 |
|
range_t KeyRange; ///< Key range for legato notes |
687 |
|
uint8_t ReleaseTriggerKey; ///< Key triggering release samples |
688 |
|
uint8_t AltSustain1Key; ///< Key triggering alternate sustain samples |
689 |
|
uint8_t AltSustain2Key; ///< Key triggering a second set of alternate sustain samples |
690 |
|
|
691 |
|
protected: |
692 |
|
MidiRuleLegato(RIFF::Chunk* _3ewg); |
693 |
|
MidiRuleLegato(); |
694 |
|
void UpdateChunks(uint8_t* pData) const; |
695 |
|
friend class Instrument; |
696 |
|
}; |
697 |
|
|
698 |
|
/** MIDI rule to automatically cycle through specified sequences of different articulations. The instrument must be using the smartmidi dimension. */ |
699 |
|
class MidiRuleAlternator : public MidiRule { |
700 |
|
public: |
701 |
|
uint8_t Articulations; ///< Number of articulations in the instrument |
702 |
|
String pArticulations[32]; ///< Names of the articulations |
703 |
|
|
704 |
|
range_t PlayRange; ///< Key range of the playable keys in the instrument |
705 |
|
|
706 |
|
uint8_t Patterns; ///< Number of alternator patterns |
707 |
|
struct pattern_t { |
708 |
|
String Name; ///< Name of the pattern |
709 |
|
int Size; ///< Number of steps in the pattern |
710 |
|
const uint8_t& operator[](int i) const { /// Articulation to play |
711 |
|
return data[i]; |
712 |
|
} |
713 |
|
uint8_t& operator[](int i) { |
714 |
|
return data[i]; |
715 |
|
} |
716 |
|
private: |
717 |
|
uint8_t data[32]; |
718 |
|
} pPatterns[32]; ///< A pattern is a sequence of articulation numbers |
719 |
|
|
720 |
|
typedef enum { |
721 |
|
selector_none, |
722 |
|
selector_key_switch, |
723 |
|
selector_controller |
724 |
|
} selector_t; |
725 |
|
selector_t Selector; ///< Method by which pattern is chosen |
726 |
|
range_t KeySwitchRange; ///< Key range for key switch selector |
727 |
|
uint8_t Controller; ///< CC number for controller selector |
728 |
|
|
729 |
|
bool Polyphonic; ///< If alternator should step forward only when all notes are off |
730 |
|
bool Chained; ///< If all patterns should be chained together |
731 |
|
|
732 |
|
protected: |
733 |
|
MidiRuleAlternator(RIFF::Chunk* _3ewg); |
734 |
|
MidiRuleAlternator(); |
735 |
|
void UpdateChunks(uint8_t* pData) const; |
736 |
|
friend class Instrument; |
737 |
|
}; |
738 |
|
|
739 |
|
/** A MIDI rule not yet implemented by libgig. */ |
740 |
|
class MidiRuleUnknown : public MidiRule { |
741 |
|
protected: |
742 |
|
MidiRuleUnknown() { } |
743 |
|
void UpdateChunks(uint8_t* pData) const { } |
744 |
|
friend class Instrument; |
745 |
|
}; |
746 |
|
|
747 |
/** Provides all neccessary information for the synthesis of an <i>Instrument</i>. */ |
/** Provides all neccessary information for the synthesis of an <i>Instrument</i>. */ |
748 |
class Instrument : protected DLS::Instrument { |
class Instrument : protected DLS::Instrument { |
749 |
public: |
public: |
750 |
// derived attributes from DLS::Resource |
// derived attributes from DLS::Resource |
751 |
DLS::Resource::pInfo; |
using DLS::Resource::pInfo; |
752 |
DLS::Resource::pDLSID; |
using DLS::Resource::pDLSID; |
753 |
// derived attributes from DLS::Instrument |
// derived attributes from DLS::Instrument |
754 |
DLS::Instrument::IsDrum; |
using DLS::Instrument::IsDrum; |
755 |
DLS::Instrument::MIDIBank; |
using DLS::Instrument::MIDIBank; |
756 |
DLS::Instrument::MIDIBankCoarse; |
using DLS::Instrument::MIDIBankCoarse; |
757 |
DLS::Instrument::MIDIBankFine; |
using DLS::Instrument::MIDIBankFine; |
758 |
DLS::Instrument::MIDIProgram; |
using DLS::Instrument::MIDIProgram; |
759 |
DLS::Instrument::Regions; |
using DLS::Instrument::Regions; |
760 |
// own attributes |
// own attributes |
761 |
int32_t Attenuation; ///< in dB |
int32_t Attenuation; ///< in dB |
762 |
uint16_t EffectSend; |
uint16_t EffectSend; |
767 |
|
|
768 |
|
|
769 |
// derived methods from DLS::Resource |
// derived methods from DLS::Resource |
770 |
DLS::Resource::GetParent; |
using DLS::Resource::GetParent; |
|
// derived methods from DLS::Instrument |
|
|
DLS::Instrument::MoveRegion; |
|
771 |
// overridden methods |
// overridden methods |
772 |
Region* GetFirstRegion(); |
Region* GetFirstRegion(); |
773 |
Region* GetNextRegion(); |
Region* GetNextRegion(); |
774 |
Region* AddRegion(); |
Region* AddRegion(); |
775 |
void DeleteRegion(Region* pRegion); |
void DeleteRegion(Region* pRegion); |
776 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
777 |
|
virtual void CopyAssign(const Instrument* orig); |
778 |
// own methods |
// own methods |
779 |
Region* GetRegion(unsigned int Key); |
Region* GetRegion(unsigned int Key); |
780 |
|
MidiRule* GetMidiRule(int i); |
781 |
|
MidiRuleCtrlTrigger* AddMidiRuleCtrlTrigger(); |
782 |
|
MidiRuleLegato* AddMidiRuleLegato(); |
783 |
|
MidiRuleAlternator* AddMidiRuleAlternator(); |
784 |
|
void DeleteMidiRule(int i); |
785 |
protected: |
protected: |
786 |
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 |
787 |
|
|
788 |
Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL); |
Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL); |
789 |
~Instrument(); |
~Instrument(); |
790 |
|
void CopyAssign(const Instrument* orig, const std::map<Sample*,Sample*>* mSamples); |
791 |
void UpdateRegionKeyTable(); |
void UpdateRegionKeyTable(); |
792 |
friend class File; |
friend class File; |
793 |
|
friend class Region; // so Region can call UpdateRegionKeyTable() |
794 |
|
private: |
795 |
|
MidiRule** pMidiRules; |
796 |
}; |
}; |
797 |
|
|
798 |
/** @brief Group of Gigasampler objects |
/** @brief Group of Gigasampler objects |
825 |
friend class File; |
friend class File; |
826 |
private: |
private: |
827 |
File* pFile; |
File* pFile; |
828 |
RIFF::Chunk* pNameChunk; |
RIFF::Chunk* pNameChunk; ///< '3gnm' chunk |
829 |
}; |
}; |
830 |
|
|
831 |
/** Parses Gigasampler files and provides abstract access to the data. */ |
/** Parses Gigasampler files and provides abstract access to the data. */ |
835 |
static const DLS::version_t VERSION_3; |
static const DLS::version_t VERSION_3; |
836 |
|
|
837 |
// derived attributes from DLS::Resource |
// derived attributes from DLS::Resource |
838 |
DLS::Resource::pInfo; |
using DLS::Resource::pInfo; |
839 |
DLS::Resource::pDLSID; |
using DLS::Resource::pDLSID; |
840 |
// derived attributes from DLS::File |
// derived attributes from DLS::File |
841 |
DLS::File::pVersion; |
using DLS::File::pVersion; |
842 |
DLS::File::Instruments; |
using DLS::File::Instruments; |
843 |
|
|
844 |
// derived methods from DLS::Resource |
// derived methods from DLS::Resource |
845 |
DLS::Resource::GetParent; |
using DLS::Resource::GetParent; |
846 |
// derived methods from DLS::File |
// derived methods from DLS::File |
847 |
DLS::File::Save; |
using DLS::File::Save; |
848 |
|
using DLS::File::GetFileName; |
849 |
|
using DLS::File::SetFileName; |
850 |
// overridden methods |
// overridden methods |
851 |
File(); |
File(); |
852 |
File(RIFF::File* pRIFF); |
File(RIFF::File* pRIFF); |
853 |
Sample* GetFirstSample(progress_t* pProgress = NULL); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
Sample* GetFirstSample(progress_t* pProgress = NULL); ///< Returns a pointer to the first <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
854 |
Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
Sample* GetNextSample(); ///< Returns a pointer to the next <i>Sample</i> object of the file, <i>NULL</i> otherwise. |
855 |
|
Sample* GetSample(uint index); |
856 |
Sample* AddSample(); |
Sample* AddSample(); |
857 |
void DeleteSample(Sample* pSample); |
void DeleteSample(Sample* pSample); |
858 |
Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
Instrument* GetFirstInstrument(); ///< Returns a pointer to the first <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
859 |
Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
Instrument* GetNextInstrument(); ///< Returns a pointer to the next <i>Instrument</i> object of the file, <i>NULL</i> otherwise. |
860 |
Instrument* GetInstrument(uint index, progress_t* pProgress = NULL); |
Instrument* GetInstrument(uint index, progress_t* pProgress = NULL); |
861 |
Instrument* AddInstrument(); |
Instrument* AddInstrument(); |
862 |
|
Instrument* AddDuplicateInstrument(const Instrument* orig); |
863 |
void DeleteInstrument(Instrument* pInstrument); |
void DeleteInstrument(Instrument* pInstrument); |
864 |
Group* GetFirstGroup(); ///< Returns a pointer to the first <i>Group</i> object of the file, <i>NULL</i> otherwise. |
Group* GetFirstGroup(); ///< Returns a pointer to the first <i>Group</i> object of the file, <i>NULL</i> otherwise. |
865 |
Group* GetNextGroup(); ///< Returns a pointer to the next <i>Group</i> object of the file, <i>NULL</i> otherwise. |
Group* GetNextGroup(); ///< Returns a pointer to the next <i>Group</i> object of the file, <i>NULL</i> otherwise. |
867 |
Group* AddGroup(); |
Group* AddGroup(); |
868 |
void DeleteGroup(Group* pGroup); |
void DeleteGroup(Group* pGroup); |
869 |
void DeleteGroupOnly(Group* pGroup); |
void DeleteGroupOnly(Group* pGroup); |
870 |
|
void SetAutoLoad(bool b); |
871 |
|
bool GetAutoLoad(); |
872 |
|
void AddContentOf(File* pFile); |
873 |
virtual ~File(); |
virtual ~File(); |
874 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
875 |
protected: |
protected: |
885 |
friend class Sample; |
friend class Sample; |
886 |
friend class Group; // so Group can access protected member pRIFF |
friend class Group; // so Group can access protected member pRIFF |
887 |
private: |
private: |
|
static const DLS::Info::FixedStringLength FixedStringLengths[]; |
|
888 |
std::list<Group*>* pGroups; |
std::list<Group*>* pGroups; |
889 |
std::list<Group*>::iterator GroupsIterator; |
std::list<Group*>::iterator GroupsIterator; |
890 |
|
bool bAutoLoad; |
891 |
}; |
}; |
892 |
|
|
893 |
/** |
/** |