beta 1-3 .dmf loading
i did it
This commit is contained in:
parent
9e0e725802
commit
8a49522e59
|
|
@ -53,6 +53,10 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
warnings="";
|
||||
try {
|
||||
DivSong ds;
|
||||
unsigned char historicColIns[DIV_MAX_CHANS];
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
historicColIns[i]=i;
|
||||
}
|
||||
|
||||
ds.nullWave.len=32;
|
||||
for (int i=0; i<32; i++) {
|
||||
|
|
@ -172,7 +176,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
|
||||
ds.timeBase=reader.readC();
|
||||
ds.speed1=reader.readC();
|
||||
if (ds.version>0x03) {
|
||||
if (ds.version>0x05) {
|
||||
ds.speed2=reader.readC();
|
||||
ds.pal=reader.readC();
|
||||
ds.hz=(ds.pal)?60:50;
|
||||
|
|
@ -258,7 +262,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
addWarning("Yamaha YMU759 emulation is incomplete! please migrate your song to the OPL3 system.");
|
||||
}
|
||||
|
||||
logI("reading pattern matrix (%d)...",ds.ordersLen);
|
||||
logV("%x",reader.tell());
|
||||
|
||||
logI("reading pattern matrix (%d * %d = %d)...",ds.ordersLen,getChannelCount(ds.system[0]),ds.ordersLen*getChannelCount(ds.system[0]));
|
||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||
for (int j=0; j<ds.ordersLen; j++) {
|
||||
ds.orders.ord[i][j]=reader.readC();
|
||||
|
|
@ -272,9 +278,14 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.pat[i].getPattern(j,true)->name=reader.readString((unsigned char)reader.readC());
|
||||
}
|
||||
}
|
||||
if (ds.version>0x03 && ds.version<0x06 && i<16) {
|
||||
historicColIns[i]=reader.readC();
|
||||
}
|
||||
}
|
||||
|
||||
if (ds.version>0x03) {
|
||||
logV("%x",reader.tell());
|
||||
|
||||
if (ds.version>0x05) {
|
||||
ds.insLen=(unsigned char)reader.readC();
|
||||
} else {
|
||||
ds.insLen=16;
|
||||
|
|
@ -282,7 +293,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
logI("reading instruments (%d)...",ds.insLen);
|
||||
for (int i=0; i<ds.insLen; i++) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
if (ds.version>0x03) {
|
||||
if (ds.version>0x05) {
|
||||
ins->name=reader.readString((unsigned char)reader.readC());
|
||||
}
|
||||
logD("%d name: %s",i,ins->name.c_str());
|
||||
|
|
@ -319,6 +330,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
if (ins->mode) { // FM
|
||||
if (ds.version>0x05) {
|
||||
ins->fm.alg=reader.readC();
|
||||
if (ds.version<0x13) {
|
||||
reader.readC();
|
||||
|
|
@ -335,13 +347,24 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
ins->fm.ops=4;
|
||||
}
|
||||
ins->fm.ams=reader.readC();
|
||||
} else {
|
||||
ins->fm.alg=reader.readC();
|
||||
reader.readC();
|
||||
ins->fm.fb=reader.readC();
|
||||
reader.readC(); // apparently an index of sorts starting from 0x59?
|
||||
ins->fm.fms=reader.readC();
|
||||
reader.readC(); // 0x59+index?
|
||||
ins->fm.ops=2+reader.readC()*2;
|
||||
}
|
||||
|
||||
logD("ALG %d FB %d FMS %d AMS %d OPS %d",ins->fm.alg,ins->fm.fb,ins->fm.fms,ins->fm.ams,ins->fm.ops);
|
||||
if (ins->fm.ops!=2 && ins->fm.ops!=4) {
|
||||
logE("invalid op count %d. did we read it wrong?",ins->fm.ops);
|
||||
lastError="file is corrupt or unreadable at operators";
|
||||
delete[] file;
|
||||
return false;
|
||||
}
|
||||
ins->fm.ams=reader.readC();
|
||||
|
||||
for (int j=0; j<ins->fm.ops; j++) {
|
||||
ins->fm.op[j].am=reader.readC();
|
||||
|
|
@ -385,7 +408,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ins->fm.op[j].dt2=reader.readC();
|
||||
}
|
||||
}
|
||||
if (ds.version>0x03) {
|
||||
if (ds.version>0x05) {
|
||||
if (ds.system[0]==DIV_SYSTEM_SMS_OPLL || ds.system[0]==DIV_SYSTEM_NES_VRC7) {
|
||||
ins->fm.op[j].ksr=reader.readC();
|
||||
ins->fm.op[j].vib=reader.readC();
|
||||
|
|
@ -588,6 +611,8 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
logV("%x",reader.tell());
|
||||
|
||||
logI("reading patterns (%d channels, %d orders)...",getChannelCount(ds.system[0]),ds.ordersLen);
|
||||
for (int i=0; i<getChannelCount(ds.system[0]); i++) {
|
||||
DivChannelData& chan=ds.pat[i];
|
||||
|
|
@ -595,7 +620,6 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
chan.effectRows=1;
|
||||
} else {
|
||||
chan.effectRows=reader.readC();
|
||||
|
||||
}
|
||||
logD("%d fx rows: %d",i,chan.effectRows);
|
||||
if (chan.effectRows>4 || chan.effectRows<1) {
|
||||
|
|
@ -606,6 +630,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
for (int j=0; j<ds.ordersLen; j++) {
|
||||
DivPattern* pat=chan.getPattern(ds.orders.ord[i][j],true);
|
||||
if (ds.version>0x05) { // current pattern format
|
||||
for (int k=0; k<ds.patLen; k++) {
|
||||
// note
|
||||
pat->data[k][0]=reader.readS();
|
||||
|
|
@ -672,13 +697,43 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else { // historic pattern format
|
||||
if (i<16) pat->data[0][2]=historicColIns[i];
|
||||
for (int k=0; k<ds.patLen; k++) {
|
||||
// note
|
||||
pat->data[k][0]=reader.readC();
|
||||
// octave
|
||||
pat->data[k][1]=reader.readC();
|
||||
if (pat->data[k][0]!=0) {
|
||||
// YMU759 is stored 2 octaves lower
|
||||
pat->data[k][1]+=2;
|
||||
}
|
||||
if (pat->data[k][0]==0 && pat->data[k][1]!=0) {
|
||||
logD("what? %d:%d:%d note %d octave %d",i,j,k,pat->data[k][0],pat->data[k][1]);
|
||||
pat->data[k][0]=12;
|
||||
pat->data[k][1]--;
|
||||
}
|
||||
// volume and effect
|
||||
unsigned char vol=reader.readC();
|
||||
unsigned char fx=reader.readC();
|
||||
unsigned char fxVal=reader.readC();
|
||||
pat->data[k][3]=(vol==0x80)?-1:vol;
|
||||
// effect
|
||||
pat->data[k][4]=(fx==0x80)?-1:fx;
|
||||
pat->data[k][5]=(fxVal==0x80)?-1:fxVal;
|
||||
// instrument wasn't stored back then
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ymuSampleRate=20;
|
||||
|
||||
ds.sampleLen=(unsigned char)reader.readC();
|
||||
logI("reading samples (%d)...",ds.sampleLen);
|
||||
if (ds.version<0x0b && ds.sampleLen>0) { // TODO what is this for?
|
||||
reader.readC();
|
||||
if (ds.version<0x0b && ds.sampleLen>0) {
|
||||
// it appears this byte stored the YMU759 sample rate
|
||||
ymuSampleRate=reader.readC();
|
||||
}
|
||||
for (int i=0; i<ds.sampleLen; i++) {
|
||||
DivSample* sample=new DivSample;
|
||||
|
|
@ -686,6 +741,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
int pitch=5;
|
||||
int vol=50;
|
||||
short* data;
|
||||
unsigned char* adpcmData;
|
||||
if (length<0) {
|
||||
logE("invalid sample length %d. are we doing something wrong?",length);
|
||||
lastError="file is corrupt or unreadable at samples";
|
||||
|
|
@ -704,6 +760,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
pitch=reader.readC();
|
||||
vol=reader.readC();
|
||||
}
|
||||
if (ds.version<=0x05) {
|
||||
sample->rate=ymuSampleRate*400;
|
||||
}
|
||||
if (ds.version>0x15) {
|
||||
sample->depth=reader.readC();
|
||||
if (sample->depth!=8 && sample->depth!=16) {
|
||||
|
|
@ -711,9 +770,15 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
sample->depth=16;
|
||||
}
|
||||
} else {
|
||||
if (ds.version>0x05) {
|
||||
sample->depth=16;
|
||||
} else {
|
||||
// it appears samples were stored as ADPCM back then
|
||||
sample->depth=6;
|
||||
}
|
||||
}
|
||||
if (length>0) {
|
||||
if (ds.version>0x05) {
|
||||
if (ds.version<0x0b) {
|
||||
data=new short[1+(length/2)];
|
||||
reader.read(data,length);
|
||||
|
|
@ -748,6 +813,22 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
delete[] data;
|
||||
} else {
|
||||
// ADPCM?
|
||||
// it appears to be a slightly modified version of ADPCM-B!
|
||||
adpcmData=new unsigned char[length];
|
||||
logV("%x",reader.tell());
|
||||
reader.read(adpcmData,length);
|
||||
for (int i=0; i<length; i++) {
|
||||
adpcmData[i]=(adpcmData[i]<<4)|(adpcmData[i]>>4);
|
||||
}
|
||||
if (!sample->init(length*2)) {
|
||||
logE("%d: error while initializing sample!",i);
|
||||
}
|
||||
|
||||
memcpy(sample->dataB,adpcmData,length);
|
||||
delete[] adpcmData;
|
||||
}
|
||||
}
|
||||
ds.sample.push_back(sample);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue