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) {
logD("creating FFT plan for channel %d",ch);
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->planI=fftw_plan_dft_c2r_1d(FURNACE_FFT_SIZE,fft->outBuf,fft->corrBuf,FFTW_ESTIMATE);
}
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));
}
} else {
float minLevel=1.0f;
float maxLevel=-1.0f;
float dcOff=0.0f;
//float minLevel=1.0f;
//float maxLevel=-1.0f;
//float dcOff=0.0f;
unsigned short needlePos=buf->needle;
//unsigned short needlePosOrig=needlePos;
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]*=sin(M_PI*(double)i/(double)FURNACE_FFT_SIZE);
}
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
fftw_complex& candPoint=fft->outBuf[point];
double phase=((double)(displaySize*2)/(double)point)*(0.5+(atan2(candPoint[1],candPoint[0])/(M_PI*2)));
for (int i=0; i<FURNACE_FFT_SIZE; i++) {
//fft->outBuf[i][0]-=fft->outBuf[0][0];
//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) {
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;
for (unsigned short i=0; i<precision; i++) {
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;
y*=chanOscAmplify;
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");
//dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
String cPhase=fmt::sprintf("\n%f",fft->corrBuf[0]);
dl->AddText(inRect.Min,0xffffffff,cPhase.c_str());
}
ImU32 color=ImGui::GetColorU32(chanOscColor);
if (chanOscUseGrad) {

View File

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

View File

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

View File

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