00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __GIG_H__
00025 #define __GIG_H__
00026
00027 #include "DLS.h"
00028
00029 #include <math.h>
00030 #include <string.h>
00031
00037 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB
00038
00039 #if WORDS_BIGENDIAN
00040 # define LIST_TYPE_3PRG 0x33707267
00041 # define LIST_TYPE_3EWL 0x3365776C
00042 # define CHUNK_ID_SMPL 0x736D706C
00043 # define CHUNK_ID_3GIX 0x33676978
00044 # define CHUNK_ID_3EWA 0x33657761
00045 # define CHUNK_ID_3LNK 0x336C6E6B
00046 # define CHUNK_ID_3EWG 0x33657767
00047 # define CHUNK_ID_EWAV 0x65776176
00048 #else // little endian
00049 # define LIST_TYPE_3PRG 0x67727033
00050 # define LIST_TYPE_3EWL 0x6C776533
00051 # define CHUNK_ID_SMPL 0x6C706D73
00052 # define CHUNK_ID_3GIX 0x78696733
00053 # define CHUNK_ID_3EWA 0x61776533
00054 # define CHUNK_ID_3LNK 0x6B6E6C33
00055 # define CHUNK_ID_3EWG 0x67776533
00056 # define CHUNK_ID_EWAV 0x76617765
00057 #endif // WORDS_BIGENDIAN
00058
00060 #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x))
00061 #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01))
00062 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03)
00063 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03)
00064 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03)
00065 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03)
00066
00068 namespace gig {
00069
00070 typedef std::string String;
00071
00073 struct range_t {
00074 uint8_t low;
00075 uint8_t high;
00076 };
00077
00079 struct buffer_t {
00080 void* pStart;
00081 unsigned long Size;
00082 unsigned long NullExtensionSize;
00083 buffer_t() {
00084 pStart = NULL;
00085 Size = 0;
00086 NullExtensionSize = 0;
00087 }
00088 };
00089
00091 typedef enum {
00092 loop_type_normal = 0x00000000,
00093 loop_type_bidirectional = 0x00000001,
00094 loop_type_backward = 0x00000002
00095 } loop_type_t;
00096
00098 typedef enum {
00099 smpte_format_no_offset = 0x00000000,
00100 smpte_format_24_frames = 0x00000018,
00101 smpte_format_25_frames = 0x00000019,
00102 smpte_format_30_frames_dropping = 0x0000001D,
00103 smpte_format_30_frames = 0x0000001E
00104 } smpte_format_t;
00105
00107 typedef enum {
00108 curve_type_nonlinear = 0,
00109 curve_type_linear = 1,
00110 curve_type_special = 2,
00111 curve_type_unknown = 0xffffffff
00112 } curve_type_t;
00113
00115 typedef enum {
00116 dim_bypass_ctrl_none,
00117 dim_bypass_ctrl_94,
00118 dim_bypass_ctrl_95
00119 } dim_bypass_ctrl_t;
00120
00122 typedef enum {
00123 lfo3_ctrl_internal = 0x00,
00124 lfo3_ctrl_modwheel = 0x01,
00125 lfo3_ctrl_aftertouch = 0x02,
00126 lfo3_ctrl_internal_modwheel = 0x03,
00127 lfo3_ctrl_internal_aftertouch = 0x04
00128 } lfo3_ctrl_t;
00129
00131 typedef enum {
00132 lfo2_ctrl_internal = 0x00,
00133 lfo2_ctrl_modwheel = 0x01,
00134 lfo2_ctrl_foot = 0x02,
00135 lfo2_ctrl_internal_modwheel = 0x03,
00136 lfo2_ctrl_internal_foot = 0x04
00137 } lfo2_ctrl_t;
00138
00140 typedef enum {
00141 lfo1_ctrl_internal = 0x00,
00142 lfo1_ctrl_modwheel = 0x01,
00143 lfo1_ctrl_breath = 0x02,
00144 lfo1_ctrl_internal_modwheel = 0x03,
00145 lfo1_ctrl_internal_breath = 0x04
00146 } lfo1_ctrl_t;
00147
00149 typedef enum {
00150 vcf_cutoff_ctrl_none = 0x00,
00151 vcf_cutoff_ctrl_modwheel = 0x81,
00152 vcf_cutoff_ctrl_effect1 = 0x8c,
00153 vcf_cutoff_ctrl_effect2 = 0x8d,
00154 vcf_cutoff_ctrl_breath = 0x82,
00155 vcf_cutoff_ctrl_foot = 0x84,
00156 vcf_cutoff_ctrl_sustainpedal = 0xc0,
00157 vcf_cutoff_ctrl_softpedal = 0xc3,
00158 vcf_cutoff_ctrl_genpurpose7 = 0xd2,
00159 vcf_cutoff_ctrl_genpurpose8 = 0xd3,
00160 vcf_cutoff_ctrl_aftertouch = 0x80
00161 } vcf_cutoff_ctrl_t;
00162
00164 typedef enum {
00165 vcf_res_ctrl_none = 0xffffffff,
00166 vcf_res_ctrl_genpurpose3 = 0,
00167 vcf_res_ctrl_genpurpose4 = 1,
00168 vcf_res_ctrl_genpurpose5 = 2,
00169 vcf_res_ctrl_genpurpose6 = 3
00170 } vcf_res_ctrl_t;
00171
00180 struct leverage_ctrl_t {
00181 typedef enum {
00182 type_none = 0x00,
00183 type_channelaftertouch = 0x2f,
00184 type_velocity = 0xff,
00185 type_controlchange = 0xfe
00186 } type_t;
00187
00188 type_t type;
00189 uint controller_number;
00190 };
00191
00197 typedef leverage_ctrl_t attenuation_ctrl_t;
00198
00204 typedef leverage_ctrl_t eg1_ctrl_t;
00205
00211 typedef leverage_ctrl_t eg2_ctrl_t;
00212
00220 typedef enum {
00221 dimension_none = 0x00,
00222 dimension_samplechannel = 0x80,
00223 dimension_layer = 0x81,
00224 dimension_velocity = 0x82,
00225 dimension_channelaftertouch = 0x83,
00226 dimension_releasetrigger = 0x84,
00227 dimension_keyboard = 0x85,
00228 dimension_roundrobin = 0x86,
00229 dimension_random = 0x87,
00230 dimension_modwheel = 0x01,
00231 dimension_breath = 0x02,
00232 dimension_foot = 0x04,
00233 dimension_portamentotime = 0x05,
00234 dimension_effect1 = 0x0c,
00235 dimension_effect2 = 0x0d,
00236 dimension_genpurpose1 = 0x10,
00237 dimension_genpurpose2 = 0x11,
00238 dimension_genpurpose3 = 0x12,
00239 dimension_genpurpose4 = 0x13,
00240 dimension_sustainpedal = 0x40,
00241 dimension_portamento = 0x41,
00242 dimension_sostenutopedal = 0x42,
00243 dimension_softpedal = 0x43,
00244 dimension_genpurpose5 = 0x30,
00245 dimension_genpurpose6 = 0x31,
00246 dimension_genpurpose7 = 0x32,
00247 dimension_genpurpose8 = 0x33,
00248 dimension_effect1depth = 0x5b,
00249 dimension_effect2depth = 0x5c,
00250 dimension_effect3depth = 0x5d,
00251 dimension_effect4depth = 0x5e,
00252 dimension_effect5depth = 0x5f
00253 } dimension_t;
00254
00259 typedef enum {
00260 split_type_normal,
00261 split_type_customvelocity,
00262 split_type_bit
00263 } split_type_t;
00264
00266 struct dimension_def_t {
00267 dimension_t dimension;
00268 uint8_t bits;
00269 uint8_t zones;
00270 split_type_t split_type;
00271 range_t* ranges;
00272 unsigned int zone_size;
00273 };
00274
00276 typedef enum {
00277 vcf_type_lowpass = 0x00,
00278 vcf_type_lowpassturbo = 0xff,
00279 vcf_type_bandpass = 0x01,
00280 vcf_type_highpass = 0x02,
00281 vcf_type_bandreject = 0x03
00282 } vcf_type_t;
00283
00291 struct crossfade_t {
00292 #if WORDS_BIGENDIAN
00293 uint8_t out_end;
00294 uint8_t out_start;
00295 uint8_t in_end;
00296 uint8_t in_start;
00297 #else // little endian
00298 uint8_t in_start;
00299 uint8_t in_end;
00300 uint8_t out_start;
00301 uint8_t out_end;
00302 #endif // WORDS_BIGENDIAN
00303 };
00304
00306 struct playback_state_t {
00307 unsigned long position;
00308 bool reverse;
00309 unsigned long loop_cycles_left;
00310 };
00311
00324 struct progress_t {
00325 void (*callback)(progress_t*);
00326 float factor;
00327 void* custom;
00328 float __range_min;
00329 float __range_max;
00330 progress_t();
00331 };
00332
00333
00334 class File;
00335 class Instrument;
00336 class Sample;
00337 class Region;
00338
00351 class DimensionRegion : protected DLS::Sampler {
00352 public:
00353 uint8_t VelocityUpperLimit;
00354 Sample* pSample;
00355
00356 uint16_t EG1PreAttack;
00357 double EG1Attack;
00358 double EG1Decay1;
00359 double EG1Decay2;
00360 bool EG1InfiniteSustain;
00361 uint16_t EG1Sustain;
00362 double EG1Release;
00363 bool EG1Hold;
00364 eg1_ctrl_t EG1Controller;
00365 bool EG1ControllerInvert;
00366 uint8_t EG1ControllerAttackInfluence;
00367 uint8_t EG1ControllerDecayInfluence;
00368 uint8_t EG1ControllerReleaseInfluence;
00369 double LFO1Frequency;
00370 uint16_t LFO1InternalDepth;
00371 uint16_t LFO1ControlDepth;
00372 lfo1_ctrl_t LFO1Controller;
00373 bool LFO1FlipPhase;
00374 bool LFO1Sync;
00375
00376 uint16_t EG2PreAttack;
00377 double EG2Attack;
00378 double EG2Decay1;
00379 double EG2Decay2;
00380 bool EG2InfiniteSustain;
00381 uint16_t EG2Sustain;
00382 double EG2Release;
00383 eg2_ctrl_t EG2Controller;
00384 bool EG2ControllerInvert;
00385 uint8_t EG2ControllerAttackInfluence;
00386 uint8_t EG2ControllerDecayInfluence;
00387 uint8_t EG2ControllerReleaseInfluence;
00388 double LFO2Frequency;
00389 uint16_t LFO2InternalDepth;
00390 uint16_t LFO2ControlDepth;
00391 lfo2_ctrl_t LFO2Controller;
00392 bool LFO2FlipPhase;
00393 bool LFO2Sync;
00394
00395 double EG3Attack;
00396 int16_t EG3Depth;
00397 double LFO3Frequency;
00398 int16_t LFO3InternalDepth;
00399 int16_t LFO3ControlDepth;
00400 lfo3_ctrl_t LFO3Controller;
00401 bool LFO3Sync;
00402
00403 bool VCFEnabled;
00404 vcf_type_t VCFType;
00405 vcf_cutoff_ctrl_t VCFCutoffController;
00406 bool VCFCutoffControllerInvert;
00407 uint8_t VCFCutoff;
00408 curve_type_t VCFVelocityCurve;
00409 uint8_t VCFVelocityScale;
00410 uint8_t VCFVelocityDynamicRange;
00411 uint8_t VCFResonance;
00412 bool VCFResonanceDynamic;
00413 vcf_res_ctrl_t VCFResonanceController;
00414 bool VCFKeyboardTracking;
00415 uint8_t VCFKeyboardTrackingBreakpoint;
00416
00417 curve_type_t VelocityResponseCurve;
00418 uint8_t VelocityResponseDepth;
00419 uint8_t VelocityResponseCurveScaling;
00420 curve_type_t ReleaseVelocityResponseCurve;
00421 uint8_t ReleaseVelocityResponseDepth;
00422 uint8_t ReleaseTriggerDecay;
00423
00424 crossfade_t Crossfade;
00425 bool PitchTrack;
00426 dim_bypass_ctrl_t DimensionBypass;
00427 int8_t Pan;
00428 bool SelfMask;
00429 attenuation_ctrl_t AttenuationController;
00430 bool InvertAttenuationController;
00431 uint8_t AttenuationControllerThreshold;
00432 uint8_t ChannelOffset;
00433 bool SustainDefeat;
00434 bool MSDecode;
00435 uint16_t SampleStartOffset;
00436 double SampleAttenuation;
00437
00438
00439 DLS::Sampler::UnityNote;
00440 DLS::Sampler::FineTune;
00441 DLS::Sampler::Gain;
00442 DLS::Sampler::SampleLoops;
00443 DLS::Sampler::pSampleLoops;
00444
00445
00446 double GetVelocityAttenuation(uint8_t MIDIKeyVelocity);
00447 double GetVelocityRelease(uint8_t MIDIKeyVelocity);
00448 double GetVelocityCutoff(uint8_t MIDIKeyVelocity);
00449
00450 protected:
00451 DimensionRegion(RIFF::List* _3ewl);
00452 ~DimensionRegion();
00453 friend class Region;
00454 private:
00455 typedef enum {
00456 _lev_ctrl_none = 0x00,
00457 _lev_ctrl_modwheel = 0x03,
00458 _lev_ctrl_breath = 0x05,
00459 _lev_ctrl_foot = 0x07,
00460 _lev_ctrl_effect1 = 0x0d,
00461 _lev_ctrl_effect2 = 0x0f,
00462 _lev_ctrl_genpurpose1 = 0x11,
00463 _lev_ctrl_genpurpose2 = 0x13,
00464 _lev_ctrl_genpurpose3 = 0x15,
00465 _lev_ctrl_genpurpose4 = 0x17,
00466 _lev_ctrl_portamentotime = 0x0b,
00467 _lev_ctrl_sustainpedal = 0x01,
00468 _lev_ctrl_portamento = 0x19,
00469 _lev_ctrl_sostenutopedal = 0x1b,
00470 _lev_ctrl_softpedal = 0x09,
00471 _lev_ctrl_genpurpose5 = 0x1d,
00472 _lev_ctrl_genpurpose6 = 0x1f,
00473 _lev_ctrl_genpurpose7 = 0x21,
00474 _lev_ctrl_genpurpose8 = 0x23,
00475 _lev_ctrl_effect1depth = 0x25,
00476 _lev_ctrl_effect2depth = 0x27,
00477 _lev_ctrl_effect3depth = 0x29,
00478 _lev_ctrl_effect4depth = 0x2b,
00479 _lev_ctrl_effect5depth = 0x2d,
00480 _lev_ctrl_channelaftertouch = 0x2f,
00481 _lev_ctrl_velocity = 0xff
00482 } _lev_ctrl_t;
00483 typedef std::map<uint32_t, double*> VelocityTableMap;
00484
00485 static uint Instances;
00486 static VelocityTableMap* pVelocityTables;
00487 double* pVelocityAttenuationTable;
00488 double* pVelocityReleaseTable;
00489 double* pVelocityCutoffTable;
00490
00491 leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController);
00492 double* GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
00493 double* CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling);
00494 };
00495
00497 class Sample : public DLS::Sample {
00498 public:
00499 uint16_t SampleGroup;
00500 uint32_t Manufacturer;
00501 uint32_t Product;
00502 uint32_t SamplePeriod;
00503 uint32_t MIDIUnityNote;
00504 uint32_t FineTune;
00505 smpte_format_t SMPTEFormat;
00506 uint32_t SMPTEOffset;
00507 uint32_t Loops;
00508 uint32_t LoopID;
00509 loop_type_t LoopType;
00510 uint32_t LoopStart;
00511 uint32_t LoopEnd;
00512 uint32_t LoopSize;
00513 uint32_t LoopFraction;
00514 uint32_t LoopPlayCount;
00515 bool Compressed;
00516 uint32_t TruncatedBits;
00517 bool Dithered;
00518
00519
00520 buffer_t LoadSampleData();
00521 buffer_t LoadSampleData(unsigned long SampleCount);
00522 buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount);
00523 buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount);
00524 buffer_t GetCache();
00525
00526 static buffer_t CreateDecompressionBuffer(unsigned long MaxReadSize);
00527 static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer);
00528
00529 void ReleaseSampleData();
00530 unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start);
00531 unsigned long GetPos();
00532 unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL);
00533 unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, buffer_t* pExternalDecompressionBuffer = NULL);
00534 protected:
00535 static unsigned int Instances;
00536 static buffer_t InternalDecompressionBuffer;
00537 unsigned long FrameOffset;
00538 unsigned long* FrameTable;
00539 unsigned long SamplePos;
00540 unsigned long SamplesInLastFrame;
00541 unsigned long WorstCaseFrameSize;
00542 unsigned long SamplesPerFrame;
00543 buffer_t RAMCache;
00544 unsigned long FileNo;
00545
00546 Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0);
00547 ~Sample();
00556 inline void SwapMemoryArea(void* pData, unsigned long AreaSize, uint WordSize) {
00557 switch (WordSize) {
00558 case 1: {
00559 uint8_t* pDst = (uint8_t*) pData;
00560 uint8_t cache;
00561 unsigned long lo = 0, hi = AreaSize - 1;
00562 for (; lo < hi; hi--, lo++) {
00563 cache = pDst[lo];
00564 pDst[lo] = pDst[hi];
00565 pDst[hi] = cache;
00566 }
00567 break;
00568 }
00569 case 2: {
00570 uint16_t* pDst = (uint16_t*) pData;
00571 uint16_t cache;
00572 unsigned long lo = 0, hi = (AreaSize >> 1) - 1;
00573 for (; lo < hi; hi--, lo++) {
00574 cache = pDst[lo];
00575 pDst[lo] = pDst[hi];
00576 pDst[hi] = cache;
00577 }
00578 break;
00579 }
00580 case 4: {
00581 uint32_t* pDst = (uint32_t*) pData;
00582 uint32_t cache;
00583 unsigned long lo = 0, hi = (AreaSize >> 2) - 1;
00584 for (; lo < hi; hi--, lo++) {
00585 cache = pDst[lo];
00586 pDst[lo] = pDst[hi];
00587 pDst[hi] = cache;
00588 }
00589 break;
00590 }
00591 default: {
00592 uint8_t* pCache = new uint8_t[WordSize];
00593 unsigned long lo = 0, hi = AreaSize - WordSize;
00594 for (; lo < hi; hi -= WordSize, lo += WordSize) {
00595 memcpy(pCache, (uint8_t*) pData + lo, WordSize);
00596 memcpy((uint8_t*) pData + lo, (uint8_t*) pData + hi, WordSize);
00597 memcpy((uint8_t*) pData + hi, pCache, WordSize);
00598 }
00599 delete[] pCache;
00600 break;
00601 }
00602 }
00603 }
00604 inline long Min(long A, long B) {
00605 return (A > B) ? B : A;
00606 }
00607 inline long Abs(long val) { return (val > 0) ? val : -val; }
00608
00609
00610 inline unsigned long GuessSize(unsigned long samples) {
00611
00612
00613
00614
00615
00616
00617 const unsigned long size =
00618 BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13
00619 : samples + (samples >> 10) * 5;
00620
00621
00622 return (Channels == 2 ? size << 1 : size) + WorstCaseFrameSize;
00623 }
00624
00625
00626
00627 inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) {
00628 return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame);
00629 }
00630 private:
00631 void ScanCompressedSample();
00632 friend class File;
00633 friend class Region;
00634 };
00635
00636
00638 class Region : public DLS::Region {
00639 public:
00640 unsigned int Dimensions;
00641 dimension_def_t pDimensionDefinitions[8];
00642 uint32_t DimensionRegions;
00643 DimensionRegion* pDimensionRegions[256];
00644 unsigned int Layers;
00645
00646 DimensionRegion* GetDimensionRegionByValue(const uint DimValues[8]);
00647 DimensionRegion* GetDimensionRegionByBit(const uint8_t DimBits[8]);
00648 Sample* GetSample();
00649 protected:
00650 uint8_t VelocityTable[128];
00651
00652 Region(Instrument* pInstrument, RIFF::List* rgnList);
00653 void LoadDimensionRegions(RIFF::List* rgn);
00654 Sample* GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress = NULL);
00655 ~Region();
00656 friend class Instrument;
00657 };
00658
00660 class Instrument : protected DLS::Instrument {
00661 public:
00662
00663 DLS::Resource::pInfo;
00664 DLS::Resource::pDLSID;
00665
00666 DLS::Instrument::IsDrum;
00667 DLS::Instrument::MIDIBank;
00668 DLS::Instrument::MIDIBankCoarse;
00669 DLS::Instrument::MIDIBankFine;
00670 DLS::Instrument::MIDIProgram;
00671 DLS::Instrument::Regions;
00672
00673 int32_t Attenuation;
00674 uint16_t EffectSend;
00675 int16_t FineTune;
00676 uint16_t PitchbendRange;
00677 bool PianoReleaseMode;
00678 range_t DimensionKeyRange;
00679
00680
00681
00682 DLS::Resource::GetParent;
00683
00684 Region* GetFirstRegion();
00685 Region* GetNextRegion();
00686
00687 Region* GetRegion(unsigned int Key);
00688 protected:
00689 Region** pRegions;
00690 Region* RegionKeyTable[128];
00691 int RegionIndex;
00692
00693 Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress = NULL);
00694 ~Instrument();
00695 friend class File;
00696 };
00697
00698
00700 class File : protected DLS::File {
00701 public:
00702
00703 DLS::Resource::pInfo;
00704 DLS::Resource::pDLSID;
00705
00706 DLS::File::pVersion;
00707 DLS::File::Instruments;
00708
00709
00710 DLS::Resource::GetParent;
00711
00712 File(RIFF::File* pRIFF);
00713 Sample* GetFirstSample(progress_t* pProgress = NULL);
00714 Sample* GetNextSample();
00715 Instrument* GetFirstInstrument();
00716 Instrument* GetNextInstrument();
00717 Instrument* GetInstrument(uint index, progress_t* pProgress = NULL);
00718 ~File();
00719 protected:
00720 typedef std::list<Sample*> SampleList;
00721 typedef std::list<Instrument*> InstrumentList;
00722
00723 SampleList* pSamples;
00724 SampleList::iterator SamplesIterator;
00725 InstrumentList* pInstruments;
00726 InstrumentList::iterator InstrumentsIterator;
00727
00728 void LoadSamples(progress_t* pProgress = NULL);
00729 void LoadInstruments(progress_t* pProgress = NULL);
00730 friend class Region;
00731
00732 std::list<RIFF::File*> ExtensionFiles;
00733 };
00734
00736 class Exception : public DLS::Exception {
00737 public:
00738 Exception(String Message);
00739 void PrintMessage();
00740 };
00741
00742 String libraryName();
00743 String libraryVersion();
00744
00745 }
00746
00747 #endif // __GIG_H__