mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-22 20:45:11 +00:00
C140: help µ-law ISN'T WORKING
This commit is contained in:
parent
0311d712b1
commit
27e454e7aa
7 changed files with 66 additions and 11 deletions
|
@ -219,6 +219,7 @@ size | description
|
|||
| - 0xcb: Casio PV-1000 - 3 channels
|
||||
| - 0xcc: K053260 - 4 channels
|
||||
| - 0xcd: TED - 2 channels
|
||||
| - 0xce: Namco C140 - 24 channels
|
||||
| - 0xde: YM2610B extended - 19 channels
|
||||
| - 0xe0: QSound - 19 channels
|
||||
| - 0xfc: Pong - 1 channel
|
||||
|
|
|
@ -143,7 +143,7 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE));
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0);
|
||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_MULAW)?0x08:0);
|
||||
if (chan[i].keyOn) {
|
||||
unsigned int bank=0;
|
||||
unsigned int start=0;
|
||||
|
@ -174,7 +174,6 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
chan[i].volChangedL=true;
|
||||
chan[i].volChangedR=true;
|
||||
}
|
||||
chan[i].keyOn=false;
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
chan[i].keyOff=false;
|
||||
|
@ -184,7 +183,10 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
rWrite(0x03+(i<<4),chan[i].freq&0xff);
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
rWrite(0x05+(i<<4),ctrl);
|
||||
if (chan[i].keyOn) {
|
||||
rWrite(0x05+(i<<4),ctrl);
|
||||
chan[i].keyOn=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -437,10 +439,20 @@ void DivPlatformC140::renderSamples(int sysID) {
|
|||
break;
|
||||
}
|
||||
if (memPos+length>=(getSampleMemCapacity())) {
|
||||
memcpy(sampleMem+(memPos/sizeof(short)),s->data16,(getSampleMemCapacity())-memPos);
|
||||
if (s->depth==DIV_SAMPLE_DEPTH_MULAW) {
|
||||
|
||||
} else {
|
||||
memcpy(sampleMem+(memPos/sizeof(short)),s->data16,(getSampleMemCapacity())-memPos);
|
||||
}
|
||||
logW("out of C140 memory for sample %d!",i);
|
||||
} else {
|
||||
memcpy(sampleMem+(memPos/sizeof(short)),s->data16,length);
|
||||
if (s->depth==DIV_SAMPLE_DEPTH_MULAW) {
|
||||
for (unsigned int i=0; i<length; i++) {
|
||||
sampleMem[i+(memPos/sizeof(short))]=(s->dataMuLaw[i]<<8)^0xff00;
|
||||
}
|
||||
} else {
|
||||
memcpy(sampleMem+(memPos/sizeof(short)),s->data16,length);
|
||||
}
|
||||
}
|
||||
sampleOff[i]=memPos>>1;
|
||||
sampleLoaded[i]=true;
|
||||
|
|
|
@ -269,6 +269,9 @@ int DivSample::getSampleOffset(int offset, int length, DivSampleDepth depth) {
|
|||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
off=(offset+1)/2;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_MULAW:
|
||||
off=offset;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
off=offset*2;
|
||||
break;
|
||||
|
@ -316,6 +319,10 @@ int DivSample::getSampleOffset(int offset, int length, DivSampleDepth depth) {
|
|||
off=(offset+1)/2;
|
||||
len=(length+1)/2;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_MULAW:
|
||||
off=offset;
|
||||
len=length;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
off=offset*2;
|
||||
len=length*2;
|
||||
|
@ -365,6 +372,9 @@ int DivSample::getEndPosition(DivSampleDepth depth) {
|
|||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
off=lengthVOX;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_MULAW:
|
||||
off=lengthMuLaw;
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
off=length16;
|
||||
break;
|
||||
|
@ -538,6 +548,12 @@ bool DivSample::initInternal(DivSampleDepth d, int count) {
|
|||
dataVOX=new unsigned char[lengthVOX];
|
||||
memset(dataVOX,0,lengthVOX);
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_MULAW: // 8-bit µ-law
|
||||
if (dataMuLaw!=NULL) delete[] dataMuLaw;
|
||||
lengthMuLaw=count;
|
||||
dataMuLaw=new unsigned char[(count+4095)&(~0xfff)];
|
||||
memset(dataMuLaw,0,(count+4095)&(~0xfff));
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_16BIT: // 16-bit
|
||||
if (data16!=NULL) delete[] data16;
|
||||
length16=count*2;
|
||||
|
@ -1155,6 +1171,13 @@ void DivSample::render(unsigned int formatMask) {
|
|||
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
||||
oki_decode(dataVOX,data16,samples);
|
||||
break;
|
||||
case DIV_SAMPLE_DEPTH_MULAW: // 8-bit µ-law PCM
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
unsigned int s=(dataMuLaw[i]^0xff);
|
||||
s=0x3f800000+(((s<<24)&0x80000000)|((s&0x7f)<<19));
|
||||
data16[i]=(short)((*(float*)&s)*128.0f);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -1233,6 +1256,16 @@ void DivSample::render(unsigned int formatMask) {
|
|||
if (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;
|
||||
oki_encode(data16,dataVOX,samples);
|
||||
}
|
||||
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_MULAW)) { // µ-law
|
||||
if (!initInternal(DIV_SAMPLE_DEPTH_MULAW,samples)) return;
|
||||
for (unsigned int i=0; i<samples; i++) {
|
||||
float s=(float)-data16[i];
|
||||
s/=32768.0f;
|
||||
unsigned int si=*(unsigned int*)&s;
|
||||
si-=0x3f800000;
|
||||
dataMuLaw[i]=(((si&0x80000000)>>24)|((si&0x03f80000)>>19))^0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* DivSample::getCurBuf() {
|
||||
|
@ -1255,6 +1288,8 @@ void* DivSample::getCurBuf() {
|
|||
return dataBRR;
|
||||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
return dataVOX;
|
||||
case DIV_SAMPLE_DEPTH_MULAW:
|
||||
return dataMuLaw;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
return data16;
|
||||
default:
|
||||
|
@ -1283,6 +1318,8 @@ unsigned int DivSample::getCurBufLen() {
|
|||
return lengthBRR;
|
||||
case DIV_SAMPLE_DEPTH_VOX:
|
||||
return lengthVOX;
|
||||
case DIV_SAMPLE_DEPTH_MULAW:
|
||||
return lengthMuLaw;
|
||||
case DIV_SAMPLE_DEPTH_16BIT:
|
||||
return length16;
|
||||
default:
|
||||
|
@ -1392,4 +1429,5 @@ DivSample::~DivSample() {
|
|||
if (dataB) delete[] dataB;
|
||||
if (dataBRR) delete[] dataBRR;
|
||||
if (dataVOX) delete[] dataVOX;
|
||||
if (dataMuLaw) delete[] dataMuLaw;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ enum DivSampleDepth: unsigned char {
|
|||
DIV_SAMPLE_DEPTH_8BIT=8,
|
||||
DIV_SAMPLE_DEPTH_BRR=9,
|
||||
DIV_SAMPLE_DEPTH_VOX=10,
|
||||
DIV_SAMPLE_DEPTH_MULAW=11,
|
||||
DIV_SAMPLE_DEPTH_16BIT=16,
|
||||
DIV_SAMPLE_DEPTH_MAX // boundary for sample depth
|
||||
};
|
||||
|
@ -108,6 +109,7 @@ struct DivSample {
|
|||
// - 8: 8-bit PCM
|
||||
// - 9: BRR (SNES)
|
||||
// - 10: VOX ADPCM
|
||||
// - 11: 8-bit µ-law PCM
|
||||
// - 16: 16-bit PCM
|
||||
DivSampleDepth depth;
|
||||
bool loop, brrEmphasis, dither;
|
||||
|
@ -130,8 +132,9 @@ struct DivSample {
|
|||
unsigned char* dataB; // 6
|
||||
unsigned char* dataBRR; // 9
|
||||
unsigned char* dataVOX; // 10
|
||||
unsigned char* dataMuLaw; // 11
|
||||
|
||||
unsigned int length8, length16, length1, lengthDPCM, lengthZ, lengthQSoundA, lengthA, lengthB, lengthBRR, lengthVOX;
|
||||
unsigned int length8, length16, length1, lengthDPCM, lengthZ, lengthQSoundA, lengthA, lengthB, lengthBRR, lengthVOX, lengthMuLaw;
|
||||
|
||||
unsigned int samples;
|
||||
|
||||
|
@ -337,6 +340,7 @@ struct DivSample {
|
|||
dataB(NULL),
|
||||
dataBRR(NULL),
|
||||
dataVOX(NULL),
|
||||
dataMuLaw(NULL),
|
||||
length8(0),
|
||||
length16(0),
|
||||
length1(0),
|
||||
|
@ -347,6 +351,7 @@ struct DivSample {
|
|||
lengthB(0),
|
||||
lengthBRR(0),
|
||||
lengthVOX(0),
|
||||
lengthMuLaw(0),
|
||||
samples(0) {
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
for (int j=0; j<DIV_MAX_SAMPLE_TYPE; j++) {
|
||||
|
|
|
@ -1872,10 +1872,9 @@ void DivEngine::registerSystems() {
|
|||
{}
|
||||
);
|
||||
|
||||
// TODO: Custom sample format
|
||||
sysDefs[DIV_SYSTEM_C140]=new DivSysDef(
|
||||
"Namco C140", NULL, 0xfe/*Placeholder*/, 0, 24, false, true, 0x161, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"Namco's first PCM chip arrived from 1987.",
|
||||
"Namco C140", NULL, 0xce, 0, 24, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_MULAW)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"Namco's first PCM chip from 1987.",
|
||||
{"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", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"},
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"},
|
||||
{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, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
|
@ -192,7 +192,7 @@ const char* sampleDepths[DIV_SAMPLE_DEPTH_MAX]={
|
|||
"8-bit PCM",
|
||||
"BRR",
|
||||
"VOX",
|
||||
NULL,
|
||||
"8-bit µ-law PCM",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -1608,7 +1608,7 @@ void FurnaceGUI::drawSampleEdit() {
|
|||
}
|
||||
posY=(0.5-pos.y/rectSize.y)*((sample->depth==DIV_SAMPLE_DEPTH_8BIT)?255:32767);
|
||||
if (posX>=0) {
|
||||
statusBar2=fmt::sprintf("(%d, %d)",posX,posY);
|
||||
statusBar2=fmt::sprintf("(%d, %d) $%.2x",posX,posY,((unsigned char*)sample->getCurBuf())[posX]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue