--- libgig/trunk/src/gig.cpp 2014/06/16 13:22:50 2639 +++ libgig/trunk/src/gig.cpp 2014/12/29 16:25:51 2682 @@ -53,38 +53,6 @@ namespace gig { -// *************** progress_t *************** -// * - - progress_t::progress_t() { - callback = NULL; - custom = NULL; - __range_min = 0.0f; - __range_max = 1.0f; - } - - // private helper function to convert progress of a subprocess into the global progress - static void __notify_progress(progress_t* pProgress, float subprogress) { - if (pProgress && pProgress->callback) { - const float totalrange = pProgress->__range_max - pProgress->__range_min; - const float totalprogress = pProgress->__range_min + subprogress * totalrange; - pProgress->factor = totalprogress; - pProgress->callback(pProgress); // now actually notify about the progress - } - } - - // private helper function to divide a progress into subprogresses - static void __divide_progress(progress_t* pParentProgress, progress_t* pSubProgress, float totalTasks, float currentTask) { - if (pParentProgress && pParentProgress->callback) { - const float totalrange = pParentProgress->__range_max - pParentProgress->__range_min; - pSubProgress->callback = pParentProgress->callback; - pSubProgress->custom = pParentProgress->custom; - pSubProgress->__range_min = pParentProgress->__range_min + totalrange * currentTask / totalTasks; - pSubProgress->__range_max = pSubProgress->__range_min + totalrange / totalTasks; - } - } - - // *************** Internal functions for sample decompression *************** // * @@ -528,13 +496,14 @@ * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. * + * @param pProgress - callback function for progress notification * @throws DLS::Exception if FormatTag != DLS_WAVE_FORMAT_PCM or no sample data * was provided yet * @throws gig::Exception if there is any invalid sample setting */ - void Sample::UpdateChunks() { + void Sample::UpdateChunks(progress_t* pProgress) { // first update base class's chunks - DLS::Sample::UpdateChunks(); + DLS::Sample::UpdateChunks(pProgress); // make sure 'smpl' chunk exists pCkSmpl = pWaveList->GetSubChunk(CHUNK_ID_SMPL); @@ -1752,10 +1721,12 @@ * * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. + * + * @param pProgress - callback function for progress notification */ - void DimensionRegion::UpdateChunks() { + void DimensionRegion::UpdateChunks(progress_t* pProgress) { // first update base class's chunk - DLS::Sampler::UpdateChunks(); + DLS::Sampler::UpdateChunks(pProgress); RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP); uint8_t* pData = (uint8_t*) wsmp->LoadChunkData(); @@ -3026,9 +2997,10 @@ * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. * + * @param pProgress - callback function for progress notification * @throws gig::Exception if samples cannot be dereferenced */ - void Region::UpdateChunks() { + void Region::UpdateChunks(progress_t* pProgress) { // in the gig format we don't care about the Region's sample reference // but we still have to provide some existing one to not corrupt the // file, so to avoid the latter we simply always assign the sample of @@ -3036,11 +3008,11 @@ pSample = pDimensionRegions[0]->pSample; // first update base class's chunks - DLS::Region::UpdateChunks(); + DLS::Region::UpdateChunks(pProgress); // update dimension region's chunks for (int i = 0; i < DimensionRegions; i++) { - pDimensionRegions[i]->UpdateChunks(); + pDimensionRegions[i]->UpdateChunks(pProgress); } File* pFile = (File*) GetParent()->GetParent(); @@ -3673,6 +3645,9 @@ throw gig::Exception("No dimension with provided old dimension type exists on this region"); if (newType == dimension_samplechannel && def->zones != 2) throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones"); + if (GetDimensionDefinition(newType)) + throw gig::Exception("There is already a dimension with requested new dimension type on this region"); + def->dimension = newType; def->split_type = __resolveSplitType(newType); } @@ -4158,7 +4133,16 @@ memcpy(&data[0], &text[0], text.size()); } - void Script::UpdateChunks() { + /** + * Apply this script to the respective RIFF chunks. You have to call + * File::Save() to make changes persistent. + * + * Usually there is absolutely no need to call this method explicitly. + * It will be called automatically when File::Save() was called. + * + * @param pProgress - callback function for progress notification + */ + void Script::UpdateChunks(progress_t* pProgress) { // recalculate CRC32 check sum __resetCRC(crc); __calculateCRC(&data[0], data.size(), crc); @@ -4248,7 +4232,16 @@ } } - void ScriptGroup::UpdateChunks() { + /** + * Apply this script group to the respective RIFF chunks. You have to call + * File::Save() to make changes persistent. + * + * Usually there is absolutely no need to call this method explicitly. + * It will be called automatically when File::Save() was called. + * + * @param pProgress - callback function for progress notification + */ + void ScriptGroup::UpdateChunks(progress_t* pProgress) { if (pScripts) { if (!pList) pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS); @@ -4259,7 +4252,7 @@ for (std::list::iterator it = pScripts->begin(); it != pScripts->end(); ++it) { - (*it)->UpdateChunks(); + (*it)->UpdateChunks(pProgress); } } } @@ -4469,18 +4462,19 @@ * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. * + * @param pProgress - callback function for progress notification * @throws gig::Exception if samples cannot be dereferenced */ - void Instrument::UpdateChunks() { + void Instrument::UpdateChunks(progress_t* pProgress) { // first update base classes' chunks - DLS::Instrument::UpdateChunks(); + DLS::Instrument::UpdateChunks(pProgress); // update Regions' chunks { RegionList::iterator iter = pRegions->begin(); RegionList::iterator end = pRegions->end(); for (; iter != end; ++iter) - (*iter)->UpdateChunks(); + (*iter)->UpdateChunks(pProgress); } // make sure 'lart' RIFF list chunk exists @@ -4517,7 +4511,11 @@ } // own gig format extensions - if (pScriptRefs) { + if (ScriptSlotCount()) { + // make sure we have converted the original loaded script file + // offsets into valid Script object pointers + LoadScripts(); + RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS); const int slotCount = pScriptRefs->size(); @@ -4544,12 +4542,16 @@ store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0); pos += sizeof(uint32_t); } + } else { + // no script slots, so get rid of any LS custom RIFF chunks (if any) + RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); + if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS); } } void Instrument::UpdateScriptFileOffsets() { // own gig format extensions - if (pScriptRefs) { + if (pScriptRefs && pScriptRefs->size() > 0) { RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); const int slotCount = pScriptRefs->size(); @@ -4993,8 +4995,10 @@ * * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. + * + * @param pProgress - callback function for progress notification */ - void Group::UpdateChunks() { + void Group::UpdateChunks(progress_t* pProgress) { // make sure <3gri> and <3gnl> list chunks exist RIFF::List* _3gri = pFile->pRIFF->GetSubList(LIST_TYPE_3GRI); if (!_3gri) { @@ -5770,9 +5774,10 @@ * Usually there is absolutely no need to call this method explicitly. * It will be called automatically when File::Save() was called. * + * @param pProgress - callback function for progress notification * @throws Exception - on errors */ - void File::UpdateChunks() { + void File::UpdateChunks(progress_t* pProgress) { bool newFile = pRIFF->GetSubList(LIST_TYPE_INFO) == NULL; b64BitWavePoolOffsets = pVersion && pVersion->major == 3; @@ -5795,13 +5800,13 @@ for (std::list::iterator it = pScriptGroups->begin(); it != pScriptGroups->end(); ++it) { - (*it)->UpdateChunks(); + (*it)->UpdateChunks(pProgress); } } } // first update base class's chunks - DLS::File::UpdateChunks(); + DLS::File::UpdateChunks(pProgress); if (newFile) { // INFO was added by Resource::UpdateChunks - make sure it @@ -5838,7 +5843,7 @@ std::list::iterator iter = pGroups->begin(); std::list::iterator end = pGroups->end(); for (; iter != end; ++iter) { - (*iter)->UpdateChunks(); + (*iter)->UpdateChunks(pProgress); } }