OPL4: fix 12-bit related glitches

This commit is contained in:
tildearrow 2025-04-02 19:18:33 -05:00
parent c3f98e50d3
commit 05f2c99bb4
2 changed files with 14 additions and 8 deletions

View file

@ -3279,7 +3279,7 @@ void DivPlatformOPL::renderSamples(int sysID) {
break; break;
case DIV_SAMPLE_DEPTH_12BIT: case DIV_SAMPLE_DEPTH_12BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_12BIT); sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_12BIT);
length=MIN(98303,sampleLength+1); length=MIN(98303,sampleLength+3);
break; break;
case DIV_SAMPLE_DEPTH_16BIT: case DIV_SAMPLE_DEPTH_16BIT:
sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_16BIT); sampleLength=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_16BIT);
@ -3294,21 +3294,21 @@ void DivPlatformOPL::renderSamples(int sysID) {
if (sampleLength<1) length=0; if (sampleLength<1) length=0;
int actualLength=MIN((int)(getSampleMemCapacity(0)-memPos),length); int actualLength=MIN((int)(getSampleMemCapacity(0)-memPos),length);
if (actualLength>0) { if (actualLength>0) {
#ifdef TA_BIG_ENDIAN
memcpy(&pcmMem[memPos],src,actualLength);
#else
if (s->depth==DIV_SAMPLE_DEPTH_16BIT) { if (s->depth==DIV_SAMPLE_DEPTH_16BIT) {
for (int i=0, j=0; i<actualLength; i++, j++) { for (int i=0, j=0; i<actualLength; i++, j++) {
if (j>=sampleLength) j=sampleLength-2; if (j>=sampleLength) j=sampleLength-2;
#ifdef TA_BIG_ENDIAN
pcmMem[memPos+i]=src[j];
#else
pcmMem[memPos+i]=src[j^1]; pcmMem[memPos+i]=src[j^1];
#endif
} }
} else { } else {
for (int i=0, j=0; i<actualLength; i++, j++) { for (int i=0, j=0; i<actualLength; i++, j++) {
if (j>=sampleLength) j=sampleLength-1; if (j>=sampleLength && s->depth!=DIV_SAMPLE_DEPTH_12BIT) j=sampleLength-1;
pcmMem[memPos+i]=src[j]; pcmMem[memPos+i]=src[j];
} }
} }
#endif
sampleOffPCM[i]=memPos; sampleOffPCM[i]=memPos;
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+length)); memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+length));
memPos+=length; memPos+=length;
@ -3334,6 +3334,10 @@ void DivPlatformOPL::renderSamples(int sysID) {
break; break;
case DIV_SAMPLE_DEPTH_12BIT: case DIV_SAMPLE_DEPTH_12BIT:
bitDepth=1; bitDepth=1;
if (!s->isLoopable()) {
endPos++;
loop++;
}
break; break;
case DIV_SAMPLE_DEPTH_16BIT: case DIV_SAMPLE_DEPTH_16BIT:
bitDepth=2; bitDepth=2;

View file

@ -619,8 +619,8 @@ bool DivSample::initInternal(DivSampleDepth d, int count) {
case DIV_SAMPLE_DEPTH_12BIT: // 12-bit PCM (MultiPCM) case DIV_SAMPLE_DEPTH_12BIT: // 12-bit PCM (MultiPCM)
if (data12!=NULL) delete[] data12; if (data12!=NULL) delete[] data12;
length12=((count*3)+1)/2; length12=((count*3)+1)/2;
data12=new unsigned char[length12]; data12=new unsigned char[length12+8];
memset(data12,0,length12); memset(data12,0,length12+8);
break; break;
case DIV_SAMPLE_DEPTH_16BIT: // 16-bit case DIV_SAMPLE_DEPTH_16BIT: // 16-bit
if (data16!=NULL) delete[] data16; if (data16!=NULL) delete[] data16;
@ -1513,6 +1513,8 @@ void DivSample::render(unsigned int formatMask) {
data12[j+1]=((data16[i+0]>>4)&0xf)|(i+1<samples?(data16[i+1]>>4)&0xf:0); data12[j+1]=((data16[i+0]>>4)&0xf)|(i+1<samples?(data16[i+1]>>4)&0xf:0);
if (i+1<samples) { if (i+1<samples) {
data12[j+2]=data16[i+1]>>8; data12[j+2]=data16[i+1]>>8;
} else {
data12[j+2]=0;
} }
} }
} }