Guitarix
gx_engine_midi.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * --------------------------------------------------------------------------
19  *
20  *
21  * This is the Guitarix MIDI Engine NOT using a ring buffer
22  *
23  *
24  * --------------------------------------------------------------------------
25  */
26 
27 #include "engine.h"
28 
29 namespace gx_engine {
30 
32  reg.registerNonMidiVar("midi_out.midistat", &midistat, false, true);
33  reg.registerNonMidiVar("midi_out.midistat1", &midistat1, false, true);
34  reg.registerNonMidiVar("midi_out.midistat2", &midistat2, false, true);
35  reg.registerNonMidiVar("midi_out.midistat3", &midistat3, false, true);
36 
37  reg.registerVar("midi_out.channel_1.velocity", "velocity", "S", "", &fslider26, 64, 0, 127, 1);
38  reg.registerVar("midi_out.channel_1.volume", "volume", "S", "", &fslider46, 64, 0, 127, 1);
39  reg.registerBoolVar("midi_out.channel_1.autogain", "autogain", "B", "", &fautogain, false);
40  reg.registerVar("midi_out.channel_1.channel", "channel 1", "S", "", &fslider30, 0, 0, 16, 1);
41  reg.registerVar("midi_out.channel_1.program", "program", "S", "", &fslider31, 0, 0, 248, 1);
42  reg.registerVar("midi_out.channel_1.oktave", "oktave", "S", "", &fslider29, 0, -2, 2, 1);
43  reg.registerVar("midi_out.channel_1.sensity", "sensity", "S", "", &fslider27, 20, 1, 500, 1);
44  reg.registerBoolVar("midi_out.channel_1.auto_pitch", "auto pitch", "B", "", &fpitch, false);
45 
46  reg.registerBoolVar("midi_out.channel_2.on_off", "on/off", "B", "", &fcheckbox10, false);
47  reg.registerVar("midi_out.channel_2.velocity", "velocity", "S", "", &fslider32, 64, 0, 127, 1);
48  reg.registerVar("midi_out.channel_2.volume", "volume", "S", "", &fslider47, 64, 0, 127, 1);
49  reg.registerBoolVar("midi_out.channel_2.autogain", "autogain", "B", "", &fautogain1, false);
50  reg.registerVar("midi_out.channel_2.channel", "channel 2", "S", "", &fslider35, 0, 0, 16, 1);
51  reg.registerVar("midi_out.channel_2.program", "program", "S", "", &fslider36, 0, 0, 248, 1);
52  reg.registerVar("midi_out.channel_2.oktave", "oktave", "S", "", &fslider34, 0, -2, 2, 1);
53  reg.registerVar("midi_out.channel_2.sensity", "sensity", "S", "", &fslider33, 20, 1, 500, 1);
54  reg.registerBoolVar("midi_out.channel_2.auto_pitch", "auto pitch", "B", "", &fpitch1, false);
55 
56  reg.registerBoolVar("midi_out.channel_3.on_off", "on/off", "B", "", &fcheckbox11, false);
57  reg.registerVar("midi_out.channel_3.velocity", "velocity", "S", "", &fslider40, 64, 0, 127, 1);
58  reg.registerVar("midi_out.channel_3.volume", "volume", "S", "", &fslider48, 64, 0, 127, 1);
59  reg.registerBoolVar("midi_out.channel_3.autogain", "autogain", "B", "", &fautogain2, false);
60  reg.registerVar("midi_out.channel_3.channel", "channel 3", "S", "", &fslider44, 0, 0, 16, 1);
61  reg.registerVar("midi_out.channel_3.program", "program", "S", "", &fslider43, 0, 0, 248, 1);
62  reg.registerVar("midi_out.channel_3.oktave", "oktave", "S", "", &fslider42, 0, -2, 2, 1);
63  reg.registerVar("midi_out.channel_3.sensity", "sensity", "S", "", &fslider41, 20, 1, 500, 1);
64  reg.registerBoolVar("midi_out.channel_3.auto_pitch", "auto pitch", "B", "", &fpitch2, false);
65 
66  reg.registerVar("midi_out.beat_detector.stepper", "stepper", "S", "", &fslider39, 1, 1, 32, 1);
67  reg.registerVar("midi_out.beat_detector.note_off", "note off", "S", "", &fslider37, 2, 1, 127, 1);
68  reg.registerVar("midi_out.beat_detector.atack_gain", "atack gain", "S", "", &fslider45, 5, 1, 127, 1);
69  reg.registerVar("midi_out.beat_detector.beat_gain", "beat gain", "S", "", &fslider38, 1, 0.0f, 127, 1);
70  reg.registerVar("midi_out.beat_detector.midi_gain", "midi gain", "S", "", &midi_gain, 0, -40, 60, 1);
71 }
72 
73 void MidiVariables::init(int samplingFreq) {
74  fConstlog = log(1.055) * 0.5;
75  fConstlog2 = 6/log(2) * -1;
76  midi_gain = 1.0;
77  fConstun0 = (0.001 * 300 * samplingFreq) * 36;
78  BeatFilterk =1.0/(samplingFreq * (1.0f/(2.0f * M_PI * 1250.0f)));
79  BeatFilter1 =0.0;
80  BeatFilter2 =0.0;
81 }
82 
83 inline float sqrf(float x) {
84  return x * x;
85 }
86 
87 // ----- jack process callback for the midi output
88 void MidiVariables::process_midi(int len, float *audiodata, void *midi_port_buf, float jcpu_load,
89  float fConsta4, float fConsta1t) {
90  static float fnote = 1000.;
91  float fConsta2 = 0.;
92  float fTemps45 = fslider45;
93  float fTemps38 = fslider38;
94  float rms = 0.;
95  float midi_db = 0.;
96  float sum = 0.;
97 
98  int preNote = 0;
99  int iTemps31 = static_cast<int>(fslider31);
100  int iTemps30 = static_cast<int>(fslider30);
101  int iTemps27 = static_cast<int>(fslider27);
102  int iTemps29 = static_cast<int>(fslider29)*12;
103  int iTemps26 = static_cast<int>(fslider26);
104  int iTemps36 = static_cast<int>(fslider36);
105  int iTemps35 = static_cast<int>(fslider35);
106  int iTemps33 = static_cast<int>(fslider33);
107  int iTemps34 = static_cast<int>(fslider34)*12;
108  int iTemps32 = static_cast<int>(fslider32);
109  int iTemps43 = static_cast<int>(fslider43);
110  int iTemps44 = static_cast<int>(fslider44);
111  int iTemps41 = static_cast<int>(fslider41);
112  int iTemps42 = static_cast<int>(fslider42)*12;
113  int iTemps40 = static_cast<int>(fslider40);
114  int step = static_cast<int>(fslider39);
115  int iTemps37 = static_cast<int>(48000/fslider37);
116  int iTemps37a = iTemps37+5;
117  int iTemps46 = static_cast<int>(fslider46);
118  int iTemps47 = static_cast<int>(fslider47);
119  int iTemps48 = static_cast<int>(fslider48);
120  int piwe = 0;
121  int cs = 0;
122 
123  double stepper = 1./step;
124 
125 
135  // fnote = 12 * log2f(2.272727e-03f * fConsta4);
136  if (fConsta1t < 999.) fnote = fConsta1t;
137  preNote = static_cast<int>(round(fnote))+57;
138  fConsta2 = fnote - (preNote - 57);
139  piwe = (static_cast<int>(fConsta2+1)) * 8192; // pitch wheel value
140  // preNote = round(fConsta1t)+57;
141  // weg = 0;
142 
143 
144  for (int i = 0; i < len; i += step) {
145 
146  float audio_db = *audiodata++;
147  BeatFilter1 = BeatFilter1+(BeatFilterk*(audio_db-BeatFilter1));
148  BeatFilter2 = BeatFilter2+(BeatFilterk*(BeatFilter1-
149  BeatFilter2));
150  audio_db = BeatFilter2*10;
151  if (audio_db > 0.00001) {
152  // ----- convert the audio gain to midi gain value
153  midi_db = (log(fabs(audio_db))*fConstlog2);
154  beat0 = 254- floor(exp(fConstlog*midi_db)*127)+ midi_gain;
155  rms = beat0;
156  }
157  // ----- check gain value and run only when gain is higher then the selected value
158  if (beat0 >= fTemps45 && jcpu_load < 65.0) {
159 
160  // ----- rms the gain for a smother output
161  if (cs == static_cast<int>(fConstun0*stepper)) {
162  cs = 0;
163  sum = 0;
164  } else {
165  cs += 1;
166  sum += sqrf(rms);
167  }
168 
169  beat0 = sqrtf(sum/cs);
170  // set the value for the tuner
171  // audio.fConsta1 = fnote;
172  // set timeout for tuner fallback
173  weg = 0;
174 
175  if (rms >= (Beat_is + fTemps38)) {
176  // Beat_is = rms;
177  Beat_is += rms*0.1;
178  send+=step;
179  if (fcheckbox10 ) send1+=step;
180  if (fcheckbox11 ) send2+=step;
181  // weg -= step;
182  }
183  // else weg +=step;
184 
185  // ----- start the midi output
186 
187  // channel0
188  if (program != iTemps31) {
189  program = iTemps31;
190  midistat = true;
191  midi_send = jack_midi_event_reserve(midi_port_buf, i, 2);
192 
193  if (midi_send) {
194  // program value
195  midi_send[1] = static_cast<int>(iTemps31);
196  // controller+ channel
197  midi_send[0] = 0xC0 | static_cast<int>(iTemps30);
198  }
199  }
200 
201  if (send > iTemps27) { // 20
202  if (fautogain) {
203  iTemps46 = static_cast<int>(beat0);
204  if ( iTemps46 < 0) iTemps46 = 0;
205  else if ( iTemps46 > 127) iTemps46 = 127;
206  fslider46 = iTemps46;
207  }
208  if (volume != iTemps46) {
209  volume = iTemps46;
210  midistat = true;
211  midi_send = jack_midi_event_reserve(midi_port_buf, i, 3);
212 
213  if (midi_send) {
214  // volume value
215  midi_send[2] = static_cast<int>(iTemps46);
216  // set controler volume
217  midi_send[1] = 0x07;
218  // controller + channel
219  midi_send[0] = 0xB0 | static_cast<int>(iTemps30);
220  }
221  }
222 
223  noten = preNote + iTemps29;
224  send = 1;
225  midistat = true;
226  midistat1 = true;
227 
228  if (( noten >= 0)&&(noten <= 127)) {
229  // pitch wheel clear
230  if (fpitch) {
231  midi_send = jack_midi_event_reserve(midi_port_buf, i, 3);
232  if (midi_send) {
233  // pitch value
234  midi_send[2] = 0x40;
235  // pitch value
236  midi_send[1] = 0x00;
237  // controller + channel
238  midi_send[0] = 0xE0 | static_cast<int>(iTemps30);
239  }
240  }
241  midi_send = jack_midi_event_reserve(midi_port_buf, i, 3);
242  if (midi_send) {
243  // velocity
244  midi_send[2] = static_cast<int>(iTemps26);
245  // note
246  midi_send[1] = noten;
247  // controller + channel
248  midi_send[0] = 0x90 | static_cast<int>(iTemps30);
249  }
250 
251  // pitch wheel set auto
252  if (fpitch) {
253  if (piwe < 0) piwe = 0;
254  if (fConsta2 > 0x3fff) piwe = 0x3fff;
255  midi_send = jack_midi_event_reserve(midi_port_buf, i, 3);
256 
257  if (midi_send) {
258  // pitch
259  midi_send[2] = (piwe >> 7) & 0x7f;
260  // pitch
261  midi_send[1] = piwe & 0x7f;
262  // controller + channel
263  midi_send[0] = 0xE0 | static_cast<int>(iTemps30);
264  }
265  }
266  }
267  }
268 
269  // channel1
270  if (fcheckbox10) {
271  if (program1 != iTemps36) {
272  program1 = iTemps36;
273  midistat = true;
274  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 2);
275 
276  if (midi_send1) {
277  // program value
278  midi_send1[1] = static_cast<int>(iTemps36);
279  // controller+ channel
280  midi_send1[0] = 0xC0 | static_cast<int>(iTemps35);
281  }
282  }
283 
284  if (send1 > iTemps33) {
285  if (fautogain1) {
286  iTemps47 = static_cast<int>(beat0);
287  if ( iTemps47 < 0) iTemps47 = 0;
288  else if ( iTemps47 > 127) iTemps47 = 127;
289 
290  fslider47 = iTemps47;
291  }
292 
293  if (volume1 != iTemps47) {
294  volume1 = iTemps47;
295  midistat = true;
296  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 3);
297  if (midi_send1) {
298  // volume value
299  midi_send1[2] = static_cast<int>(iTemps47);
300  // set controler channel volume
301  midi_send1[1] = 0x07;
302  // controller + channel
303  midi_send1[0] = 0xB0 | static_cast<int>(iTemps35);
304  }
305  }
306 
307  noten1 = preNote + iTemps34;
308  send1 = 1;
309  midistat = true;
310  midistat2 = true;
311  if ((noten1 >= 0)&&(noten1 <= 127)) {
312  // pitch wheel clear
313  if (fpitch1) {
314  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 3);
315  if (midi_send1) {
316  // pitch value
317  midi_send1[2] = 0x40;
318  // pitch value
319  midi_send1[1] = 0x00;
320  // controller + channel
321  midi_send1[0] = 0xE0 | static_cast<int>(iTemps35);
322  }
323  }
324  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 3);
325 
326  if (midi_send1) {
327  // velocity
328  midi_send1[2] = static_cast<int>(iTemps32);
329  // note
330  midi_send1[1] = noten1;
331  // note on + channel
332  midi_send1[0] = 0x90 | static_cast<int>(iTemps35);
333  }
334 
335  // pitch wheel set auto
336  if (fpitch1) {
337  if (piwe < 0) piwe = 0;
338  if (fConsta2 > 0x3fff) piwe = 0x3fff;
339  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 3);
340 
341  if (midi_send1) {
342  // pitch
343  midi_send1[2] = (piwe >> 7) & 0x7f;
344  // pitch
345  midi_send1[1] = piwe & 0x7f;
346  // controller + channel
347  midi_send1[0] = 0xE0 | static_cast<int>(iTemps35);
348  }
349  }
350  }
351  }
352  }
353  // channel2
354  if (fcheckbox11) {
355  if (program2 != iTemps43) {
356  program2 = iTemps43;
357  midistat = true;
358  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 2);
359 
360  if (midi_send2) {
361  // program value
362  midi_send2[1] = static_cast<int>(iTemps43);
363  // controller
364  midi_send2[0] = 0xC0 | static_cast<int>(iTemps44);
365  }
366  }
367 
368  if (send2 > iTemps41) { // 20
369  if (fautogain2) {
370  iTemps48 = static_cast<int>(beat0);
371  if ( iTemps48 < 0) iTemps48 = 0;
372  else if ( iTemps48 > 127) iTemps48 = 127;
373  fslider48 = iTemps48;
374  }
375 
376  if (volume2 != iTemps48) {
377  volume2 = iTemps48;
378  midistat = true;
379  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 3);
380  if (midi_send2) {
381  // volume value
382  midi_send2[2] = static_cast<int>(iTemps48);
383  // set controler channel volume
384  midi_send2[1] = 0x07;
385  // controller + channel
386  midi_send2[0] = 0xB0 | static_cast<int>(iTemps44);
387  }
388  }
389 
390  // pitch wheel clear
391  if (fpitch2) {
392  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 3);
393  if (midi_send2) {
394  // pitch value
395  midi_send2[2] = 0x40;
396  // pitch value
397  midi_send2[1] = 0x00;
398  // controller + channel
399  midi_send2[0] = 0xE0 | static_cast<int>(iTemps44);
400  }
401  }
402 
403  noten2 = preNote + iTemps42;
404  send2 = 1;
405  midistat = true;
406  midistat3 = true;
407 
408  if ((noten2 >= 0)&&(noten2 <= 127)) {
409  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 3);
410 
411  if (midi_send2) {
412  // velocity
413  midi_send2[2] = static_cast<int>(iTemps40);
414  // note
415  midi_send2[1] = noten2;
416  // note on + channel
417  midi_send2[0] = 0x90 | static_cast<int>(iTemps44);
418  }
419 
420  // pitch wheel set auto
421  if (fpitch2) {
422  if (piwe < 0) piwe = 0;
423  if (fConsta2 > 0x3fff) piwe = 0x3fff;
424  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 3);
425  if (midi_send2) {
426  // pitch
427  midi_send2[2] = (piwe >> 7) & 0x7f;
428  // pitch
429  midi_send2[1] = piwe & 0x7f;
430  // controller + channel
431  midi_send2[0] = 0xE0 | static_cast<int>(iTemps44);
432  }
433  }
434  }
435  }
436  }
437 
438  // end if playmidi = 1
439  } else {
440  if (weg > iTemps37 || jcpu_load > 64.0) {
441 
442  Beat_is = static_cast<int>(fTemps45);
443  if (weg < iTemps37a) { // 5.0
444  if (send) {
445  send = 0;
446  midistat = true;
447  midi_send = jack_midi_event_reserve(midi_port_buf, i, 3);
448 
449  if (midi_send) {
450  // velocity
451  midi_send[2] = static_cast<int>(iTemps26);
452  // fix me all notes off
453  midi_send[1] = 123;
454  // controller
455  midi_send[0] = 0xB0 | static_cast<int>(iTemps30);
456  }
457  }
458 
459  if (fcheckbox10) {
460  if (send1) {
461  send1 = 0;
462  midistat = true;
463  midi_send1 = jack_midi_event_reserve(midi_port_buf, i, 3);
464 
465  if (midi_send1) {
466  // velocity
467  midi_send1[2] = static_cast<int>(iTemps32);
468  // fix me all notes off
469  midi_send1[1] = 123;
470  // controller
471  midi_send1[0] = 0xB0 | static_cast<int>(iTemps35);
472  }
473  }
474  }
475 
476  if (fcheckbox11) {
477  if (send2) {
478  send2 = 0;
479  midistat = true;
480  midi_send2 = jack_midi_event_reserve(midi_port_buf, i, 3);
481 
482  if (midi_send2) {
483  // velocity
484  midi_send2[2] = static_cast<int>(iTemps40);
485  // fix me all notes off
486  midi_send2[1] = 123;
487  // controller
488  midi_send2[0] = 0xB0 | static_cast<int>(iTemps44);
489  }
490  }
491  }
492  midistat = midistat1 = midistat2 = midistat3 = false;
493  }
494  }
495  weg+=step;
496  }
497  }
498 }
499 } /* end of gx_engine namespace */
void process_midi(int len, float *audiodata, void *midi_port_buf, float jcpu_load, float fConsta4, float fConsta1t)
float sqrf(float x)
float *(* registerVar)(const char *id, const char *name, const char *tp, const char *tooltip, float *var, float val, float low, float up, float step)
Definition: gx_plugin.h:124
#define M_PI
void(* registerNonMidiVar)(const char *id, bool *var, bool preset, bool nosave)
Definition: gx_plugin.h:129
void init(int samplingFreq)
void(* registerBoolVar)(const char *id, const char *name, const char *tp, const char *tooltip, bool *var, bool val)
Definition: gx_plugin.h:127
void register_parameter(const ParamReg &reg)