~ubuntu-branches/ubuntu/raring/muse/raring

« back to all changes in this revision

Viewing changes to synti/simpledrums2/simpledrums.cpp

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2011-08-12 11:16:41 UTC
  • mfrom: (1.1.9) (10.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20110812111641-sjz0e93fr0ozfv0b
Tags: 2.0~beta2-1
* New maintainer (see bug 637185#12), thanks Daniel!
* New upstream release (Closes: #627371):
  - New interface Qt4-based (Closes: #604584)
* Refresh packaging:
  - Move to DH7 and source format 3.0 (quilt).
  - Refresh patchset.
  - Fix a bunch lintian warnings.
  - debian/postinst:
    + Use set -e in the body rather than pass -e on the #! line to make it
      have actually effect if it is run by hand with "sh /path/to/script".
  - Update instructions on how-to increase RTC clock frequency.
    Thanks to Torquil Macdonald Sørensen for the report (Closes: #570833).
  - Bump Standards.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Implementation: simplesynth
 
3
//
 
4
// Description:
 
5
//
 
6
//
 
7
// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004
 
8
//
 
9
// Copyright: See COPYING file that comes with this distribution
 
10
//
 
11
//
 
12
 
 
13
#include "muse/midictrl.h"
 
14
#include "muse/midi.h"
 
15
//#include "libsynti/mpevent.h"
 
16
#include "muse/mpevent.h"   
 
17
#include "simpledrums.h"
 
18
 
 
19
#include <samplerate.h>
 
20
 
 
21
const char* SimpleSynth::synth_state_descr[] =
 
22
      {
 
23
      "SS_INITIALIZING",
 
24
      "SS_LOADING_SAMPLE",
 
25
      "SS_CLEARING_SAMPLE",
 
26
      "SS_RUNNING"
 
27
      };
 
28
 
 
29
const char* SimpleSynth::channel_state_descr[] =
 
30
      {
 
31
      "SS_CHANNEL_INACTIVE",
 
32
      "SS_SAMPLE_PLAYING"
 
33
      };
 
34
 
 
35
#define SWITCH_SYNTH_STATE(state)\
 
36
synth_state = state; \
 
37
if (SS_DEBUG_STATE) \
 
38
      fprintf (stderr, "SS STATE: %s\n", SimpleSynth::synth_state_descr[state]);
 
39
 
 
40
#define SWITCH_CHAN_STATE(ch, s)\
 
41
channels[ch].state = s; \
 
42
if (SS_DEBUG_STATE) \
 
43
      fprintf (stderr, "SS CHAN %d STATE: %s\n", ch, SimpleSynth::channel_state_descr[s]);
 
44
 
 
45
#define SS_CHANNEL_VOLUME_QUOT 100.0
 
46
#define SS_MASTER_VOLUME_QUOT  100.0
 
47
int SS_samplerate;
 
48
 
 
49
#define SS_LOG_MAX   0
 
50
#define SS_LOG_MIN -10
 
51
#define SS_LOG_OFFSET SS_LOG_MIN
 
52
 
 
53
 
 
54
//
 
55
// Map plugin parameter on domain [SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX] to domain [SS_LOG_MIN, SS_LOG_MAX] (log domain)
 
56
//
 
57
float SS_map_pluginparam2logdomain(int pluginparam_val)
 
58
      {
 
59
      float scale = (float) (SS_LOG_MAX - SS_LOG_MIN)/ (float) SS_PLUGIN_PARAM_MAX;
 
60
      float scaled = (float) pluginparam_val * scale;
 
61
      float mapped = scaled + SS_LOG_OFFSET;
 
62
      return mapped;
 
63
      }
 
64
//
 
65
// Map plugin parameter on domain to domain [SS_LOG_MIN, SS_LOG_MAX] to [SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX]  (from log-> [0,127])
 
66
// (inverse func to the above)
 
67
int SS_map_logdomain2pluginparam(float pluginparam_log)
 
68
      {
 
69
      float mapped = pluginparam_log - SS_LOG_OFFSET;
 
70
      float scale = (float) SS_PLUGIN_PARAM_MAX / (float) (SS_LOG_MAX - SS_LOG_MIN);
 
71
      int scaled  = (int) round(mapped * scale);
 
72
      return scaled;
 
73
      }
 
74
 
 
75
//---------------------------------------------------------
 
76
//   SimpleSynth
 
77
//---------------------------------------------------------
 
78
SimpleSynth::SimpleSynth(int sr)
 
79
      : Mess(SS_AUDIO_CHANNELS)
 
80
      {
 
81
      SS_TRACE_IN
 
82
      SS_samplerate = sr;
 
83
      SS_initPlugins();
 
84
 
 
85
      simplesynth_ptr = this;
 
86
      master_vol = 100.0 / SS_MASTER_VOLUME_QUOT;
 
87
      master_vol_ctrlval = 100;
 
88
 
 
89
      //initialize
 
90
      for (int i=0; i<SS_NR_OF_CHANNELS; i++) {
 
91
            channels[i].sample = 0;
 
92
            channels[i].playoffset = 0;
 
93
            channels[i].noteoff_ignore = false;
 
94
            channels[i].volume = (double) (100.0/SS_CHANNEL_VOLUME_QUOT );
 
95
            channels[i].volume_ctrlval = 100;
 
96
            channels[i].pan = 64;
 
97
            channels[i].balanceFactorL = 1.0;
 
98
            channels[i].balanceFactorR = 1.0;
 
99
            SWITCH_CHAN_STATE(i, SS_CHANNEL_INACTIVE);
 
100
            channels[i].channel_on = false;
 
101
            for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) {
 
102
                  channels[i].sendfxlevel[j] = 0.0;
 
103
                  }
 
104
            }
 
105
 
 
106
      //Process buffer:
 
107
      processBuffer[0] = new double[SS_PROCESS_BUFFER_SIZE]; //left
 
108
      processBuffer[1] = new double[SS_PROCESS_BUFFER_SIZE]; //right
 
109
 
 
110
      //Send effects
 
111
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
112
            sendFxLineOut[i][0] = new float[SS_SENDFX_BUFFER_SIZE]; //left out
 
113
            sendFxLineOut[i][1] = new float[SS_SENDFX_BUFFER_SIZE]; //right out
 
114
            sendFxReturn[i][0]  = new float[SS_SENDFX_BUFFER_SIZE]; //left in
 
115
            sendFxReturn[i][1]  = new float[SS_SENDFX_BUFFER_SIZE]; //right in
 
116
            }
 
117
 
 
118
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
119
            sendEffects[i].state       = SS_SENDFX_OFF;
 
120
            sendEffects[i].plugin      = 0;
 
121
            sendEffects[i].retgain     = 1.0;
 
122
            sendEffects[i].retgain_ctrlval = 100;
 
123
            sendEffects[i].nrofparameters = 0;
 
124
            }
 
125
 
 
126
      //Build controller list:
 
127
      controllers[0].name = "Master volume";
 
128
      controllers[0].num  = CTRL_NRPN14_OFFSET;
 
129
      controllers[0].min  = 0;
 
130
      controllers[0].max  = 127;
 
131
 
 
132
      int i=1;
 
133
      for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
 
134
            QString c1 = "Channel " + QString::number(ch + 1) + " volume";
 
135
            QString c2 = "Channel " + QString::number(ch + 1) + " pan";
 
136
            QString c3 = "Channel " + QString::number(ch + 1) + " noteoff ignore";
 
137
            QString c4 = "Channel " + QString::number(ch + 1) + " on/off";
 
138
            QString c5 = "Channel " + QString::number(ch + 1) + " fx send 1";
 
139
            QString c6 = "Channel " + QString::number(ch + 1) + " fx send 2";
 
140
            QString c7 = "Channel " + QString::number(ch + 1) + " fx send 3";
 
141
            QString c8 = "Channel " + QString::number(ch + 1) + " fx send 4";
 
142
            controllers[i].name = c1.toLatin1().constData();
 
143
            controllers[i].num  = CTRL_NRPN14_OFFSET+i;
 
144
            controllers[i].min  = 0;
 
145
            controllers[i].max  = 127;
 
146
 
 
147
            controllers[i+1].name = c2.toLatin1().constData();
 
148
            controllers[i+1].num  = CTRL_NRPN14_OFFSET+i+1;
 
149
            controllers[i+1].min  = 0;
 
150
            controllers[i+1].max  = 127;
 
151
 
 
152
            controllers[i+2].name = c3.toLatin1().constData();
 
153
            controllers[i+2].num  = CTRL_NRPN14_OFFSET+i+2;
 
154
            controllers[i+2].min  = 0;
 
155
            controllers[i+2].max  = 1;
 
156
 
 
157
            controllers[i+3].name = c4.toLatin1().constData();
 
158
            controllers[i+3].num  = CTRL_NRPN14_OFFSET+i+3;
 
159
            controllers[i+3].min  = 0;
 
160
            controllers[i+3].max  = 1;
 
161
 
 
162
            controllers[i+4].name = c5.toLatin1().constData();
 
163
            controllers[i+4].num  = CTRL_NRPN14_OFFSET+i+4;
 
164
 
 
165
            controllers[i+5].name = c6.toLatin1().constData();
 
166
            controllers[i+5].num  = CTRL_NRPN14_OFFSET+i+5;
 
167
 
 
168
            controllers[i+6].name = c7.toLatin1().constData();
 
169
            controllers[i+6].num  = CTRL_NRPN14_OFFSET+i+6;
 
170
 
 
171
            controllers[i+7].name = c8.toLatin1().constData();
 
172
            controllers[i+7].num  = CTRL_NRPN14_OFFSET+i+7;
 
173
 
 
174
            controllers[i+4].min = controllers[i+5].min = controllers[i+6].min = controllers[i+7].min = 0;
 
175
            controllers[i+4].max = controllers[i+5].max = controllers[i+6].max = controllers[i+7].max = 127;
 
176
 
 
177
            i+=8;
 
178
            }
 
179
 
 
180
      for (int sfx=0; sfx<SS_NR_OF_SENDEFFECTS; sfx++) {
 
181
            QString c1 = "Sendfx " + QString::number(sfx) + " ret gain";
 
182
            QString c2 = "Sendfx " + QString::number(sfx) + " on/off";
 
183
            controllers[i].name = c1.toLatin1().constData();
 
184
            controllers[i].num  = CTRL_NRPN14_OFFSET+i;
 
185
            controllers[i].min  = 0;
 
186
            controllers[i].max  = 127;
 
187
 
 
188
            controllers[i+1].name = c2.toLatin1().constData();
 
189
            controllers[i+1].num  = CTRL_NRPN14_OFFSET+i+1;
 
190
            controllers[i+1].min  = 0;
 
191
            controllers[i+1].max  = 1;
 
192
            i+=2;
 
193
            }
 
194
 
 
195
      pthread_mutex_init(&SS_LoaderMutex, NULL);
 
196
      SS_TRACE_OUT
 
197
      }
 
198
 
 
199
//---------------------------------------------------------
 
200
//   ~SimpleSynth
 
201
//---------------------------------------------------------
 
202
SimpleSynth::~SimpleSynth()
 
203
      {
 
204
      SS_TRACE_IN
 
205
 
 
206
      // Cleanup channels and samples:
 
207
      SS_DBG("Cleaning up sample data");
 
208
      for (int i=0; i<SS_NR_OF_CHANNELS; i++) {
 
209
            if (channels[i].sample) {
 
210
                  delete[] channels[i].sample->data;
 
211
                  delete channels[i].sample;
 
212
                  }
 
213
            }
 
214
      simplesynth_ptr = NULL;
 
215
 
 
216
      SS_DBG("Deleting pluginlist");
 
217
      //Cleanup plugins:
 
218
      for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) {
 
219
            delete (*i);
 
220
            }
 
221
      plugins.clear();
 
222
 
 
223
      SS_DBG("Deleting sendfx buffers");
 
224
      //Delete sendfx buffers:
 
225
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
226
            delete[] sendFxLineOut[i][0];
 
227
            delete[] sendFxLineOut[i][1];
 
228
            delete[] sendFxReturn[i][0];
 
229
            delete[] sendFxReturn[i][1];
 
230
            }
 
231
 
 
232
      //processBuffer:
 
233
      SS_DBG("Deleting process buffer");
 
234
      delete[] processBuffer[0];
 
235
      delete[] processBuffer[1];
 
236
      SS_TRACE_OUT
 
237
      }
 
238
 
 
239
//---------------------------------------------------------
 
240
//   nativeGuiVisible
 
241
/*!
 
242
    \fn SimpleSynth::nativeGuiVisible
 
243
    \brief Tells if the gui is hidden or shown
 
244
    \return true/false if gui is shown/hidden
 
245
 */
 
246
//---------------------------------------------------------
 
247
bool SimpleSynth::nativeGuiVisible() const
 
248
      {
 
249
      SS_TRACE_IN
 
250
      bool v = gui->isVisible();
 
251
      SS_TRACE_OUT
 
252
      return v;
 
253
      }
 
254
 
 
255
//---------------------------------------------------------
 
256
//   hasNativeGui
 
257
/*!
 
258
    \fn SimpleSynth::hasNativeGui
 
259
    \brief Tells if the synth has a gui or not
 
260
    \return true if synth has gui, false it synth has no gui
 
261
 */
 
262
//---------------------------------------------------------
 
263
bool SimpleSynth::hasNativeGui() const
 
264
      {
 
265
      SS_TRACE_IN
 
266
      SS_TRACE_OUT
 
267
      return true;
 
268
      }
 
269
 
 
270
//---------------------------------------------------------
 
271
//   playNote
 
272
/*!
 
273
    \fn SimpleSynth::playNote
 
274
    \brief Triggers a note on (noteoffs are noteons with velo=0)
 
275
    \param channel midi channel
 
276
    \param pitch note pitch
 
277
    \param velo note velocity
 
278
    \return false for ok, true for not ok (not sure these are handled differently, but...)
 
279
 */
 
280
//---------------------------------------------------------
 
281
bool SimpleSynth::playNote(int /*channel*/, int pitch, int velo)
 
282
      {
 
283
      SS_TRACE_IN
 
284
      //Don't bother about channel, we're processing every playnote!
 
285
      if ((pitch >= SS_LOWEST_NOTE) && (pitch <= SS_HIGHEST_NOTE)) {
 
286
            bool noteOff = (velo == 0 ? 1 : 0);
 
287
            int ch = pitch - SS_LOWEST_NOTE;
 
288
            if(!noteOff) {
 
289
                  if (channels[ch].sample) {
 
290
                        //Turn on the white stuff:
 
291
                        channels[ch].playoffset = 0;
 
292
                        SWITCH_CHAN_STATE(ch , SS_SAMPLE_PLAYING);
 
293
                        channels[ch].cur_velo = (double) velo / 127.0;
 
294
                        channels[ch].gain_factor = channels[ch].cur_velo * channels[ch].volume;
 
295
                        if (SS_DEBUG_MIDI) {
 
296
                              printf("Playing note %d on channel %d\n", pitch, ch);
 
297
                              }
 
298
                        }
 
299
                  }
 
300
            else {
 
301
                  //Note off:
 
302
                  if (channels[ch].noteoff_ignore) {
 
303
                        if (SS_DEBUG_MIDI) {
 
304
                              printf("Note off on channel %d\n", ch);
 
305
                              }
 
306
                        SWITCH_CHAN_STATE(ch , SS_CHANNEL_INACTIVE);
 
307
                        channels[ch].playoffset = 0;
 
308
                        channels[ch].cur_velo = 0;
 
309
                        }
 
310
                  }
 
311
            }
 
312
      SS_TRACE_OUT
 
313
      return false;
 
314
      }
 
315
 
 
316
//---------------------------------------------------------
 
317
//   processEvent
 
318
/*!
 
319
    \fn SimpleSynth::processEvent
 
320
    \brief All events from sequencer first shows up here and are forwarded to their correct functions
 
321
    \param event The event sent from sequencer
 
322
    \return false for ok, true for not ok
 
323
 */
 
324
//---------------------------------------------------------
 
325
bool SimpleSynth::processEvent(const MidiPlayEvent& ev)
 
326
      {
 
327
      SS_TRACE_IN
 
328
      switch(ev.type()) {
 
329
            case ME_CONTROLLER:
 
330
                  if (SS_DEBUG_MIDI) {
 
331
                        printf("SimpleSynth::processEvent - Controller. Chan: %x dataA: %x dataB: %x\n", ev.channel(), ev.dataA(), ev.dataB());
 
332
                        for (int i=0; i< ev.len(); i++)
 
333
                              printf("%x ", ev.data()[i]);
 
334
                        }
 
335
                  setController(ev.channel(), ev.dataA(), ev.dataB(), false);
 
336
                  return true;
 
337
            case ME_NOTEON:
 
338
                  return playNote(ev.channel(), ev.dataA(), ev.dataB());
 
339
            case ME_NOTEOFF:
 
340
                  return playNote(ev.channel(), ev.dataA(), 0);
 
341
            case ME_SYSEX:
 
342
                  //Debug print
 
343
                  if (SS_DEBUG_MIDI) {
 
344
                        printf("SimpleSynth::processEvent - Sysex received\n");
 
345
                        for (int i=0; i< ev.len(); i++)
 
346
                              printf("%x ", ev.data()[i]);
 
347
                        printf("\n");
 
348
                        }
 
349
                  return sysex(ev.len(), ev.data());
 
350
            }
 
351
      return false;
 
352
      SS_TRACE_OUT
 
353
      }
 
354
 
 
355
//---------------------------------------------------------
 
356
//   setController
 
357
/*!
 
358
    \fn SimpleSynth::setController
 
359
    \brief Called from sequencer indirectly via SimpleSynth::processEvent
 
360
    \brief when the synth is supposed to set a controller value
 
361
    \param channel channel nr
 
362
    \param id controller id
 
363
    \param val value of controller
 
364
    \return false for ok, true for not ok
 
365
 */
 
366
//---------------------------------------------------------
 
367
bool SimpleSynth::setController(int channel, int id, int val)
 
368
      {
 
369
      SS_TRACE_IN
 
370
      if (SS_DEBUG_MIDI) {
 
371
            printf("SimpleSynth::setController - received controller on channel %d, id %d value %d\n", channel, id, val);
 
372
            }
 
373
 
 
374
      // Channel controllers:
 
375
      if (id >= SS_FIRST_CHANNEL_CONTROLLER && id <= SS_LAST_CHANNEL_CONTROLLER ) {
 
376
            // Find out which channel we're dealing with:
 
377
            id-= SS_FIRST_CHANNEL_CONTROLLER;
 
378
            int ch = (id / SS_NR_OF_CHANNEL_CONTROLLERS);
 
379
            id = (id % SS_NR_OF_CHANNEL_CONTROLLERS);
 
380
 
 
381
            switch (id) {
 
382
                  case SS_CHANNEL_CTRL_VOLUME:
 
383
                        if (SS_DEBUG_MIDI)
 
384
                              printf("Received channel ctrl volume %d for channel %d\n", val, ch);
 
385
                        channels[ch].volume_ctrlval = val;
 
386
                        updateVolume(ch, val);
 
387
                        break;
 
388
                  case SS_CHANNEL_CTRL_NOFF:
 
389
                        if (SS_DEBUG_MIDI)
 
390
                              printf("Received ctrl noff %d for channel %d\n", val, ch);
 
391
                        channels[ch].noteoff_ignore = val;
 
392
                        break;
 
393
                  case SS_CHANNEL_CTRL_PAN:
 
394
                        {
 
395
                        if (SS_DEBUG_MIDI)
 
396
                              printf("Received ctrl pan %d for channel %d\n", val, ch);
 
397
                        channels[ch].pan = val;
 
398
                        updateBalance(ch, val);
 
399
                        break;
 
400
                        }
 
401
                  case SS_CHANNEL_CTRL_ONOFF:
 
402
                        {
 
403
                        if (SS_DEBUG_MIDI)
 
404
                              printf("Received ctrl onoff %d for channel %d\n", val, ch);
 
405
 
 
406
                        if (val == false && channels[ch].channel_on == true) {
 
407
                              SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
 
408
                              channels[ch].channel_on = val;
 
409
                              }
 
410
                        else if (val == true && channels[ch].channel_on == false) { // if it actually _was_ off:
 
411
                              SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
 
412
                              channels[ch].playoffset = 0;
 
413
                              channels[ch].channel_on = val;
 
414
                              }
 
415
                        break;
 
416
                        }
 
417
                  case SS_CHANNEL_SENDFX1:
 
418
                  case SS_CHANNEL_SENDFX2:
 
419
                  case SS_CHANNEL_SENDFX3:
 
420
                  case SS_CHANNEL_SENDFX4:
 
421
                        {
 
422
                        int fxid = id - SS_CHANNEL_SENDFX1;
 
423
                        channels[ch].sendfxlevel[fxid] = (double)val/127.0;
 
424
                        break;
 
425
                        }
 
426
 
 
427
                  default:
 
428
                        if (SS_DEBUG_MIDI)
 
429
                              printf("Unknown controller received for channel %d. id=%d\n", ch, id);
 
430
                        break;
 
431
                  }
 
432
            }
 
433
      // Master controllers:
 
434
      else if (id >= SS_FIRST_MASTER_CONTROLLER && id <= SS_LAST_MASTER_CONTROLLER) {
 
435
            if (SS_DEBUG_MIDI)
 
436
                  printf("Mastervol controller received: %d\n", id);
 
437
            master_vol_ctrlval = val;
 
438
            master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT;
 
439
            }
 
440
      // Emmm, this one should've been there in the beginning
 
441
      else if (id == CTRL_VOLUME) {
 
442
            if (SS_DEBUG_MIDI) {
 
443
                  printf("Ctrl volume received: vol: %d\n", val);
 
444
                  }
 
445
            master_vol_ctrlval = val;
 
446
            master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT;
 
447
            //This one can't be from the gui, update gui:
 
448
            guiUpdateMasterVol(val);
 
449
            }
 
450
      // Plugin controllers:
 
451
      else if (id >= SS_FIRST_PLUGIN_CONTROLLER && id <= SS_LAST_PLUGIN_CONTROLLER) {
 
452
 
 
453
            int fxid = (id - SS_FIRST_PLUGIN_CONTROLLER) / SS_NR_OF_PLUGIN_CONTROLLERS;
 
454
            int cmd = (id - SS_FIRST_PLUGIN_CONTROLLER) % SS_NR_OF_PLUGIN_CONTROLLERS;
 
455
 
 
456
            // Plugin return-gain:
 
457
            if (cmd == SS_PLUGIN_RETURN) {
 
458
                  if (SS_DEBUG_MIDI)
 
459
                        printf("Ctrl fx retgain received: fxid: %d val: %d\n", fxid, val);
 
460
                  sendEffects[fxid].retgain_ctrlval = val;
 
461
                  sendEffects[fxid].retgain = (double) val / 75.0;
 
462
                  }
 
463
            // Plugin on/off:
 
464
            else if (cmd == SS_PLUGIN_ONOFF) {
 
465
                  if (SS_DEBUG_MIDI)
 
466
                        printf("Ctrl fx onoff received: fxid: %d val: %d\n", fxid, val);
 
467
                  sendEffects[fxid].state = (SS_SendFXState) val;
 
468
                  }
 
469
            }
 
470
      else {
 
471
            if (SS_DEBUG_MIDI)
 
472
                  printf("Unknown controller received: %d\n", id);
 
473
            }
 
474
      SS_TRACE_OUT
 
475
      return false;
 
476
      }
 
