diff --git a/src/engine/filter.cpp b/src/engine/filter.cpp index 5c8ab218e..25d581b5a 100644 --- a/src/engine/filter.cpp +++ b/src/engine/filter.cpp @@ -26,6 +26,7 @@ float* DivFilterTables::cubicTable=NULL; float* DivFilterTables::sincTable=NULL; float* DivFilterTables::sincTable8=NULL; float* DivFilterTables::sincIntegralTable=NULL; +float* DivFilterTables::sincIntegralSmallTable=NULL; // portions from Schism Tracker (scripts/lutgen.c) // licensed under same license as this program. @@ -106,3 +107,25 @@ float* DivFilterTables::getSincIntegralTable() { } return sincIntegralTable; } + +float* DivFilterTables::getSincIntegralSmallTable() { + if (sincIntegralSmallTable==NULL) { + logD("initializing small sinc integral table."); + sincIntegralSmallTable=new float[256]; + + sincIntegralSmallTable[0]=-0.5f; + for (int i=1; i<256; i++) { + int mapped=((i&31)<<3)|(i>>5); + int mappedPrev=(((i-1)&31)<<3)|((i-1)>>5); + double x=(double)i*M_PI/32.0; + double sinc=sin(x)/x; + sincIntegralSmallTable[mapped]=sincIntegralSmallTable[mappedPrev]+(sinc/32.0); + } + + for (int i=0; i<256; i++) { + int mapped=((i&31)<<3)|(i>>5); + sincIntegralSmallTable[mapped]*=pow(cos(M_PI*(double)i/512.0),2.0); + } + } + return sincIntegralSmallTable; +} \ No newline at end of file diff --git a/src/engine/filter.h b/src/engine/filter.h index 1e6597e4f..1406ee145 100644 --- a/src/engine/filter.h +++ b/src/engine/filter.h @@ -23,6 +23,7 @@ class DivFilterTables { static float* sincTable; static float* sincTable8; static float* sincIntegralTable; + static float* sincIntegralSmallTable; /** * get a 1024x4 cubic spline table. @@ -47,4 +48,10 @@ class DivFilterTables { * @return the table. */ static float* getSincIntegralTable(); + + /** + * get a 32x8 one-side sine-windowed sinc integral table. + * @return the table. + */ + static float* getSincIntegralSmallTable(); }; \ No newline at end of file diff --git a/src/gui/osc.cpp b/src/gui/osc.cpp index d2f62910e..4a12ff34c 100644 --- a/src/gui/osc.cpp +++ b/src/gui/osc.cpp @@ -55,7 +55,7 @@ void FurnaceGUI::readOsc() { oscValues[ch]=new float[1024]; } memset(oscValues[ch],0,1024*sizeof(float)); - float* sincITable=DivFilterTables::getSincIntegralTable(); + float* sincITable=DivFilterTables::getSincIntegralSmallTable(); float posFrac=0.0; float factor=(float)oscWidth/(float)winSize; @@ -67,11 +67,11 @@ void FurnaceGUI::readOsc() { posFrac+=1.0; while (posFrac>=1.0) { - unsigned int n=((unsigned int)(posFrac*8192.0))&8191; + unsigned int n=((unsigned int)(posFrac*32.0))&31; posFrac-=factor; posInt++; - float* t1=&sincITable[(8191-n)<<3]; + float* t1=&sincITable[(31-n)<<3]; float* t2=&sincITable[n<<3]; float delta=e->oscBuf[ch][posInt&0x7fff]-e->oscBuf[ch][(posInt-1)&0x7fff];