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; |
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(Region* pParent, RIFF::List* _3ewl); |
DimensionRegion(Region* pParent, RIFF::List* _3ewl); |
502 |
|
|
503 |
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController); |
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController); |
504 |
_lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController); |
_lev_ctrl_t EncodeLeverageController(leverage_ctrl_t DecodedController); |
505 |
|
double* GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth); |
506 |
|
double* GetCutoffVelocityTable(curve_type_t vcfVelocityCurve, uint8_t vcfVelocityDynamicRange, uint8_t vcfVelocityScale, vcf_cutoff_ctrl_t vcfCutoffController); |
507 |
double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
508 |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling); |
509 |
}; |
}; |
577 |
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) |
578 |
RIFF::Chunk* pCk3gix; |
RIFF::Chunk* pCk3gix; |
579 |
RIFF::Chunk* pCkSmpl; |
RIFF::Chunk* pCkSmpl; |
580 |
CRC crc; ///< CRC-32 checksum of the raw sample data |
uint32_t crc; ///< CRC-32 checksum of the raw sample data |
581 |
|
|
582 |
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); |
583 |
~Sample(); |
~Sample(); |
629 |
// overridden methods |
// overridden methods |
630 |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
virtual void SetKeyRange(uint16_t Low, uint16_t High); |
631 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
632 |
|
virtual void CopyAssign(const Region* orig); |
633 |
protected: |
protected: |
634 |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
Region(Instrument* pInstrument, RIFF::List* rgnList); |
635 |
void LoadDimensionRegions(RIFF::List* rgn); |
void LoadDimensionRegions(RIFF::List* rgn); |
639 |
friend class Instrument; |
friend class Instrument; |
640 |
}; |
}; |
641 |
|
|
642 |
|
/** Abstract base class for all MIDI rules. */ |
643 |
|
class MidiRule { |
644 |
|
public: |
645 |
|
virtual ~MidiRule() { } |
646 |
|
}; |
647 |
|
|
648 |
|
/** MIDI rule for triggering notes by control change events. */ |
649 |
|
class MidiRuleCtrlTrigger : public MidiRule { |
650 |
|
public: |
651 |
|
uint8_t ControllerNumber; ///< MIDI controller number. |
652 |
|
uint8_t Triggers; ///< Number of triggers. |
653 |
|
struct trigger_t { |
654 |
|
uint8_t TriggerPoint; ///< The CC value to pass for the note to be triggered. |
655 |
|
bool Descending; ///< If the change in CC value should be downwards. |
656 |
|
uint8_t VelSensitivity; ///< How sensitive the velocity should be to the speed of the controller change. |
657 |
|
uint8_t Key; ///< Key to trigger. |
658 |
|
bool NoteOff; ///< If a note off should be triggered instead of a note on. |
659 |
|
uint8_t Velocity; ///< Velocity of the note to trigger. 255 means that velocity should depend on the speed of the controller change. |
660 |
|
bool OverridePedal; ///< If a note off should be triggered even if the sustain pedal is down. |
661 |
|
} pTriggers[32]; |
662 |
|
|
663 |
|
protected: |
664 |
|
MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg); |
665 |
|
friend class Instrument; |
666 |
|
}; |
667 |
|
|
668 |
/** Provides all neccessary information for the synthesis of an <i>Instrument</i>. */ |
/** Provides all neccessary information for the synthesis of an <i>Instrument</i>. */ |
669 |
class Instrument : protected DLS::Instrument { |
class Instrument : protected DLS::Instrument { |
670 |
public: |
public: |
671 |
// derived attributes from DLS::Resource |
// derived attributes from DLS::Resource |
672 |
DLS::Resource::pInfo; |
using DLS::Resource::pInfo; |
673 |
DLS::Resource::pDLSID; |
using DLS::Resource::pDLSID; |
674 |
// derived attributes from DLS::Instrument |
// derived attributes from DLS::Instrument |
675 |
DLS::Instrument::IsDrum; |
using DLS::Instrument::IsDrum; |
676 |
DLS::Instrument::MIDIBank; |
using DLS::Instrument::MIDIBank; |
677 |
DLS::Instrument::MIDIBankCoarse; |
using DLS::Instrument::MIDIBankCoarse; |
678 |
DLS::Instrument::MIDIBankFine; |
using DLS::Instrument::MIDIBankFine; |
679 |
DLS::Instrument::MIDIProgram; |
using DLS::Instrument::MIDIProgram; |
680 |
DLS::Instrument::Regions; |
using DLS::Instrument::Regions; |
681 |
// own attributes |
// own attributes |
682 |
int32_t Attenuation; ///< in dB |
int32_t Attenuation; ///< in dB |
683 |
uint16_t EffectSend; |
uint16_t EffectSend; |
688 |
|
|
689 |
|
|
690 |
// derived methods from DLS::Resource |
// derived methods from DLS::Resource |
691 |
DLS::Resource::GetParent; |
using DLS::Resource::GetParent; |
692 |
// overridden methods |
// overridden methods |
693 |
Region* GetFirstRegion(); |
Region* GetFirstRegion(); |
694 |
Region* GetNextRegion(); |
Region* GetNextRegion(); |
695 |
Region* AddRegion(); |
Region* AddRegion(); |
696 |
void DeleteRegion(Region* pRegion); |
void DeleteRegion(Region* pRegion); |
697 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
698 |
|
virtual void CopyAssign(const Instrument* orig); |
699 |
// own methods |
// own methods |
700 |
Region* GetRegion(unsigned int Key); |
Region* GetRegion(unsigned int Key); |
701 |
|
MidiRule* GetMidiRule(int i); |
702 |
protected: |
protected: |
703 |
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 |
704 |
|
|
707 |
void UpdateRegionKeyTable(); |
void UpdateRegionKeyTable(); |
708 |
friend class File; |
friend class File; |
709 |
friend class Region; // so Region can call UpdateRegionKeyTable() |
friend class Region; // so Region can call UpdateRegionKeyTable() |
710 |
|
private: |
711 |
|
MidiRule** pMidiRules; |
712 |
}; |
}; |
713 |
|
|
714 |
/** @brief Group of Gigasampler objects |
/** @brief Group of Gigasampler objects |
751 |
static const DLS::version_t VERSION_3; |
static const DLS::version_t VERSION_3; |
752 |
|
|
753 |
// derived attributes from DLS::Resource |
// derived attributes from DLS::Resource |
754 |
DLS::Resource::pInfo; |
using DLS::Resource::pInfo; |
755 |
DLS::Resource::pDLSID; |
using DLS::Resource::pDLSID; |
756 |
// derived attributes from DLS::File |
// derived attributes from DLS::File |
757 |
DLS::File::pVersion; |
using DLS::File::pVersion; |
758 |
DLS::File::Instruments; |
using DLS::File::Instruments; |
759 |
|
|
760 |
// derived methods from DLS::Resource |
// derived methods from DLS::Resource |
761 |
DLS::Resource::GetParent; |
using DLS::Resource::GetParent; |
762 |
// derived methods from DLS::File |
// derived methods from DLS::File |
763 |
DLS::File::Save; |
using DLS::File::Save; |
764 |
|
using DLS::File::GetFileName; |
765 |
// overridden methods |
// overridden methods |
766 |
File(); |
File(); |
767 |
File(RIFF::File* pRIFF); |
File(RIFF::File* pRIFF); |
773 |
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. |
774 |
Instrument* GetInstrument(uint index, progress_t* pProgress = NULL); |
Instrument* GetInstrument(uint index, progress_t* pProgress = NULL); |
775 |
Instrument* AddInstrument(); |
Instrument* AddInstrument(); |
776 |
|
Instrument* AddDuplicateInstrument(const Instrument* orig); |
777 |
void DeleteInstrument(Instrument* pInstrument); |
void DeleteInstrument(Instrument* pInstrument); |
778 |
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. |
779 |
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. |
781 |
Group* AddGroup(); |
Group* AddGroup(); |
782 |
void DeleteGroup(Group* pGroup); |
void DeleteGroup(Group* pGroup); |
783 |
void DeleteGroupOnly(Group* pGroup); |
void DeleteGroupOnly(Group* pGroup); |
784 |
|
void SetAutoLoad(bool b); |
785 |
|
bool GetAutoLoad(); |
786 |
virtual ~File(); |
virtual ~File(); |
787 |
virtual void UpdateChunks(); |
virtual void UpdateChunks(); |
788 |
protected: |
protected: |
798 |
friend class Sample; |
friend class Sample; |
799 |
friend class Group; // so Group can access protected member pRIFF |
friend class Group; // so Group can access protected member pRIFF |
800 |
private: |
private: |
|
static const DLS::Info::FixedStringLength FixedStringLengths[]; |
|
801 |
std::list<Group*>* pGroups; |
std::list<Group*>* pGroups; |
802 |
std::list<Group*>::iterator GroupsIterator; |
std::list<Group*>::iterator GroupsIterator; |
803 |
|
bool bAutoLoad; |
804 |
}; |
}; |
805 |
|
|
806 |
/** |
/** |