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
|
|
@ -434,26 +434,6 @@ void DivEngine::notifyWaveChange(int wave) {
|
|||
isBusy.unlock();
|
||||
}
|
||||
|
||||
// ADPCM code attribution: https://wiki.neogeodev.org/index.php?title=ADPCM_codecs
|
||||
|
||||
static short adSteps[49]={
|
||||
16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
|
||||
41, 45, 50, 55, 60, 66, 73, 80, 88, 97,
|
||||
107, 118, 130, 143, 157, 173, 190, 209, 230, 253,
|
||||
279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
|
||||
724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
|
||||
};
|
||||
|
||||
static int adStepSeek[16]={
|
||||
-1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9
|
||||
};
|
||||
|
||||
static double samplePitches[11]={
|
||||
0.1666666666, 0.2, 0.25, 0.333333333, 0.5,
|
||||
1,
|
||||
2, 3, 4, 5, 6
|
||||
};
|
||||
|
||||
void DivEngine::renderSamplesP() {
|
||||
isBusy.lock();
|
||||
renderSamples();
|
||||
|
|
@ -463,117 +443,12 @@ void DivEngine::renderSamplesP() {
|
|||
void DivEngine::renderSamples() {
|
||||
sPreview.sample=-1;
|
||||
sPreview.pos=0;
|
||||
if (jediTable==NULL) {
|
||||
jediTable=new int[16*49];
|
||||
for (int step=0; step<49; step++) {
|
||||
for (int nib=0; nib<16; nib++) {
|
||||
int value=(2*(nib&0x07)+1)*adSteps[step]/8;
|
||||
jediTable[step*16+nib]=((nib&0x08)!=0)?-value:value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<song.sampleLen; i++) {
|
||||
DivSample* s=song.sample[i];
|
||||
if (s->rendLength!=0) {
|
||||
delete[] s->rendData;
|
||||
delete[] s->adpcmRendData;
|
||||
}
|
||||
s->rendLength=(double)s->length/samplePitches[s->pitch];
|
||||
if (s->rendLength==0) {
|
||||
s->adpcmRendLength=0;
|
||||
continue;
|
||||
}
|
||||
s->rendData=new short[s->rendLength];
|
||||
size_t adpcmLen=((s->rendLength>>1)+255)&0xffffff00;
|
||||
if (adpcmLen>1048576) adpcmLen=1048576;
|
||||
s->adpcmRendLength=adpcmLen;
|
||||
s->adpcmRendData=new unsigned char[adpcmLen];
|
||||
memset(s->adpcmRendData,0,adpcmLen);
|
||||
|
||||
// step 1: render to PCM
|
||||
unsigned int k=0;
|
||||
float mult=(float)(s->vol)/50.0f;
|
||||
for (double j=0; j<s->length; j+=samplePitches[s->pitch]) {
|
||||
if (k>=s->rendLength) {
|
||||
break;
|
||||
}
|
||||
if (s->depth==8) {
|
||||
float next=(float)(s->data[(unsigned int)j]-0x80)*mult;
|
||||
s->rendData[k++]=fmin(fmax(next,-128),127);
|
||||
} else {
|
||||
float next=(float)s->data[(unsigned int)j]*mult;
|
||||
s->rendData[k++]=fmin(fmax(next,-32768),32767);
|
||||
}
|
||||
}
|
||||
|
||||
// step 2: render to ADPCM
|
||||
int acc=0;
|
||||
int decstep=0;
|
||||
int diff=0;
|
||||
int step=0;
|
||||
int predsample=0;
|
||||
int index=0;
|
||||
int prevsample=0;
|
||||
int previndex=0;
|
||||
for (unsigned int j=0; j<s->adpcmRendLength*2; j++) {
|
||||
unsigned char encoded=0;
|
||||
int tempstep=0;
|
||||
|
||||
predsample=prevsample;
|
||||
index=previndex;
|
||||
step=adSteps[index];
|
||||
|
||||
short sample=(j<s->rendLength)?((s->depth==16)?(s->rendData[j]>>4):(s->rendData[j]<<4)):0;
|
||||
if (sample>0x7d0) sample=0x7d0;
|
||||
if (sample<-0x7d0) sample=-0x7d0;
|
||||
diff=sample-predsample;
|
||||
if (diff>=0) {
|
||||
encoded=0;
|
||||
} else {
|
||||
encoded=8;
|
||||
diff=-diff;
|
||||
}
|
||||
|
||||
tempstep=step;
|
||||
if (diff>=tempstep) {
|
||||
encoded|=4;
|
||||
diff-=tempstep;
|
||||
}
|
||||
tempstep>>=1;
|
||||
if (diff>=tempstep) {
|
||||
encoded|=2;
|
||||
diff-=tempstep;
|
||||
}
|
||||
tempstep>>=1;
|
||||
if (diff>=tempstep) encoded|=1;
|
||||
|
||||
acc+=jediTable[decstep+encoded];
|
||||
/*if (acc>0x7ff || acc<-0x800) {
|
||||
logW("clipping! %d\n",acc);
|
||||
}*/
|
||||
acc&=0xfff;
|
||||
if (acc&0x800) acc|=~0xfff;
|
||||
decstep+=adStepSeek[encoded&7]*16;
|
||||
if (decstep<0) decstep=0;
|
||||
if (decstep>48*16) decstep=48*16;
|
||||
predsample=(short)acc;
|
||||
|
||||
index+=adStepSeek[encoded];
|
||||
if (index<0) index=0;
|
||||
if (index>48) index=48;
|
||||
|
||||
prevsample=predsample;
|
||||
previndex=index;
|
||||
|
||||
if (j&1) {
|
||||
s->adpcmRendData[j>>1]|=encoded;
|
||||
} else {
|
||||
s->adpcmRendData[j>>1]=encoded<<4;
|
||||
}
|
||||
}
|
||||
song.sample[i]->render();
|
||||
}
|
||||
|
||||
/*
|
||||
// step 3: allocate ADPCM samples
|
||||
if (adpcmMem==NULL) adpcmMem=new unsigned char[16777216];
|
||||
|
||||
|
|
@ -631,6 +506,7 @@ void DivEngine::renderSamples() {
|
|||
memPos+=length+16;
|
||||
}
|
||||
qsoundMemLen=memPos+256;
|
||||
*/
|
||||
}
|
||||
|
||||
void DivEngine::createNew() {
|
||||
|
|
@ -1901,22 +1777,23 @@ bool DivEngine::addSampleFromFile(const char* path) {
|
|||
sample->name=sName;
|
||||
|
||||
int index=0;
|
||||
sample->length=si.frames;
|
||||
sample->data=new short[si.frames];
|
||||
sample->depth=16;
|
||||
sample->vol=50;
|
||||
sample->pitch=5;
|
||||
if ((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8) {
|
||||
sample->depth=8;
|
||||
} else {
|
||||
sample->depth=16;
|
||||
}
|
||||
sample->init(si.frames);
|
||||
for (int i=0; i<si.frames*si.channels; i+=si.channels) {
|
||||
int averaged=0;
|
||||
for (int j=0; j<si.channels; j++) {
|
||||
if (((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8)) {
|
||||
averaged+=buf[i+j];
|
||||
} else {
|
||||
averaged+=buf[i+j];
|
||||
}
|
||||
averaged+=buf[i+j];
|
||||
}
|
||||
averaged/=si.channels;
|
||||
sample->data[index++]=averaged;
|
||||
if (((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8)) {
|
||||
sample->data8[index++]=averaged;
|
||||
} else {
|
||||
sample->data16[index++]=averaged;
|
||||
}
|
||||
}
|
||||
delete[] buf;
|
||||
sample->rate=si.samplerate;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue