File: m_midiout.cpp

package info (click to toggle)
ams 1.8.7-5
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,880 kB
  • ctags: 2,171
  • sloc: cpp: 17,793; makefile: 433; sh: 101
file content (399 lines) | stat: -rw-r--r-- 17,123 bytes parent folder | download | duplicates (3)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <qwidget.h>
#include <qstring.h>
#include <qslider.h>   
#include <qcheckbox.h>  
#include <qlabel.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qspinbox.h>
#include <qradiobutton.h>
#include <qpushbutton.h>
#include <qdialog.h>
#include <qpainter.h>
#include <qtimer.h>
#include <qfiledialog.h>
#include <alsa/asoundlib.h>
#include "synthdata.h"
#include "m_midiout.h"
#include "module.h"
#include "port.h"


M_midiout::M_midiout(QWidget* parent, const char *name, SynthData *p_synthdata) 
              : Module(0, parent, name, p_synthdata) {

  QString qs;
  int l1, l2;

  M_type = M_type_midiout;
  setGeometry(MODULE_NEW_X, MODULE_NEW_Y, MODULE_MIDIOUT_WIDTH, MODULE_MIDIOUT_HEIGHT);
  mixer_gain[0] = 1.0;
  mixer_gain[1] = 1.0;
  midiMode = 0;
  offset[0] = 0;
  offset[1] = 0;
  controller[0] = 24;
  controller[1] = 25;
  triggerLevel = 0.5;
  port_in[0] = new Port("In 0", PORT_IN, 0, this, synthdata);          
  port_in[0]->move(0, 35);
  port_in[0]->outTypeAcceptList.append(outType_audio);
  portList.append(port_in[0]);
  port_in[1] = new Port("In 1", PORT_IN, 1, this, synthdata);          
  port_in[1]->move(0, 55);
  port_in[1]->outTypeAcceptList.append(outType_audio);
  portList.append(port_in[1]);
  port_M_trigger = new Port("Trigger", PORT_IN, 2, this, synthdata);
  port_M_trigger->move(0, 75);
  port_M_trigger->outTypeAcceptList.append(outType_audio);
  portList.append(port_M_trigger);
  qs.sprintf("MIDI Out ID %d", moduleID);
  configDialog->setCaption(qs);
  configDialog->initTabWidget();
  QVBox *gainTab = new QVBox(configDialog->tabWidget);
  QVBox *midiTab = new QVBox(configDialog->tabWidget);
  QStrList *channelNames = new QStrList(true);
  for (l1 = 0; l1 < 16; l1++) {
    qs.sprintf("%4d", l1);
    channelNames->append(qs);
  }
  channel = 0;
  configDialog->addComboBox(0, "MIDI Channel", &channel, channelNames->count(), channelNames, midiTab);
  configDialog->addSlider(0, 10, mixer_gain[0], "Gain 0", &mixer_gain[0], false, gainTab);
  configDialog->addSlider(0, 10, mixer_gain[1], "Gain 1", &mixer_gain[1], false, gainTab);
  configDialog->addIntSlider(0, 127, offset[0], "Offset 0", &offset[0], gainTab);
  configDialog->addIntSlider(0, 127, offset[1], "Offset 1", &offset[1], gainTab);
  QStrList *midiNames = new QStrList(true);
  midiNames->append("In 0/1: Controller");
  midiNames->append("In 0: Controller In 1: Pitchbend");
  midiNames->append("In 0/1: Note");
  midiNames->append("In 0: Note, In 1: Velocity");
  configDialog->addComboBox(midiMode, "MIDI Event Type", &midiMode, midiNames->count(), midiNames, midiTab);
  configDialog->addIntSlider(0, 127, controller[0], "Controller 0", &controller[0], midiTab);
  configDialog->addIntSlider(0, 127, controller[1], "Controller 1", &controller[1], midiTab);
  configDialog->addSlider(0, 10, triggerLevel, "Trigger Level", &triggerLevel, false, gainTab);
  configDialog->addTab(gainTab, "Gain / Offset / Trigger Level");
  configDialog->addTab(midiTab, "MIDI Settings");
  for (l1 = 0; l1 < synthdata->poly; l1++) {
    trigger[l1] = false;
    for (l2 = 0; l2 < 2; l2++) {
      triggeredNote[l2][l1] = 0;
      lastmididata[l2][l1] = 0;
    }
  }
}

M_midiout::~M_midiout() {

}

void M_midiout::generateCycle() {

  int l1, l2, l3, mididata, velocitydata;
  snd_seq_event_t ev;

  triggerData = port_M_trigger->getinputdata();
  for (l1 = 0; l1 < 2; l1++) inData [l1] = port_in [l1]->getinputdata();

  switch (midiMode) {
    case 0:
      if (triggerData == synthdata->zeroModuleData) {
        for (l1 = 0; l1 < 2; l1++) {
          if (mixer_gain[l1] > 0.01) {
            for (l3 = 0; l3 < synthdata->poly; l3++) {
              for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
                mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.8) - 1000;
                if (mididata < 0) mididata = 0;
                else if (mididata > 127) mididata = 127;
                if (mididata != lastmididata[l1][l3]) {
                  snd_seq_ev_clear(&ev);     
                  snd_seq_ev_set_subs(&ev);  
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_CONTROLLER;
                  ev.data.control.channel = channel;
                  ev.data.control.param = controller[l1];
                  ev.data.control.value = mididata;
                  triggeredNote[l1][l3] = 0;
                  lastmididata[l1][l3] = mididata;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              } 
            }
          } 
        }
      } else {
        for (l3 = 0; l3 < synthdata->poly; l3++) {
          for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
            if (!trigger[l3] && (triggerData[l3][l2] > triggerLevel)) {
              trigger[l3] = true;
              for (l1 = 0; l1 < 2; l1++) {
                if (mixer_gain[l1] > 0.01) {
                  snd_seq_ev_clear(&ev);     
                  snd_seq_ev_set_subs(&ev);  
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_CONTROLLER;
                  mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.8) - 1000;
                  if (mididata < 0) mididata = 0;
                  else if (mididata > 127) mididata = 127;
                  ev.data.control.channel = channel;
                  ev.data.control.param = controller[l1];
                  ev.data.control.value = mididata;
                  triggeredNote[l1][l3] = 0;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              }
            } else {
              if (trigger[l3] && (triggerData[l3][l2] < triggerLevel)) {
                trigger[l3] = false;
              }
            }
          } 
        }
      }
      break;
    case 1:
      if (triggerData == synthdata->zeroModuleData ) {
        for (l1 = 0; l1 < 2; l1++) {
          if (mixer_gain[l1] > 0.01) {
            for (l3 = 0; l3 < synthdata->poly; l3++) {
              for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
               if (l1) {
                 mididata = (int)(128.0 * offset[l1] + (int)(mixer_gain[l1] * inData[l1][l3][l2] * 16384.0) - 8192.0);
                 if (mididata < -8191) mididata = -8191;                                              
                 else if (mididata > 8191) mididata = 8191;
                } else {
                  mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.8) - 1000;
                  if (mididata < 0) mididata = 0;
                  else if (mididata > 127) mididata = 127;
                }
                if (mididata != lastmididata[l1][l3]) {
                  snd_seq_ev_clear(&ev);     
                  snd_seq_ev_set_subs(&ev);  
                  snd_seq_ev_set_direct(&ev);
                  if (l1) {
                    ev.type = SND_SEQ_EVENT_PITCHBEND;
                    ev.data.control.param = 0;
                  } else {
                    ev.type = SND_SEQ_EVENT_CONTROLLER;
                    ev.data.control.param = controller[l1];
                  }
                  ev.data.control.channel = channel;
                  ev.data.control.value = mididata;
                  triggeredNote[l1][l3] = 0;
                  lastmididata[l1][l3] = mididata;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              } 
            }
          } 
        }
      } else {
        for (l3 = 0; l3 < synthdata->poly; l3++) {
          for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
            if (!trigger[l3] && (triggerData[l3][l2] > triggerLevel)) {
              trigger[l3] = true;
              for (l1 = 0; l1 < 2; l1++) {
                if (mixer_gain[l1] > 0.01) {
                  snd_seq_ev_clear(&ev);     
                  snd_seq_ev_set_subs(&ev);  
                  snd_seq_ev_set_direct(&ev);
                  if (l1) {
                    ev.type = SND_SEQ_EVENT_PITCHBEND; 
                    ev.data.control.param = 0;
                    mididata = (int)(128.0 * offset[l1] + (int)(mixer_gain[l1] * inData[l1][l3][l2] * 16384.0) - 8192.0);
                    if (mididata < -8191) mididata = -8191;
                    else if (mididata > 8191) mididata = 8191;
                  } else {
                    ev.type = SND_SEQ_EVENT_CONTROLLER; 
                    ev.data.control.param = controller[l1];
                    mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.8) - 1000;
                    if (mididata < 0) mididata = 0;
                    else if (mididata > 127) mididata = 127;
                  }
                  ev.data.control.channel = channel;
                  ev.data.control.value = mididata;
                  triggeredNote[l1][l3] = 0;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              }
            } else {
              if (trigger[l3] && (triggerData[l3][l2] < triggerLevel)) {
                trigger[l3] = false;
              }
            }
          } 
        }
      }
      break;
    case 2: 
      if (triggerData != synthdata->zeroModuleData ) {
        for (l3 = 0; l3 < synthdata->poly; l3++) {
          for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
            if (!trigger[l3] && (triggerData[l3][l2] > triggerLevel)) {
              trigger[l3] = true;
              for (l1 = 0; l1 < 2; l1++) {
                if (mixer_gain[l1] > 0.01) {
                  snd_seq_ev_clear(&ev);
                  snd_seq_ev_set_subs(&ev);
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_NOTEON;
                  ev.data.control.channel = channel;
                  mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.0) - 1000;
                  if (mididata < 0) mididata = 0;
                  else if (mididata > 127) mididata = 127;
                  ev.data.note.note = mididata;
                  ev.data.note.velocity = 127; 
                  triggeredNote[l1][l3] = mididata;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              }
            } else {
              if (trigger[l3] && (triggerData[l3][l2] < triggerLevel)) {
                trigger[l3] = false;
                for (l1 = 0; l1 < 2; l1++) {
                  if (mixer_gain[l1] > 0.01) {
                    snd_seq_ev_clear(&ev);
                    snd_seq_ev_set_subs(&ev);
                    snd_seq_ev_set_direct(&ev);
                    ev.type = SND_SEQ_EVENT_NOTEOFF;
                    ev.data.control.channel = channel;   
                    ev.data.note.velocity = 0;
                    ev.data.note.note = triggeredNote[l1][l3];       
                    snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                    snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                  }
                }
              }
            } 
          }
        }
      } else {
        for (l1 = 0; l1 < 2; l1++) {
          if (mixer_gain[l1] > 0.01) {
            for (l3 = 0; l3 < synthdata->poly; l3++) {
              for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
                mididata = offset[l1] + (int)(1000.0 + mixer_gain[l1] * inData[l1][l3][l2] * 12.0) - 1000;
                if (mididata < 0) mididata = 0;
                else if (mididata > 127) mididata = 127;
                if (mididata != lastmididata[l1][l3]) {
                  snd_seq_ev_clear(&ev);
                  snd_seq_ev_set_subs(&ev);
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_NOTEOFF;
                  ev.data.control.channel = channel;
                  ev.data.note.note = triggeredNote[l1][l3];
                  ev.data.note.velocity = 0; 
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                  snd_seq_ev_clear(&ev);
                  snd_seq_ev_set_subs(&ev);
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_NOTEON;
                  ev.data.control.channel = channel;
                  ev.data.note.note = mididata;
                  ev.data.note.velocity = 127; 
                  triggeredNote[l1][l3] = mididata;
                  lastmididata[l1][l3] = mididata;
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[l1]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev); 
                }
              }  
            }
          } 
        }          
      }
      break;
    case 3: 
      if (triggerData != synthdata->zeroModuleData ) {
        for (l3 = 0; l3 < synthdata->poly; l3++) {
          for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
            if (!trigger[l3] && (triggerData[l3][l2] > triggerLevel)) {
              trigger[l3] = true;
              if (mixer_gain[0] > 0.01) {
                snd_seq_ev_clear(&ev);
                snd_seq_ev_set_subs(&ev);
                snd_seq_ev_set_direct(&ev);
                ev.type = SND_SEQ_EVENT_NOTEON;
                ev.data.control.channel = channel;
                mididata = offset[0] + (int)(1000.0 + mixer_gain[0] * inData[0][l3][l2] * 12.0) - 1000;
                velocitydata = offset[1] + (int)(1000.0 + mixer_gain[1] * inData[1][l3][l2] * 12.8) - 1000;
                if (mididata < 0) mididata = 0;
                else if (mididata > 127) mididata = 127;
                if (velocitydata < 0) velocitydata = 0;
                else if (velocitydata > 127) velocitydata = 127;
                ev.data.note.note = mididata;
                ev.data.note.velocity = velocitydata; 
                triggeredNote[0][l3] = mididata;
                snd_seq_ev_set_source(&ev, synthdata->midi_out_port[0]);
                snd_seq_event_output_direct(synthdata->seq_handle, &ev);
              }
            } else {
              if (trigger[l3] && (triggerData[l3][l2] < triggerLevel)) {
                trigger[l3] = false;
                if (mixer_gain[0] > 0.01) {
                  snd_seq_ev_clear(&ev);
                  snd_seq_ev_set_subs(&ev);
                  snd_seq_ev_set_direct(&ev);
                  ev.type = SND_SEQ_EVENT_NOTEOFF;
                  ev.data.control.channel = channel;   
                  ev.data.note.velocity = 0;
                  ev.data.note.note = triggeredNote[0][l3];       
                  snd_seq_ev_set_source(&ev, synthdata->midi_out_port[0]);
                  snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                }
              }
            }
          }
        } 
      } else {
        if (mixer_gain[0] > 0.01) {
          for (l3 = 0; l3 < synthdata->poly; l3++) {
            for (l2 = 0; l2 < synthdata->cyclesize; l2++) {
              mididata = offset[0] + (int)(1000.0 + mixer_gain[0] * inData[0][l3][l2] * 12.0) - 1000;
              if (mididata < 0) mididata = 0;
              else if (mididata > 127) mididata = 127;
              if (mididata != lastmididata[0][l3]) {
                snd_seq_ev_clear(&ev);
                snd_seq_ev_set_subs(&ev);
                snd_seq_ev_set_direct(&ev);
                ev.type = SND_SEQ_EVENT_NOTEOFF;
                ev.data.control.channel = channel;
                ev.data.note.note = triggeredNote[0][l3];
                ev.data.note.velocity = 0;
                snd_seq_ev_set_source(&ev, synthdata->midi_out_port[0]);
                snd_seq_event_output_direct(synthdata->seq_handle, &ev);
                snd_seq_ev_clear(&ev);   
                snd_seq_ev_set_subs(&ev);
                snd_seq_ev_set_direct(&ev);
                ev.type = SND_SEQ_EVENT_NOTEON;
                ev.data.control.channel = channel;
                velocitydata = offset[1] + (int)(1000.0 + mixer_gain[1] * inData[1][l3][l2] * 12.8) - 1000;
                if (velocitydata < 0) velocitydata = 0; 
                else if (velocitydata > 127) velocitydata = 127;
                ev.data.note.note = mididata;
                ev.data.note.velocity = velocitydata;
                triggeredNote[0][l3] = mididata;
                lastmididata[0][l3] = mididata; 
                lastmididata[1][l3] = velocitydata;
                snd_seq_ev_set_source(&ev, synthdata->midi_out_port[0]);
                snd_seq_event_output_direct(synthdata->seq_handle, &ev);
              }
            }
          }      
        }        
      }
      break;
  }
}

void M_midiout::showConfigDialog() {
}