|
09-21-2014, 06:35 AM
|
#1
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
SetBlockSize()
I have some kind of spectrum analyzer. When I plot the spectrum in Logic it is veeery slow. So now I have set the block size to something like 10 or so. It now gets updated fast, just like I wanted.
But then there seems to be the problem (I can only tell this case) that when I have two tracks routed to one bus and each has its own test oscillator and I have the spectrum plug on the bus, it crashes Logic.
I think it has to do with the block size. If I set it with GetBlockSize() it works fine I think.
Any ideas why this is? Or suggestions how I can update my GUI faster without changing the block size via IPlugBase::SetBlockSize() ?
Thanks,
MezmerizeR
|
|
|
09-21-2014, 11:22 PM
|
#2
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
|
I don't think you should call SetBlockSize() yourself, it is called by the host to tell your plug-in about the maximum number of samples it will receive through ProcessDoubleReplacing().
Maybe you can change the GUI redraw speed via MakeGraphics() i.e.:
Code:
int fps = 24; // I think 24 is the default, so change this number.
IGraphics* pGraphics = MakeGraphics(this, 803, 447, fps);
|
|
|
09-22-2014, 04:25 AM
|
#3
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
Unfortunately this does not change the speed. At least not in my plug-in.
I found out that when I set the block size in the reset() function that the GUI redraws as fast as i want it to. But if I create a second track with the plug-in on it, then in crashes.
When I set the block size in the constructor and not in the reset() function it does no redrawing.
The whole thing is kind of strange.
|
|
|
09-22-2014, 06:07 AM
|
#4
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
|
Quote:
Originally Posted by MezmerizeR
Unfortunately this does not change the speed. At least not in my plug-in.
|
OK, my bad.
Quote:
Originally Posted by MezmerizeR
I found out that when I set the block size in the reset() function that the GUI redraws as fast as i want it to. But if I create a second track with the plug-in on it, then in crashes.
When I set the block size in the constructor and not in the reset() function it does no redrawing.
The whole thing is kind of strange.
|
Again:
Quote:
Originally Posted by Tale
I don't think you should call SetBlockSize() yourself, it is called by the host to tell your plug-in about the maximum number of samples it will receive through ProcessDoubleReplacing().
|
So I guess you will have to rethink your code, because the host determines the block size, not your plug-in. Note also that in some hosts the block size (nFrames) isn't constant.
|
|
|
09-22-2014, 06:46 AM
|
#5
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
Ok thank you for your help.
That's too bad because just setting the block size myself does exactly what I want, at least for one plugin on one track.
Maybe it's possible to call IsDirty more often? Or am I thinking in the wrong direction? Sorry, my prgramming knowledge is not that big. I do it in school for 2 years now. So audio programming is a complete new topic to me.
I'd be very grateful if you had more tips .
|
|
|
09-23-2014, 05:38 PM
|
#6
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
Has anybody an idea?
I really need your help. I still don't get it.
|
|
|
09-24-2014, 12:31 PM
|
#7
|
Human being with feelings
Join Date: Apr 2012
Posts: 279
|
I tried Tales suggestion and it behaves as expected. Did you implement the fps value in the plugs constructor?
Just for testing purpose set it down to 1 an watch if it works at all.
|
|
|
09-24-2014, 04:15 PM
|
#8
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
No, it doesn't work. Here's the function that gets called in the constructor:
Code:
void SpectrumAnalyzer::CreateGraphics()
{
int fps =1;
IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight,fps);
...
graph = new Graph(this, kGraph_X, kGraph_Y, kGraph_W, kGraph_H, kGraphDummy);
graph->SetGraphVals(magFFT);
pGraphics->AttachControl(graph);
...
AttachGraphics(pGraphics);
}
When I open the plug-in in Logic it draws a line and then it takes forever until something happens and then again forever.
So I now I shouldn't set the block size myself but what I also recognized if I do so, is that actually the spectrum isn't mirrored. But when I compile the plug as app then it does and I don't understand why. What is going wrong?
MezmerizeR
|
|
|
09-30-2014, 04:37 AM
|
#9
|
Human being with feelings
Join Date: Aug 2014
Posts: 13
|
My header-file:
Code:
#ifndef __SPECTRUMANALYZER__
#define __SPECTRUMANALYZER__
#include "IPlug_include_in_plug_hdr.h"
#include "PeakEQ.h"
#include "fft.h"
#define WDL_FFT_REALSIZE 8
#define FFT_BUFFERSIZE 1024
class Graph : public IControl
{
public:
Graph(IPlugBase* pPlug, int x, int y, int width, int height, int paramIdx);
bool Draw(IGraphics* pGraphics);
bool IsDirty(){return true;};
void SetGraphVals(double* mag);
private:
IPlugBase *m_pPlug;
double * FFTmag;
};
class SpectrumAnalyzer : public IPlug
{
public:
SpectrumAnalyzer(IPlugInstanceInfo instanceInfo);
~SpectrumAnalyzer();
void Reset();
void OnParamChange(int paramIdx);
void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames);
double sinc(double x);
bool IsDirty(){return true;};
void FFT(double *in, int fftbuffersize);
private:
void CreateParams();
void CreateGraphics();
void CreatePresets();
double *mFreqVek;
int mMaxIndex;
Graph *graph;
double *blackman;
const double a0 = (1-0.16)/2;
const double a1 = 1/2;
const double a2 = 0.16/2;
CPeakEQ **peq;
int bins;
WDL_FFT_COMPLEX *fftbuffer;
WDL_FFT_COMPLEX *sortedbuffer;
WDL_FFT_COMPLEX *unsortedbuffer;
double magFFT[FFT_BUFFERSIZE];
};
#endif
My cpp-file:
Code:
#define MAXCHNS 8
const int kNumPrograms = 1;
enum EParams
{
kGain = 0,
kFreq,
kQ,
kGraphDummy,
kNumParams
};
enum ELayout
{
kWidth = GUI_WIDTH,
kHeight = GUI_HEIGHT,
kGainX = GUI_WIDTH/10,
kGainY = GUI_HEIGHT-GUI_HEIGHT/6,
kFreqX = 2*GUI_WIDTH/10,
kFreqY = GUI_HEIGHT-GUI_HEIGHT/6,
kQX = 3*GUI_WIDTH/10,
kQY = GUI_HEIGHT-GUI_HEIGHT/6,
kKnobFrames = 60,
kGraph_X = 50,
kGraph_Y = 0,
kGraph_W = GUI_WIDTH -2*kGraph_X,
kGraph_H = GUI_HEIGHT/2,
};
typedef struct {
const char* name;
const int x;
const int y;
const double defaultVal;
const double minVal;
const double maxVal;
const double stepSize;
} parameterProperties_struct;
const parameterProperties_struct parameterProperties[kNumParams] =
{
{.name = "Gain", .x = kGainX, .y = kGainY, .defaultVal = 0.0, .minVal = -24.0, .maxVal = 24.0, .stepSize = 0.25},
{.name = "Frequency", .x = kFreqX, .y = kFreqY, .defaultVal = -57.0, .minVal = 0.0, .maxVal = 123.0 },
{.name = "Q-Factor", .x = kQX, .y = kQY, .defaultVal = 1.0, .minVal = 0.25, .maxVal = 4.0, .stepSize = 0.125}
};
SpectrumAnalyzer::SpectrumAnalyzer(IPlugInstanceInfo instanceInfo)
: IPLUG_CTOR(kNumParams, kNumPrograms, instanceInfo)
{
TRACE;
CreateParams();
CreateGraphics();
CreatePresets();
WDL_fft_init();
}
SpectrumAnalyzer::~SpectrumAnalyzer()
{
for (int kk = 0; kk < MAXCHNS; kk++)
{
delete peq[kk]; // destroy the EQs
peq[kk] = 0;
}
delete[] peq;
peq = 0;
delete[] mFreqVek;
mFreqVek = 0;
delete [] unsortedbuffer;
delete [] sortedbuffer;
delete [] fftbuffer;
delete [] blackman;
}
void SpectrumAnalyzer::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
// Mutex is already locked for us.
bool bInputConnected;
for (int cc = 0; cc < MAXCHNS; cc++)
{
bInputConnected = IsInChannelConnected(cc);
if (bInputConnected)
{
double *in = inputs[cc];
double *out = outputs[cc];
peq[cc]->processSamples(in, out, nFrames);
FFT(in, FFT_BUFFERSIZE);
}
}
}
void SpectrumAnalyzer::Reset()
{
TRACE;
IMutexLock lock(this);
for (int cc = 0; cc < MAXCHNS;cc++)
{
peq[cc]->reset();
}
}
void SpectrumAnalyzer::OnParamChange(int paramIdx)
{
IMutexLock lock(this);
// double fs = GetSampleRate();
double Gain, Freq, Q;
int index;
switch (paramIdx)
{
case kGain:
Gain = GetParam(kGain)->Value();
for (int cc = 0; cc < MAXCHNS;cc++)
{
peq[cc]->setGain(Gain);
}
break;
case kFreq:
index = GetParam(kFreq)->Value();
Freq = mFreqVek[index];
for (int cc = 0; cc < MAXCHNS;cc++)
{
peq[cc]->setFreq(Freq);
}
break;
case kQ:
Q = GetParam(kQ)->Value();
for (int cc = 0; cc < MAXCHNS;cc++)
{
peq[cc]->setQFactor(Q);
}
break;
default:
break;
}
}
double SpectrumAnalyzer::sinc(double x)
{
if(x == 0)
{
return 1;
}
return sin(PI*x)/(PI*x);
}
void SpectrumAnalyzer::FFT(double *in, int fftbuffersize)
{
static int qq = 0;
if (qq==fftbuffersize)
{
WDL_fft(fftbuffer, fftbuffersize, false);
for (int i = 0; i < fftbuffersize; i++)
{
int j = WDL_fft_permute(fftbuffersize, i);
blackman[i] = (a0 - a1*cos((2*M_PI*i)/(fftbuffersize-1)) + a2*cos((4*M_PI*i)/(fftbuffersize-1)));
sortedbuffer[i].re = fftbuffer[j].re ;
sortedbuffer[i].im = fftbuffer[j].im ;
magFFT[i] = ((sqrt(sortedbuffer[i].re*sortedbuffer[i].re + sortedbuffer[i].im*sortedbuffer[i].im)));
}
qq=0;
}
fftbuffer[qq].re = *in ;
fftbuffer[qq].im = 0 ;
qq++;
}
Graph::Graph(IPlugBase *pPlug, int x, int y, int width, int height, int paramIdx)
: IControl(pPlug, IRECT(x,y,width,height))
{
mPlug = pPlug;
}
bool Graph::Draw(IGraphics *pGraphics)
{
double mag = 0 ,x = kGraph_X;
int bins = FFT_BUFFERSIZE/2;
for (int i=0; i<bins; i++)
{
if (FFTmag[i] > double(kGraph_H)/2.)
{
mag = double(kGraph_H)/2.;
}
else
{
mag = FFTmag[i];
}
pGraphics->DrawLine( &COLOR_BLACK,
x, //x1
kGraph_Y+kGraph_H-FFTmag[i], //y1
x + double(kGraph_W)/double(bins) , //x2
kGraph_Y+kGraph_H-FFTmag[i+1] // y2
);
x= x + double(kGraph_W)/double(bins);
}
return true;
}
void Graph::SetGraphVals(double* mag)
{
FFTmag = mag;
}
void SpectrumAnalyzer::CreateParams()
{
bins = FFT_BUFFERSIZE/2;
fftbuffer = new WDL_FFT_COMPLEX[FFT_BUFFERSIZE];
sortedbuffer = new WDL_FFT_COMPLEX[FFT_BUFFERSIZE];
unsortedbuffer = new WDL_FFT_COMPLEX[FFT_BUFFERSIZE];
blackman = new double[FFT_BUFFERSIZE];
mMaxIndex = 124;
mFreqVek = new double[mMaxIndex];
int LowestSemitone = -57;
int HighestSemitone = 66;
double StandardPitchFreq = 440.;
for (int kk = LowestSemitone; kk <= HighestSemitone ;kk++)
{
mFreqVek[kk-LowestSemitone] = StandardPitchFreq*pow(2,double(kk)/12.);
}
for (int i=0;i<FFT_BUFFERSIZE;i++) //initialize buffer
{
magFFT[i]=0;
}
for (int i = 0; i<kNumParams; i++)
{
IParam *param = GetParam(i);
const parameterProperties_struct& properties = parameterProperties[i];
switch (i) {
case kGain:
param->InitDouble(properties.name, properties.defaultVal, properties.minVal, properties.maxVal, properties.stepSize);
param->SetShape(1.);
break;
case kFreq:
param->InitInt(properties.name, properties.defaultVal, properties.minVal, properties.maxVal);
break;
case kQ:
param->InitDouble(properties.name, properties.defaultVal, properties.minVal, properties.maxVal, properties.stepSize);
param->SetShape(2.);
break;
default:
break;
}
}
for (int i; i<kNumParams; i++) {
OnParamChange(i);
}
double Gain = 00;
double Freq = 1000;
double Q = 1;
double fs = GetSampleRate();
// Multi-Channel EQ
peq = new CPeakEQ*[MAXCHNS];
for (int kk = 0; kk < MAXCHNS; kk++)
{
peq[kk] = new CPeakEQ(Gain,Freq,fs,Q);
}
}
void SpectrumAnalyzer::CreateGraphics()
{
int fps =25;
IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight,fps);
pGraphics->AttachPanelBackground(&COLOR_WHITE);
IBitmap knob = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, kKnobFrames);
graph = new Graph(this, kGraph_X, kGraph_Y, kGraph_W, kGraph_H, kGraphDummy);
graph->SetGraphVals(magFFT);
pGraphics->AttachControl(graph);
pGraphics->AttachControl(new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
pGraphics->AttachControl(new IKnobMultiControl(this, kFreqX, kFreqY, kFreq, &knob));
pGraphics->AttachControl(new IKnobMultiControl(this, kQX, kQY, kQ, &knob));
AttachGraphics(pGraphics);
}
void SpectrumAnalyzer::CreatePresets()
{
//MakePreset("preset 1", ... );
MakeDefaultPreset((char *) "-", kNumPrograms);
}
|
|
|
04-11-2017, 12:12 AM
|
#10
|
Human being with feelings
Join Date: Apr 2017
Location: Russia
Posts: 22
|
Wrong:
: IControl(pPlug, IRECT(x,y,width,height))
Has to be so:
: IControl(pPlug, IRECT(x, y , x + width, y + height))
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 02:01 PM.
|