fix 4 bit pcm

This commit is contained in:
Eknous-P 2025-06-04 14:37:01 +04:00
parent bcf4f5f508
commit 000c85b4cb
4 changed files with 38 additions and 11 deletions

View file

@ -505,6 +505,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
case DIV_SAMPLE_DEPTH_ADPCM_B: case DIV_SAMPLE_DEPTH_ADPCM_B:
case DIV_SAMPLE_DEPTH_ADPCM_K: case DIV_SAMPLE_DEPTH_ADPCM_K:
case DIV_SAMPLE_DEPTH_VOX: case DIV_SAMPLE_DEPTH_VOX:
case DIV_SAMPLE_DEPTH_4BIT:
samples=lenDivided*2; samples=lenDivided*2;
break; break;
case DIV_SAMPLE_DEPTH_IMA_ADPCM: case DIV_SAMPLE_DEPTH_IMA_ADPCM:
@ -617,6 +618,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
case DIV_SAMPLE_DEPTH_ADPCM_B: case DIV_SAMPLE_DEPTH_ADPCM_B:
case DIV_SAMPLE_DEPTH_ADPCM_K: case DIV_SAMPLE_DEPTH_ADPCM_K:
case DIV_SAMPLE_DEPTH_VOX: case DIV_SAMPLE_DEPTH_VOX:
case DIV_SAMPLE_DEPTH_4BIT:
// swap nibbles // swap nibbles
for (unsigned int i=0; i<sample->getCurBufLen(); i++) { for (unsigned int i=0; i<sample->getCurBufLen(); i++) {
b[i]=(b[i]<<4)|(b[i]>>4); b[i]=(b[i]<<4)|(b[i]>>4);
@ -629,7 +631,7 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
for (unsigned int i=0; i<sample->getCurBufLen(); i++) { for (unsigned int i=0; i<sample->getCurBufLen(); i++) {
b[i]=(((b[i]&7)<<4)|(((b[i]>>3)&15)^((b[i]&0x80)?15:0))|(b[i]&0x80))^0xff; b[i]=(((b[i]&7)<<4)|(((b[i]>>3)&15)^((b[i]&0x80)?15:0))|(b[i]&0x80))^0xff;
} }
break; break;\
default: default:
break; break;
} }

View file

@ -633,7 +633,7 @@ bool DivSample::initInternal(DivSampleDepth d, int count) {
break; break;
case DIV_SAMPLE_DEPTH_4BIT: case DIV_SAMPLE_DEPTH_4BIT:
if (data4!=NULL) delete[] data4; if (data4!=NULL) delete[] data4;
length4=count; length4=(count+1)/2;
data4=new unsigned char[length4]; data4=new unsigned char[length4];
memset(data4,0,length4); memset(data4,0,length4);
break; break;
@ -1334,11 +1334,18 @@ void DivSample::render(unsigned int formatMask) {
} }
} }
break; break;
case DIV_SAMPLE_DEPTH_4BIT: case DIV_SAMPLE_DEPTH_4BIT: {
unsigned short nibble=0;
for (unsigned int i=0; i<samples; i++) { for (unsigned int i=0; i<samples; i++) {
data16[i]=data4[i]<<12; if (i&1) {
nibble=data4[i/2]&0xf;
} else {
nibble=data4[i/2]>>4;
}
data16[i]=(nibble<<12)^0x8000;
} }
break; break;
}
default: default:
return; return;
} }
@ -1542,11 +1549,16 @@ void DivSample::render(unsigned int formatMask) {
} }
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_4BIT)) { if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_4BIT)) {
if (!initInternal(DIV_SAMPLE_DEPTH_4BIT,samples)) return; if (!initInternal(DIV_SAMPLE_DEPTH_4BIT,samples)) return;
for (unsigned int i=0; i<samples; i++) { unsigned char _sample=0, sample4=0;
data4[i]=(data16[i]>>12)&0xf; unsigned short* samplePtr = (unsigned short*)data16;
// if (i+1<samples) { for (unsigned int i=0; i<samples; i+=2) {
// data4[i/2]|=(data16[i+1]>>12); _sample=(*samplePtr++^0x8000)>>12;
// } sample4=_sample<<4;
if (i+1<samples) {
_sample=(*samplePtr++^0x8000)>>12;
sample4|=_sample;
}
data4[i/2]=sample4;
} }
} }
} }

View file

@ -7010,6 +7010,7 @@ bool FurnaceGUI::loop() {
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(120.0f*dpiScale); ImGui::SetNextItemWidth(120.0f*dpiScale);
if (ImGui::InputInt("##RSChans",&pendingRawSampleChannels,1,2)) { if (ImGui::InputInt("##RSChans",&pendingRawSampleChannels,1,2)) {
CLAMP_VAR(pendingRawSampleChannels, 1, 16)
} }
ImGui::Text(_("(will be mixed down to mono)")); ImGui::Text(_("(will be mixed down to mono)"));
ImGui::Checkbox(_("Unsigned"),&pendingRawSampleUnsigned); ImGui::Checkbox(_("Unsigned"),&pendingRawSampleUnsigned);
@ -7023,7 +7024,8 @@ bool FurnaceGUI::loop() {
pendingRawSampleDepth==DIV_SAMPLE_DEPTH_QSOUND_ADPCM || pendingRawSampleDepth==DIV_SAMPLE_DEPTH_QSOUND_ADPCM ||
pendingRawSampleDepth==DIV_SAMPLE_DEPTH_ADPCM_A || pendingRawSampleDepth==DIV_SAMPLE_DEPTH_ADPCM_A ||
pendingRawSampleDepth==DIV_SAMPLE_DEPTH_ADPCM_B || pendingRawSampleDepth==DIV_SAMPLE_DEPTH_ADPCM_B ||
pendingRawSampleDepth==DIV_SAMPLE_DEPTH_VOX) { pendingRawSampleDepth==DIV_SAMPLE_DEPTH_VOX ||
pendingRawSampleDepth==DIV_SAMPLE_DEPTH_4BIT) {
ImGui::Checkbox(_("Swap nibbles"),&pendingRawSampleSwapNibbles); ImGui::Checkbox(_("Swap nibbles"),&pendingRawSampleSwapNibbles);
} }

View file

@ -1917,7 +1917,18 @@ void FurnaceGUI::drawSampleEdit() {
posX=samplePos+pos.x*sampleZoom; posX=samplePos+pos.x*sampleZoom;
if (posX>(int)sample->samples) posX=-1; if (posX>(int)sample->samples) posX=-1;
} }
posY=(0.5-pos.y/rectSize.y)*((sample->depth==DIV_SAMPLE_DEPTH_8BIT)?255:65535); switch (sample->depth) {
case DIV_SAMPLE_DEPTH_8BIT:
posY=(0.5-pos.y/rectSize.y)*255;
break;
case DIV_SAMPLE_DEPTH_4BIT:
posY=(1-pos.y/rectSize.y)*15;
break;
default:
posY=(0.5-pos.y/rectSize.y)*65535;
break;
}
if (posX>=0) { if (posX>=0) {
statusBar2=fmt::sprintf("(%d, %d)",posX,posY); statusBar2=fmt::sprintf("(%d, %d)",posX,posY);
} }