iPlug2 Forum

How to use mMeterSender1.ProcessBlock (with sample**)

Hello, I will be very grateful if anyone can help me.

In my plugin, I calculate the white noise level for 30 frequencies. And I want the user to be able to view the values on the GUI (I use IVMeterControl). to display the values I use:
mLastOutputData1.vals[0] = (double)outputs100[0][s];
mRTTextSender1.PushData(mLastOutputData1);
mMeterSender1.ProcessBlock(outputs100, nFrames, kCtrlTagMeter);

but it doesn’t work. I create an output for each frequency as follows: samples** outputs100

Please tell me what I’m doing wrong or if there is a better way to do it

here my code:

void IPlugEffect::OnIdle()
{  
  mMeterSender1.TransmitData(*this);
  mRTTextSender1.TransmitData(*this);
}
void IPlugEffect::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
{
  const int nChans = NOutChansConnected();
  sample** outputs100;
  for (int s = 0; s < nFrames; s++) {  
    double rausch = (double)((rand() % 32768) / 32768.0 - 0.5); 
    if (s == 0) {
      y_n1[s] = filterbank.terzband(rausch, 100);                    
      y_n12[s] = y_n1[s] * y_n1[s];
    }
    else {
      y_n1[s] = filterbank.terzband(rausch, 100);         
      y_n12[s] = y_n12[s - 1] + y_n1[s] * y_n1[s];        
    }
    if (s == 63) {
      y_nEff1 = sqrt(ringbuffer1(y_n12[s]) / 48000);    
      outputs100[0][s] = 20 * log10(y_nEff1 / 0.1); 

      mLastOutputData1.vals[0] = (double)outputs100[0][s]; 
      mRTTextSender1.PushData(mLastOutputData1); 

      mMeterSender1.ProcessBlock(outputs100, nFrames, kCtrlTagMeter); 
    }
}

Just guessing from what i see…
This part

if (s == 63) {

seems a bit strange. Wherever this 63 comes from (i guess you take a fixed 64 frame buffer size into account?). You’re only calculating, storing and sending sample 63.

welcome,

In addition to what stw said… what memory does the outputs100 double pointer variable point to? it seems un-initialised. You need to allocate some memory for a “scratch” buffer. Here is an example of how I do that using some WDL classes, but you can also do it with, e.g std::vector.

For a 30 channel meter, you could create an IPeakSender member variable in your plug-in class…

IPeakSender<30> mSender;
WDL_TypedBuf<float> mScratchBufferMemory; // see gist for how to resize
WDL_PtrList<float> mScratchBufferPtrs; // see gist for how to assign

Then attach a 30 channel meter in your UI Layout func

pGraphics->AttachControl(new IVLEDMeterControl<30>(bounds, kCtrlTagMeter);

Then update the scratch buffer and pass to the sender in ProcessBlock()

  void ProcessBlock(int nFrames)
  {
    float** frequencyBands = mScratchBufferPtrs.GetList();

    // TODO: for each band, for each sample... update frequencyBands[band][sample] = value;

    mSender.ProcessBlock(frequencyBands, nFrames, kCtrlTagMeter);

exactly, because I need the 64 samples before calculating and displaying the value due level of noise

thank you for your very quick answer, I try to do it that way. Thank you

exactly, because I need the 64 samples before calculating and displaying the value due level of noise

Ok, but even if this is done correctly you’re storing your value to the output100 buffer only every 64 sample. This buffer is transmitted by your meter sender which is most probably an IPeakSender objetc. In ProcessBlock your values then will be averaged over nFrames, so in your case you’ll get an level/64 output (supposed other buffer values are zero inited?) which might not be what you want.

BTW we already have built in DB<=>Amp conversions: DBToAmp() and AmpToDB()