477
 
 
478
//---------------------------------------------------------
 
479
/*!
 
480
    \fn SimpleSynth::setController
 
481
 */
 
482
//---------------------------------------------------------
 
483
bool SimpleSynth::setController(int channel, int id, int val, bool /*fromGui*/)
 
484
      {
 
485
      SS_TRACE_IN
 
486
      bool ret = setController(channel, id, val); //Perhaps TODO... Separate events from the gui
 
487
      SS_TRACE_OUT
 
488
      return ret;
 
489
      }
 
490
//---------------------------------------------------------
 
491
//   sysex
 
492
/*!
 
493
    \fn SimpleSynth::sysex
 
494
    \brief Called from sequencer indirectly via SimpleSynth::processEvent
 
495
    \param len length of the sysex data
 
496
    \param data the sysex data
 
497
    \return false for ok, true for not ok
 
498
*/
 
499
//---------------------------------------------------------
 
500
bool SimpleSynth::sysex(int /*len*/, const unsigned char* data)
 
501
      {
 
502
      SS_TRACE_IN
 
503
      int cmd = data[0];
 
504
      switch (cmd) {
 
505
            case SS_SYSEX_LOAD_SAMPLE:
 
506
                  {
 
507
                  int channel = data[1];
 
508
                  //int l = data[2];
 
509
                  const char* filename = (const char*)(data+3);
 
510
                  if (SS_DEBUG_MIDI) {
 
511
                        printf("Sysex cmd: load sample, filename %s, on channel: %d\n", filename, channel);
 
512
                        }
 
513
                  loadSample(channel, filename);
 
514
                  break;
 
515
                  }
 
516
            case SS_SYSEX_CLEAR_SAMPLE:
 
517
                  {
 
518
                  int ch = data[1];
 
519
                  clearSample(ch);
 
520
                  break;
 
521
                  }
 
522
 
 
523
            case SS_SYSEX_INIT_DATA:
 
524
                  {
 
525
                  parseInitData(data);
 
526
                  break;
 
527
                  }
 
528
 
 
529
            case SS_SYSEX_LOAD_SENDEFFECT:
 
530
                  {
 
531
                  int fxid = data[1];
 
532
                  QString lib = (const char*) (data + 2);
 
533
                  QString label = (const char*) (data + lib.length() + 3);
 
534
                  if (SS_DEBUG_MIDI) {
 
535
                        printf("Sysex cmd load effect: %d %s %s\n", fxid, lib.toLatin1().constData(), label.toLatin1().constData());
 
536
                        }
 
537
                  initSendEffect(fxid, lib, label);
 
538
                  break;
 
539
                  }
 
540
 
 
541
            case SS_SYSEX_CLEAR_SENDEFFECT:
 
542
                  {
 
543
                  int fxid = data[1];
 
544
                  if (SS_DEBUG_MIDI) {
 
545
                        printf("Sysex cmd clear effect: %d\n", fxid);
 
546
                        }
 
547
                  sendEffects[fxid].state = SS_SENDFX_OFF;
 
548
                  cleanupPlugin(fxid);
 
549
                  sendEffects[fxid].plugin = 0;
 
550
                  break;
 
551
                  }
 
552
 
 
553
            case SS_SYSEX_SET_PLUGIN_PARAMETER:
 
554
                  {
 
555
                  int fxid = data[1];
 
556
                  int parameter = data[2];
 
557
                  int val = data[3];
 
558
                  // Write it to the plugin:
 
559
                  float floatval = sendEffects[fxid].plugin->convertGuiControlValue(parameter, val);
 
560
                  setFxParameter(fxid, parameter, floatval);
 
561
                  break;
 
562
                  }
 
563
 
 
564
            case SS_SYSEX_GET_INIT_DATA:
 
565
                  {
 
566
                  int initdata_len = 0;
 
567
                  const byte* tmp_initdata = NULL;
 
568
                  byte* event_data = NULL;
 
569
 
 
570
                  getInitData(&initdata_len, &tmp_initdata);
 
571
                  int totlen = initdata_len + 1;
 
572
 
 
573
                  event_data = new byte[initdata_len + 1];
 
574
                  event_data[0] = SS_SYSEX_SEND_INIT_DATA;
 
575
                  memcpy(event_data + 1, tmp_initdata, initdata_len);
 
576
                  delete[] tmp_initdata;
 
577
                  tmp_initdata = NULL;
 
578
 
 
579
                  MidiPlayEvent ev(0, 0, ME_SYSEX, event_data, totlen);
 
580
                  gui->writeEvent(ev);
 
581
                  delete[] event_data;
 
582
 
 
583
                  break;
 
584
                  }
 
585
 
 
586
            default:
 
587
                  if (SS_DEBUG_MIDI)
 
588
                        printf("Unknown sysex cmd received: %d\n", cmd);
 
589
                  break;
 
590
            }
 
591
      SS_TRACE_OUT
 
592
      return false;
 
593
      }
 
594
 
 
595
//---------------------------------------------------------
 
596
//   getPatchName
 
597
/*!
 
598
    \fn SimpleSynth::getPatchName
 
599
    \brief Called from host to get names of patches
 
600
    \param index - which patchnr we're about to deliver
 
601
    \return const char* with patchname
 
602
 */
 
603
//---------------------------------------------------------
 
604
const char* SimpleSynth::getPatchName(int /*index*/, int, int) const
 
605
      {
 
606
      SS_TRACE_IN
 
607
      SS_TRACE_OUT
 
608
      return 0;
 
609
      }
 
610
 
 
611
//---------------------------------------------------------
 
612
//   getPatchInfo
 
613
/*!
 
614
    \fn SimpleSynth::getPatchInfo
 
615
    \brief Called from host to get info about patches
 
616
    \param index - which patchnr we're about to deliver
 
617
    \param patch - if this one is 0, this is the first call, otherwise keep deliver the host patches... or something
 
618
    \return MidiPatch with patch info for host
 
619
 */
 
620
//---------------------------------------------------------
 
621
const MidiPatch* SimpleSynth::getPatchInfo(int index, const MidiPatch* patch) const
 
622
      {
 
623
      SS_TRACE_IN
 
624
      index = 0; patch = 0;
 
625
      SS_TRACE_OUT
 
626
      return 0;
 
627
      }
 
628
 
 
629
//---------------------------------------------------------
 
630
//   getControllerInfo
 
631
/*!
 
632
    \fn SimpleSynth::getControllerInfo
 
633
    \brief Called from host to collect info about which controllers the synth supports
 
634
    \param index current controller number
 
635
    \param name pointer where name is stored
 
636
    \param controller int pointer where muse controller number is stored
 
637
    \param min int pointer where controller min value is stored
 
638
    \param max int pointer where controller max value is stored
 
639
    \return 0 when done, otherwise return next desired controller index
 
640
 */
 
641
//---------------------------------------------------------
 
642
int SimpleSynth::getControllerInfo(int index, const char** name, int* controller, int* min, int* max)
 
643
      {
 
644
      SS_TRACE_IN
 
645
      if (index >= SS_NR_OF_CONTROLLERS) {
 
646
            SS_TRACE_OUT
 
647
            return 0;
 
648
            }
 
649
 
 
650
      *name = controllers[index].name.c_str();
 
651
      *controller = controllers[index].num;
 
652
      *min = controllers[index].min;
 
653
      *max = controllers[index].max;
 
654
 
 
655
      if (SS_DEBUG_MIDI) {
 
656
            printf("setting controller info: index %d name %s controller %d min %d max %d\n", index, *name, *controller, *min, *max);
 
657
            }
 
658
      SS_TRACE_OUT
 
659
      return (index +1);
 
660
      }
 
661
 
 
662
//---------------------------------------------------------
 
663
//   process
 
664
/*!
 
665
    \fn SimpleSynth::process
 
666
    \brief Realtime function where the processing actually occurs
 
667
    \param channels - audio data
 
668
    \param offset - sample offset
 
669
    \param len - nr of samples to process
 
670
 */
 
