From 0f63db2dac6ca84a084693555c76e54378d86982 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 5 Dec 2022 19:13:21 -0500 Subject: [PATCH] BRR loop fixes! --- src/engine/brrUtils.c | 67 +++++++++++++++++++++++++++++++++--- src/engine/brrUtils.h | 2 +- src/engine/platform/snes.cpp | 6 ++-- src/engine/sample.cpp | 6 ++-- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/engine/brrUtils.c b/src/engine/brrUtils.c index ef354375..a147c6ae 100644 --- a/src/engine/brrUtils.c +++ b/src/engine/brrUtils.c @@ -171,10 +171,24 @@ long brrEncode(short* buf, unsigned char* out, long len, long loopStart) { memset(avgError,0,4*13*sizeof(int)); memset(possibleOut,0,4*13*8); - len&=~15; - loopStart&=~15; for (long i=0; ilen) { + 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 for (int j=0; j<4; j++) { @@ -206,7 +220,51 @@ long brrEncode(short* buf, unsigned char* out, long len, long loopStart) { } // 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]=0 && chan[i].samplesong.sampleLen) { 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); if (chan[i].audPos>0) { start=start+MIN(chan[i].audPos,s->lengthBRR-1)/16*9; } 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 { start=0; @@ -817,7 +817,7 @@ void DivPlatformSNES::renderSamples(int sysID) { 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); if (actualLength>0) { sampleOff[i]=memPos; diff --git a/src/engine/sample.cpp b/src/engine/sample.cpp index 5460aed3..95066710 100644 --- a/src/engine/sample.cpp +++ b/src/engine/sample.cpp @@ -490,8 +490,8 @@ bool DivSample::initInternal(DivSampleDepth d, int count) { case DIV_SAMPLE_DEPTH_BRR: // BRR if (dataBRR!=NULL) delete[] dataBRR; lengthBRR=9*((count+15)/16); - dataBRR=new unsigned char[lengthBRR]; - memset(dataBRR,0,lengthBRR); + dataBRR=new unsigned char[lengthBRR+9]; + memset(dataBRR,0,lengthBRR+9); break; case DIV_SAMPLE_DEPTH_VOX: // VOX 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 (!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 (!initInternal(DIV_SAMPLE_DEPTH_VOX,samples)) return;