This commit is contained in:
tildearrow 2023-09-02 23:57:55 -05:00
parent 20ed22d6e8
commit 19d0ed617a
4 changed files with 41 additions and 27 deletions

View File

@ -417,8 +417,10 @@ void FurnaceGUI::drawChanOsc() {
if (fft->plan==NULL) { if (fft->plan==NULL) {
logD("creating FFT plan for channel %d",ch); logD("creating FFT plan for channel %d",ch);
fft->inBuf=(double*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(double)); fft->inBuf=(double*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(double));
fft->outBuf=(fftw_complex*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(fftw_complex)); fft->outBuf=(fftw_complex*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(fftw_complex)*2);
fft->corrBuf=(double*)fftw_malloc(FURNACE_FFT_SIZE*sizeof(double)*2);
fft->plan=fftw_plan_dft_r2c_1d(FURNACE_FFT_SIZE,fft->inBuf,fft->outBuf,FFTW_ESTIMATE); fft->plan=fftw_plan_dft_r2c_1d(FURNACE_FFT_SIZE,fft->inBuf,fft->outBuf,FFTW_ESTIMATE);
fft->planI=fftw_plan_dft_c2r_1d(FURNACE_FFT_SIZE,fft->outBuf,fft->corrBuf,FFTW_ESTIMATE);
} }
int displaySize=(float)(buf->rate)*(chanOscWindowSize/1000.0f); int displaySize=(float)(buf->rate)*(chanOscWindowSize/1000.0f);
@ -447,38 +449,44 @@ void FurnaceGUI::drawChanOsc() {
waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f)); waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f));
} }
} else { } else {
float minLevel=1.0f; //float minLevel=1.0f;
float maxLevel=-1.0f; //float maxLevel=-1.0f;
float dcOff=0.0f; //float dcOff=0.0f;
unsigned short needlePos=buf->needle; unsigned short needlePos=buf->needle;
//unsigned short needlePosOrig=needlePos; //unsigned short needlePosOrig=needlePos;
for (int i=0; i<FURNACE_FFT_SIZE; i++) { for (int i=0; i<FURNACE_FFT_SIZE; i++) {
fft->inBuf[i]=(double)buf->data[(unsigned short)(needlePos-displaySize*2+((i*displaySize*2)/FURNACE_FFT_SIZE))]/32768.0; fft->inBuf[i]=(double)buf->data[(unsigned short)(needlePos-displaySize*2+((i*displaySize*2)/FURNACE_FFT_SIZE))]/32768.0;
fft->inBuf[i]*=sin(M_PI*(double)i/(double)FURNACE_FFT_SIZE);
} }
fftw_execute(fft->plan); fftw_execute(fft->plan);
// find origin frequency
int point=1;
double candAmp=0.0;
for (unsigned short i=1; i<512; i++) {
fftw_complex& f=fft->outBuf[i];
// AMPLITUDE
double amp=sqrt(pow(f[0],2.0)+pow(f[1],2.0))/pow((double)i,0.8);
if (amp>candAmp) {
point=i;
candAmp=amp;
}
}
// PHASE for (int i=0; i<FURNACE_FFT_SIZE; i++) {
fftw_complex& candPoint=fft->outBuf[point]; //fft->outBuf[i][0]-=fft->outBuf[0][0];
double phase=((double)(displaySize*2)/(double)point)*(0.5+(atan2(candPoint[1],candPoint[0])/(M_PI*2))); //fft->outBuf[i][1]-=fft->outBuf[0][1];
fft->outBuf[i][0]/=FURNACE_FFT_SIZE;
fft->outBuf[i][1]/=FURNACE_FFT_SIZE;
fft->outBuf[i][0]=fft->outBuf[i][0]*fft->outBuf[i][0];
fft->outBuf[i][1]=fft->outBuf[i][1]*fft->outBuf[i][1];
}
memset(&fft->outBuf[FURNACE_FFT_SIZE],0,sizeof(fftw_complex)*FURNACE_FFT_SIZE);
fftw_execute(fft->planI);
if (chanOscWaveCorr) { if (chanOscWaveCorr) {
needlePos-=phase; //needlePos-=phase;
} }
chanOscPitch[ch]=(float)point/32.0f; //chanOscPitch[ch]=(float)point/32.0f;
for (unsigned short i=0; i<precision; i++) {
float x=(float)i/(float)precision;
float y=fft->corrBuf[(i*FURNACE_FFT_SIZE)/precision]-fft->corrBuf[FURNACE_FFT_SIZE-1-((i*FURNACE_FFT_SIZE)/precision)];
if (i>=precision/2) {
y=fft->inBuf[((i-(precision/2))*FURNACE_FFT_SIZE*2)/(precision)];
}
waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
}
/*
needlePos-=displaySize; needlePos-=displaySize;
for (unsigned short i=0; i<precision; i++) { for (unsigned short i=0; i<precision; i++) {
float y=(float)buf->data[(unsigned short)(needlePos+(i*displaySize/precision))]/32768.0f; float y=(float)buf->data[(unsigned short)(needlePos+(i*displaySize/precision))]/32768.0f;
@ -494,10 +502,10 @@ void FurnaceGUI::drawChanOsc() {
if (y>0.5f) y=0.5f; if (y>0.5f) y=0.5f;
y*=chanOscAmplify; y*=chanOscAmplify;
waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y)); waveform[i]=ImLerp(inRect.Min,inRect.Max,ImVec2(x,0.5f-y));
} }*/
//String cPhase=fmt::sprintf("%d cphase: %f\nvol: %f\nmin: %.2f\nmax: %.2f\ndcOff: %.2f\nneedles:\n- %d\n- %d\n- %d (%s)",point,phase,chanOscVol[ch],minLevel,maxLevel,dcOff,needlePosOrig,needlePos,(needlePos+displaySize),((needlePos+displaySize)>=needlePosOrig)?"WARN":"OK"); String cPhase=fmt::sprintf("\n%f",fft->corrBuf[0]);
//dl->AddText(inRect.Min,0xffffffff,cPhase.c_str()); dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
} }
ImU32 color=ImGui::GetColorU32(chanOscColor); ImU32 color=ImGui::GetColorU32(chanOscColor);
if (chanOscUseGrad) { if (chanOscUseGrad) {

View File

@ -6273,7 +6273,8 @@ bool FurnaceGUI::init() {
pianoView=e->getConfInt("pianoView",pianoView); pianoView=e->getConfInt("pianoView",pianoView);
pianoInputPadMode=e->getConfInt("pianoInputPadMode",pianoInputPadMode); pianoInputPadMode=e->getConfInt("pianoInputPadMode",pianoInputPadMode);
chanOscCols=e->getConfInt("chanOscCols",3); //chanOscCols=e->getConfInt("chanOscCols",3);
chanOscCols=1;
chanOscAutoColsType=e->getConfInt("chanOscAutoColsType",0); chanOscAutoColsType=e->getConfInt("chanOscAutoColsType",0);
chanOscColorX=e->getConfInt("chanOscColorX",GUI_OSCREF_CENTER); chanOscColorX=e->getConfInt("chanOscColorX",GUI_OSCREF_CENTER);
chanOscColorY=e->getConfInt("chanOscColorY",GUI_OSCREF_CENTER); chanOscColorY=e->getConfInt("chanOscColorY",GUI_OSCREF_CENTER);

View File

@ -2060,14 +2060,18 @@ class FurnaceGUI {
double inBufPosFrac; double inBufPosFrac;
unsigned short needle; unsigned short needle;
fftw_complex* outBuf; fftw_complex* outBuf;
double* corrBuf;
fftw_plan plan; fftw_plan plan;
fftw_plan planI;
ChanOscStatus(): ChanOscStatus():
inBuf(NULL), inBuf(NULL),
inBufPos(0), inBufPos(0),
inBufPosFrac(0.0f), inBufPosFrac(0.0f),
needle(0), needle(0),
outBuf(NULL), outBuf(NULL),
plan(NULL) {} corrBuf(NULL),
plan(NULL),
planI(NULL) {}
} chanOscChan[DIV_MAX_CHANS]; } chanOscChan[DIV_MAX_CHANS];
// visualizer // visualizer

View File

@ -1197,6 +1197,7 @@ void FurnaceGUI::drawSampleEdit() {
sameLineMaybe(ImGui::CalcTextSize("Zoom").x+150.0f*dpiScale+ImGui::CalcTextSize("100%").x); sameLineMaybe(ImGui::CalcTextSize("Zoom").x+150.0f*dpiScale+ImGui::CalcTextSize("100%").x);
double zoomPercent=100.0/sampleZoom; double zoomPercent=100.0/sampleZoom;
bool checkZoomLimit=false; bool checkZoomLimit=false;
ImGui::AlignTextToFramePadding();
ImGui::Text("Zoom"); ImGui::Text("Zoom");
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(150.0f*dpiScale); ImGui::SetNextItemWidth(150.0f*dpiScale);