671
//---------------------------------------------------------
 
672
void SimpleSynth::process(float** out, int offset, int len)
 
673
      {
 
674
      //Process messages from the gui
 
675
      while (gui->fifoSize()) {
 
676
            MidiPlayEvent ev = gui->readEvent();
 
677
            if (ev.type() == ME_SYSEX) {
 
678
                  sysex(ev.len(), ev.data());
 
679
                  sendEvent(ev);
 
680
                  }
 
681
            else if (ev.type() == ME_CONTROLLER) {
 
682
                  setController(ev.channel(), ev.dataA(), ev.dataB(), true);
 
683
                  sendEvent(ev);
 
684
                  }
 
685
            else {
 
686
                  if (SS_DEBUG)
 
687
                        printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type());
 
688
                  }
 
689
            }
 
690
 
 
691
      if (synth_state == SS_RUNNING) {
 
692
 
 
693
      //Temporary mix-doubles
 
694
      double out1, out2;
 
695
      //double ltemp, rtemp;
 
696
      float* data;
 
697
      // Velocity factor:
 
698
      double gain_factor;
 
699
 
 
700
 
 
701
      // Clear send-channels. Skips if fx not turned on
 
702
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
703
            if (sendEffects[i].state == SS_SENDFX_ON) {
 
704
                  memset(sendFxLineOut[i][0], 0, SS_SENDFX_BUFFER_SIZE * sizeof(float));
 
705
                  memset(sendFxLineOut[i][1], 0, SS_SENDFX_BUFFER_SIZE * sizeof(float));
 
706
                  }
 
707
            }
 
708
 
 
709
 
 
710
      memset(out[0] + offset, 0, len * sizeof(float));
 
711
      memset(out[1] + offset, 0, len * sizeof(float));
 
712
 
 
713
      //Process 1 channel at a time
 
714
      for (int ch=0; ch < SS_NR_OF_CHANNELS; ch++) {
 
715
            // If channels is turned off, skip:
 
716
            if (channels[ch].channel_on == false)
 
717
                  continue;
 
718
 
 
719
            //If sample isn't playing, skip:
 
720
            if (channels[ch].state == SS_SAMPLE_PLAYING) {
 
721
                  memset(processBuffer[0], 0, SS_PROCESS_BUFFER_SIZE * sizeof(double));
 
722
                  memset(processBuffer[1], 0, SS_PROCESS_BUFFER_SIZE * sizeof(double));
 
723
 
 
724
                  for (int i=0; i<len; i++) {
 
725
                        // Current channel sample data:
 
726
                        data = channels[ch].sample->data;
 
727
                        gain_factor = channels[ch].gain_factor;
 
728
                        // Current velocity factor:
 
729
 
 
730
                        if (channels[ch].sample->channels == 2) {
 
731
                              //
 
732
                              // Stereo sample:
 
733
                              //
 
734
                              // Add from sample:
 
735
                              out1 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorL);
 
736
                              out2 = (double) (data[channels[ch].playoffset + 1] * gain_factor * channels[ch].balanceFactorR);
 
737
                              channels[ch].playoffset += 2;
 
738
                              }
 
739
                        else {
 
740
                              //
 
741
                              // Mono sample:
 
742
                              //
 
743
                              out1 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorL);
 
744
                              out2 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorR);
 
745
                              channels[ch].playoffset++;
 
746
                              }
 
747
 
 
748
                        processBuffer[0][i] = out1;
 
749
                        processBuffer[1][i] = out2;
 
750
 
 
751
                        // If send-effects tap is on, tap signal to respective lineout channel
 
752
                        for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) {
 
753
                              if (channels[ch].sendfxlevel[j] != 0.0) {
 
754
                                    //If the effect has 2 inputs (stereo in):
 
755
                                    if (sendEffects[j].inputs == 2) {
 
756
                                          sendFxLineOut[j][0][i]+= (out1 * channels[ch].sendfxlevel[j]);
 
757
                                          sendFxLineOut[j][1][i]+= (out2 * channels[ch].sendfxlevel[j]);
 
758
                                          }
 
759
                                    //If the effect is mono (1 input), only use first fxLineOut
 
760
                                    else if (sendEffects[j].inputs == 1) {
 
761
                                          sendFxLineOut[j][0][i]+= ((out1 + out2) * channels[ch].sendfxlevel[j] / 2.0);
 
762
                                          }
 
763
                                    //Effects with 0 or >2 inputs are ignored
 
764
                                    }
 
765
                              }
 
766
 
 
767
                        //
 
768
                        // If we've reached the last sample, set state to inactive
 
769
                        //
 
770
                        if (channels[ch].playoffset >= channels[ch].sample->samples) {
 
771
                              SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
 
772
                              channels[ch].playoffset = 0;
 
773
                              break;
 
774
                              }
 
775
                        }
 
776
                        // Add contribution for this channel, for this frame, to final result:
 
777
                        for (int i=0; i<len; i++) {
 
778
                              out[0][i+offset]+=processBuffer[0][i];
 
779
                              out[1][i+offset]+=processBuffer[1][i];
 
780
                              }
 
781
                  }
 
782
            }
 
783
            // Do something funny with the sendies:
 
784
            for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) {
 
785
                  if (sendEffects[j].state == SS_SENDFX_ON) {
 
786
                        sendEffects[j].plugin->process(len);
 
787
                        for (int i=0; i<len; i++) {
 
788
                              //Effect has mono output:
 
789
                              if (sendEffects[j].outputs == 1) {
 
790
                                    //Add the result to both channels:
 
791
                                    out[0][i+offset]+=((sendEffects[j].retgain * sendFxReturn[j][0][i]) / 2.0);
 
792
                                    out[1][i+offset]+=((sendEffects[j].retgain * sendFxReturn[j][0][i]) / 2.0);
 
793
                                    }
 
794
                              else if (sendEffects[j].outputs == 2) {
 
795
                                    // Effect has stereo output
 
796
                                    out[0][i+offset]+=(sendEffects[j].retgain * sendFxReturn[j][0][i]);
 
797
                                    out[1][i+offset]+=(sendEffects[j].retgain * sendFxReturn[j][1][i]);
 
798
                                    }
 
799
                              }
 
800
                        }
 
801
                  }
 
802
            // Finally master gain:
 
803
            for (int i=0; i<len; i++) {
 
804
                  out[0][i+offset] = (out[0][i+offset] * master_vol);
 
805
                  out[1][i+offset] = (out[1][i+offset] * master_vol);
 
806
                  }
 
807
            }
 
808
      }
 
809
 
 
810
//---------------------------------------------------------
 
811
//   showNativeGui
 
812
/*!
 
813
    \fn SimpleSynth::showNativeGui
 
814
    \brief Displays or hides the gui window
 
815
    \param val true or false = gui shown or hidden
 
816
 */
 
817
//---------------------------------------------------------
 
818
void SimpleSynth::showNativeGui(bool val)
 
819
      {
 
820
      SS_TRACE_IN
 
821
      gui->setVisible(val);
 
822
      SS_TRACE_OUT
 
823
      }
 
824
 
 
825
//---------------------------------------------------------
 
826
/*!
 
827
    \fn SimpleSynth::init
 
828
    \brief Initializes the SimpleSynth
 
829
    \param name string set to caption in the gui dialog
 
830
    \return true if successful, false if unsuccessful
 
831
 */
 
832
//---------------------------------------------------------
 
833
bool SimpleSynth::init(const char* name)
 
834
      {
 
835
      SS_TRACE_IN
 
836
      SWITCH_SYNTH_STATE(SS_INITIALIZING);
 
837
      gui = new SimpleSynthGui();
 
838
      gui->show();
 
839
      gui->setWindowTitle(name);
 
840
      SWITCH_SYNTH_STATE(SS_RUNNING);
 
841
      SS_TRACE_OUT
 
842
      return true;
 
843
      }
 
844
 
 
845
//---------------------------------------------------------
 
846
/*!
 
847
    \fn SimpleSynth::getInitData
 
848
    \brief Data for reinitialization of SimpleSynth when loading project
 
849
    \param n - number of chars used in the data
 
850
    \param data - data that is sent as a sysex to the synth on reload of project
 
851
 */
 
852
//---------------------------------------------------------
 
853
void SimpleSynth::getInitData(int* n, const unsigned char** data)
 
854
      {
 
855
      SS_TRACE_IN
 
856
      // Calculate length of data
 
857
      // For each channel, we need to store volume, pan, noff, onoff
 
858
      int len = SS_NR_OF_CHANNEL_CONTROLLERS * SS_NR_OF_CHANNELS;
 
859
      // Sampledata: filenames len
 
860
      for (int i=0; i<SS_NR_OF_CHANNELS; i++) {
 
861
            if (channels[i].sample) {
 
862
                  int filenamelen = strlen(channels[i].sample->filename.c_str()) + 2;
 
863
                  len+=filenamelen;
 
864
                  }
 
865
            else
 
866
                  len++; //Add place for SS_NO_SAMPLE
 
867
            }
 
868
      len+=3; // 1 place for SS_SYSEX_INIT_DATA, 1 byte for master vol, 1 byte for version data
 
869
 
 
870
      // Effect data length
 
871
      len++; //Add place for SS_SYSEX_INIT_DATA_VERSION, as control
 
872
 
 
873
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
874
            Plugin* plugin = sendEffects[i].plugin;
 
875
            if (plugin) {
 
876
                  int namelen = plugin->lib().size() + 2;
 
877
                  int labelnamelen = plugin->label().size() + 2;
 
878
                  len+=(namelen + labelnamelen);
 
879
 
 
880
                  len+=3; //1 byte for nr of parameters, 1 byte for return gain, 1 byte for effect on/off
 
881
                  len+=sendEffects[i].nrofparameters; // 1 byte for each parameter value
 
882
                  }
 
883
            else {
 
884
                  len++; //place for SS_NO_PLUGIN
 
885
                  }
 
886
            }
 
887
 
 
888
      // First, SS_SYSEX_INIT_DATA
 
889
      byte* buffer = new byte[len];
 
890
      memset(buffer, 0, len);
 
891
      buffer[0] = SS_SYSEX_INIT_DATA;
 
892
      buffer[1] = SS_SYSEX_INIT_DATA_VERSION;
 
893
      if (SS_DEBUG_INIT) {
 
894
            printf("Length of init data: %d\n", len);
 
895
            printf("buffer[0] - SS_SYSEX_INIT_DATA: %d\n", SS_SYSEX_INIT_DATA);
 
896
            printf("buffer[1] - SS_SYSEX_INIT_DATA_VERSION: %d\n", SS_SYSEX_INIT_DATA_VERSION);
 
897
            }
 
898
      int i = 2;
 
899
      // All channels:
 
900
      // 0       - volume ctrlval (0-127)
 
901
      // 1       - pan (0-127)
 
902
      // 2       - noff ignore (0-1)
 
903
      // 3       - channel on/off (0-1)
 
904
      // 4 - 7   - sendfx 1-4 (0-127)
 
905
      // 8       - len of filename, n
 
906
      // 9 - 9+n - filename
 
907
      for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
 
908
            buffer[i]   = (byte) channels[ch].volume_ctrlval;
 
909
            buffer[i+1] = (byte) channels[ch].pan;
 
910
            buffer[i+2] = (byte) channels[ch].noteoff_ignore;
 
911
            buffer[i+3] = (byte) channels[ch].channel_on;
 
912
            buffer[i+4] = (byte) round(channels[ch].sendfxlevel[0] * 127.0);
 
913
            buffer[i+5] = (byte) round(channels[ch].sendfxlevel[1] * 127.0);
 
914
            buffer[i+6] = (byte) round(channels[ch].sendfxlevel[2] * 127.0);
 
915
            buffer[i+7] = (byte) round(channels[ch].sendfxlevel[3] * 127.0);
 
916
 
 
917
            if (SS_DEBUG_INIT) {
 
918
                  printf("Channel %d:\n", ch);
 
919
                  printf("buffer[%d] - channels[ch].volume_ctrlval = \t%d\n", i, channels[ch].volume_ctrlval);
 
920
                  printf("buffer[%d] - channels[ch].pan = \t\t%d\n", i+1, channels[ch].pan);
 
921
                  printf("buffer[%d] - channels[ch].noteoff_ignore = \t%d\n", i+2, channels[ch].noteoff_ignore );
 
922
                  printf("buffer[%d] - channels[ch].channel_on = \t%d\n", i+3, channels[ch].channel_on);
 
923
                  for (int j= i+4; j < i+8; j++) {
 
924
                        printf("buffer[%d] - channels[ch].sendfxlevel[%d]= \t%d\n", j, j-i-4, (int)round(channels[ch].sendfxlevel[j-i-4] * 127.0));
 
925
                        }
 
926
                  }
 
927
            if (channels[ch].sample) {
 
928
                  int filenamelen = strlen(channels[ch].sample->filename.c_str()) + 1;
 
929
                  buffer[i+8] = (byte) filenamelen;
 
930
                  memcpy((buffer+(i+9)), channels[ch].sample->filename.c_str(), filenamelen);
 
931
                  if (SS_DEBUG_INIT) {
 
932
                        printf("buffer[%d] - filenamelen: %d\n", i+8, filenamelen);
 
933
                        printf("buffer[%d] - buffer[%d] - filename: ", (i+9), (i+9) + filenamelen - 1);
 
934
                        for (int j = i+9; j< i+9+filenamelen; j++) {
 
935
                              printf("%c",buffer[j]);
 
936
                              }
 
937
                        printf("\n");
 
938
                        }
 
939
                  i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1 + filenamelen);
 
940
                  }
 
941
            else {
 
942
                  buffer[i+8] = SS_NO_SAMPLE;
 
943
                  if (SS_DEBUG_INIT) {
 
944
                        printf("buffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE);
 
945
                        }
 
946
                  i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1);
 
947
                  }
 
948
            }
 
949
      if (SS_DEBUG_INIT) {
 
950
            printf("buffer[%d]: Master vol: - %d\n", i, master_vol_ctrlval);
 
951
            }
 
952
      buffer[i] = master_vol_ctrlval;
 
953
      *(data) = buffer; *n = len;
 
954
      i++;
 
955
 
 
956
      //Send effects:
 
957
      buffer[i] = SS_SYSEX_INIT_DATA_VERSION; //Just for check
 
958
      if (SS_DEBUG_INIT) {
 
959
            printf("buffer[%d]: Control value, SS_SYSEX_INIT_DATA_VERSION\n", i);
 
960
            }
 
961
 
 
962
      i++;
 
963
      for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) {
 
964
            if (sendEffects[j].plugin) {
 
965
                  int labelnamelen = sendEffects[j].plugin->label().size() + 1;
 
966
                  buffer[i] = labelnamelen;
 
967
                  memcpy((buffer+i+1), sendEffects[j].plugin->label().toLatin1().constData(), labelnamelen);
 
968
                  if (SS_DEBUG_INIT) {
 
969
                        printf("buffer[%d] - labelnamelen: %d\n", i, labelnamelen);
 
970
                        printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + labelnamelen - 1);
 
971
                        for (int k = i+1; k < i+1+labelnamelen; k++) {
 
972
                              printf("%c",buffer[k]);
 
973
                              }
 
974
                        printf("\n");
 
975
                        }
 
976
 
 
977
                  i+=(labelnamelen + 1);
 
978
 
 
979
                  int namelen = sendEffects[j].plugin->lib().size() + 1;
 
980
                  buffer[i] = namelen;
 
981
                  memcpy((buffer+i+1), sendEffects[j].plugin->lib().toLatin1().constData(), namelen);
 
982
                  if (SS_DEBUG_INIT) {
 
983
                        printf("buffer[%d] - libnamelen : %d\n", i, namelen);
 
984
                        printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + namelen - 1);
 
985
                        for (int k = i+1; k < i+1+namelen; k++) {
 
986
                              printf("%c",buffer[k]);
 
987
                              }
 
988
                        printf("\n");
 
989
                        }
 
990
 
 
991
                  i+=(namelen + 1);
 
992
 
 
993
                  buffer[i]=sendEffects[j].nrofparameters;
 
994
                  if (SS_DEBUG_INIT) {
 
995
                        printf("buffer[%d]: sendEffects[%d].nrofparameters=%d\n", i, j, buffer[i]);
 
996
                        }
 
997
                  i++;
 
998
 
 
999
                  buffer[i]=sendEffects[j].retgain_ctrlval;
 
1000
                  if (SS_DEBUG_INIT) {
 
1001
                        printf("buffer[%d]: sendEffects[%d].retgain_ctrlval=%d\n", i, j, buffer[i]);
 
1002
                        }
 
1003
                  i++;
 
1004
 
 
1005
                  for (int k=0; k<sendEffects[j].nrofparameters; k++) {
 
1006
                        //TODO: Convert to 127-scale
 
1007
                        buffer[i] = sendEffects[j].plugin->getGuiControlValue(k);
 
1008
                        if (SS_DEBUG_INIT) {
 
1009
                              printf("buffer[%d]: sendEffects[%d].parameterval[%d]=%d\n", i, j, k, buffer[i]);
 
1010
                              }
 
1011
                        i++;
 
1012
                        }
 
1013
                  }
 
1014
            // No plugin loaded:
 
1015
            else {
 
1016
                  buffer[i] = SS_NO_PLUGIN;
 
1017
                  if (SS_DEBUG_INIT) {
 
1018
                        printf("buffer[%d]: SS_NO_PLUGIN\n", i);
 
1019
                        }
 
1020
                  i++;
 
1021
                  }
 
1022
            }
 
1023
 
 
1024
      SS_TRACE_OUT
 
1025
      }
 
1026
 
 
1027
 
 
1028
/*!
 
1029
    \fn SimpleSynth::parseInitData()
 
1030
 */
 
1031
void SimpleSynth::parseInitData(const unsigned char* data)
 
1032
      {
 
1033
      SS_TRACE_IN
 
1034
      //int len = strlen((const char*)data);
 
1035
      if (SS_DEBUG_INIT) {
 
1036
            printf("buffer[1], SS_SYSEX_INIT_DATA_VERSION=%d\n", *(data+1));
 
1037
            }
 
1038
      const byte* ptr = data+2;
 
1039
      for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
 
1040
               channels[ch].volume_ctrlval = (byte) *(ptr);
 
1041
 
 
1042
               if (SS_DEBUG_INIT) {
 
1043
                     printf("Channel %d:\n", ch);
 
1044
                     //willyfoobar-2011-02-13
 
1045
                     // ptr-data might be long long on 64 bit machine --> cast to "long"
 
1046
                     // *(ptr+...) has type byte --> use %hhd as format item
 
1047
                     /* old code  
 
1048
                     printf("buffer[%ld] - channels[ch].volume_ctrlval = \t%d\n", ptr-data, *ptr);
 
1049
                     printf("buffer[%ld] - channels[ch].pan = \t\t%d\n", ptr-data+1, *(ptr+1));
 
1050
                     printf("buffer[%ld] - channels[ch].noteoff_ignore = \t%d\n", ptr-data+2, *(ptr+2));
 
1051
                     printf("buffer[%ld] - channels[ch].channel_on = \t%d\n", ptr-data+3, *(ptr+3));
 
1052
                     */
 
1053
                     printf("buffer[%ld] - channels[ch].volume_ctrlval = \t%hhd\n", long(ptr-data), *ptr);
 
1054
                     printf("buffer[%ld] - channels[ch].pan = \t\t%hhd\n", long(ptr-data+1), *(ptr+1));
 
1055
                     printf("buffer[%ld] - channels[ch].noteoff_ignore = \t%hhd\n", long(ptr-data+2), *(ptr+2));
 
1056
                     printf("buffer[%ld] - channels[ch].channel_on = \t%hhd\n", long(ptr-data+3), *(ptr+3));
 
1057
                     }
 
1058
               updateVolume(ch, *(ptr));
 
1059
               guiUpdateVolume(ch, *(ptr));
 
1060
 
 
1061
               channels[ch].pan = *(ptr+1);
 
1062
               updateBalance(ch, *(ptr+1));
 
1063
               guiUpdateBalance(ch, *(ptr+1));
 
1064
 
 
1065
               channels[ch].noteoff_ignore = *(ptr+2);
 
1066
               guiUpdateNoff(ch, *(ptr+2));
 
1067
 
 
1068
               channels[ch].channel_on = *(ptr+3);
 
1069
               guiUpdateChoff(ch, *(ptr+3));
 
1070
 
 
1071
               ptr+=4;
 
1072
 
 
1073
               for (int i=0; i<4; i++) {
 
1074
                     channels[ch].sendfxlevel[i] = (float) (*(ptr)/127.0);
 
1075
                     guiUpdateSendFxLevel(ch, i, *(ptr));
 
1076
                     ptr++;
 
1077
                     }
 
1078
 
 
1079
               bool hasSample = *(ptr);
 
1080
               ptr++;
 
1081
 
 
1082
               channels[ch].sample = 0;
 
1083
               channels[ch].playoffset = 0;
 
1084
               SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
 
1085
               if (SS_DEBUG_INIT) {
 
1086
                     printf("parseInitData: channel %d, volume: %f pan: %d bfL %f bfR %f chON %d s1: %f s2: %f s3: %f s4: %f\n",
 
1087
                              ch,
 
1088
                              channels[ch].volume,
 
1089
                              channels[ch].pan,
 
1090
                              channels[ch].balanceFactorL,
 
1091
                              channels[ch].balanceFactorR,
 
1092
                              channels[ch].channel_on,
 
1093
                              channels[ch].sendfxlevel[0],
 
1094
                              channels[ch].sendfxlevel[1],
 
1095
                              channels[ch].sendfxlevel[2],
 
1096
                              channels[ch].sendfxlevel[3]
 
1097
                              );
 
1098
                     }
 
1099
               if (hasSample) {
 
1100
                     std::string filenametmp = (const char*) ptr;
 
1101
                     ptr+= strlen(filenametmp.c_str()) + 1;
 
1102
                     //printf("We should load %s\n", filenametmp.c_str());
 
1103
                     loadSample(ch, filenametmp.c_str());
 
1104
                     }
 
1105
               else {
 
1106
                     //Clear sample
 
1107
                     clearSample(ch);
 
1108
                     guiNotifySampleCleared(ch);
 
1109
                     }
 
1110
               }
 
1111
      //Master vol:
 
1112
      master_vol_ctrlval = *(ptr);
 
1113
      master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT;
 
1114
      guiUpdateMasterVol(master_vol_ctrlval);
 
1115
      if (SS_DEBUG_INIT) {
 
1116
                  printf("Master vol: %d\n", master_vol_ctrlval);
 
1117
                  }
 
1118
      ptr++;
 
1119
 
 
1120
      // Effects:
 
1121
      if (*(ptr) != SS_SYSEX_INIT_DATA_VERSION) {
 
1122
            fprintf(stderr, "Error loading init data - control byte not found. Skipping...\n");
 
1123
            SS_TRACE_OUT
 
1124
            return;
 
1125
            }
 
1126
      ptr++;
 
1127
 
 
1128
      for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
 
1129
          if (SS_DEBUG_INIT){
 
1130
                  //wilyfoobar-2011-02-13
 
1131
                  // arg2 :pointer diifference might be 64 bit (long long)  on 64 bit machine,  this requires cast to long
 
1132
                  // arg4: *ptr is type byte, not int, this requires format %hhd
 
1133
                  //old code //printf("buffer[%ld] - sendeffect[%d], labelnamelen=%d\n", ptr-data, i, *ptr);
 
1134
                  printf("buffer[%ld] - sendeffect[%d], labelnamelen=%hhd\n", long(ptr-data), i, *ptr);
 
1135
                  }
 
1136
            int labelnamelen = *(ptr);
 
1137
 
 
1138
            if (labelnamelen != SS_NO_PLUGIN) {
 
1139
                  ptr++;
 
1140
                  std::string labelnametmp = (const char*) ptr;
 
1141
                  ptr+= labelnamelen;
 
1142
 
 
1143
                  //int libnamelen = *(ptr);
 
1144
                  ptr++;
 
1145
                  std::string libnametmp = (const char*) ptr;
 
1146
                  ptr+= strlen(libnametmp.c_str()) + 1;
 
1147
 
 
1148
 
 
1149
                  initSendEffect(i, libnametmp.c_str(), labelnametmp.c_str());
 
1150
                  //initSendEffect(0, "cmt", "freeverb3");
 
1151
 
 
1152
                  byte params = *(ptr);
 
1153
                  byte retgain = *(ptr+1);
 
1154
                  ptr+=2;
 
1155
 
 
1156
                  sendEffects[i].nrofparameters = params;
 
1157
 
 
1158
                  sendEffects[i].retgain_ctrlval = retgain;
 
1159
                  sendEffects[i].retgain = retgain;
 
1160
                  sendEffects[i].retgain = (double) retgain/ 75.0;
 
1161
                  MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_PLUGIN_RETURNLEVEL_CONTROLLER(i), retgain);
 
1162
                  gui->writeEvent(ev);
 
1163
 
 
1164
                  for (int j=0; j<params; j++) {
 
1165
                      if (SS_DEBUG_INIT){
 
1166
                          //wilyfoobar-2011-02-13
 
1167
                          // arg2 :pointer diifference might be 64 bit (long long)  on 64 bit machine,  this requires cast to long
 
1168
                          // arg5: *ptr is type byte, not int, this requires format %hhd
 
1169
                          //old code//printf("buffer[%ld] - sendeffect[%d], parameter[%d]=%d\n", long(ptr-data, i, j, *ptr);
 
1170
                          printf("buffer[%ld] - sendeffect[%d], parameter[%d]=%hhd\n", long(ptr-data), i, j, *ptr);
 
1171
                          }
 
1172
                        setFxParameter(i, j, sendEffects[i].plugin->convertGuiControlValue(j, *(ptr)));
 
1173
                        ptr++;
 
1174
                        }
 
1175
                  }
 
1176
            else {
 
1177
                  if (sendEffects[i].plugin)
 
1178
                        cleanupPlugin(i);
 
1179
                  ptr++;
 
1180
                  }
 
1181
            }
 
1182
 
 
1183
      SS_TRACE_OUT
 
1184
      }
 
1185
 
 
1186
/*!
 
1187
    \fn SimpleSynth::loadSample(int chno, const char* filename)
 
1188
 */
 
1189
bool SimpleSynth::loadSample(int chno, const char* filename)
 
1190
      {
 
1191
      SS_TRACE_IN
 
1192
      SS_Channel* ch = &channels[chno];
 
1193
 
 
1194
      // Thread stuff:
 
1195
      SS_SampleLoader* loader = new SS_SampleLoader;
 
1196
      loader->channel = ch;
 
1197
      loader->filename = std::string(filename);
 
1198
      loader->ch_no   = chno;
 
1199
      if (SS_DEBUG) {
 
1200
            printf("Loader filename is: %s\n", filename);
 
1201
            }
 
1202
      pthread_t sampleThread;
 
1203
      pthread_attr_t* attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t));
 
1204
      pthread_attr_init(attributes);
 
1205
      pthread_attr_setdetachstate(attributes, PTHREAD_CREATE_DETACHED);
 
1206
      if (pthread_create(&sampleThread, attributes, ::loadSampleThread, (void*) loader)) {
 
1207
            perror("creating thread failed:");
 
1208
            pthread_attr_destroy(attributes);
 
1209
            delete loader;
 
1210
            return false;
 
1211
            }
 
1212
 
 
1213
      pthread_attr_destroy(attributes);
 
1214
      SS_TRACE_OUT
 
1215
      return true;
 
1216
      }
 
1217
 
 
1218
/*!
 
1219
    \fn loadSampleThread(void* p)
 
1220
    \brief Since process needs to respond withing a certain time, loading of samples need to be done in a separate thread
 
1221
 */
 
1222
static void* loadSampleThread(void* p)
 
