2
// C++ Implementation: simplesynth
7
// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004
9
// Copyright: See COPYING file that comes with this distribution
13
#include "muse/midictrl.h"
14
#include "muse/midi.h"
15
//#include "libsynti/mpevent.h"
16
#include "muse/mpevent.h"
17
#include "simpledrums.h"
19
#include <samplerate.h>
21
const char* SimpleSynth::synth_state_descr[] =
29
const char* SimpleSynth::channel_state_descr[] =
31
"SS_CHANNEL_INACTIVE",
35
#define SWITCH_SYNTH_STATE(state)\
36
synth_state = state; \
38
fprintf (stderr, "SS STATE: %s\n", SimpleSynth::synth_state_descr[state]);
40
#define SWITCH_CHAN_STATE(ch, s)\
41
channels[ch].state = s; \
43
fprintf (stderr, "SS CHAN %d STATE: %s\n", ch, SimpleSynth::channel_state_descr[s]);
45
#define SS_CHANNEL_VOLUME_QUOT 100.0
46
#define SS_MASTER_VOLUME_QUOT 100.0
50
#define SS_LOG_MIN -10
51
#define SS_LOG_OFFSET SS_LOG_MIN
55
// Map plugin parameter on domain [SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX] to domain [SS_LOG_MIN, SS_LOG_MAX] (log domain)
57
float SS_map_pluginparam2logdomain(int pluginparam_val)
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;
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)
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);
75
//---------------------------------------------------------
77
//---------------------------------------------------------
78
SimpleSynth::SimpleSynth(int sr)
79
: Mess(SS_AUDIO_CHANNELS)
85
simplesynth_ptr = this;
86
master_vol = 100.0 / SS_MASTER_VOLUME_QUOT;
87
master_vol_ctrlval = 100;
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;
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;
107
processBuffer[0] = new double[SS_PROCESS_BUFFER_SIZE]; //left
108
processBuffer[1] = new double[SS_PROCESS_BUFFER_SIZE]; //right
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
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;
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;
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;
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;
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;
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;
162
controllers[i+4].name = c5.toLatin1().constData();
163
controllers[i+4].num = CTRL_NRPN14_OFFSET+i+4;
165
controllers[i+5].name = c6.toLatin1().constData();
166
controllers[i+5].num = CTRL_NRPN14_OFFSET+i+5;
168
controllers[i+6].name = c7.toLatin1().constData();
169
controllers[i+6].num = CTRL_NRPN14_OFFSET+i+6;
171
controllers[i+7].name = c8.toLatin1().constData();
172
controllers[i+7].num = CTRL_NRPN14_OFFSET+i+7;
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;
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;
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;
195
pthread_mutex_init(&SS_LoaderMutex, NULL);
199
//---------------------------------------------------------
201
//---------------------------------------------------------
202
SimpleSynth::~SimpleSynth()
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;
214
simplesynth_ptr = NULL;
216
SS_DBG("Deleting pluginlist");
218
for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) {
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];
233
SS_DBG("Deleting process buffer");
234
delete[] processBuffer[0];
235
delete[] processBuffer[1];
239
//---------------------------------------------------------
242
\fn SimpleSynth::nativeGuiVisible
243
\brief Tells if the gui is hidden or shown
244
\return true/false if gui is shown/hidden
246
//---------------------------------------------------------
247
bool SimpleSynth::nativeGuiVisible() const
250
bool v = gui->isVisible();
255
//---------------------------------------------------------
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
262
//---------------------------------------------------------
263
bool SimpleSynth::hasNativeGui() const
270
//---------------------------------------------------------
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...)
280
//---------------------------------------------------------
281
bool SimpleSynth::playNote(int /*channel*/, int pitch, int velo)
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;
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;
296
printf("Playing note %d on channel %d\n", pitch, ch);
302
if (channels[ch].noteoff_ignore) {
304
printf("Note off on channel %d\n", ch);
306
SWITCH_CHAN_STATE(ch , SS_CHANNEL_INACTIVE);
307
channels[ch].playoffset = 0;
308
channels[ch].cur_velo = 0;
316
//---------------------------------------------------------
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
324
//---------------------------------------------------------
325
bool SimpleSynth::processEvent(const MidiPlayEvent& ev)
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]);
335
setController(ev.channel(), ev.dataA(), ev.dataB(), false);
338
return playNote(ev.channel(), ev.dataA(), ev.dataB());
340
return playNote(ev.channel(), ev.dataA(), 0);
344
printf("SimpleSynth::processEvent - Sysex received\n");
345
for (int i=0; i< ev.len(); i++)
346
printf("%x ", ev.data()[i]);
349
return sysex(ev.len(), ev.data());
355
//---------------------------------------------------------
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
366
//---------------------------------------------------------
367
bool SimpleSynth::setController(int channel, int id, int val)
371
printf("SimpleSynth::setController - received controller on channel %d, id %d value %d\n", channel, id, val);
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);
382
case SS_CHANNEL_CTRL_VOLUME:
384
printf("Received channel ctrl volume %d for channel %d\n", val, ch);
385
channels[ch].volume_ctrlval = val;
386
updateVolume(ch, val);
388
case SS_CHANNEL_CTRL_NOFF:
390
printf("Received ctrl noff %d for channel %d\n", val, ch);
391
channels[ch].noteoff_ignore = val;
393
case SS_CHANNEL_CTRL_PAN:
396
printf("Received ctrl pan %d for channel %d\n", val, ch);
397
channels[ch].pan = val;
398
updateBalance(ch, val);
401
case SS_CHANNEL_CTRL_ONOFF:
404
printf("Received ctrl onoff %d for channel %d\n", val, ch);
406
if (val == false && channels[ch].channel_on == true) {
407
SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
408
channels[ch].channel_on = val;
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;
417
case SS_CHANNEL_SENDFX1:
418
case SS_CHANNEL_SENDFX2:
419
case SS_CHANNEL_SENDFX3:
420
case SS_CHANNEL_SENDFX4:
422
int fxid = id - SS_CHANNEL_SENDFX1;
423
channels[ch].sendfxlevel[fxid] = (double)val/127.0;
429
printf("Unknown controller received for channel %d. id=%d\n", ch, id);
433
// Master controllers:
434
else if (id >= SS_FIRST_MASTER_CONTROLLER && id <= SS_LAST_MASTER_CONTROLLER) {
436
printf("Mastervol controller received: %d\n", id);
437
master_vol_ctrlval = val;
438
master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT;
440
// Emmm, this one should've been there in the beginning
441
else if (id == CTRL_VOLUME) {
443
printf("Ctrl volume received: vol: %d\n", val);
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);
450
// Plugin controllers:
451
else if (id >= SS_FIRST_PLUGIN_CONTROLLER && id <= SS_LAST_PLUGIN_CONTROLLER) {
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;
456
// Plugin return-gain:
457
if (cmd == SS_PLUGIN_RETURN) {
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;
464
else if (cmd == SS_PLUGIN_ONOFF) {
466
printf("Ctrl fx onoff received: fxid: %d val: %d\n", fxid, val);
467
sendEffects[fxid].state = (SS_SendFXState) val;
472
printf("Unknown controller received: %d\n", id);
478
//---------------------------------------------------------
480
\fn SimpleSynth::setController
482
//---------------------------------------------------------
483
bool SimpleSynth::setController(int channel, int id, int val, bool /*fromGui*/)
486
bool ret = setController(channel, id, val); //Perhaps TODO... Separate events from the gui
490
//---------------------------------------------------------
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
499
//---------------------------------------------------------
500
bool SimpleSynth::sysex(int /*len*/, const unsigned char* data)
505
case SS_SYSEX_LOAD_SAMPLE:
507
int channel = data[1];
509
const char* filename = (const char*)(data+3);
511
printf("Sysex cmd: load sample, filename %s, on channel: %d\n", filename, channel);
513
loadSample(channel, filename);
516
case SS_SYSEX_CLEAR_SAMPLE:
523
case SS_SYSEX_INIT_DATA:
529
case SS_SYSEX_LOAD_SENDEFFECT:
532
QString lib = (const char*) (data + 2);
533
QString label = (const char*) (data + lib.length() + 3);
535
printf("Sysex cmd load effect: %d %s %s\n", fxid, lib.toLatin1().constData(), label.toLatin1().constData());
537
initSendEffect(fxid, lib, label);
541
case SS_SYSEX_CLEAR_SENDEFFECT:
545
printf("Sysex cmd clear effect: %d\n", fxid);
547
sendEffects[fxid].state = SS_SENDFX_OFF;
549
sendEffects[fxid].plugin = 0;
553
case SS_SYSEX_SET_PLUGIN_PARAMETER:
556
int parameter = data[2];
558
// Write it to the plugin:
559
float floatval = sendEffects[fxid].plugin->convertGuiControlValue(parameter, val);
560
setFxParameter(fxid, parameter, floatval);
564
case SS_SYSEX_GET_INIT_DATA:
566
int initdata_len = 0;
567
const byte* tmp_initdata = NULL;
568
byte* event_data = NULL;
570
getInitData(&initdata_len, &tmp_initdata);
571
int totlen = initdata_len + 1;
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;
579
MidiPlayEvent ev(0, 0, ME_SYSEX, event_data, totlen);
588
printf("Unknown sysex cmd received: %d\n", cmd);
595
//---------------------------------------------------------
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
603
//---------------------------------------------------------
604
const char* SimpleSynth::getPatchName(int /*index*/, int, int) const
611
//---------------------------------------------------------
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
620
//---------------------------------------------------------
621
const MidiPatch* SimpleSynth::getPatchInfo(int index, const MidiPatch* patch) const
624
index = 0; patch = 0;
629
//---------------------------------------------------------
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
641
//---------------------------------------------------------
642
int SimpleSynth::getControllerInfo(int index, const char** name, int* controller, int* min, int* max)
645
if (index >= SS_NR_OF_CONTROLLERS) {
650
*name = controllers[index].name.c_str();
651
*controller = controllers[index].num;
652
*min = controllers[index].min;
653
*max = controllers[index].max;
656
printf("setting controller info: index %d name %s controller %d min %d max %d\n", index, *name, *controller, *min, *max);
662
//---------------------------------------------------------
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
671
//---------------------------------------------------------
672
void SimpleSynth::process(float** out, int offset, int len)
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());
681
else if (ev.type() == ME_CONTROLLER) {
682
setController(ev.channel(), ev.dataA(), ev.dataB(), true);
687
printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type());
691
if (synth_state == SS_RUNNING) {
693
//Temporary mix-doubles
695
//double ltemp, rtemp;
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));
710
memset(out[0] + offset, 0, len * sizeof(float));
711
memset(out[1] + offset, 0, len * sizeof(float));
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)
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));
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:
730
if (channels[ch].sample->channels == 2) {
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;
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++;
748
processBuffer[0][i] = out1;
749
processBuffer[1][i] = out2;
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]);
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);
763
//Effects with 0 or >2 inputs are ignored
768
// If we've reached the last sample, set state to inactive
770
if (channels[ch].playoffset >= channels[ch].sample->samples) {
771
SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE);
772
channels[ch].playoffset = 0;
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];
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);
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]);
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);
810
//---------------------------------------------------------
813
\fn SimpleSynth::showNativeGui
814
\brief Displays or hides the gui window
815
\param val true or false = gui shown or hidden
817
//---------------------------------------------------------
818
void SimpleSynth::showNativeGui(bool val)
821
gui->setVisible(val);
825
//---------------------------------------------------------
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
832
//---------------------------------------------------------
833
bool SimpleSynth::init(const char* name)
836
SWITCH_SYNTH_STATE(SS_INITIALIZING);
837
gui = new SimpleSynthGui();
839
gui->setWindowTitle(name);
840
SWITCH_SYNTH_STATE(SS_RUNNING);
845
//---------------------------------------------------------
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
852
//---------------------------------------------------------
853
void SimpleSynth::getInitData(int* n, const unsigned char** data)
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;
866
len++; //Add place for SS_NO_SAMPLE
868
len+=3; // 1 place for SS_SYSEX_INIT_DATA, 1 byte for master vol, 1 byte for version data
870
// Effect data length
871
len++; //Add place for SS_SYSEX_INIT_DATA_VERSION, as control
873
for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
874
Plugin* plugin = sendEffects[i].plugin;
876
int namelen = plugin->lib().size() + 2;
877
int labelnamelen = plugin->label().size() + 2;
878
len+=(namelen + labelnamelen);
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
884
len++; //place for SS_NO_PLUGIN
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;
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);
900
// 0 - volume ctrlval (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);
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));
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);
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]);
939
i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1 + filenamelen);
942
buffer[i+8] = SS_NO_SAMPLE;
944
printf("buffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE);
946
i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1);
950
printf("buffer[%d]: Master vol: - %d\n", i, master_vol_ctrlval);
952
buffer[i] = master_vol_ctrlval;
953
*(data) = buffer; *n = len;
957
buffer[i] = SS_SYSEX_INIT_DATA_VERSION; //Just for check
959
printf("buffer[%d]: Control value, SS_SYSEX_INIT_DATA_VERSION\n", 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);
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]);
977
i+=(labelnamelen + 1);
979
int namelen = sendEffects[j].plugin->lib().size() + 1;
981
memcpy((buffer+i+1), sendEffects[j].plugin->lib().toLatin1().constData(), namelen);
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]);
993
buffer[i]=sendEffects[j].nrofparameters;
995
printf("buffer[%d]: sendEffects[%d].nrofparameters=%d\n", i, j, buffer[i]);
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]);
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]);
1014
// No plugin loaded:
1016
buffer[i] = SS_NO_PLUGIN;
1017
if (SS_DEBUG_INIT) {
1018
printf("buffer[%d]: SS_NO_PLUGIN\n", i);
1029
\fn SimpleSynth::parseInitData()
1031
void SimpleSynth::parseInitData(const unsigned char* data)
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));
1038
const byte* ptr = data+2;
1039
for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
1040
channels[ch].volume_ctrlval = (byte) *(ptr);
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
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));
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));
1058
updateVolume(ch, *(ptr));
1059
guiUpdateVolume(ch, *(ptr));
1061
channels[ch].pan = *(ptr+1);
1062
updateBalance(ch, *(ptr+1));
1063
guiUpdateBalance(ch, *(ptr+1));
1065
channels[ch].noteoff_ignore = *(ptr+2);
1066
guiUpdateNoff(ch, *(ptr+2));
1068
channels[ch].channel_on = *(ptr+3);
1069
guiUpdateChoff(ch, *(ptr+3));
1073
for (int i=0; i<4; i++) {
1074
channels[ch].sendfxlevel[i] = (float) (*(ptr)/127.0);
1075
guiUpdateSendFxLevel(ch, i, *(ptr));
1079
bool hasSample = *(ptr);
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",
1088
channels[ch].volume,
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]
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());
1108
guiNotifySampleCleared(ch);
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);
1121
if (*(ptr) != SS_SYSEX_INIT_DATA_VERSION) {
1122
fprintf(stderr, "Error loading init data - control byte not found. Skipping...\n");
1128
for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) {
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);
1136
int labelnamelen = *(ptr);
1138
if (labelnamelen != SS_NO_PLUGIN) {
1140
std::string labelnametmp = (const char*) ptr;
1143
//int libnamelen = *(ptr);
1145
std::string libnametmp = (const char*) ptr;
1146
ptr+= strlen(libnametmp.c_str()) + 1;
1149
initSendEffect(i, libnametmp.c_str(), labelnametmp.c_str());
1150
//initSendEffect(0, "cmt", "freeverb3");
1152
byte params = *(ptr);
1153
byte retgain = *(ptr+1);
1156
sendEffects[i].nrofparameters = params;
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);
1164
for (int j=0; j<params; j++) {
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);
1172
setFxParameter(i, j, sendEffects[i].plugin->convertGuiControlValue(j, *(ptr)));
1177
if (sendEffects[i].plugin)
1187
\fn SimpleSynth::loadSample(int chno, const char* filename)
1189
bool SimpleSynth::loadSample(int chno, const char* filename)
1192
SS_Channel* ch = &channels[chno];
1195
SS_SampleLoader* loader = new SS_SampleLoader;
1196
loader->channel = ch;
1197
loader->filename = std::string(filename);
1198
loader->ch_no = chno;
1200
printf("Loader filename is: %s\n", filename);
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);
1213
pthread_attr_destroy(attributes);
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
1222
static void* loadSampleThread(void* p)
1225
pthread_mutex_lock(&SS_LoaderMutex);
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;
1235
delete[] ch->sample->data;
1238
ch->sample = new SS_Sample;
1239
SS_Sample* smp = ch->sample;
1242
const char* filename = loader->filename.c_str();
1246
printf("loadSampleThread: filename = %s\n", filename);
1248
sf = sf_open(filename, SFM_READ, &sfi);
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;
1255
pthread_mutex_unlock(&SS_LoaderMutex);
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);
1269
// Allocate and read the thingie
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;
1280
printf("%ld frames read\n", (long) n);
1283
else // otherwise, resample:
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;
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);
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);
1308
SWITCH_SYNTH_STATE(prevState);
1309
delete ch->sample; ch->sample = 0;
1311
pthread_mutex_unlock(&SS_LoaderMutex);
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);
1320
// libsamplerate & co (secret rabbits in the code!)
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;
1329
printf("Converting sample....\n");
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
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);
1342
//Just close the dam thing
1344
SWITCH_SYNTH_STATE(prevState);
1345
ch->sample->filename = loader->filename;
1346
simplesynth_ptr->guiSendSampleLoaded(true, ch_no, filename);
1348
pthread_mutex_unlock(&SS_LoaderMutex);
1354
//static Mess* instantiate(int sr, const char* name)
1355
static Mess* instantiate(int sr, QWidget*, QString* /*projectPathPtr*/, const char* name)
1357
printf("SimpleSynth sampleRate %d\n", sr);
1358
SimpleSynth* synth = new SimpleSynth(sr);
1359
if (!synth->init(name)) {
1368
\fn SimpleSynth::updateBalance(int pan)
1370
void SimpleSynth::updateBalance(int ch, int val)
1373
channels[ch].pan = val;
1376
channels[ch].balanceFactorL = 1.0;
1377
channels[ch].balanceFactorR = 1.0;
1380
offset = (double) dev / 64.0;
1382
channels[ch].balanceFactorR = 1.0 + offset;
1385
channels[ch].balanceFactorL = 1.0 - offset;
1389
printf("balanceFactorL %f balanceFactorR %f\n", channels[ch].balanceFactorL, channels[ch].balanceFactorR);
1395
\fn SimpleSynth::updateVolume(int invol_ctrlval)
1397
void SimpleSynth::updateVolume(int ch, int invol_ctrlval)
1400
channels[ch].volume = (double)invol_ctrlval/ (double) SS_CHANNEL_VOLUME_QUOT;
1401
channels[ch].volume_ctrlval = invol_ctrlval;
1407
\fn SimpleSynth::guiUpdateBalance(int ch, int bal)
1409
void SimpleSynth::guiUpdateBalance(int ch, int bal)
1412
MidiPlayEvent ev(0, 0, ch, ME_CONTROLLER, SS_CHANNEL_PAN_CONTROLLER(ch), bal);
1413
gui->writeEvent(ev);
1419
\fn SimpleSynth::guiUpdateVolume(int ch, int val)
1421
void SimpleSynth::guiUpdateVolume(int ch, int val)
1424
MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_VOLUME_CONTROLLER(ch), val);
1425
gui->writeEvent(ev);
1431
\fn SimpleSynth::guiUpdateNoff(bool b)
1433
void SimpleSynth::guiUpdateNoff(int ch, bool b)
1436
MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_NOFF_CONTROLLER(ch), b);
1437
gui->writeEvent(ev);
1443
\fn SimpleSynth::guiUpdateChoff(int ch, bool b)
1445
void SimpleSynth::guiUpdateChoff(int ch, bool b)
1448
MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_ONOFF_CONTROLLER(ch), b);
1449
gui->writeEvent(ev);
1455
\fn SimpleSynth::guiUpdateMasterVol(int val)
1457
void SimpleSynth::guiUpdateMasterVol(int val)
1460
MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_MASTER_CTRL_VOLUME, val);
1461
gui->writeEvent(ev);
1466
\fn SimpleSynth::guiUpdateSendFxLevel(int fxid, int level)
1468
void SimpleSynth::guiUpdateSendFxLevel(int channel, int fxid, int level)
1471
MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_SENDFX_CONTROLLER(channel, fxid), level);
1472
gui->writeEvent(ev);
1478
\fn SimpleSynth::guiSendSampleLoaded(int ch, const char* filename)
1480
void SimpleSynth::guiSendSampleLoaded(bool success, int ch, const char* filename)
1483
int len = strlen(filename) + 3; //2 + filenamelen + 1;
1487
out[0] = SS_SYSEX_LOAD_SAMPLE_OK;
1490
out[0] = SS_SYSEX_LOAD_SAMPLE_ERROR;
1493
memcpy(out+2, filename, strlen(filename)+1);
1494
MidiPlayEvent ev(0, 0, ME_SYSEX, out, len);
1495
gui->writeEvent(ev);
1501
\fn SimpleSynth::guiSendError(const char* errorstring)
1503
void SimpleSynth::guiSendError(const char* errorstring)
1506
byte out[strlen(errorstring)+2];
1507
out[0] = SS_SYSEX_ERRORMSG;
1508
memcpy(out+1, errorstring, strlen(errorstring) +1);
1514
static MESS descriptor = {
1516
"SimpleSynth by Mathias Lundgren", // (lunar_shuttle@users.sf.net)",
1517
"0.1", //Version string
1518
MESS_MAJOR_VERSION, MESS_MINOR_VERSION,
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)
1526
__attribute__ ((visibility("default")))
1527
const MESS* mess_descriptor() { return &descriptor; }
1532
\fn SimpleSynth::initSendEffect(int sendeffectid, QString lib, QString name)
1534
bool SimpleSynth::initSendEffect(int id, QString lib, QString name)
1537
bool success = false;
1538
if (sendEffects[id].plugin) {
1539
//Cleanup if one was already there:
1542
sendEffects[id].plugin = (LadspaPlugin*) plugins.find(lib, name);
1543
LadspaPlugin* plugin = sendEffects[id].plugin;
1544
if (plugin) { //We found one
1546
sendEffects[id].inputs = plugin->inports();
1547
sendEffects[id].outputs = plugin->outports();
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());
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");
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");
1572
SS_DBG("Ports connected");
1573
if (plugin->start()) {
1574
sendEffects[id].state = SS_SENDFX_ON;
1577
int n = plugin->parameter();
1578
sendEffects[id].nrofparameters = n;
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);
1590
//TODO: cleanup if failed
1596
out[0] = SS_SYSEX_LOAD_SENDEFFECT_OK;
1599
for (iPlugin i = plugins.begin(); i!=plugins.end(); i++, j++) {
1600
if ((*i)->lib() == plugin->lib() && (*i)->label() == plugin->label()) {
1602
MidiPlayEvent ev(0, 0, ME_SYSEX, out, len);
1603
gui->writeEvent(ev);
1608
QString errorString = "Error loading plugin \"" + plugin->label() + "\"";
1609
guiSendError(errorString.toLatin1().constData());
1617
\fn SimpleSynth::setSendFxLevel(int channel, int effectid, double val)
1619
void SimpleSynth::setSendFxLevel(int channel, int effectid, double val)
1622
channels[channel].sendfxlevel[effectid] = val;
1628
\fn SimpleSynth::cleanupPlugin(int id)
1630
void SimpleSynth::cleanupPlugin(int id)
1633
LadspaPlugin* plugin = sendEffects[id].plugin;
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;
1641
d[0] = SS_SYSEX_CLEAR_SENDEFFECT_OK;
1643
MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2);
1644
gui->writeEvent(ev);
1650
\fn SimpleSynth::setFxParameter(int fxid, int param, float val)
1651
\brief Set fx-parameter on plugin and notify gui
1653
void SimpleSynth::setFxParameter(int fxid, int param, float val)
1656
LadspaPlugin* plugin = sendEffects[fxid].plugin;
1657
if (SS_DEBUG_LADSPA) {
1658
printf("Setting fx parameter: %f\n", val);
1660
plugin->setParam(param, val);
1661
//sendEffects[fxid].parameter[param] = val;
1662
//guiUpdateFxParameter(fxid, param, val);
1669
\fn SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val)
1670
\brief Notify gui of changed fx-parameter
1672
void SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val)
1675
LadspaPlugin* plugin = sendEffects[fxid].plugin;
1677
plugin->range(param, &min, &max);
1681
int intval = plugin->getGuiControlValue(param);
1682
/*if (plugin->isLog(param)) {
1683
intval = SS_map_logdomain2pluginparam(logf(val/(max - min) + min));
1685
else if (plugin->isBool(param)) {
1689
float scale = SS_PLUGIN_PARAM_MAX / (max - min);
1690
intval = (int) ((val - min) * scale);
1692
if (SS_DEBUG_MIDI) {
1693
printf("Updating gui, fx parameter. fxid=%d, param=%d val=%d\n", fxid, param, intval);
1697
d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER_OK;
1701
MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4);
1702
gui->writeEvent(ev);
1708
\fn SimpleSynth::clearSample(int ch)
1709
\brief Clears a sample (actually clears a channel)
1711
void SimpleSynth::clearSample(int ch)
1714
if (channels[ch].sample) {
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;
1724
if (channels[ch].sample) {
1725
delete channels[ch].sample;
1726
channels[ch].sample = 0;
1728
SWITCH_SYNTH_STATE(prevstate);
1729
guiNotifySampleCleared(ch);
1731
printf("Clear sample - sample cleared on channel %d\n", ch);
1739
\fn SimpleSynth::guiNotifySampleCleared(int ch)
1741
void SimpleSynth::guiNotifySampleCleared(int ch)
1745
d[0] = SS_SYSEX_CLEAR_SAMPLE_OK;
1747
MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2);
1748
gui->writeEvent(ev);