iPlug2 - C++ Audio Plug-in Framework
ISender.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
19 #include "IPlugPlatform.h"
20 #include "IPlugQueue.h"
21 #include <array>
22 
23 BEGIN_IPLUG_NAMESPACE
24 BEGIN_IGRAPHICS_NAMESPACE
25 
26 static const float SENDER_THRESHOLD = (float) DBToAmp(-90.);
27 
29 template <int MAXNC = 1, typename T = float>
31 {
32  int ctrlTag = kNoTag;
33  int nChans = MAXNC;
34  int chanOffset = 0;
35  std::array<T, MAXNC> vals {0};
36 
37  ISenderData() {}
38 
39  ISenderData(int ctrlTag, int nChans, int chanOffset)
40  : ctrlTag(ctrlTag)
41  , nChans(nChans)
42  , chanOffset(chanOffset)
43  {
44  }
45 
46  ISenderData(int ctrlTag, const std::array<T, MAXNC>& vals, int nChans = MAXNC, int chanOffset = 0)
47  : ctrlTag(ctrlTag)
48  , nChans(nChans)
49  , chanOffset(chanOffset)
50  , vals(vals)
51  {
52  }
53 };
54 
56 template <int MAXNC = 1, int QUEUE_SIZE = 64, typename T = float>
57 class ISender
58 {
59 public:
60  static constexpr int kUpdateMessage = 0;
61 
64  {
65  mQueue.Push(d);
66  }
67 
71  {
72  while(mQueue.ElementsAvailable())
73  {
75  mQueue.Pop(d);
76  dlg.SendControlMsgFromDelegate(d.ctrlTag, kUpdateMessage, sizeof(ISenderData<MAXNC, T>), (void*) &d);
77  }
78  }
79 
80 private:
81  IPlugQueue<ISenderData<MAXNC, T>> mQueue {QUEUE_SIZE};
82 };
83 
85 template <int MAXNC = 1, int QUEUE_SIZE = 64>
86 class IPeakSender : public ISender<MAXNC, QUEUE_SIZE, float>
87 {
88 public:
90  void ProcessBlock(sample** inputs, int nFrames, int ctrlTag, int nChans = MAXNC, int chanOffset = 0)
91  {
92  ISenderData<MAXNC, float> d {ctrlTag, nChans, chanOffset};
93 
94  for (auto s = 0; s < nFrames; s++)
95  {
96  for (auto c = chanOffset; c < (chanOffset + nChans); c++)
97  {
98  d.vals[c] += std::fabs((float) inputs[c][s]);
99  }
100  }
101 
102  float sum = 0.;
103 
104  for (auto c = chanOffset; c < (chanOffset + nChans); c++)
105  {
106  d.vals[c] /= (float) nFrames;
107  sum += d.vals[c];
108  }
109 
110  if(sum > SENDER_THRESHOLD || mPreviousSum > SENDER_THRESHOLD)
112 
113  mPreviousSum = sum;
114  }
115 private:
116  float mPreviousSum = 1.f;
117 };
118 
120 template <int MAXNC = 1, int QUEUE_SIZE = 64, int MAXBUF = 128>
121 class IBufferSender : public ISender<MAXNC, QUEUE_SIZE, std::array<float, MAXBUF>>
122 {
123 public:
124 
126  void ProcessBlock(sample** inputs, int nFrames, int ctrlTag, int nChans = MAXNC, int chanOffset = 0)
127  {
128  for (auto s = 0; s < nFrames; s++)
129  {
130  if(mBufCount == MAXBUF)
131  {
132  float sum = 0.f;
133  for (auto c = chanOffset; c < (chanOffset + nChans); c++)
134  {
135  sum += mRunningSum[c];
136  mRunningSum[c] = 0.f;
137  }
138 
139  if (sum > SENDER_THRESHOLD || mPreviousSum > SENDER_THRESHOLD)
140  {
141  mBuffer.ctrlTag = ctrlTag;
142  mBuffer.nChans = nChans;
143  mBuffer.chanOffset = chanOffset;
145  }
146 
147  mPreviousSum = sum;
148  mBufCount = 0;
149  }
150 
151  for (auto c = chanOffset; c < (chanOffset + nChans); c++)
152  {
153  mBuffer.vals[c][mBufCount] = (float) inputs[c][s];
154  mRunningSum[c] += std::fabs( (float) inputs[c][s]);
155  }
156 
157  mBufCount++;
158  }
159  }
160 protected:
162  int mBufCount = 0;
163  std::array<float, MAXNC> mRunningSum {0.};
164  float mPreviousSum = 1.f;
165 };
166 
167 END_IPLUG_NAMESPACE
168 END_IGRAPHICS_NAMESPACE
A lock-free SPSC queue used to transfer data between threads based on MLQueue.h by Randy Jones based ...
IBufferSender is a utility class which can be used to defer buffer data for sending to the GUI...
Definition: ISender.h:121
virtual void SendControlMsgFromDelegate(int ctrlTag, int msgTag, int dataSize=0, const void *pData=nullptr)
SendControlMsgFromDelegate (Abbreviation: SCMFD) WARNING: should not be called on the realtime audio ...
Include to get consistently named preprocessor macros for different platforms and logging functionali...
void ProcessBlock(sample **inputs, int nFrames, int ctrlTag, int nChans=MAXNC, int chanOffset=0)
Queue peaks from sample buffers into the sender, checking the data is over the required threshold...
Definition: ISender.h:90
ISenderData is used to represent a typed data packet, that may contain values for multiple channels...
Definition: ISender.h:30
void TransmitData(IEditorDelegate &dlg)
Pops elements off the queue and sends messages to controls.
Definition: ISender.h:70
This pure virtual interface delegates communication in both directions between a UI editor and someth...
void ProcessBlock(sample **inputs, int nFrames, int ctrlTag, int nChans=MAXNC, int chanOffset=0)
Queue sample buffers into the sender, checking the data is over the required threshold.
Definition: ISender.h:126
static double DBToAmp(double dB)
Calculates gain from a given dB value.
void PushData(const ISenderData< MAXNC, T > &d)
Pushes a data element onto the queue.
Definition: ISender.h:63
IPeakSender is a utility class which can be used to defer peak data from sample buffers for sending t...
Definition: ISender.h:86
ISender is a utility class which can be used to defer data from the realtime audio processing and sen...
Definition: ISender.h:57
A lock-free SPSC queue used to transfer data between threads based on MLQueue.h by Randy Jones based ...
Definition: IPlugQueue.h:29