Hi Christian On 11/12/2019 12:30, Christian Schoenebeck wrote:
Hmm... I wonder what GSt actually expects on gig file level if no loop was enabled. I mean it's probably not a big deal if GSt spits out a warning on such gig files, but would be nice to have if fixed on libgig side if reasonable. Can you identify what GSt instrument editor changes/fixes after you created a simple .gig file from scratch with Gigedit with no loop on?
Yes, I managed to get GSEdit3 to output debug logs showing the structure (as it sees it) of input gig files (like gigdump in LS). This showed me several differences between gig files created with gigedit and the ones corrected by GSEdit3. The problem causing the 'irregular structure' message was the wrong number of '3gnm' strings - there should always be 128.
There was also a duplicate DimensionRegion chunk being created when designing an instrument from scratch with gigedit.
Finally, I discovered two new chunks from the official spec. They always seem to have the same content and I have no idea what they do :-) I just wanted to rule them out as a cause of the problem.
I've attached a patch with these changes.
CU Christian
All the best, Ivan
diff -Naur libgig_orig/src/gig.cpp libgig_mod/src/gig.cpp --- libgig_orig/src/gig.cpp 2019-12-11 23:58:54.753927653 +0000 +++ libgig_mod/src/gig.cpp 2019-12-12 03:05:34.087726647 +0000 @@ -3384,6 +3384,18 @@ pDimensionRegions[0] = new DimensionRegion(this, _3ewl); DimensionRegions = 1; } + + // add 3dnm list which always seems to be empty + RIFF::List* _3dnm = rgnList->GetSubList(LIST_TYPE_3DNM); + if (!_3dnm) _3dnm = rgnList->AddSubList(LIST_TYPE_3DNM); + + // add 3ddp chunk which always seems to have 16 bytes of 0xFF + RIFF::Chunk* _3ddp = rgnList->GetSubChunk(CHUNK_ID_3DDP); + if (!_3ddp) _3ddp = rgnList->AddSubChunk(CHUNK_ID_3DDP, 16); + uint8_t* pData = (uint8_t*) _3ddp->LoadChunkData(); + for (int i = 0; i < 16; i+=4) { + store32(&pData[i], 0xFFFFFFFF); + } } /** @@ -3459,6 +3471,10 @@ } store32(&pData[iWavePoolOffset + i * 4], iWaveIndex); } + + // move 3dnm and 3ddp to the end of the region list + pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3DNM), (RIFF::Chunk*)NULL); + pCkRegion->MoveSubChunk(pCkRegion->GetSubChunk(CHUNK_ID_3DDP), (RIFF::Chunk*)NULL); } void Region::LoadDimensionRegions(RIFF::List* rgn) { @@ -3640,14 +3656,30 @@ } for (int j = 1 ; j < (1 << pDimDef->bits) ; j++) { for (int k = 0 ; k < (1 << bitpos) ; k++) { - RIFF::List* pNewDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL); - if (moveTo) _3prg->MoveSubChunk(pNewDimRgnListChunk, moveTo); + DimensionRegion* pDimRgn = NULL; + RIFF::List* pDimRgnListChunk = NULL; + int nDimRegionsAdded = 1; + + // use the placeholder DimensionRegion and chunk if added in Region::Region() + if (!Dimensions && DimensionRegions == 1) { + pDimRgn = pDimensionRegions[0]; + pDimRgnListChunk = pDimRgn->pParentList; + nDimRegionsAdded = 0; + } + + if (!pDimRgnListChunk) + pDimRgnListChunk = _3prg->AddSubList(LIST_TYPE_3EWL); + if (moveTo) _3prg->MoveSubChunk(pDimRgnListChunk, moveTo); + if (!pDimRgn) + pDimRgn = new DimensionRegion(pDimRgnListChunk, *pDimensionRegions[i + k]); + else + *pDimRgn = *pDimensionRegions[i + k]; + // create a new dimension region and copy all parameter values from // an existing dimension region - pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] = - new DimensionRegion(pNewDimRgnListChunk, *pDimensionRegions[i + k]); + pDimensionRegions[(i << pDimDef->bits) + (j << bitpos) + k] = pDimRgn; - DimensionRegions++; + DimensionRegions += nDimRegionsAdded; } } moveTo = pDimensionRegions[i]->pParentList; @@ -6625,7 +6657,9 @@ if (pVersion && pVersion->major > 2) { RIFF::Chunk* _3gnm = _3gnl->GetFirstSubChunk(); for (int i = 0 ; i < 128 ; i++) { - if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64); + // create 128 empty placeholder strings which will either + // be filled by Group::UpdateChunks below or left empty. + ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl, "", "", true, 64); if (_3gnm) _3gnm = _3gnl->GetNextSubChunk(); } } diff -Naur libgig_orig/src/gig.h libgig_mod/src/gig.h --- libgig_orig/src/gig.h 2019-12-11 23:58:54.752927647 +0000 +++ libgig_mod/src/gig.h 2019-12-12 03:01:23.947652226 +0000 @@ -50,6 +50,7 @@ # define LIST_TYPE_3GNL 0x33676E6C # define LIST_TYPE_3LS 0x334c5320 // own gig format extension # define LIST_TYPE_RTIS 0x52544953 // own gig format extension +# define LIST_TYPE_3DNM 0x33646e6d # define CHUNK_ID_3GIX 0x33676978 # define CHUNK_ID_3EWA 0x33657761 # define CHUNK_ID_3LNK 0x336C6E6B @@ -62,6 +63,7 @@ # define CHUNK_ID_LSNM 0x4c534e4d // own gig format extension # define CHUNK_ID_SCSL 0x5343534c // own gig format extension # define CHUNK_ID_LSDE 0x4c534445 // own gig format extension +# define CHUNK_ID_3DDP 0x33646470 #else // little endian # define LIST_TYPE_3PRG 0x67727033 # define LIST_TYPE_3EWL 0x6C776533 @@ -69,6 +71,7 @@ # define LIST_TYPE_3GNL 0x6C6E6733 # define LIST_TYPE_3LS 0x20534c33 // own gig format extension # define LIST_TYPE_RTIS 0x53495452 // own gig format extension +# define LIST_TYPE_3DNM 0x6d6e6433 # define CHUNK_ID_3GIX 0x78696733 # define CHUNK_ID_3EWA 0x61776533 # define CHUNK_ID_3LNK 0x6B6E6C33 @@ -81,6 +84,7 @@ # define CHUNK_ID_LSNM 0x4d4e534c // own gig format extension # define CHUNK_ID_SCSL 0x4c534353 // own gig format extension # define CHUNK_ID_LSDE 0x4544534c // own gig format extension +# define CHUNK_ID_3DDP 0x70646433 #endif // WORDS_BIGENDIAN #ifndef GIG_DECLARE_ENUM
_______________________________________________ Linuxsampler-devel mailing list Linuxsampler-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxsampler-devel