--- libgig/trunk/src/DLS.cpp 2007/05/13 13:24:22 1184 +++ libgig/trunk/src/DLS.cpp 2007/09/09 21:22:58 1335 @@ -25,6 +25,12 @@ #include +#ifdef __APPLE__ +#include +#elif defined(HAVE_UUID_UUID_H) +#include +#endif + #include "helper.h" // macros to decode connection transforms @@ -293,6 +299,7 @@ for (int i = 0 ; FixedStringLengths[i].length ; i++) { if (FixedStringLengths[i].chunkId == ChunkID) { size = FixedStringLengths[i].length; + break; } } } @@ -407,9 +414,63 @@ */ void Resource::UpdateChunks() { pInfo->UpdateChunks(); - //TODO: save DLSID + + if (pDLSID) { + // make sure 'dlid' chunk exists + RIFF::Chunk* ckDLSID = pResourceList->GetSubChunk(CHUNK_ID_DLID); + if (!ckDLSID) ckDLSID = pResourceList->AddSubChunk(CHUNK_ID_DLID, 16); + uint8_t* pData = (uint8_t*)ckDLSID->LoadChunkData(); + // update 'dlid' chunk + store32(&pData[0], pDLSID->ulData1); + store16(&pData[4], pDLSID->usData2); + store16(&pData[6], pDLSID->usData3); + memcpy(&pData[8], pDLSID->abData, 8); + } } + /** + * Generates a new DLSID for the resource. + */ + void Resource::GenerateDLSID() { +#if defined(WIN32) || defined(__APPLE__) || defined(HAVE_UUID_GENERATE) + + if (!pDLSID) pDLSID = new dlsid_t; + +#ifdef WIN32 + + UUID uuid; + UuidCreate(&uuid); + pDLSID->ulData1 = uuid.Data1; + pDLSID->usData2 = uuid.Data2; + pDLSID->usData3 = uuid.Data3; + memcpy(pDLSID->abData, uuid.Data4, 8); + +#elif defined(__APPLE__) + + CFUUIDRef uuidRef = CFUUIDCreate(NULL); + CFUUIDBytes uuid = CFUUIDGetUUIDBytes(uuidRef); + CFRelease(uuidRef); + pDLSID->ulData1 = uuid.byte0 | uuid.byte1 << 8 | uuid.byte2 << 16 | uuid.byte3 << 24; + pDLSID->usData2 = uuid.byte4 | uuid.byte5 << 8; + pDLSID->usData3 = uuid.byte6 | uuid.byte7 << 8; + pDLSID->abData[0] = uuid.byte8; + pDLSID->abData[1] = uuid.byte9; + pDLSID->abData[2] = uuid.byte10; + pDLSID->abData[3] = uuid.byte11; + pDLSID->abData[4] = uuid.byte12; + pDLSID->abData[5] = uuid.byte13; + pDLSID->abData[6] = uuid.byte14; + pDLSID->abData[7] = uuid.byte15; +#else + uuid_t uuid; + uuid_generate(uuid); + pDLSID->ulData1 = uuid[0] | uuid[1] << 8 | uuid[2] << 16 | uuid[3] << 24; + pDLSID->usData2 = uuid[4] | uuid[5] << 8; + pDLSID->usData3 = uuid[6] | uuid[7] << 8; + memcpy(pDLSID->abData, &uuid[8], 8); +#endif +#endif + } // *************** Sampler *************** @@ -427,7 +488,7 @@ SampleLoops = wsmp->ReadUint32(); } else { // 'wsmp' chunk missing uiHeaderSize = 0; - UnityNote = 64; + UnityNote = 60; FineTune = 0; // +- 0 cents Gain = 0; // 0 dB SamplerOptions = F_WSMP_NO_COMPRESSION; @@ -488,7 +549,7 @@ /** * Adds a new sample loop with the provided loop definition. * - * @param - points to a loop definition that is to be copied + * @param pLoopDef - points to a loop definition that is to be copied */ void Sampler::AddSampleLoop(sample_loop_t* pLoopDef) { sample_loop_t* pNewLoops = new sample_loop_t[SampleLoops + 1]; @@ -852,6 +913,41 @@ } /** + * Modifies the key range of this Region and makes sure the respective + * chunks are in correct order. + * + * @param Low - lower end of key range + * @param High - upper end of key range + */ + void Region::SetKeyRange(uint16_t Low, uint16_t High) { + KeyRange.low = Low; + KeyRange.high = High; + + // make sure regions are already loaded + Instrument* pInstrument = (Instrument*) GetParent(); + if (!pInstrument->pRegions) pInstrument->LoadRegions(); + if (!pInstrument->pRegions) return; + + // find the r which is the first one to the right of this region + // at its new position + Region* r = NULL; + Region* prev_region = NULL; + for ( + Instrument::RegionList::iterator iter = pInstrument->pRegions->begin(); + iter != pInstrument->pRegions->end(); iter++ + ) { + if ((*iter)->KeyRange.low > this->KeyRange.low) { + r = *iter; + break; + } + prev_region = *iter; + } + + // place this region before r if it's not already there + if (prev_region != this) pInstrument->MoveRegion(this, r); + } + + /** * Apply Region settings to the respective RIFF chunks. You have to * call File::Save() to make changes persistent. * @@ -902,7 +998,6 @@ } } } - if (index < 0) throw Exception("Could not save Region, could not find Region's sample"); WavePoolTableIndex = index; // update 'wlnk' chunk store16(&pData[0], WaveLinkOptionFlags);