BRR loop fixes!
This commit is contained in:
parent
2dd8886db1
commit
0f63db2dac
|
@ -171,10 +171,24 @@ long brrEncode(short* buf, unsigned char* out, long len, long loopStart) {
|
||||||
memset(avgError,0,4*13*sizeof(int));
|
memset(avgError,0,4*13*sizeof(int));
|
||||||
memset(possibleOut,0,4*13*8);
|
memset(possibleOut,0,4*13*8);
|
||||||
|
|
||||||
len&=~15;
|
|
||||||
loopStart&=~15;
|
|
||||||
for (long i=0; i<len; i+=16) {
|
for (long i=0; i<len; i+=16) {
|
||||||
memcpy(in,buf,16*sizeof(short));
|
if (i+16>len) {
|
||||||
|
long p=i;
|
||||||
|
for (int j=0; j<16; j++) {
|
||||||
|
if (p>=len) {
|
||||||
|
if (loopStart<0 || loopStart>=len) {
|
||||||
|
in[j]=0;
|
||||||
|
} else {
|
||||||
|
p=loopStart;
|
||||||
|
in[j]=buf[p++];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in[j]=buf[p++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(in,&buf[i],16*sizeof(short));
|
||||||
|
}
|
||||||
|
|
||||||
// encode
|
// encode
|
||||||
for (int j=0; j<4; j++) {
|
for (int j=0; j<4; j++) {
|
||||||
|
@ -206,7 +220,51 @@ long brrEncode(short* buf, unsigned char* out, long len, long loopStart) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write
|
// write
|
||||||
out[0]=(range<<4)|(filter<<2)|((i+16>=len)?((loopStart>=0)?3:1):0);
|
out[0]=(range<<4)|(filter<<2)|((i+16>=len && loopStart<0)?1:0);
|
||||||
|
for (int j=0; j<8; j++) {
|
||||||
|
out[j+1]=possibleOut[filter][range][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j=0; j<4; j++) {
|
||||||
|
for (int k=0; k<13; k++) {
|
||||||
|
last1[j][k]=last1[filter][range];
|
||||||
|
last2[j][k]=last2[filter][range];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out+=9;
|
||||||
|
total+=9;
|
||||||
|
}
|
||||||
|
// encode loop block
|
||||||
|
if (loopStart>=0) {
|
||||||
|
long p=loopStart;
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
if (p>=len) {
|
||||||
|
p=loopStart;
|
||||||
|
}
|
||||||
|
in[i]=buf[p++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// encode (filter 0/1 only)
|
||||||
|
for (int j=0; j<2; j++) {
|
||||||
|
for (int k=0; k<13; k++) {
|
||||||
|
brrEncodeBlock(in,possibleOut[j][k],k,j,&last1[j][k],&last2[j][k],&avgError[j][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find best filter/range
|
||||||
|
int candError=0x7fffffff;
|
||||||
|
for (int j=0; j<2; j++) {
|
||||||
|
for (int k=0; k<13; k++) {
|
||||||
|
if (avgError[j][k]<candError) {
|
||||||
|
candError=avgError[j][k];
|
||||||
|
filter=j;
|
||||||
|
range=k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write
|
||||||
|
out[0]=(range<<4)|(filter<<2)|3;
|
||||||
for (int j=0; j<8; j++) {
|
for (int j=0; j<8; j++) {
|
||||||
out[j+1]=possibleOut[filter][range][j];
|
out[j+1]=possibleOut[filter][range][j];
|
||||||
}
|
}
|
||||||
|
@ -217,7 +275,6 @@ long brrEncode(short* buf, unsigned char* out, long len, long loopStart) {
|
||||||
last2[j][k]=last2[filter][range];
|
last2[j][k]=last2[filter][range];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf+=16;
|
|
||||||
out+=9;
|
out+=9;
|
||||||
total+=9;
|
total+=9;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* read len samples from buf, encode in BRR and output to out.
|
* read len samples from buf, encode in BRR and output to out.
|
||||||
* @param buf input data.
|
* @param buf input data.
|
||||||
* @param out output buffer. shall be at least 9*(len/16) shorts in size.
|
* @param out output buffer. shall be at least 9*((15+len)/16) shorts in size (9 more if loopStart is not -1!)
|
||||||
* @param len input length (should be a multiple of 16. if it isn't, the output will be padded).
|
* @param len input length (should be a multiple of 16. if it isn't, the output will be padded).
|
||||||
* @param loopStart beginning of loop area (may be -1 for no loop). this is used to ensure the respective block has no filter in order to loop properly.
|
* @param loopStart beginning of loop area (may be -1 for no loop). this is used to ensure the respective block has no filter in order to loop properly.
|
||||||
* @return number of written samples.
|
* @return number of written samples.
|
||||||
|
|
|
@ -214,13 +214,13 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
loop=start;
|
loop=start;
|
||||||
} else if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
} else if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
start=sampleOff[chan[i].sample];
|
start=sampleOff[chan[i].sample];
|
||||||
end=MIN(start+MAX(s->lengthBRR,1),getSampleMemCapacity());
|
end=MIN(start+MAX(s->lengthBRR+((s->loop && s->depth!=DIV_SAMPLE_DEPTH_BRR)?9:0),1),getSampleMemCapacity());
|
||||||
loop=MAX(start,end-1);
|
loop=MAX(start,end-1);
|
||||||
if (chan[i].audPos>0) {
|
if (chan[i].audPos>0) {
|
||||||
start=start+MIN(chan[i].audPos,s->lengthBRR-1)/16*9;
|
start=start+MIN(chan[i].audPos,s->lengthBRR-1)/16*9;
|
||||||
}
|
}
|
||||||
if (s->loopStart>=0) {
|
if (s->loopStart>=0) {
|
||||||
loop=start+s->loopStart/16*9;
|
loop=((s->depth!=DIV_SAMPLE_DEPTH_BRR)?9:0)+start+((s->loopStart/16)*9);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start=0;
|
start=0;
|
||||||
|
@ -817,7 +817,7 @@ void DivPlatformSNES::renderSamples(int sysID) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int length=s->lengthBRR;
|
int length=s->lengthBRR+((s->loop && s->depth!=DIV_SAMPLE_DEPTH_BRR)?9:0);
|
||||||
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)/9*9,length);
|
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)/9*9,length);
|
||||||
if (actualLength>0) {
|
if (actualLength>0) {
|
||||||
sampleOff[i]=memPos;
|
sampleOff[i]=memPos;
|
||||||
|
|
|
@ -490,8 +490,8 @@ bool DivSample::initInternal(DivSampleDepth d, int count) {
|
||||||
case DIV_SAMPLE_DEPTH_BRR: // BRR
|
case DIV_SAMPLE_DEPTH_BRR: // BRR
|
||||||
if (dataBRR!=NULL) delete[] dataBRR;
|
if (dataBRR!=NULL) delete[] dataBRR;
|
||||||
lengthBRR=9*((count+15)/16);
|
lengthBRR=9*((count+15)/16);
|
||||||
dataBRR=new unsigned char[lengthBRR];
|
dataBRR=new unsigned char[lengthBRR+9];
|
||||||
memset(dataBRR,0,lengthBRR);
|
memset(dataBRR,0,lengthBRR+9);
|
||||||
break;
|
break;
|
||||||
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
case DIV_SAMPLE_DEPTH_VOX: // VOX
|
||||||
if (dataVOX!=NULL) delete[] dataVOX;
|
if (dataVOX!=NULL) delete[] dataVOX;
|
||||||
|
@ -1100,7 +1100,7 @@ void DivSample::render(unsigned int formatMask) {
|
||||||
}
|
}
|
||||||
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_BRR)) { // BRR
|
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_BRR)) { // BRR
|
||||||
if (!initInternal(DIV_SAMPLE_DEPTH_BRR,samples)) return;
|
if (!initInternal(DIV_SAMPLE_DEPTH_BRR,samples)) return;
|
||||||
brrEncode(data16,dataBRR,(samples+15)&(~15),loop?loopStart:-1);
|
brrEncode(data16,dataBRR,samples,loop?loopStart:-1);
|
||||||
}
|
}
|
||||||
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_VOX)) { // VOX
|
if (NOT_IN_FORMAT(DIV_SAMPLE_DEPTH_VOX)) { // VOX
|
||||||
if (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;
|
if (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;
|
||||||
|
|
Loading…
Reference in a new issue