kind of implement K05 ADPCM

low quality
This commit is contained in:
tildearrow 2023-08-29 06:16:07 -05:00
parent 32ec87ca27
commit 61b0179da1
2 changed files with 73 additions and 5 deletions

View file

@ -1196,6 +1196,10 @@ unsigned char c219ShiftToVal[16]={
5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8
};
signed char adpcmKTable[16]={
0, 1, 2, 4, 8, 16, 32, 64, -128, -64, -32, -16, -8, -4, -2, -1
};
void DivSample::render(unsigned int formatMask) {
// step 1: convert to 16-bit if needed
if (depth!=DIV_SAMPLE_DEPTH_16BIT) {
@ -1228,11 +1232,20 @@ void DivSample::render(unsigned int formatMask) {
case DIV_SAMPLE_DEPTH_ADPCM_B: // ADPCM-B
ymb_decode(dataB,data16,samples);
break;
case DIV_SAMPLE_DEPTH_ADPCM_K: // K05 ADPCM
case DIV_SAMPLE_DEPTH_ADPCM_K: { // K05 ADPCM
signed char s=0;
for (unsigned int i=0; i<samples; i++) {
// TODO: ADPCM-K
unsigned char nibble=dataK[i>>1];
if (i&1) { // TODO: is this right?
nibble>>=4;
} else {
nibble&=15;
}
s+=adpcmKTable[nibble];
data16[i]=s<<8;
}
break;
}
case DIV_SAMPLE_DEPTH_8BIT: // 8-bit PCM
for (unsigned int i=0; i<samples; i++) {
data16[i]=data8[i]<<8;
@ -1308,7 +1321,62 @@ void DivSample::render(unsigned int formatMask) {
}
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_ADPCM_K)) { // K05 ADPCM
if (!initInternal(DIV_SAMPLE_DEPTH_ADPCM_K,samples)) return;
// TODO: ADPCM-K
signed char accum=0;
unsigned char out=0;
for (unsigned int i=0; i<samples; i++) {
signed char target=data16[i]>>8;
short delta=target-accum;
unsigned char next=0;
if (delta!=0) {
int b=bsr((delta>=0)?delta:-delta);
if (delta>=0) {
if (b>7) b=7;
next=b&15;
// test previous
if (next>1) {
const signed char t1=accum+adpcmKTable[next];
const signed char t2=accum+adpcmKTable[next-1];
const signed char d1=((t1-target)<0)?(target-t1):(t1-target);
const signed char d2=((t2-target)<0)?(target-t2):(t2-target);
if (d2<d1) next--;
}
} else {
if (b>8) b=8;
next=(16-b)&15;
// test next
if (next<15) {
const signed char t1=accum+adpcmKTable[next];
const signed char t2=accum+adpcmKTable[next+1];
const signed char d1=((t1-target)<0)?(target-t1):(t1-target);
const signed char d2=((t2-target)<0)?(target-t2):(t2-target);
if (d2<d1) next++;
}
}
/*if (accum+adpcmKTable[next]>=128 || accum+adpcmKTable[next]<-128) {
if (delta>=0) {
next--;
} else {
next++;
if (next>15) next=15;
}
}*/
}
out<<=4;
out|=next;
accum+=adpcmKTable[next];
if (i&1) {
dataK[i>>1]=out;
out=0;
}
}
}
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_8BIT)) { // 8-bit PCM
if (!initInternal(DIV_SAMPLE_DEPTH_8BIT,samples)) return;

View file

@ -1854,7 +1854,7 @@ void DivEngine::registerSystems() {
);
sysDefs[DIV_SYSTEM_K053260]=new DivSysDef(
"Konami K053260", NULL, 0xcc, 0, 4, false, true, 0x161, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"Konami K053260", NULL, 0xcc, 0, 4, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_K)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"this PCM chip was widely used at Konami arcade boards in 1990-1992.",
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
{"CH1", "CH2", "CH3", "CH4"},
@ -1889,7 +1889,7 @@ void DivEngine::registerSystems() {
sysDefs[DIV_SYSTEM_C219]=new DivSysDef(
"Namco C219", NULL, 0xcf, 0, 16, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_C219)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
"Namco's PCM chip used in their NA1/2 hardware.",
"Namco's PCM chip used in their NA-1/2 hardware.",
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16"},
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},