diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 91ba1000..fa2e1364 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -23,47 +23,25 @@ #include #include -//#define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;} -//#define immWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } +#define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } +#define chWrite(c,a,v) rWrite(((c)<<3)+(a),v) void DivPlatformSegaPCM::acquire(short** buf, size_t len) { static int os[2]; for (size_t h=0; h=0 && chan[i].pcm.samplesong.sampleLen) { - DivSample* s=parent->getSample(chan[i].pcm.sample); - if (s->samples<=0) { - chan[i].pcm.sample=-1; - oscBuf[i]->data[oscBuf[i]->needle++]=0; - continue; - } - if (!isMuted[i]) { - oscBuf[i]->data[oscBuf[i]->needle++]=s->data8[chan[i].pcm.pos>>8]*(chan[i].chVolL+chan[i].chVolR)>>1; - pcmL+=(s->data8[chan[i].pcm.pos>>8]*chan[i].chVolL); - pcmR+=(s->data8[chan[i].pcm.pos>>8]*chan[i].chVolR); - } else { - oscBuf[i]->data[oscBuf[i]->needle++]=0; - } - chan[i].pcm.pos+=chan[i].pcm.freq; - if (s->isLoopable() && chan[i].pcm.pos>=((unsigned int)s->loopEnd<<8)) { - chan[i].pcm.pos=s->loopStart<<8; - } else if (chan[i].pcm.pos>=(s->samples<<8)) { - chan[i].pcm.sample=-1; - } - } else { - oscBuf[i]->data[oscBuf[i]->needle++]=0; - } + while (!writes.empty()) { + QueuedWrite w=writes.front(); + pcm.write(w.addr,w.val); + regPool[w.addr&0xff]=w.val; + writes.pop(); } - os[0]=pcmL; + pcm.sound_stream_update(os); + if (os[0]<-32768) os[0]=-32768; if (os[0]>32767) os[0]=32767; - os[1]=pcmR; if (os[1]<-32768) os[1]=-32768; if (os[1]>32767) os[1]=32767; @@ -81,10 +59,8 @@ void DivPlatformSegaPCM::tick(bool sysTick) { chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul; chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/127; chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/127; - if (dumpWrites) { - addWrite(0x10002+(i<<3),chan[i].chVolL); - addWrite(0x10003+(i<<3),chan[i].chVolR); - } + rWrite(2+(i<<3),chan[i].chVolL); + rWrite(3+(i<<3),chan[i].chVolR); } } @@ -100,17 +76,13 @@ void DivPlatformSegaPCM::tick(bool sysTick) { if (parent->song.newSegaPCM) if (chan[i].std.panL.had) { chan[i].chPanL=chan[i].std.panL.val&127; chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/127; - if (dumpWrites) { - addWrite(0x10002+(i<<3),chan[i].chVolL); - } + rWrite(2+(i<<3),chan[i].chVolL); } if (parent->song.newSegaPCM) if (chan[i].std.panR.had) { chan[i].chPanR=chan[i].std.panR.val&127; chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/127; - if (dumpWrites) { - addWrite(0x10003+(i<<3),chan[i].chVolR); - } + rWrite(3+(i<<3),chan[i].chVolR); } if (chan[i].std.pitch.had) { @@ -145,56 +117,48 @@ void DivPlatformSegaPCM::tick(bool sysTick) { off=(double)s->centerRate/8363.0; } chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250)+chan[i].pitch2; - if (dumpWrites) { - addWrite(0x10007+(i<<3),chan[i].pcm.freq); - } + rWrite(7+(i<<3),chan[i].pcm.freq); } chan[i].freqChanged=false; if (chan[i].keyOn || chan[i].keyOff) { if (chan[i].keyOn && !chan[i].keyOff) { - if (dumpWrites) { - addWrite(0x10086+(i<<3),3); - } + rWrite(0x86+(i<<3),3); chan[i].pcm.pos=0; if (chan[i].furnacePCM) { - if (dumpWrites) { // Sega PCM writes - DivSample* s=parent->getSample(chan[i].pcm.sample); - int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); - int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); - if (actualLength>0xfeff) actualLength=0xfeff; - addWrite(0x10086+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - addWrite(0x10084+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); - addWrite(0x10085+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); - addWrite(0x10006+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-1)>>8)); - if (loopStart<0 || loopStart>=actualLength) { - addWrite(0x10086+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - } else { - int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart+s->loopOffP; - addWrite(0x10004+(i<<3),loopPos&0xff); - addWrite(0x10005+(i<<3),(loopPos>>8)&0xff); - addWrite(0x10086+(i<<3),((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - } + DivSample* s=parent->getSample(chan[i].pcm.sample); + int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); + int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); + if (actualLength>0xfeff) actualLength=0xfeff; + rWrite(0x86+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); + rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); + rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); + rWrite(6+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-1)>>8)); + if (loopStart<0 || loopStart>=actualLength) { + rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); + } else { + int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart+sampleLoopOff[chan[i].pcm.sample]; + rWrite(4+(i<<3),loopPos&0xff); + rWrite(5+(i<<3),(loopPos>>8)&0xff); + rWrite(0x86+(i<<3),((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); } } else { - if (dumpWrites) { // Sega PCM writes - DivSample* s=parent->getSample(chan[i].pcm.sample); - int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); - int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); - if (actualLength>65536) actualLength=65536; - addWrite(0x10086+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - addWrite(0x10084+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); - addWrite(0x10085+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); - addWrite(0x10006+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-1)>>8)); - if (loopStart<0 || loopStart>=actualLength) { - addWrite(0x10086+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - } else { - int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart+s->loopOffP; - addWrite(0x10004+(i<<3),loopPos&0xff); - addWrite(0x10005+(i<<3),(loopPos>>8)&0xff); - addWrite(0x10086+(i<<3),((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); - } - addWrite(0x10007+(i<<3),chan[i].pcm.freq); + DivSample* s=parent->getSample(chan[i].pcm.sample); + int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); + int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)); + if (actualLength>0xfeff) actualLength=0xfeff; + rWrite(0x86+(i<<3),3+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); + rWrite(0x84+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample])&0xff); + rWrite(0x85+(i<<3),(sampleOffSegaPCM[chan[i].pcm.sample]>>8)&0xff); + rWrite(6+(i<<3),MIN(255,((sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+actualLength-1)>>8)); + if (loopStart<0 || loopStart>=actualLength) { + rWrite(0x86+(i<<3),2+((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); + } else { + int loopPos=(sampleOffSegaPCM[chan[i].pcm.sample]&0xffff)+loopStart+sampleLoopOff[chan[i].pcm.sample]; + rWrite(4+(i<<3),loopPos&0xff); + rWrite(5+(i<<3),(loopPos>>8)&0xff); + rWrite(0x86+(i<<3),((sampleOffSegaPCM[chan[i].pcm.sample]>>16)<<3)); } + rWrite(7+(i<<3),chan[i].pcm.freq); } } chan[i].keyOn=false; @@ -206,6 +170,7 @@ void DivPlatformSegaPCM::tick(bool sysTick) { void DivPlatformSegaPCM::muteChannel(int ch, bool mute) { isMuted[ch]=mute; + pcm.mute(ch,mute); } int DivPlatformSegaPCM::dispatch(DivCommand c) { @@ -219,9 +184,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { if (c.value!=DIV_NOTE_NULL) chan[c.chan].pcm.sample=ins->amiga.getSample(c.value); if (chan[c.chan].pcm.sample<0 || chan[c.chan].pcm.sample>=parent->song.sampleLen) { chan[c.chan].pcm.sample=-1; - if (dumpWrites) { - addWrite(0x10086+(c.chan<<3),3); - } + rWrite(0x86+(c.chan<<3),3); chan[c.chan].macroInit(NULL); if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { chan[c.chan].outVol=chan[c.chan].vol; @@ -245,9 +208,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { chan[c.chan].pcm.sample=12*sampleBank+chan[c.chan].note%12; if (chan[c.chan].pcm.sample>=parent->song.sampleLen) { chan[c.chan].pcm.sample=-1; - if (dumpWrites) { - addWrite(0x10086+(c.chan<<3),3); - } + rWrite(0x86+(c.chan<<3),3); break; } chan[c.chan].pcm.freq=MIN(255,(parent->getSample(chan[c.chan].pcm.sample)->rate*255)/31250); @@ -259,9 +220,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { } case DIV_CMD_NOTE_OFF: chan[c.chan].pcm.sample=-1; - if (dumpWrites) { - addWrite(0x10086+(c.chan<<3),3); - } + rWrite(0x86+(c.chan<<3),3); chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; chan[c.chan].active=false; @@ -288,10 +247,8 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { chan[c.chan].chVolL=c.value; chan[c.chan].chVolR=c.value; } - if (dumpWrites) { - addWrite(0x10002+(c.chan<<3),chan[c.chan].chVolL); - addWrite(0x10003+(c.chan<<3),chan[c.chan].chVolR); - } + rWrite(2+(c.chan<<3),chan[c.chan].chVolL); + rWrite(3+(c.chan<<3),chan[c.chan].chVolR); break; } case DIV_CMD_GET_VOLUME: { @@ -314,10 +271,8 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { chan[c.chan].chVolL=c.value>>1; chan[c.chan].chVolR=c.value2>>1; } - if (dumpWrites) { - addWrite(0x10002+(c.chan<<3),chan[c.chan].chVolL); - addWrite(0x10003+(c.chan<<3),chan[c.chan].chVolR); - } + rWrite(2+(c.chan<<3),chan[c.chan].chVolL); + rWrite(3+(c.chan<<3),chan[c.chan].chVolR); break; } case DIV_CMD_PITCH: { @@ -381,9 +336,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { break; case DIV_CMD_SAMPLE_FREQ: chan[c.chan].pcm.freq=c.value; - if (dumpWrites) { - addWrite(0x10007+(c.chan<<3),chan[c.chan].pcm.freq); - } + rWrite(7+(c.chan<<3),chan[c.chan].pcm.freq); break; default: //printf("WARNING: unimplemented command %d\n",c.cmd); @@ -395,6 +348,10 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { void DivPlatformSegaPCM::forceIns() { for (int i=0; i<16; i++) { chan[i].insChanged=true; + + rWrite(2+(i<<3),chan[i].chVolL); + rWrite(3+(i<<3),chan[i].chVolR); + rWrite(7+(i<<3),chan[i].pcm.freq); } } @@ -425,7 +382,7 @@ DivDispatchOscBuffer* DivPlatformSegaPCM::getOscBuffer(int ch) { } unsigned char* DivPlatformSegaPCM::getRegisterPool() { - return regPool; + return pcm.get_ram(); } int DivPlatformSegaPCM::getRegisterPoolSize() { @@ -433,11 +390,29 @@ int DivPlatformSegaPCM::getRegisterPoolSize() { } void DivPlatformSegaPCM::poke(unsigned int addr, unsigned short val) { - //immWrite(addr,val); + rWrite(addr,val); } void DivPlatformSegaPCM::poke(std::vector& wlist) { - //for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + +const void* DivPlatformSegaPCM::getSampleMem(int index) { + return index == 0 ? sampleMem : NULL; +} + +size_t DivPlatformSegaPCM::getSampleMemCapacity(int index) { + return index == 0 ? 16777216 : 0; +} + +size_t DivPlatformSegaPCM::getSampleMemUsage(int index) { + return index == 0 ? sampleMemLen : 0; +} + +bool DivPlatformSegaPCM::isSampleLoaded(int index, int sample) { + if (index!=0) return false; + if (sample<0 || sample>255) return false; + return sampleLoaded[sample]; } void DivPlatformSegaPCM::reset() { @@ -457,17 +432,20 @@ void DivPlatformSegaPCM::reset() { sampleBank=0; delay=0; - if (dumpWrites) { - for (int i=0; i<16; i++) { - addWrite(0x10086+(i<<3),3); - addWrite(0x10002+(i<<3),0x7f); - addWrite(0x10003+(i<<3),0x7f); - } + pcm.device_start(); + + for (int i=0; i<16; i++) { + rWrite(0x86+(i<<3),3); + rWrite(2+(i<<3),0x7f); + rWrite(3+(i<<3),0x7f); } } void DivPlatformSegaPCM::renderSamples(int sysID) { size_t memPos=0; + + memset(sampleMem,0,16777216); + memset(sampleLoaded,0,256*sizeof(bool)); for (int i=0; isong.sampleLen; i++) { DivSample* sample=parent->getSample(i); @@ -477,6 +455,7 @@ void DivPlatformSegaPCM::reset() { memPos=(memPos+0xffff)&0xff0000; } logV("- sample %d will be at %x with length %x",i,memPos,alignedSize); + sampleLoaded[i]=true; if (memPos>=16777216) break; sampleOffSegaPCM[i]=memPos; unsigned int readPos=0; @@ -484,20 +463,21 @@ void DivPlatformSegaPCM::reset() { if (readPos>=(unsigned int)sample->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)) { if (sample->isLoopable()) { readPos=sample->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); - memPos++; + sampleMem[memPos++]=((unsigned char)sample->data8[readPos]+0x80); } else { - memPos++; + sampleMem[memPos++]=0x80; } } else { - memPos++; + sampleMem[memPos++]=((unsigned char)sample->data8[readPos]+0x80); } readPos++; if (memPos>=16777216) break; } - sample->loopOffP=readPos-sample->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); + sampleLoopOff[i]=readPos-sample->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); if (memPos>=16777216) break; } - } + sampleMemLen=memPos; +} void DivPlatformSegaPCM::setFlags(const DivConfig& flags) { chipClock=8000000.0; @@ -520,6 +500,11 @@ int DivPlatformSegaPCM::init(DivEngine* p, int channels, int sugRate, const DivC isMuted[i]=false; oscBuf[i]=new DivDispatchOscBuffer; } + sampleMem=new unsigned char[16777216]; + pcm.set_bank(segapcm_device::BANK_12M|segapcm_device::BANK_MASKF8); + pcm.set_read([this](unsigned int addr) -> unsigned char { + return sampleMem[addr&0xffffff]; + }); setFlags(flags); reset(); @@ -530,6 +515,7 @@ void DivPlatformSegaPCM::quit() { for (int i=0; i<16; i++) { delete oscBuf[i]; } + delete sampleMem; } DivPlatformSegaPCM::~DivPlatformSegaPCM() { diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index dd776826..75af90e3 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -53,6 +53,8 @@ class DivPlatformSegaPCM: public DivDispatch { }; Channel chan[16]; DivDispatchOscBuffer* oscBuf[16]; + unsigned char* sampleMem; + size_t sampleMemLen; struct QueuedWrite { unsigned short addr; unsigned char val; @@ -74,6 +76,8 @@ class DivPlatformSegaPCM: public DivDispatch { short pendingWrites[256]; unsigned int sampleOffSegaPCM[256]; + unsigned int sampleLoopOff[256]; + bool sampleLoaded[256]; friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); @@ -97,6 +101,10 @@ class DivPlatformSegaPCM: public DivDispatch { int getOutputCount(); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); + const void* getSampleMem(int index=0); + size_t getSampleMemCapacity(int index=0); + size_t getSampleMemUsage(int index=0); + bool isSampleLoaded(int index, int sample); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); void quit(); ~DivPlatformSegaPCM(); diff --git a/src/engine/platform/sound/segapcm.cpp b/src/engine/platform/sound/segapcm.cpp index 29bff292..4dd58eb2 100644 --- a/src/engine/platform/sound/segapcm.cpp +++ b/src/engine/platform/sound/segapcm.cpp @@ -16,6 +16,7 @@ segapcm_device::segapcm_device() : m_bankshift(12) , m_bankmask(0x70) { + memset(m_muted,0,16*sizeof(bool)); } @@ -94,8 +95,13 @@ void segapcm_device::sound_stream_update(int* outputs) v = read_byte(offset + (addr >> 8)) - 0x80; /* apply panning and advance */ - lastOut[ch][0]=v * (regs[2] & 0x7f); - lastOut[ch][1]=v * (regs[3] & 0x7f); + if (m_muted[ch]) { + lastOut[ch][0]=0; + lastOut[ch][1]=0; + } else { + lastOut[ch][0]=v * (regs[2] & 0x7f); + lastOut[ch][1]=v * (regs[3] & 0x7f); + } outputs[0]+=lastOut[ch][0]; outputs[1]+=lastOut[ch][1]; addr = (addr + regs[7]) & 0xffffff; @@ -123,3 +129,11 @@ uint8_t segapcm_device::read(unsigned int offset) { return m_ram[offset & 0x07ff]; } + +uint8_t* segapcm_device::get_ram() { + return m_ram; +} + +void segapcm_device::mute(int ch, bool doMute) { + m_muted[ch&15]=doMute; +} \ No newline at end of file diff --git a/src/engine/platform/sound/segapcm.h b/src/engine/platform/sound/segapcm.h index 830cc47d..40ca35a4 100644 --- a/src/engine/platform/sound/segapcm.h +++ b/src/engine/platform/sound/segapcm.h @@ -7,6 +7,7 @@ #ifndef MAMESOUND_SEGAPCM_H #define MAMESOUND_SEGAPCM_H +#include #include //************************************************************************** @@ -22,7 +23,7 @@ public: static constexpr int BANK_MASKF = 0xf0 << 16; static constexpr int BANK_MASKF8 = 0xf8 << 16; - short lastOut[16][2]; + short lastOut[16][2]; segapcm_device(); @@ -32,6 +33,8 @@ public: void write(unsigned int offset, uint8_t data); uint8_t read(unsigned int offset); + uint8_t* get_ram(); + void mute(int ch, bool doMute); // device-level overrides void device_start(); @@ -42,6 +45,7 @@ public: private: uint8_t m_ram[0x800]; uint8_t m_low[16]; + bool m_muted[16]; int m_bankshift; int m_bankmask; std::function read_byte; diff --git a/src/engine/sample.h b/src/engine/sample.h index 35eda8c5..76eaee9a 100644 --- a/src/engine/sample.h +++ b/src/engine/sample.h @@ -95,8 +95,7 @@ struct DivSampleHistory { struct DivSample { String name; - // TODO: get rid of loopOffP - int rate, centerRate, loopStart, loopEnd, loopOffP; + int rate, centerRate, loopStart, loopEnd; // valid values are: // - 0: ZX Spectrum overlay drum (1-bit) // - 1: 1-bit NES DPCM (1-bit) @@ -306,7 +305,6 @@ struct DivSample { centerRate(8363), loopStart(-1), loopEnd(-1), - loopOffP(0), depth(DIV_SAMPLE_DEPTH_16BIT), loop(false), brrEmphasis(true), diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index f3ba3766..0b9b1873 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -1085,7 +1085,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p DivDispatch* writeADPCM_OPNA[2]={NULL,NULL}; DivDispatch* writeADPCM_OPNB[2]={NULL,NULL}; DivDispatch* writeADPCM_Y8950[2]={NULL,NULL}; - int writeSegaPCM=0; + DivDispatch* writeSegaPCM[2]={NULL,NULL}; DivDispatch* writeX1010[2]={NULL,NULL}; DivDispatch* writeQSound[2]={NULL,NULL}; DivDispatch* writeES5506[2]={NULL,NULL}; @@ -1177,12 +1177,12 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p hasSegaPCM=4000000; CHIP_VOL(4,0.67); willExport[i]=true; - writeSegaPCM=1; + writeSegaPCM[0]=disCont[i].dispatch; } else if (!(hasSegaPCM&0x40000000)) { isSecond[i]=true; CHIP_VOL_SECOND(4,0.67); willExport[i]=true; - writeSegaPCM=2; + writeSegaPCM[1]=disCont[i].dispatch; hasSegaPCM|=0x40000000; howManyChips++; } @@ -1843,53 +1843,17 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p } } - if (writeSegaPCM>0) { - unsigned char* pcmMem=new unsigned char[16777216]; - - size_t memPos=0; - for (int i=0; igetLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)+0xff)&(~0xff); - if (alignedSize>65536) alignedSize=65536; - if ((memPos&0xff0000)!=((memPos+alignedSize)&0xff0000)) { - memPos=(memPos+0xffff)&0xff0000; - } - logV("- sample %d will be at %x with length %x",i,memPos,alignedSize); - if (memPos>=16777216) break; - sampleOffSegaPCM[i]=memPos; - unsigned int readPos=0; - for (unsigned int j=0; j=(unsigned int)sample->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)) { - if (sample->isLoopable()) { - readPos=sample->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); - pcmMem[memPos++]=((unsigned char)sample->data8[readPos]+0x80); - } else { - pcmMem[memPos++]=0x80; - } - } else { - pcmMem[memPos++]=((unsigned char)sample->data8[readPos]+0x80); - } - readPos++; - if (memPos>=16777216) break; - } - sample->loopOffP=readPos-sample->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT); - if (memPos>=16777216) break; - } - - for (unsigned char i=0; igetSampleMemUsage(0)>0) { w->writeC(0x67); w->writeC(0x66); - w->writeC(0x80); - w->writeI((memPos+8)|(i*0x80000000)); - w->writeI(memPos); + w->writeC(0x81); + w->writeI((writeSegaPCM[i]->getSampleMemUsage(0)+8)|(i*0x80000000)); + w->writeI(writeSegaPCM[i]->getSampleMemCapacity(0)); w->writeI(0); - w->write(pcmMem,memPos); + w->write(writeSegaPCM[i]->getSampleMem(0),writeSegaPCM[i]->getSampleMemUsage(0)); } - - delete[] pcmMem; - } - - for (int i=0; i<2; i++) { // ADPCM (OPNA) if (writeADPCM_OPNA[i]!=NULL && writeADPCM_OPNA[i]->getSampleMemUsage(0)>0) { w->writeC(0x67); diff --git a/src/gui/about.cpp b/src/gui/about.cpp index 350aba45..dcd90537 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -149,6 +149,7 @@ const char* aboutLine[]={ "MAME MSM6258 core by Barry Rodewald", "MAME YMZ280B core by Aaron Giles", "MAME GA20 core by Acho A. Tang and R. Belmont", + "MAME SegaPCM core by Hiromitsu Shioya and Olivier Galibert", "SAASound by Dave Hooper and Simon Owen", "SameBoy by Lior Halphon", "Mednafen PCE, WonderSwan, T6W28 and Virtual Boy audio cores", diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index af275735..d7179204 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -183,7 +183,6 @@ void FurnaceGUI::drawDebug() { ImGui::Text("centerRate: %d",sample->centerRate); ImGui::Text("loopStart: %d",sample->loopStart); ImGui::Text("loopEnd: %d", sample->loopEnd); - ImGui::Text("loopOffP: %d",sample->loopOffP); ImGui::Text(sample->loop?"loop: Enabled":"loop: Disabled"); if (sampleLoopModes[sample->loopMode]!=NULL) { ImGui::Text("loopMode: %d (%s)",(unsigned char)sample->loopMode,sampleLoopModes[sample->loopMode]); diff --git a/src/main.cpp b/src/main.cpp index 094e5b93..54fbc783 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -185,6 +185,7 @@ TAParamResult pVersion(String) { printf("- MAME MSM6258 core by Barry Rodewald (BSD 3-clause)\n"); printf("- MAME YMZ280B core by Aaron Giles (BSD 3-clause)\n"); printf("- MAME GA20 core by Acho A. Tang and R. Belmont (BSD 3-clause)\n"); + printf("- MAME SegaPCM core by Hiromitsu Shioya and Olivier Galibert (BSD 3-clause)\n"); printf("- QSound core by superctr (BSD 3-clause)\n"); printf("- VICE VIC-20 by Rami Rasanen and viznut (GPLv2)\n"); printf("- VERA core by Frank van den Hoef (BSD 2-clause)\n");