--- libgig/trunk/src/gig.cpp 2007/11/25 17:29:37 1524 +++ libgig/trunk/src/gig.cpp 2009/03/22 11:13:25 1869 @@ -2,7 +2,7 @@ * * * libgig - C++ cross-platform Gigasampler format file access library * * * - * Copyright (C) 2003-2007 by Christian Schoenebeck * + * Copyright (C) 2003-2009 by Christian Schoenebeck * * * * * * This library is free software; you can redistribute it and/or modify * @@ -25,6 +25,7 @@ #include "helper.h" +#include #include #include @@ -676,6 +677,7 @@ if (SampleCount > this->SamplesTotal) SampleCount = this->SamplesTotal; if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; unsigned long allocationsize = (SampleCount + NullSamplesCount) * this->FrameSize; + SetPos(0); // reset read position to begin of sample RAMCache.pStart = new int8_t[allocationsize]; RAMCache.Size = Read(RAMCache.pStart, SampleCount) * this->FrameSize; RAMCache.NullExtensionSize = allocationsize - RAMCache.Size; @@ -713,6 +715,7 @@ if (RAMCache.pStart) delete[] (int8_t*) RAMCache.pStart; RAMCache.pStart = NULL; RAMCache.Size = 0; + RAMCache.NullExtensionSize = 0; } /** @brief Resize sample. @@ -1834,7 +1837,7 @@ const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth : uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */ - pData[116] = eg3depth; + store16(&pData[116], eg3depth); // next 2 bytes unknown @@ -2923,6 +2926,27 @@ } +// *************** MidiRule *************** +// * + +MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(RIFF::Chunk* _3ewg) { + _3ewg->SetPos(36); + Triggers = _3ewg->ReadUint8(); + _3ewg->SetPos(40); + ControllerNumber = _3ewg->ReadUint8(); + _3ewg->SetPos(46); + for (int i = 0 ; i < Triggers ; i++) { + pTriggers[i].TriggerPoint = _3ewg->ReadUint8(); + pTriggers[i].Descending = _3ewg->ReadUint8(); + pTriggers[i].VelSensitivity = _3ewg->ReadUint8(); + pTriggers[i].Key = _3ewg->ReadUint8(); + pTriggers[i].NoteOff = _3ewg->ReadUint8(); + pTriggers[i].Velocity = _3ewg->ReadUint8(); + pTriggers[i].OverridePedal = _3ewg->ReadUint8(); + _3ewg->ReadUint8(); + } +} + // *************** Instrument *************** // * @@ -2944,6 +2968,8 @@ PianoReleaseMode = false; DimensionKeyRange.low = 0; DimensionKeyRange.high = 0; + pMidiRules = new MidiRule*[3]; + pMidiRules[0] = NULL; // Loading RIFF::List* lart = insList->GetSubList(LIST_TYPE_LART); @@ -2958,6 +2984,21 @@ PianoReleaseMode = dimkeystart & 0x01; DimensionKeyRange.low = dimkeystart >> 1; DimensionKeyRange.high = _3ewg->ReadUint8(); + + if (_3ewg->GetSize() > 32) { + // read MIDI rules + int i = 0; + _3ewg->SetPos(32); + uint8_t id1 = _3ewg->ReadUint8(); + uint8_t id2 = _3ewg->ReadUint8(); + + if (id1 == 4 && id2 == 16) { + pMidiRules[i++] = new MidiRuleCtrlTrigger(_3ewg); + } + //TODO: all the other types of rules + + pMidiRules[i] = NULL; + } } } @@ -2994,6 +3035,7 @@ } Instrument::~Instrument() { + delete[] pMidiRules; } /** @@ -3108,6 +3150,19 @@ UpdateRegionKeyTable(); } + /** + * Returns a MIDI rule of the instrument. + * + * The list of MIDI rules, at least in gig v3, always contains at + * most two rules. The second rule can only be the DEF filter + * (which currently isn't supported by libgig). + * + * @param i - MIDI rule number + * @returns pointer address to MIDI rule number i or NULL if there is none + */ + MidiRule* Instrument::GetMidiRule(int i) { + return pMidiRules[i]; + } // *************** Group *************** @@ -3351,6 +3406,7 @@ pSamples->erase(iter); delete pSample; + SampleList::iterator tmp = SamplesIterator; // remove all references to the sample for (Instrument* instrument = GetFirstInstrument() ; instrument ; instrument = GetNextInstrument()) { @@ -3365,6 +3421,7 @@ } } } + SamplesIterator = tmp; // restore iterator } void File::LoadSamples() {