sample system rewrite! **PLEASE READ**
this commit mostly rewrites the sample system. as of now samples can be ADPCM, 8-bit, BRR or 16-bit or something... consider this VERY EXPERIMENTAL. if you find any issues REPORT THEM immediately. it's nearly 4am...
This commit is contained in:
parent
3542229448
commit
1e98f0c4a1
19 changed files with 545 additions and 390 deletions
|
|
@ -42,6 +42,12 @@ struct InflateBlock {
|
|||
}
|
||||
};
|
||||
|
||||
static double samplePitches[11]={
|
||||
0.1666666666, 0.2, 0.25, 0.333333333, 0.5,
|
||||
1,
|
||||
2, 3, 4, 5, 6
|
||||
};
|
||||
|
||||
bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||
SafeReader reader=SafeReader(file,len);
|
||||
warnings="";
|
||||
|
|
@ -607,9 +613,12 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
for (int i=0; i<ds.sampleLen; i++) {
|
||||
DivSample* sample=new DivSample;
|
||||
sample->length=reader.readI();
|
||||
if (sample->length<0) {
|
||||
logE("invalid sample length %d. are we doing something wrong?\n",sample->length);
|
||||
int length=reader.readI();
|
||||
int pitch=5;
|
||||
int vol=50;
|
||||
short* data;
|
||||
if (length<0) {
|
||||
logE("invalid sample length %d. are we doing something wrong?\n",length);
|
||||
lastError="file is corrupt or unreadable at samples";
|
||||
delete[] file;
|
||||
return false;
|
||||
|
|
@ -619,31 +628,57 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
sample->name="";
|
||||
}
|
||||
logD("%d name %s (%d)\n",i,sample->name.c_str(),sample->length);
|
||||
if (ds.version<0x0b) {
|
||||
sample->rate=22050;
|
||||
sample->pitch=5;
|
||||
sample->vol=50;
|
||||
} else {
|
||||
logD("%d name %s (%d)\n",i,sample->name.c_str(),length);
|
||||
sample->rate=22050;
|
||||
if (ds.version>=0x0b) {
|
||||
sample->rate=fileToDivRate(reader.readC());
|
||||
sample->pitch=reader.readC();
|
||||
sample->vol=reader.readC();
|
||||
pitch=reader.readC();
|
||||
vol=reader.readC();
|
||||
}
|
||||
logI("pitch and vol: %d %d\n",sample->pitch,sample->vol);
|
||||
if (ds.version>0x15) {
|
||||
sample->depth=reader.readC();
|
||||
if (sample->depth!=8 && sample->depth!=16) {
|
||||
logW("%d: sample depth is wrong! (%d)\n",i,sample->depth);
|
||||
sample->depth=16;
|
||||
}
|
||||
} else {
|
||||
sample->depth=16;
|
||||
}
|
||||
if (sample->length>0) {
|
||||
if (length>0) {
|
||||
if (ds.version<0x0b) {
|
||||
sample->data=new short[1+(sample->length/2)];
|
||||
reader.read(sample->data,sample->length);
|
||||
sample->length/=2;
|
||||
data=new short[1+(length/2)];
|
||||
reader.read(data,length);
|
||||
length/=2;
|
||||
} else {
|
||||
sample->data=new short[sample->length];
|
||||
reader.read(sample->data,sample->length*2);
|
||||
data=new short[length];
|
||||
reader.read(data,length*2);
|
||||
}
|
||||
|
||||
if (pitch!=5) {
|
||||
logD("%d: scaling from %d...\n",i,pitch);
|
||||
}
|
||||
|
||||
// render data
|
||||
if (!sample->init((double)length/samplePitches[pitch])) {
|
||||
logE("%d: error while initializing sample!\n",i);
|
||||
}
|
||||
|
||||
unsigned int k=0;
|
||||
float mult=(float)(vol)/50.0f;
|
||||
for (double j=0; j<length; j+=samplePitches[pitch]) {
|
||||
if (k>=sample->samples) {
|
||||
break;
|
||||
}
|
||||
if (sample->depth==8) {
|
||||
float next=(float)(data[(unsigned int)j]-0x80)*mult;
|
||||
sample->data8[k++]=fmin(fmax(next,-128),127);
|
||||
} else {
|
||||
float next=(float)data[(unsigned int)j]*mult;
|
||||
sample->data16[k++]=fmin(fmax(next,-32768),32767);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
ds.sample.push_back(sample);
|
||||
}
|
||||
|
|
@ -996,6 +1031,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
|
||||
// read samples
|
||||
for (int i=0; i<ds.sampleLen; i++) {
|
||||
int vol=0;
|
||||
int pitch=0;
|
||||
|
||||
reader.seek(samplePtr[i],SEEK_SET);
|
||||
reader.read(magic,4);
|
||||
if (strcmp(magic,"SMPL")!=0) {
|
||||
|
|
@ -1008,10 +1046,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
DivSample* sample=new DivSample;
|
||||
|
||||
sample->name=reader.readString();
|
||||
sample->length=reader.readI();
|
||||
sample->samples=reader.readI();
|
||||
sample->rate=reader.readI();
|
||||
sample->vol=reader.readS();
|
||||
sample->pitch=reader.readS();
|
||||
if (ds.version<58) {
|
||||
vol=reader.readS();
|
||||
pitch=reader.readS();
|
||||
} else {
|
||||
reader.readI();
|
||||
}
|
||||
sample->depth=reader.readC();
|
||||
|
||||
// reserved
|
||||
|
|
@ -1030,8 +1072,42 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
reader.readI();
|
||||
}
|
||||
|
||||
sample->data=new short[sample->length];
|
||||
reader.read(sample->data,2*sample->length);
|
||||
if (ds.version>=58) { // modern sample
|
||||
sample->init(sample->samples);
|
||||
reader.read(sample->getCurBuf(),sample->getCurBufLen());
|
||||
} else { // legacy sample
|
||||
int length=sample->samples;
|
||||
short* data=new short[length];
|
||||
reader.read(data,2*length);
|
||||
|
||||
if (pitch!=5) {
|
||||
logD("%d: scaling from %d...\n",i,pitch);
|
||||
}
|
||||
|
||||
// render data
|
||||
if (sample->depth!=8 && sample->depth!=16) {
|
||||
logW("%d: sample depth is wrong! (%d)\n",i,sample->depth);
|
||||
sample->depth=16;
|
||||
}
|
||||
sample->init(sample->samples);
|
||||
|
||||
unsigned int k=0;
|
||||
float mult=(float)(vol)/50.0f;
|
||||
for (double j=0; j<length; j+=samplePitches[pitch]) {
|
||||
if (k>=sample->samples) {
|
||||
break;
|
||||
}
|
||||
if (sample->depth==8) {
|
||||
float next=(float)(data[(unsigned int)j]-0x80)*mult;
|
||||
sample->data8[k++]=fmin(fmax(next,-128),127);
|
||||
} else {
|
||||
float next=(float)data[(unsigned int)j]*mult;
|
||||
sample->data16[k++]=fmin(fmax(next,-32768),32767);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
ds.sample.push_back(sample);
|
||||
}
|
||||
|
|
@ -1390,16 +1466,15 @@ SafeWriter* DivEngine::saveFur() {
|
|||
w->writeI(0);
|
||||
|
||||
w->writeString(sample->name,false);
|
||||
w->writeI(sample->length);
|
||||
w->writeI(sample->samples);
|
||||
w->writeI(sample->rate);
|
||||
w->writeS(sample->vol);
|
||||
w->writeS(sample->pitch);
|
||||
w->writeI(0); // reserved (for now)
|
||||
w->writeC(sample->depth);
|
||||
w->writeC(0);
|
||||
w->writeS(sample->centerRate);
|
||||
w->writeI(sample->loopStart);
|
||||
|
||||
w->write(sample->data,sample->length*2);
|
||||
w->write(sample->getCurBuf(),sample->getCurBufLen());
|
||||
}
|
||||
|
||||
/// PATTERN
|
||||
|
|
@ -1728,13 +1803,14 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
|
||||
w->writeC(song.sample.size());
|
||||
for (DivSample* i: song.sample) {
|
||||
w->writeI(i->length);
|
||||
w->writeI(i->samples);
|
||||
w->writeString(i->name,true);
|
||||
w->writeC(divToFileRate(i->rate));
|
||||
w->writeC(i->pitch);
|
||||
w->writeC(i->vol);
|
||||
w->writeC(i->depth);
|
||||
w->write(i->data,2*i->length);
|
||||
w->writeC(5);
|
||||
w->writeC(50);
|
||||
// i'm too lazy to deal with .dmf's weird way of storing 8-bit samples
|
||||
w->writeC(16);
|
||||
w->write(i->data16,i->length16);
|
||||
}
|
||||
|
||||
return w;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue