Add OPL4/MultiPCM 12-bit PCM support
This commit is contained in:
parent
2c417811b3
commit
16ca40e0d2
|
@ -587,6 +587,7 @@ size | description
|
||||||
| - 11: 8-bit μ-law PCM
|
| - 11: 8-bit μ-law PCM
|
||||||
| - 12: C219 PCM
|
| - 12: C219 PCM
|
||||||
| - 13: IMA ADPCM
|
| - 13: IMA ADPCM
|
||||||
|
| - 14: 12-bit PCM (MultiPCM)
|
||||||
| - 16: 16-bit PCM
|
| - 16: 16-bit PCM
|
||||||
1 | loop direction (>=123) or reserved
|
1 | loop direction (>=123) or reserved
|
||||||
| - 0: forward
|
| - 0: forward
|
||||||
|
|
|
@ -3197,6 +3197,9 @@ void DivPlatformOPL::renderSamples(int sysID) {
|
||||||
case DIV_SAMPLE_DEPTH_8BIT:
|
case DIV_SAMPLE_DEPTH_8BIT:
|
||||||
length=MIN(65535,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
length=MIN(65535,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
length=MIN(98303,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_12BIT));
|
||||||
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
length=MIN(131070,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_16BIT));
|
length=MIN(131070,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_16BIT));
|
||||||
break;
|
break;
|
||||||
|
@ -3239,7 +3242,9 @@ void DivPlatformOPL::renderSamples(int sysID) {
|
||||||
case DIV_SAMPLE_DEPTH_8BIT:
|
case DIV_SAMPLE_DEPTH_8BIT:
|
||||||
bitDepth=0;
|
bitDepth=0;
|
||||||
break;
|
break;
|
||||||
// TODO: 12 bit PCM
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
bitDepth=1;
|
||||||
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
bitDepth=2;
|
bitDepth=2;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -285,6 +285,9 @@ int DivSample::getSampleOffset(int offset, int length, DivSampleDepth depth) {
|
||||||
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
||||||
off=(offset+1)/2;
|
off=(offset+1)/2;
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
off=((offset*3)+1)/2;
|
||||||
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
off=offset*2;
|
off=offset*2;
|
||||||
break;
|
break;
|
||||||
|
@ -348,6 +351,10 @@ int DivSample::getSampleOffset(int offset, int length, DivSampleDepth depth) {
|
||||||
off=(offset+1)/2;
|
off=(offset+1)/2;
|
||||||
len=(length+1)/2;
|
len=(length+1)/2;
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
off=((offset*3)+1)/2;
|
||||||
|
len=((length*3)+1)/2;
|
||||||
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
off=offset*2;
|
off=offset*2;
|
||||||
len=length*2;
|
len=length*2;
|
||||||
|
@ -409,6 +416,9 @@ int DivSample::getEndPosition(DivSampleDepth depth) {
|
||||||
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
||||||
off=lengthIMA;
|
off=lengthIMA;
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
off=length12;
|
||||||
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
off=length16;
|
off=length16;
|
||||||
break;
|
break;
|
||||||
|
@ -606,6 +616,12 @@ bool DivSample::initInternal(DivSampleDepth d, int count) {
|
||||||
dataIMA=new unsigned char[lengthIMA];
|
dataIMA=new unsigned char[lengthIMA];
|
||||||
memset(dataIMA,0,lengthIMA);
|
memset(dataIMA,0,lengthIMA);
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT: // 12-bit PCM (MultiPCM)
|
||||||
|
if (data12!=NULL) delete[] data12;
|
||||||
|
length12=((count*3)+1)/2;
|
||||||
|
data12=new unsigned char[length12];
|
||||||
|
memset(data12,0,length12);
|
||||||
|
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;
|
||||||
length16=count*2;
|
length16=count*2;
|
||||||
|
@ -1293,6 +1309,14 @@ void DivSample::render(unsigned int formatMask) {
|
||||||
case DIV_SAMPLE_DEPTH_IMA_ADPCM: // IMA ADPCM
|
case DIV_SAMPLE_DEPTH_IMA_ADPCM: // IMA ADPCM
|
||||||
if (adpcm_decode_block(data16,dataIMA,lengthIMA,samples)==0) logE("oh crap!");
|
if (adpcm_decode_block(data16,dataIMA,lengthIMA,samples)==0) logE("oh crap!");
|
||||||
break;
|
break;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT: // 12-bit PCM (MultiPCM)
|
||||||
|
for (unsigned int i=0,j=0; i<samples; i+=2,j+=3) {
|
||||||
|
data16[i+0]=(data12[j+0]<<8)|(data12[j+1]&0xf0);
|
||||||
|
if (i+1<samples) {
|
||||||
|
data16[i+1]=(data12[j+2]<<8)|((data12[j+1]<<4)&0xf0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1482,6 +1506,15 @@ void DivSample::render(unsigned int formatMask) {
|
||||||
adpcm_free_context(codec);
|
adpcm_free_context(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_12BIT)) { // 12-bit PCM (MultiPCM)
|
||||||
|
if (!initInternal(DIV_SAMPLE_DEPTH_12BIT,samples)) return;
|
||||||
|
for (unsigned int i=0,j=0; i<samples; i+=2,j+=3) {
|
||||||
|
data12[j+0]=data16[i+0]>>8;
|
||||||
|
data12[j+1]=((data16[i+0]>>4)&0xf)|(i+1<samples?(data16[i+1]>>4)&0xf:0);
|
||||||
|
if (i+1<samples)
|
||||||
|
data12[j+2]=data16[i+1]>>8;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* DivSample::getCurBuf() {
|
void* DivSample::getCurBuf() {
|
||||||
|
@ -1512,6 +1545,8 @@ void* DivSample::getCurBuf() {
|
||||||
return dataC219;
|
return dataC219;
|
||||||
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
||||||
return dataIMA;
|
return dataIMA;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
return data12;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
return data16;
|
return data16;
|
||||||
default:
|
default:
|
||||||
|
@ -1548,6 +1583,8 @@ unsigned int DivSample::getCurBufLen() {
|
||||||
return lengthC219;
|
return lengthC219;
|
||||||
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
case DIV_SAMPLE_DEPTH_IMA_ADPCM:
|
||||||
return lengthIMA;
|
return lengthIMA;
|
||||||
|
case DIV_SAMPLE_DEPTH_12BIT:
|
||||||
|
return length12;
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
return length16;
|
return length16;
|
||||||
default:
|
default:
|
||||||
|
@ -1662,4 +1699,5 @@ DivSample::~DivSample() {
|
||||||
if (dataMuLaw) delete[] dataMuLaw;
|
if (dataMuLaw) delete[] dataMuLaw;
|
||||||
if (dataC219) delete[] dataC219;
|
if (dataC219) delete[] dataC219;
|
||||||
if (dataIMA) delete[] dataIMA;
|
if (dataIMA) delete[] dataIMA;
|
||||||
|
if (data12) delete[] data12;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum DivSampleDepth: unsigned char {
|
||||||
DIV_SAMPLE_DEPTH_MULAW=11,
|
DIV_SAMPLE_DEPTH_MULAW=11,
|
||||||
DIV_SAMPLE_DEPTH_C219=12,
|
DIV_SAMPLE_DEPTH_C219=12,
|
||||||
DIV_SAMPLE_DEPTH_IMA_ADPCM=13,
|
DIV_SAMPLE_DEPTH_IMA_ADPCM=13,
|
||||||
|
DIV_SAMPLE_DEPTH_12BIT=14,
|
||||||
DIV_SAMPLE_DEPTH_16BIT=16,
|
DIV_SAMPLE_DEPTH_16BIT=16,
|
||||||
DIV_SAMPLE_DEPTH_MAX // boundary for sample depth
|
DIV_SAMPLE_DEPTH_MAX // boundary for sample depth
|
||||||
};
|
};
|
||||||
|
@ -118,6 +119,7 @@ struct DivSample {
|
||||||
// - 11: 8-bit µ-law PCM
|
// - 11: 8-bit µ-law PCM
|
||||||
// - 12: C219 "µ-law" PCM
|
// - 12: C219 "µ-law" PCM
|
||||||
// - 13: IMA ADPCM
|
// - 13: IMA ADPCM
|
||||||
|
// - 14: 12-bit PCM (MultiPCM)
|
||||||
// - 16: 16-bit PCM
|
// - 16: 16-bit PCM
|
||||||
DivSampleDepth depth;
|
DivSampleDepth depth;
|
||||||
bool loop, brrEmphasis, brrNoFilter, dither;
|
bool loop, brrEmphasis, brrNoFilter, dither;
|
||||||
|
@ -144,8 +146,9 @@ struct DivSample {
|
||||||
unsigned char* dataMuLaw; // 11
|
unsigned char* dataMuLaw; // 11
|
||||||
unsigned char* dataC219; // 12
|
unsigned char* dataC219; // 12
|
||||||
unsigned char* dataIMA; // 13
|
unsigned char* dataIMA; // 13
|
||||||
|
unsigned char* data12; // 14
|
||||||
|
|
||||||
unsigned int length8, length16, length1, lengthDPCM, lengthZ, lengthQSoundA, lengthA, lengthB, lengthK, lengthBRR, lengthVOX, lengthMuLaw, lengthC219, lengthIMA;
|
unsigned int length8, length16, length1, lengthDPCM, lengthZ, lengthQSoundA, lengthA, lengthB, lengthK, lengthBRR, lengthVOX, lengthMuLaw, lengthC219, lengthIMA, length12;
|
||||||
|
|
||||||
unsigned int samples;
|
unsigned int samples;
|
||||||
|
|
||||||
|
@ -356,6 +359,7 @@ struct DivSample {
|
||||||
dataMuLaw(NULL),
|
dataMuLaw(NULL),
|
||||||
dataC219(NULL),
|
dataC219(NULL),
|
||||||
dataIMA(NULL),
|
dataIMA(NULL),
|
||||||
|
data12(NULL),
|
||||||
length8(0),
|
length8(0),
|
||||||
length16(0),
|
length16(0),
|
||||||
length1(0),
|
length1(0),
|
||||||
|
@ -370,6 +374,7 @@ struct DivSample {
|
||||||
lengthMuLaw(0),
|
lengthMuLaw(0),
|
||||||
lengthC219(0),
|
lengthC219(0),
|
||||||
lengthIMA(0),
|
lengthIMA(0),
|
||||||
|
length12(0),
|
||||||
samples(0) {
|
samples(0) {
|
||||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||||
for (int j=0; j<DIV_MAX_SAMPLE_TYPE; j++) {
|
for (int j=0; j<DIV_MAX_SAMPLE_TYPE; j++) {
|
||||||
|
|
|
@ -1635,9 +1635,8 @@ void DivEngine::registerSystems() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// to Grauw: feel free to change this to 24 during development of OPL4's PCM part.
|
// to Grauw: feel free to change this to 24 during development of OPL4's PCM part.
|
||||||
// TODO: add 12-bit sample formats
|
|
||||||
sysDefs[DIV_SYSTEM_OPL4]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_OPL4]=new DivSysDef(
|
||||||
_("Yamaha YMF278B (OPL4)"), NULL, 0xae, 0, 42, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
_("Yamaha YMF278B (OPL4)"), NULL, 0xae, 0, 42, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_12BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
||||||
_("like OPL3, but this time it also has a 24-channel version of MultiPCM."),
|
_("like OPL3, but this time it also has a 24-channel version of MultiPCM."),
|
||||||
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("FM 16"), _("FM 17"), _("FM 18"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("FM 16"), _("FM 17"), _("FM 18"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
||||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
||||||
|
@ -1648,9 +1647,8 @@ void DivEngine::registerSystems() {
|
||||||
fmOPL4PostEffectHandlerMap
|
fmOPL4PostEffectHandlerMap
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: same here
|
|
||||||
sysDefs[DIV_SYSTEM_OPL4_DRUMS]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_OPL4_DRUMS]=new DivSysDef(
|
||||||
_("Yamaha YMF278B (OPL4) with drums"), NULL, 0xaf, 0, 44, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
_("Yamaha YMF278B (OPL4) with drums"), NULL, 0xaf, 0, 44, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_12BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
||||||
_("the OPL4 but with drums mode turned on."),
|
_("the OPL4 but with drums mode turned on."),
|
||||||
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("Kick/FM 16"), _("Snare"), _("Tom"), _("Top"), _("HiHat"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("Kick/FM 16"), _("Snare"), _("Tom"), _("Top"), _("HiHat"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
||||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "BD", "SD", "TM", "TP", "HH", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "BD", "SD", "TM", "TP", "HH", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
||||||
|
|
|
@ -208,7 +208,7 @@ const char* sampleDepths[DIV_SAMPLE_DEPTH_MAX]={
|
||||||
"8-bit µ-law PCM",
|
"8-bit µ-law PCM",
|
||||||
"C219 PCM",
|
"C219 PCM",
|
||||||
"IMA ADPCM",
|
"IMA ADPCM",
|
||||||
NULL,
|
"12-bit PCM",
|
||||||
NULL,
|
NULL,
|
||||||
"16-bit PCM"
|
"16-bit PCM"
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue