MultiPCM: add renderInstruments()

call it on instrument addition/removal/modification,
reset and/or renderSamples
This commit is contained in:
tildearrow 2025-09-14 05:25:44 -05:00
parent 684bebf202
commit c1b7a06a37
2 changed files with 78 additions and 65 deletions

View file

@ -468,6 +468,8 @@ void DivPlatformMultiPCM::reset() {
pcm.reset();
renderInstruments();
for (int i=0; i<28; i++) {
chan[i]=DivPlatformMultiPCM::Channel();
chan[i].std.setEngine(parent);
@ -506,6 +508,7 @@ bool DivPlatformMultiPCM::getLegacyAlwaysSetVolume() {
}
void DivPlatformMultiPCM::notifyInsChange(int ins) {
renderInstruments();
for (int i=0; i<28; i++) {
if (chan[i].ins==ins) {
chan[i].insChanged=true;
@ -514,10 +517,11 @@ void DivPlatformMultiPCM::notifyInsChange(int ins) {
}
void DivPlatformMultiPCM::notifyInsAddition(int sysID) {
renderSamples(sysID);
renderInstruments();
}
void DivPlatformMultiPCM::notifyInsDeletion(void* ins) {
renderInstruments();
for (int i=0; i<28; i++) {
chan[i].std.notifyInsDeletion((DivInstrument*)ins);
}
@ -577,66 +581,10 @@ const DivMemoryComposition* DivPlatformMultiPCM::getMemCompo(int index) {
return &memCompo;
}
void DivPlatformMultiPCM::renderSamples(int sysID) {
memset(pcmMem,0,2097152);
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
size_t memPos=0x1800;
int sampleCount=parent->song.sampleLen;
if (sampleCount>512) {
// mark the rest as unavailable
for (int i=512; i<sampleCount; i++) {
sampleLoaded[i]=false;
}
sampleCount=512;
}
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOff[i]=0;
continue;
}
int length;
int sampleLength;
unsigned char* src=(unsigned char*)s->getCurBuf();
switch (s->depth) {
case DIV_SAMPLE_DEPTH_8BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
length=MIN(65535,sampleLength+1);
break;
case DIV_SAMPLE_DEPTH_12BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_12BIT);
length=MIN(98303,sampleLength+3);
break;
default:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
length=MIN(65535,sampleLength+1);
src=(unsigned char*)s->data8;
break;
}
if (sampleLength<1) length=0;
int actualLength=MIN((int)(getSampleMemCapacity(0)-memPos),length);
if (actualLength>0) {
for (int i=0, j=0; i<actualLength; i++, j++) {
if (j>=sampleLength && s->depth!=DIV_SAMPLE_DEPTH_12BIT) j=sampleLength-1;
pcmMem[memPos+i]=src[j];
}
sampleOff[i]=memPos;
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+length));
memPos+=length;
}
if (actualLength<length) {
logW("out of MultiPCM memory for sample %d!",i);
break;
}
sampleLoaded[i]=true;
pcmMemLen=memPos+256;
// this is called on instrument change, reset and/or renderSamples().
// I am not making this part of DivDispatch as this is the only chip with
// instruments in ROM.
void DivPlatformMultiPCM::renderInstruments() {
// instrument table
int insCount=parent->song.insLen;
for (int i=0; i<insCount; i++) {
@ -700,6 +648,69 @@ void DivPlatformMultiPCM::renderSamples(int sysID) {
pcmMem[11+insAddr]=0; // AM
}
}
}
void DivPlatformMultiPCM::renderSamples(int sysID) {
memset(pcmMem,0,2097152);
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
renderInstruments();
size_t memPos=0x1800;
int sampleCount=parent->song.sampleLen;
if (sampleCount>512) {
// mark the rest as unavailable
for (int i=512; i<sampleCount; i++) {
sampleLoaded[i]=false;
}
sampleCount=512;
}
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOff[i]=0;
continue;
}
int length;
int sampleLength;
unsigned char* src=(unsigned char*)s->getCurBuf();
switch (s->depth) {
case DIV_SAMPLE_DEPTH_8BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
length=MIN(65535,sampleLength+1);
break;
case DIV_SAMPLE_DEPTH_12BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_12BIT);
length=MIN(98303,sampleLength+3);
break;
default:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
length=MIN(65535,sampleLength+1);
src=(unsigned char*)s->data8;
break;
}
if (sampleLength<1) length=0;
int actualLength=MIN((int)(getSampleMemCapacity(0)-memPos),length);
if (actualLength>0) {
for (int i=0, j=0; i<actualLength; i++, j++) {
if (j>=sampleLength && s->depth!=DIV_SAMPLE_DEPTH_12BIT) j=sampleLength-1;
pcmMem[memPos+i]=src[j];
}
sampleOff[i]=memPos;
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+length));
memPos+=length;
}
if (actualLength<length) {
logW("out of MultiPCM memory for sample %d!",i);
break;
}
sampleLoaded[i]=true;
pcmMemLen=memPos+256;
memCompo.used=pcmMemLen;
}
memCompo.capacity=getSampleMemCapacity(0);

View file

@ -96,6 +96,8 @@ class DivPlatformMultiPCM: public DivDispatch {
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);
void renderInstruments();
public:
void acquire(short** buf, size_t len);
int dispatch(DivCommand c);