diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index c048ad918..04092a917 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -982,6 +982,13 @@ class DivDispatch { */ virtual const char* getSampleMemName(int index=0); + /** + * Get sample memory start offset. + * @param index the memory index. + * @return memory start offset in bytes. + */ + virtual size_t getSampleMemOffset(int index = 0); + /** * Get sample memory usage. * @param index the memory index. diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index a5ae25676..5649646eb 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -213,6 +213,10 @@ size_t DivDispatch::getSampleMemUsage(int index) { return 0; } +size_t DivDispatch::getSampleMemOffset(int index) { + return 0; +} + const DivMemoryComposition* DivDispatch::getMemCompo(int index) { return NULL; } diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 51f5505e1..150d0c925 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -1433,6 +1433,10 @@ size_t DivPlatformES5506::getSampleMemUsage(int index) { return index == 0 ? sampleMemLen : 0; } +size_t DivPlatformES5506::getSampleMemOffset(int index) { + return index == 0 ? 128 : 0; +} + bool DivPlatformES5506::isSampleLoaded(int index, int sample) { if (index!=0) return false; if (sample<0 || sample>32767) return false; @@ -1452,7 +1456,7 @@ void DivPlatformES5506::renderSamples(int sysID) { memCompo=DivMemoryComposition(); memCompo.name="Sample Memory"; - size_t memPos=128; // add silent at begin and end of each bank for reverse playback and add 1 for loop + size_t memPos=getSampleMemOffset(); // add silent at begin and end of each bank for reverse playback and add 1 for loop for (int i=0; isong.sampleLen; i++) { DivSample* s=parent->song.sample[i]; if (!s->renderOn[0][sysID]) { @@ -1462,18 +1466,18 @@ void DivPlatformES5506::renderSamples(int sysID) { unsigned int length=s->length16; // fit sample size to single bank size - if (length>(4194304-128)) { - length=4194304-128; + if (length>(4194304-getSampleMemOffset())) { + length=4194304-getSampleMemOffset(); } - if ((memPos&0xc00000)!=((memPos+length+128)&0xc00000)) { - memPos=((memPos+0x3fffff)&0xffc00000)+128; + if ((memPos&0xc00000)!=((memPos+length+getSampleMemOffset())&0xc00000)) { + memPos=((memPos+0x3fffff)&0xffc00000)+getSampleMemOffset(); } - if (memPos>=(getSampleMemCapacity()-128)) { + if (memPos>=(getSampleMemCapacity()-getSampleMemOffset())) { logW("out of ES5506 memory for sample %d!",i); break; } - if (memPos+length>=(getSampleMemCapacity()-128)) { - memcpy(sampleMem+(memPos/sizeof(short)),s->data16,(getSampleMemCapacity()-128)-memPos); + if (memPos+length>=(getSampleMemCapacity()-getSampleMemOffset())) { + memcpy(sampleMem+(memPos/sizeof(short)),s->data16,(getSampleMemCapacity()-getSampleMemOffset())-memPos); logW("out of ES5506 memory for sample %d!",i); } else { memcpy(sampleMem+(memPos/sizeof(short)),s->data16,length); diff --git a/src/engine/platform/es5506.h b/src/engine/platform/es5506.h index 970fa0e5f..1e038be7c 100644 --- a/src/engine/platform/es5506.h +++ b/src/engine/platform/es5506.h @@ -317,6 +317,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf { virtual const void* getSampleMem(int index = 0) override; virtual size_t getSampleMemCapacity(int index = 0) override; virtual size_t getSampleMemUsage(int index = 0) override; + virtual size_t getSampleMemOffset(int index = 0) override; virtual bool isSampleLoaded(int index, int sample) override; virtual const DivMemoryComposition* getMemCompo(int index) override; virtual void renderSamples(int sysID) override; diff --git a/src/engine/platform/k053260.cpp b/src/engine/platform/k053260.cpp index 561cc08d8..4b1b4bc39 100644 --- a/src/engine/platform/k053260.cpp +++ b/src/engine/platform/k053260.cpp @@ -468,6 +468,10 @@ size_t DivPlatformK053260::getSampleMemUsage(int index) { return index == 0 ? sampleMemLen : 0; } +size_t DivPlatformK053260::getSampleMemOffset(int index) { + return index == 0 ? 1 : 0; +} + bool DivPlatformK053260::isSampleLoaded(int index, int sample) { if (index!=0) return false; if (sample<0 || sample>32767) return false; @@ -487,7 +491,7 @@ void DivPlatformK053260::renderSamples(int sysID) { memCompo=DivMemoryComposition(); memCompo.name="Sample ROM"; - size_t memPos=1; // for avoid silence + size_t memPos=getSampleMemOffset(); // for avoid silence for (int i=0; isong.sampleLen; i++) { DivSample* s=parent->song.sample[i]; if (!s->renderOn[0][sysID]) { @@ -499,10 +503,10 @@ void DivPlatformK053260::renderSamples(int sysID) { if (s->depth==DIV_SAMPLE_DEPTH_ADPCM_K) { length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_ADPCM_K)); - actualLength=MIN((int)(getSampleMemCapacity()-memPos-1),length); + actualLength=MIN((int)(getSampleMemCapacity()-memPos-getSampleMemOffset()),length); if (actualLength>0) { - sampleOff[i]=memPos-1; - memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+1)); + sampleOff[i]=memPos-getSampleMemOffset(); + memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+getSampleMemOffset())); for (int j=0; jdataK[j]; } @@ -510,10 +514,10 @@ void DivPlatformK053260::renderSamples(int sysID) { } } else { length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT)); - actualLength=MIN((int)(getSampleMemCapacity()-memPos-1),length); + actualLength=MIN((int)(getSampleMemCapacity()-memPos-getSampleMemOffset()),length); if (actualLength>0) { - sampleOff[i]=memPos-1; - memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+1)); + sampleOff[i]=memPos-getSampleMemOffset(); + memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+getSampleMemOffset())); for (int j=0; jdata8[j]; } diff --git a/src/engine/platform/k053260.h b/src/engine/platform/k053260.h index a9ae679e9..073ccda52 100644 --- a/src/engine/platform/k053260.h +++ b/src/engine/platform/k053260.h @@ -84,6 +84,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf { virtual const void* getSampleMem(int index = 0) override; virtual size_t getSampleMemCapacity(int index = 0) override; virtual size_t getSampleMemUsage(int index = 0) override; + virtual size_t getSampleMemOffset(int index = 0) override; virtual bool isSampleLoaded(int index, int sample) override; virtual const DivMemoryComposition* getMemCompo(int index) override; virtual void renderSamples(int chipID) override; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 5a8f81a4e..507c299fb 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -3244,6 +3244,10 @@ size_t DivPlatformOPL::getSampleMemUsage(int index) { (index==0 && adpcmChan>=0)?adpcmBMemLen:0; } +size_t DivPlatformOPL::getSampleMemOffset(int index) { + return (index==0 && pcmChanOffs>=0 && ramSize<=0x200000)?0x200000:0; +} + bool DivPlatformOPL::isSampleLoaded(int index, int sample) { if (index!=0) return false; if (sample<0 || sample>32767) return false; diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index 43cf9bd3c..b30e02807 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -218,6 +218,7 @@ class DivPlatformOPL: public DivDispatch { const void* getSampleMem(int index); size_t getSampleMemCapacity(int index); size_t getSampleMemUsage(int index); + size_t getSampleMemOffset(int index); bool isSampleLoaded(int index, int sample); const DivMemoryComposition* getMemCompo(int index); void renderSamples(int chipID); diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 7081a8e1f..07b2485f6 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -2369,13 +2369,17 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p } // PCM (OPL4) if (writePCM_OPL4[i]!=NULL && writePCM_OPL4[i]->getSampleMemUsage(0)>0) { + size_t usage=writePCM_OPL4[i]->getSampleMemUsage(0)-writePCM_OPL4[i]->getSampleMemOffset(0); + unsigned char* mem=((unsigned char*)writePCM_OPL4[i]->getSampleMem(0))+writePCM_OPL4[i]->getSampleMemOffset(0); w->writeC(0x67); w->writeC(0x66); w->writeC(0x84); - w->writeI((writePCM_OPL4[i]->getSampleMemUsage(0)+8)|(i*0x80000000)); + w->writeI((usage+8)|(i*0x80000000)); w->writeI(writePCM_OPL4[i]->getSampleMemCapacity(0)); - w->writeI(0); - w->write(writePCM_OPL4[i]->getSampleMem(0),writePCM_OPL4[i]->getSampleMemUsage(0)); + w->writeI(writePCM_OPL4[i]->getSampleMemOffset(0)); + for (size_t i=0; iwriteC(mem[i]); + } } } @@ -2407,13 +2411,17 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p w->write(writeGA20[i]->getSampleMem(),writeGA20[i]->getSampleMemUsage()); } if (writeK053260[i]!=NULL && writeK053260[i]->getSampleMemUsage()>0) { + size_t usage=writeK053260[i]->getSampleMemUsage()-writeK053260[i]->getSampleMemOffset(); + unsigned char* mem=((unsigned char*)writeK053260[i]->getSampleMem())+writeK053260[i]->getSampleMemOffset(); w->writeC(0x67); w->writeC(0x66); w->writeC(0x8e); - w->writeI((writeK053260[i]->getSampleMemUsage()+8)|(i*0x80000000)); + w->writeI((usage+8)|(i*0x80000000)); w->writeI(writeK053260[i]->getSampleMemCapacity()); - w->writeI(0); - w->write(writeK053260[i]->getSampleMem(),writeK053260[i]->getSampleMemUsage()); + w->writeI(writeK053260[i]->getSampleMemOffset()); + for (size_t i=0; iwriteC(mem[i]); + } } if (writeNES[i]!=NULL && writeNES[i]->getSampleMemUsage()>0) { if (dpcm07) { @@ -2458,17 +2466,18 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p for (int i=0; i<2; i++) { if (writeES5506[i]!=NULL && writeES5506[i]->getSampleMemUsage()>0) { // split sample data into 4 areas - unsigned short* mem=(unsigned short*)writeES5506[i]->getSampleMem(); + int memOffs=(int)writeES5506[i]->getSampleMemOffset(); + unsigned short* mem=((unsigned short*)writeES5506[i]->getSampleMem())+(memOffs>>1); for (int b=0; b<4; b++) { int offs=b<<22; - int memLen=CLAMP((int)writeES5506[i]->getSampleMemUsage()-offs,0,0x400000); + int memLen=CLAMP((int)writeES5506[i]->getSampleMemUsage()-memOffs-offs,0,0x400000-memOffs); if (memLen>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x90); w->writeI((memLen+8)|(i*0x80000000)); w->writeI(MIN(writeES5506[i]->getSampleMemCapacity(),0x400000)); - w->writeI(b<<28); + w->writeI(memOffs+(b<<28)); for (int i=0; i<(memLen>>1); i++) { w->writeS(mem[(offs>>1)+i]); }