II.3.5. Writing Control Event Handler
From the previous volume level control example, rather than directly access the control[0].value inside the processing function, we can write a handler that compute an intermediate variable called gain and gainRange. Without these intermediate variables, we have to compute the control[0].value from 0-127 integer values into 0.0-1.0 (floating point) and convert control[1].value to gain range value (floating point) at every new sample data.
To write the handler, we have to define the handler function void onControlChange(int controlIndex) inside the effectModule descendant class. Wee need to add the intermediate variables gain and gainRange as well. Here is the example code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
#include <blackstomp.h> //effect module class definition class gainDoubler:public effectModule { private: float gain; float gainRange; public: void init(); void deInit(); void onButtonChange(int buttonIndex); void onControlChange(int controlIndex); void process(float* inLeft, float* inRight, float* outLeft, float* outRight, int sampleCount); }; //effect module class implementation void gainDoubler::init() { //select the appropriate device by uncommenting one of the following two lines: //setDeviceType(DT_ESP32_A1S_AC101); setDeviceType(DT_ESP32_A1S_ES8388); //define your effect name name = "GAIN DOUBLER"; //define the input mode (IM_LR or IM_LMIC) inputMode = IM_LR; //setting up the buttons //setup the first button as toggle button button[0].mode = BM_TOGGLE; //enable encoder port for buttons encoderMode = EM_BUTTONS; //setup the second button as tap tempo button button[1].mode = BM_TAPTEMPO; button[1].min = 50; button[1].max = 2000; //setup the third button as temporary button button[2].mode = BM_MOMENTARY; //add gain control control[0].name = "Gain"; control[0].mode = CM_POT; control[0].levelCount = 128; control[0].slowSpeed = true; //add range control control[1].name = "Range"; control[1].mode = CM_SELECTOR; control[1].levelCount = 3; gain = 1; gainRange = 1; } void gainDoubler::deInit() { //do all the necessary deinitialization here } void gainDoubler::onButtonChange(int buttonIndex) { switch(buttonIndex) { case 0: //main button state has changed { if(button[0].value) //if effect is activated { analogBypass(false); mainLed->turnOn(); } else //if effect is bypassed { analogBypass(true); mainLed->turnOff(); } break; } case 1: //the button[1] state has changed { auxLed->blink(10,button[1].value-10,1,0,0); break; } case 2: //the button[0] state has changed { //do something here break; } } } void gainDoubler::onControlChange(int controlIndex) { switch(controlIndex) { case 0: { gain = (float)control[0].value/127.0; break; } case 1: { if(control[1].value==0) gainRange = 0.5; else if(control[1].value==1) gainRange = 1; else gainRange = 2; break; } } } void gainDoubler::process(float* inLeft, float* inRight, float* outLeft, float* outRight, int sampleCount) { for(int i=0;i<sampleCount;i++) { outLeft[i] = gain * gainRange * inLeft[i]; outRight[i] = gain * gainRange * inRight[i]; } } //Arduino core setup //declare an instance of your effect module gainDoubler myPedal; void setup() { //setting up the effect module blackstompSetup(&myPedal); //run system monitor at 38400 baud rat, at 2000 ms update period //don't call this function when MIDI is implemented //try lowering the baudrate if audible noise is introduced on some boards runSystemMonitor(38400, 2000); } //Arduino core loop //let the main loop empty to dedicate the core 1 for the main audio task void loop() { } |
As you can see, the gain and gainRange variables have been added to the class at line#7 and line #8, and the handler onControlChange at line #14. The handler function is implemented at line #92, and now the process() function accounts both gain and gainRange control variables to scale the output signal level (line #117,#118).