1223
      {
 
1224
      SS_TRACE_IN
 
1225
      pthread_mutex_lock(&SS_LoaderMutex);
 
1226
 
 
1227
      // Crit section:
 
1228
      SS_State prevState = synth_state;
 
1229
      SWITCH_SYNTH_STATE(SS_LOADING_SAMPLE);
 
1230
      SS_SampleLoader* loader = (SS_SampleLoader*) p;
 
1231
      SS_Channel* ch = loader->channel;
 
1232
      int ch_no      = loader->ch_no;
 
1233
 
 
1234
      if (ch->sample) {
 
1235
            delete[] ch->sample->data;
 
1236
            delete ch->sample;
 
1237
            }
 
1238
      ch->sample = new SS_Sample;
 
1239
      SS_Sample* smp = ch->sample;
 
1240
 
 
1241
      SNDFILE* sf;
 
1242
      const char* filename = loader->filename.c_str();
 
1243
      SF_INFO sfi;
 
1244
 
 
1245
      if (SS_DEBUG)
 
1246
            printf("loadSampleThread: filename = %s\n", filename);
 
1247
 
 
1248
      sf = sf_open(filename, SFM_READ, &sfi);
 
1249
      if (sf == 0) {
 
1250
            fprintf(stderr,"Error opening file: %s\n", filename);
 
1251
            SWITCH_SYNTH_STATE(prevState);
 
1252
            simplesynth_ptr->guiSendSampleLoaded(false, loader->ch_no, filename);
 
1253
            delete ch->sample; ch->sample = 0;
 
1254
            delete loader;
 
1255
            pthread_mutex_unlock(&SS_LoaderMutex);
 
1256
            SS_TRACE_OUT
 
1257
            pthread_exit(0);
 
1258
            }
 
1259
 
 
1260
      //Print some info:
 
1261
      if (SS_DEBUG) {
 
1262
            printf("Sample info:\n");
 
1263
            printf("Frames: \t%ld\n", (long) sfi.frames);
 
1264
            printf("Channels: \t%d\n", sfi.channels);
 
1265
            printf("Samplerate: \t%d\n", sfi.samplerate);
 
1266
            }
 
1267
 
 
1268
      //
 
1269
      // Allocate and read the thingie
 
1270
      //
 
1271
 
 
1272
      // If current samplerate is the same as MusE's:
 
1273
      if (SS_samplerate == sfi.samplerate) {
 
1274
            smp->data = new float[sfi.channels * sfi.frames];
 
1275
            sf_count_t n = sf_readf_float(sf, smp->data, sfi.frames);
 
1276
            smp->frames = sfi.frames;
 
1277
            smp->samples = (n * sfi.channels);
 
1278
            smp->channels = sfi.channels;
 
1279
            if (SS_DEBUG) {
 
1280
                  printf("%ld frames read\n", (long) n);
 
1281
                  }
 
1282
            }
 
1283
      else  // otherwise, resample:
 
1284
      {
 
1285
            smp->channels = sfi.channels;
 
1286
            // Get new nr of frames:
 
1287
            double srcratio = (double) SS_samplerate/ (double) sfi.samplerate;
 
1288
            smp->frames = (long) floor(((double) sfi.frames * srcratio));
 
1289
            smp->frames = (sfi.channels == 1 ? smp->frames * 2 : smp->frames ); // Double nr of new frames if mono->stereo
 
1290
            smp->samples = smp->frames * smp->channels;
 
1291
 
 
1292
            if (SS_DEBUG) {
 
1293
                  //wilyfoobar-2011-02-13
 
1294
                  // arg2 :sfi.frames is of type sf_count_t (== 64 bit)  (long long)  
 
1295
                  // this requires format %lld (twice 'l' in format string (arg1)
 
1296
                  // old code//printf("Resampling from %ld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
 
1297
                  printf("Resampling from %lld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
 
1298
                  printf("Nr of new samples: %ld\n", smp->samples);
 
1299
                  }
 
1300
 
 
1301
            // Read to temporary:
 
1302
            float temp[sfi.frames * sfi.channels];
 
1303
            int frames_read = sf_readf_float(sf, temp, sfi.frames);
 
1304
            if (frames_read != sfi.frames) {
 
1305
                  fprintf(stderr,"Error reading sample %s\n", filename);
 
1306
                  simplesynth_ptr->guiSendSampleLoaded(false, loader->ch_no, filename);
 
1307
                  sf_close(sf);
 
1308
                  SWITCH_SYNTH_STATE(prevState);
 
1309
                  delete ch->sample; ch->sample = 0;
 
1310
                  delete loader;
 
1311
                  pthread_mutex_unlock(&SS_LoaderMutex);
 
1312
                  pthread_exit(0);
 
1313
                  SS_TRACE_OUT
 
1314
                  }
 
1315
 
 
1316
            // Allocate mem for the new one
 
1317
            smp->data = new float[smp->frames * smp->channels];
 
1318
            memset(smp->data, 0, sizeof(float)* smp->frames * smp->channels);
 
1319
 
 
1320
            // libsamplerate & co (secret rabbits in the code!)
 
1321
            SRC_DATA srcdata;
 
1322
            srcdata.data_in  = temp;
 
1323
            srcdata.data_out = smp->data;
 
1324
            srcdata.input_frames  = sfi.frames;
 
1325
            srcdata.output_frames = smp->frames;
 
1326
            srcdata.src_ratio = (double) SS_samplerate / (double) sfi.samplerate;
 
1327
 
 
1328
            if (SS_DEBUG) {
 
1329
                  printf("Converting sample....\n");
 
1330
                  }
 
1331
 
 
1332
            if (src_simple(&srcdata, SRC_SINC_BEST_QUALITY, sfi.channels)) {
 
1333
                  SS_ERROR("Error when resampling, ignoring current sample");
 
1334
                  //TODO: deallocate and stuff
 
1335
                  }
 
1336
            else if (SS_DEBUG) {
 
1337
                  printf("Sample converted. %ld input frames used, %ld output frames generated\n",
 
1338
                           srcdata.input_frames_used,
 
1339
                           srcdata.output_frames_gen);
 
1340
                  }
 
1341
         }
 
1342
      //Just close the dam thing
 
1343
      sf_close(sf);
 
1344
      SWITCH_SYNTH_STATE(prevState);
 
1345
      ch->sample->filename = loader->filename;
 
1346
      simplesynth_ptr->guiSendSampleLoaded(true, ch_no, filename);
 
1347
      delete loader;
 
1348
      pthread_mutex_unlock(&SS_LoaderMutex);
 
1349
      SS_TRACE_OUT
 
1350
      pthread_exit(0);
 
1351
      }
 
1352
 
 
1353
 
 
1354
//static Mess* instantiate(int sr, const char* name)
 
1355
static Mess* instantiate(int sr, QWidget*, QString* /*projectPathPtr*/, const char* name)
 
1356
      {
 
1357
      printf("SimpleSynth sampleRate %d\n", sr);
 
1358
      SimpleSynth* synth = new SimpleSynth(sr);
 
1359
      if (!synth->init(name)) {
 
1360
            delete synth;
 
1361
            synth = 0;
 
1362
            }
 
1363
      return synth;
 
1364
      }
 
1365
 
 
1366
 
 
1367
/*!
 
1368
    \fn SimpleSynth::updateBalance(int pan)
 
1369
 */
 
1370
void SimpleSynth::updateBalance(int ch, int val)
 
1371
      {
 
1372
      SS_TRACE_IN
 
1373
      channels[ch].pan = val;
 
1374
 
 
1375
      // Balance:
 
1376
      channels[ch].balanceFactorL = 1.0;
 
1377
      channels[ch].balanceFactorR = 1.0;
 
1378
      double offset = 0;
 
1379
      int dev = val - 64;
 
1380
      offset = (double) dev / 64.0;
 
1381
      if (offset < 0) {
 
1382
            channels[ch].balanceFactorR = 1.0 + offset;
 
1383
            }
 
1384
      else {
 
1385
            channels[ch].balanceFactorL = 1.0 - offset;
 
1386
            }
 
1387
 
 
1388
      if (SS_DEBUG_MIDI)
 
1389
            printf("balanceFactorL %f balanceFactorR %f\n", channels[ch].balanceFactorL, channels[ch].balanceFactorR);
 
1390
      SS_TRACE_OUT
 
1391
      }
 
1392
 
 
1393
 
 
1394
/*!
 
1395
    \fn SimpleSynth::updateVolume(int invol_ctrlval)
 
1396
 */
 
1397
void SimpleSynth::updateVolume(int ch, int invol_ctrlval)
 
1398
      {
 
1399
      SS_TRACE_IN
 
1400
      channels[ch].volume = (double)invol_ctrlval/ (double) SS_CHANNEL_VOLUME_QUOT;
 
1401
      channels[ch].volume_ctrlval = invol_ctrlval;
 
1402
      SS_TRACE_OUT
 
1403
      }
 
1404
 
 
1405
 
 
1406
/*!
 
1407
    \fn SimpleSynth::guiUpdateBalance(int ch, int bal)
 
1408
 */
 
1409
void SimpleSynth::guiUpdateBalance(int ch, int bal)
 
1410
      {
 
1411
      SS_TRACE_IN
 
1412
      MidiPlayEvent ev(0, 0, ch, ME_CONTROLLER, SS_CHANNEL_PAN_CONTROLLER(ch), bal);
 
1413
      gui->writeEvent(ev);
 
1414
      SS_TRACE_OUT
 
1415
      }
 
1416
 
 
1417
 
 
1418
/*!
 
1419
    \fn SimpleSynth::guiUpdateVolume(int ch, int val)
 
1420
 */
 
1421
void SimpleSynth::guiUpdateVolume(int ch, int val)
 
1422
      {
 
1423
      SS_TRACE_IN
 
1424
      MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_VOLUME_CONTROLLER(ch), val);
 
1425
      gui->writeEvent(ev);
 
1426
      SS_TRACE_OUT
 
1427
      }
 
1428
 
 
1429
 
 
1430
/*!
 
1431
    \fn SimpleSynth::guiUpdateNoff(bool b)
 
1432
 */
 
1433
void SimpleSynth::guiUpdateNoff(int ch, bool b)
 
1434
      {
 
1435
      SS_TRACE_IN
 
1436
      MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_NOFF_CONTROLLER(ch), b);
 
1437
      gui->writeEvent(ev);
 
1438
      SS_TRACE_OUT
 
1439
      }
 
1440
 
 
1441
 
 
1442
/*!
 
1443
    \fn SimpleSynth::guiUpdateChoff(int ch, bool b)
 
1444
 */
 
1445
void SimpleSynth::guiUpdateChoff(int ch, bool b)
 
1446
      {
 
1447
      SS_TRACE_IN
 
1448
      MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_ONOFF_CONTROLLER(ch), b);
 
1449
      gui->writeEvent(ev);
 
1450
      SS_TRACE_OUT
 
1451
      }
 
1452
 
 
1453
 
 
1454
/*!
 
1455
    \fn SimpleSynth::guiUpdateMasterVol(int val)
 
1456
 */
 
1457
void SimpleSynth::guiUpdateMasterVol(int val)
 
1458
      {
 
1459
      SS_TRACE_IN
 
1460
      MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_MASTER_CTRL_VOLUME, val);
 
1461
      gui->writeEvent(ev);
 
1462
      SS_TRACE_OUT
 
1463
      }
 
1464
 
 
1465
/*!
 
1466
    \fn SimpleSynth::guiUpdateSendFxLevel(int fxid, int level)
 
1467
 */
 
1468
void SimpleSynth::guiUpdateSendFxLevel(int channel, int fxid, int level)
 
1469
      {
 
1470
      SS_TRACE_IN
 
1471
      MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_SENDFX_CONTROLLER(channel, fxid), level);
 
1472
      gui->writeEvent(ev);
 
1473
      SS_TRACE_OUT
 
1474
      }
 
1475
 
 
1476
 
 
1477
/*!
 
1478
    \fn SimpleSynth::guiSendSampleLoaded(int ch, const char* filename)
 
1479
 */
 
1480
void SimpleSynth::guiSendSampleLoaded(bool success, int ch, const char* filename)
 
1481
      {
 
1482
      SS_TRACE_IN
 
1483
      int len = strlen(filename) + 3; //2 + filenamelen + 1;
 
1484
      byte out[len];
 
1485
 
 
1486
      if (success) {
 
1487
            out[0] = SS_SYSEX_LOAD_SAMPLE_OK;
 
1488
            }
 
1489
      else {
 
1490
            out[0] = SS_SYSEX_LOAD_SAMPLE_ERROR;
 
1491
            }
 
1492
      out[1] = ch;
 
1493
      memcpy(out+2, filename, strlen(filename)+1);
 
1494
      MidiPlayEvent ev(0, 0, ME_SYSEX, out, len);
 
1495
      gui->writeEvent(ev);
 
1496
      SS_TRACE_OUT
 
1497
      }
 
1498
 
 
1499
 
 
1500
/*!
 
1501
    \fn SimpleSynth::guiSendError(const char* errorstring)
 
1502
 */
 
1503
void SimpleSynth::guiSendError(const char* errorstring)
 
1504
      {
 
1505
      SS_TRACE_IN
 
1506
      byte out[strlen(errorstring)+2];
 
1507
      out[0] = SS_SYSEX_ERRORMSG;
 
1508
      memcpy(out+1, errorstring, strlen(errorstring) +1);
 
1509
      SS_TRACE_OUT
 
1510
      }
 
1511
 
 
1512
extern "C"
 
1513
      {
 
1514
      static MESS descriptor = {
 
1515
            "SimpleSynth",
 
1516
            "SimpleSynth by Mathias Lundgren",   // (lunar_shuttle@users.sf.net)",
 
1517
            "0.1",      //Version string
 
1518
            MESS_MAJOR_VERSION, MESS_MINOR_VERSION,
 
1519
            instantiate,
 
1520
            };
 
1521
      // We must compile with -fvisibility=hidden to avoid namespace
 
1522
      // conflicts with global variables.
 
1523
      // Only visible symbol is "mess_descriptor".
 
1524
      // (TODO: all plugins should be compiled this way)
 
1525
 
 
1526
      __attribute__ ((visibility("default")))
 
1527
      const MESS* mess_descriptor() { return &descriptor; }
 
1528
      }
 
