// 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