// 4 chars, single quotes. At least one capital letter #define PLUG_UNIQUE_ID 'Ipef' // make sure this is not the same as BUNDLE_MFR #define PLUG_MFR_ID 'Acme'
// Unique IDs for each image resource. #define KNOB_ID 101 // Image resource locations for this plug. #define KNOB_FN "resources/img/knob.png"
#define GUI_WIDTH 300 #define GUI_HEIGHT 300
public
part includes a constructor, a destructor, and three member functions of the class:Reset
is called when the sample rate changes.OnParamChange
is called when the plug-in parameters change, for example, when we twist the handle.ProcessDoubleReplacing
is the core of the plugin. It is in it that the incoming audio is processed.private
part there is only a double
variable that stores the current volume value.enum
type: enum EParams { kGain = 0, kNumParams };
kGain = 0
and putting kNumParams
after it, kNumParams
becomes the number of parameters for the plugin (in this case, 1).enum
uses the constants described in resource.h and sets the handle coordinates in the plugin window: enum ELayout { kWidth = GUI_WIDTH, kHeight = GUI_HEIGHT, kGainX = 100, kGainY = 100, kKnobFrames = 60 };
//arguments are: name, defaultVal, minVal, maxVal, step, label GetParam(kGain)->InitDouble("Gain", 50., 0., 100.0, 0.01, "%");
0
to 100
. The default value is 50
. You may notice that the gradation of values ​​is not uniform on the circle. This is because of SetShape(2.)
. If this is replaced with SetShape(1.)
, Then the distribution of values ​​will be linear. SetShape
sets non-linear behavior. IGraphics* pGraphics = MakeGraphics(this, kWidth, kHeight); pGraphics->AttachPanelBackground(&COLOR_RED);
IKnobMultiControl
is a class for interface handles. IBitmap knob = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, kKnobFrames); pGraphics->AttachControl(new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
MakeDefaultPreset((char *) "-", kNumPrograms);
OnParamChange
look at OnParamChange
(at the end of the file). IMutexLock
provides streaming security - a concept that we will examine later. Everything else is just a set of options depending on which parameter is changed: case kGain: mGain = GetParam(kGain)->Value() / 100.; break;
kGain
changes from 0 to 100. So after dividing the value by 100, we assign the value from 0 to 1 to a private
member of the mGain
class.mGain
. Let's now take a look at how the plugin handles incoming audio. In our case, the audio stream is a sequence of samples represented by a double
data type, each of which contains the signal amplitude value at a given point in time.ProcessDoubleReplacing
function is double** inputs
. You can pass a sequence of double
using double*
. But the plugin processes two channels (stereo) or even more, so we need several sequences of samples, and we report this with double**
. The first two lines in the function illustrate this: double* in1 = inputs[0]; double* in2 = inputs[1];
in1
indicates the first sequence of samples (left channel), in2
indicates the samples of the right channel. After performing similar actions for the output buffer, we can iterate over the elements of the input and output buffers: for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2) { *out1 = *in1 * mGain; *out2 = *in2 * mGain; }
mGain
and write it to the output buffer. nFrames
tells us how many samples per channel there are, so that we know the length of the buffers.Reset
function. Change the Sampling Rate on the right and apply the changes. The debugger will abort the execution of the code in the Reset
function. Bottom right where lldb
works. Enter print GetSampleRate()
.Source: https://habr.com/ru/post/225019/
All Articles