diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 9dee6ecfe..29c293e86 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -444,46 +444,45 @@ void DivEngine::renderSamples() { sPreview.sample=-1; sPreview.pos=0; + // step 1: render samples for (int i=0; irender(); } - /* - // step 3: allocate ADPCM samples - if (adpcmMem==NULL) adpcmMem=new unsigned char[16777216]; + // step 2: allocate ADPCM-A samples + if (adpcmAMem==NULL) adpcmAMem=new unsigned char[16777216]; size_t memPos=0; for (int i=0; iadpcmRendLength)&0xf00000)) { + int paddedLen=(s->lengthA+255)&(~0xff); + if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) { memPos=(memPos+0xfffff)&0xf00000; } if (memPos>=16777216) { logW("out of ADPCM memory for sample %d!\n",i); break; } - if (memPos+s->adpcmRendLength>=16777216) { - memcpy(adpcmMem+memPos,s->adpcmRendData,16777216-memPos); + if (memPos+paddedLen>=16777216) { + memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos); logW("out of ADPCM memory for sample %d!\n",i); } else { - memcpy(adpcmMem+memPos,s->adpcmRendData,s->adpcmRendLength); + memcpy(adpcmAMem+memPos,s->dataA,paddedLen); } - s->rendOff=memPos; - memPos+=s->adpcmRendLength; + s->offA=memPos; + memPos+=paddedLen; } - adpcmMemLen=memPos+256; + adpcmAMemLen=memPos+256; // step 4: allocate qsound pcm samples if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216]; - memset(qsoundMem, 0, 16777216); - memPos=0; for (int i=0; irendLength; - if (length > 65536-16) { - length = 65536-16; + int length=s->length8; + if (length>65536-16) { + length=65536-16; } if ((memPos&0xff0000)!=((memPos+length)&0xff0000)) { memPos=(memPos+0xffff)&0xff0000; @@ -494,19 +493,18 @@ void DivEngine::renderSamples() { } if (memPos+length>=16777216) { for (unsigned int i=0; i<16777216-(memPos+length); i++) { - qsoundMem[(memPos + i) ^ 0x8000] = s->rendData[i] >> ((s->depth == 16) ? 8 : 0); + qsoundMem[(memPos+i)^0x8000]=s->data8[i]; } logW("out of QSound PCM memory for sample %d!\n",i); } else { for (int i=0; irendData[i] >> ((s->depth == 16) ? 8 : 0); + qsoundMem[(memPos+i)^0x8000]=s->data8[i]; } } - s->rendOffQsound=memPos ^ 0x8000; + s->offQSound=memPos^0x8000; memPos+=length+16; } qsoundMemLen=memPos+256; - */ } void DivEngine::createNew() { diff --git a/src/engine/engine.h b/src/engine/engine.h index 96594a3ca..c02416996 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -621,8 +621,8 @@ class DivEngine { // terminate the engine. bool quit(); - unsigned char* adpcmMem; - size_t adpcmMemLen; + unsigned char* adpcmAMem; + size_t adpcmAMemLen; unsigned char* adpcmBMem; size_t adpcmBMemLen; unsigned char* qsoundMem; @@ -680,8 +680,8 @@ class DivEngine { totalProcessed(0), oscBuf{NULL,NULL}, oscSize(1), - adpcmMem(NULL), - adpcmMemLen(0), + adpcmAMem(NULL), + adpcmAMemLen(0), adpcmBMem(NULL), adpcmBMemLen(0), qsoundMem(NULL), diff --git a/src/engine/platform/ym2610Interface.cpp b/src/engine/platform/ym2610Interface.cpp index 8d53e48ce..45fb5288b 100644 --- a/src/engine/platform/ym2610Interface.cpp +++ b/src/engine/platform/ym2610Interface.cpp @@ -22,12 +22,16 @@ #include "../engine.h" uint8_t DivYM2610Interface::ymfm_external_read(ymfm::access_class type, uint32_t address) { - //printf("wants to read from %x\n",address); - if (type!=ymfm::ACCESS_ADPCM_A) return 0; - return parent->adpcmMem[address&0xffffff]; - /*if (12*sampleBank+(address>>16)>=parent->song.sampleLen) return 0; - return parent->song.sample[12*sampleBank+(address>>16)]->adpcmRendData[(address&0xffff)];*/ + switch (type) { + case ymfm::ACCESS_ADPCM_A: + return parent->adpcmAMem[address&0xffffff]; + case ymfm::ACCESS_ADPCM_B: + return parent->adpcmBMem[address&0xffffff]; + default: + return 0; + } + return 0; } void DivYM2610Interface::ymfm_external_write(ymfm::access_class type, uint32_t address, uint8_t data) { -} \ No newline at end of file +} diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index ec0ffad5c..ec6313fff 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -73,6 +73,7 @@ bool DivSample::save(const char* path) { return true; } +// 16-bit memory is padded to 512, to make things easier for ADPCM-A/B. bool DivSample::initInternal(unsigned char d, int count) { switch (d) { case 0: // 1-bit @@ -96,14 +97,14 @@ bool DivSample::initInternal(unsigned char d, int count) { case 5: // ADPCM-A if (dataA!=NULL) delete[] dataA; lengthA=(count+1)/2; - dataA=new unsigned char[lengthA]; - memset(dataA,0,lengthA); + dataA=new unsigned char[(lengthA+255)&(~0xff)]; + memset(dataA,0,(lengthA+255)&(~0xff)); break; case 6: // ADPCM-B if (dataB!=NULL) delete[] dataB; lengthB=(count+1)/2; - dataB=new unsigned char[lengthB]; - memset(dataB,0,lengthB); + dataB=new unsigned char[(lengthB+255)&(~0xff)]; + memset(dataB,0,(lengthB+255)&(~0xff)); break; case 7: // X68000 ADPCM if (dataX68!=NULL) delete[] dataX68; @@ -132,8 +133,8 @@ bool DivSample::initInternal(unsigned char d, int count) { case 16: // 16-bit if (data16!=NULL) delete[] data16; length16=count*2; - data16=new short[count]; - memset(data16,0,count*sizeof(short)); + data16=new short[(count+511)&(~0x1ff)]; + memset(data16,0,((count+511)&(~0x1ff))*sizeof(short)); break; default: return false; @@ -223,13 +224,14 @@ void DivSample::render() { if (!initInternal(4,samples)) return; bs_encode(data16,dataQSoundA,samples); } + // TODO: pad to 256. if (depth!=5) { // ADPCM-A if (!initInternal(5,samples)) return; - yma_encode(data16,dataA,samples); + yma_encode(data16,dataA,(samples+511)&(~0x1ff)); } if (depth!=6) { // ADPCM-B if (!initInternal(6,samples)) return; - ymb_encode(data16,dataB,samples); + ymb_encode(data16,dataB,(samples+511)&(~0x1ff)); } if (depth!=7) { // X68000 ADPCM if (!initInternal(7,samples)) return; diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 93a2bcf42..e51217dc4 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -928,14 +928,14 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop) { delete[] pcmMem; } - if (writeADPCM && adpcmMemLen>0) { + if (writeADPCM && adpcmAMemLen>0) { w->writeC(0x67); w->writeC(0x66); w->writeC(0x82); - w->writeI(adpcmMemLen+8); - w->writeI(adpcmMemLen); + w->writeI(adpcmAMemLen+8); + w->writeI(adpcmAMemLen); w->writeI(0); - w->write(adpcmMem,adpcmMemLen); + w->write(adpcmAMem,adpcmAMemLen); } if (writeQSound && qsoundMemLen>0) { diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index ee8d5a954..bc15e5e5f 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1898,12 +1898,12 @@ void FurnaceGUI::drawStats() { } if (!statsOpen) return; if (ImGui::Begin("Statistics",&statsOpen)) { - String adpcmUsage=fmt::sprintf("%d/16384KB",e->adpcmMemLen/1024); + String adpcmAUsage=fmt::sprintf("%d/16384KB",e->adpcmAMemLen/1024); String adpcmBUsage=fmt::sprintf("%d/16384KB",e->adpcmBMemLen/1024); String qsoundUsage=fmt::sprintf("%d/16384KB",e->qsoundMemLen/1024); ImGui::Text("ADPCM-A"); ImGui::SameLine(); - ImGui::ProgressBar(((float)e->adpcmMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmUsage.c_str()); + ImGui::ProgressBar(((float)e->adpcmAMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmAUsage.c_str()); ImGui::Text("ADPCM-B"); ImGui::SameLine(); ImGui::ProgressBar(((float)e->adpcmBMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmBUsage.c_str());