1529
 
 
1530
 
 
1531
/*!
 
1532
    \fn SimpleSynth::initSendEffect(int sendeffectid, QString lib, QString name)
 
1533
 */
 
1534
bool SimpleSynth::initSendEffect(int id, QString lib, QString name)
 
1535
      {
 
1536
      SS_TRACE_IN
 
1537
      bool success = false;
 
1538
      if (sendEffects[id].plugin) {
 
1539
            //Cleanup if one was already there:
 
1540
            cleanupPlugin(id);
 
1541
            }
 
1542
      sendEffects[id].plugin  = (LadspaPlugin*) plugins.find(lib, name);
 
1543
      LadspaPlugin* plugin = sendEffects[id].plugin;
 
1544
      if (plugin) { //We found one
 
1545
 
 
1546
            sendEffects[id].inputs  = plugin->inports();
 
1547
            sendEffects[id].outputs = plugin->outports();
 
1548
 
 
1549
            if (plugin->instantiate()) {
 
1550
                  SS_DBG2("Plugin instantiated", name.toLatin1().constData());
 
1551
                  SS_DBG_I("Parameters", plugin->parameter());
 
1552
                  SS_DBG_I("No of inputs", plugin->inports());
 
1553
                  SS_DBG_I("No of outputs",plugin->outports());
 
1554
                  SS_DBG_I("Inplace-capable", plugin->inPlaceCapable());
 
1555
 
 
1556
                  // Connect inputs/outputs:
 
1557
                  // If single output/input, only use first channel in sendFxLineOut/sendFxReturn
 
1558
                  SS_DBG("Connecting ports...");
 
1559
                  plugin->connectInport(0, sendFxLineOut[id][0]);
 
1560
                  if (plugin->inports() == 2)
 
1561
                        plugin->connectInport(1, sendFxLineOut[id][1]);
 
1562
                  else if (plugin->inports() > 2) {
 
1563
                        fprintf(stderr, "Plugin has more than 2 inputs, not supported\n");
 
1564
                        }
 
1565
 
 
1566
                  plugin->connectOutport(0, sendFxReturn[id][0]);
 
1567
                  if (plugin->outports() == 2)
 
1568
                        plugin->connectOutport(1, sendFxReturn[id][1]);
 
1569
                  else if (plugin->outports() > 2) {
 
1570
                        fprintf(stderr, "Plugin has more than 2 outputs, not supported\n");
 
1571
                        }
 
1572
                  SS_DBG("Ports connected");
 
1573
                  if (plugin->start()) {
 
1574
                        sendEffects[id].state = SS_SENDFX_ON;
 
1575
                        success = true;
 
1576
 
 
1577
                        int n = plugin->parameter();
 
1578
                        sendEffects[id].nrofparameters = n;
 
1579
 
 
1580
                        // This is not nice, but freeverb doesn't want to play until some values are set:
 
1581
                        if (name == "freeverb3") {
 
1582
                              setFxParameter(id, 2, 0.5);
 
1583
                              setFxParameter(id, 3, 0.5);
 
1584
                              setFxParameter(id, 4, 0.5);
 
1585
                              guiUpdateFxParameter(id, 2, 0.5);
 
1586
                              guiUpdateFxParameter(id, 3, 0.5);
 
1587
                              guiUpdateFxParameter(id, 4, 0.5);
 
1588
                              }
 
1589
                        }
 
1590
                  //TODO: cleanup if failed
 
1591
                  }
 
1592
            }
 
1593
      //Notify gui
 
1594
      int len = 3;
 
1595
      byte out[len];
 
1596
      out[0] = SS_SYSEX_LOAD_SENDEFFECT_OK;
 
1597
      out[1] = id;
 
1598
      int j=0;
 
1599
      for (iPlugin i = plugins.begin(); i!=plugins.end(); i++, j++) {
 
1600
            if ((*i)->lib() == plugin->lib() && (*i)->label() == plugin->label()) {
 
1601
                  out[2] = j;
 
1602
                  MidiPlayEvent ev(0, 0, ME_SYSEX, out, len);
 
1603
                  gui->writeEvent(ev);
 
1604
                  }
 
1605
            }
 
1606
 
 
1607
      if (!success) {
 
1608
            QString errorString = "Error loading plugin \"" + plugin->label() + "\"";
 
1609
            guiSendError(errorString.toLatin1().constData());
 
1610
            }
 
1611
      return success;
 
1612
      SS_TRACE_OUT
 
1613
      }
 
1614
 
 
1615
 
 
1616
/*!
 
1617
    \fn SimpleSynth::setSendFxLevel(int channel, int effectid, double val)
 
1618
 */
 
1619
void SimpleSynth::setSendFxLevel(int channel, int effectid, double val)
 
1620
      {
 
1621
      SS_TRACE_IN
 
1622
      channels[channel].sendfxlevel[effectid] = val;
 
1623
      SS_TRACE_OUT
 
1624
      }
 
1625
 
 
1626
 
 
1627
/*!
 
1628
    \fn SimpleSynth::cleanupPlugin(int id)
 
1629
 */
 
1630
void SimpleSynth::cleanupPlugin(int id)
 
1631
      {
 
1632
      SS_TRACE_IN
 
1633
      LadspaPlugin* plugin = sendEffects[id].plugin;
 
1634
      plugin->stop();
 
1635
      SS_DBG2("Stopped fx", plugin->label().toLatin1().constData());
 
1636
      sendEffects[id].nrofparameters = 0;
 
1637
      sendEffects[id].state = SS_SENDFX_OFF;
 
1638
      sendEffects[id].plugin = 0;
 
1639
 
 
1640
      byte d[2];
 
1641
      d[0] = SS_SYSEX_CLEAR_SENDEFFECT_OK;
 
1642
      d[1] = id;
 
1643
      MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2);
 
1644
      gui->writeEvent(ev);
 
1645
      SS_TRACE_OUT
 
1646
      }
 
1647
 
 
1648
 
 
1649
/*!
 
1650
    \fn SimpleSynth::setFxParameter(int fxid, int param, float val)
 
1651
    \brief Set fx-parameter on plugin and notify gui
 
1652
 */
 
1653
void SimpleSynth::setFxParameter(int fxid, int param, float val)
 
1654
      {
 
1655
      SS_TRACE_IN
 
1656
      LadspaPlugin* plugin = sendEffects[fxid].plugin;
 
1657
      if (SS_DEBUG_LADSPA) {
 
1658
            printf("Setting fx parameter: %f\n", val);
 
1659
            }
 
1660
      plugin->setParam(param, val);
 
1661
      //sendEffects[fxid].parameter[param] = val;
 
1662
      //guiUpdateFxParameter(fxid, param, val);
 
1663
      SS_TRACE_OUT
 
1664
      }
 
1665
 
 
1666
 
 
1667
 
 
1668
/*!
 
1669
    \fn SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val)
 
1670
    \brief Notify gui of changed fx-parameter
 
1671
 */
 
1672
void SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val)
 
1673
      {
 
1674
      SS_TRACE_IN
 
1675
      LadspaPlugin* plugin = sendEffects[fxid].plugin;
 
1676
      float min, max;
 
1677
      plugin->range(param, &min, &max);
 
1678
      //offset:
 
1679
      val-= min;
 
1680
 
 
1681
      int intval = plugin->getGuiControlValue(param);
 
1682
      /*if (plugin->isLog(param)) {
 
1683
            intval = SS_map_logdomain2pluginparam(logf(val/(max - min) + min));
 
1684
            }
 
1685
      else if (plugin->isBool(param)) {
 
1686
            intval = (int) val;
 
1687
            }
 
1688
      else {
 
1689
            float scale = SS_PLUGIN_PARAM_MAX / (max - min);
 
1690
            intval = (int) ((val - min) * scale);
 
1691
            }*/
 
1692
      if (SS_DEBUG_MIDI) {
 
1693
            printf("Updating gui, fx parameter. fxid=%d, param=%d val=%d\n", fxid, param, intval);
 
1694
            }
 
1695
 
 
1696
      byte d[4];
 
1697
      d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER_OK;
 
1698
      d[1] = fxid;
 
1699
      d[2] = param;
 
1700
      d[3] = intval;
 
1701
      MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4);
 
1702
      gui->writeEvent(ev);
 
1703
      SS_TRACE_OUT
 
1704
      }
 
1705
 
 
1706
 
 
1707
/*!
 
1708
    \fn SimpleSynth::clearSample(int ch)
 
1709
    \brief Clears a sample (actually clears a channel)
 
1710
 */
 
1711
void SimpleSynth::clearSample(int ch)
 
1712
      {
 
1713
      SS_TRACE_IN
 
1714
      if (channels[ch].sample) {
 
1715
            if (SS_DEBUG)
 
1716
                  printf("Clearing sample on channel %d\n", ch);
 
1717
            SS_State prevstate = synth_state;
 
1718
            SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
 
1719
            SWITCH_SYNTH_STATE(SS_CLEARING_SAMPLE);
 
1720
            if (channels[ch].sample->data) {
 
1721
                  delete[] channels[ch].sample->data;
 
1722
                  channels[ch].sample->data = 0;
 
1723
                  }
 
1724
            if (channels[ch].sample) {
 
1725
                  delete channels[ch].sample;
 
1726
                  channels[ch].sample = 0;
 
1727
                  }
 
1728
            SWITCH_SYNTH_STATE(prevstate);
 
1729
            guiNotifySampleCleared(ch);
 
1730
            if (SS_DEBUG) {
 
1731
                  printf("Clear sample - sample cleared on channel %d\n", ch);
 
1732
                  }
 
1733
            }
 
1734
      SS_TRACE_OUT
 
1735
      }
 
1736
 
 
1737
 
 
1738
/*!
 
1739
    \fn SimpleSynth::guiNotifySampleCleared(int ch)
 
1740
 */
 
1741
void SimpleSynth::guiNotifySampleCleared(int ch)
 
1742
      {
 
1743
      SS_TRACE_IN
 
1744
      byte d[2];
 
1745
      d[0] = SS_SYSEX_CLEAR_SAMPLE_OK;
 
1746
      d[1] = (byte) ch;
 
1747
      MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2);
 
1748
      gui->writeEvent(ev);
 
1749
      SS_TRACE_OUT
 
1750
      }