Guitarix
gx_internal_plugins.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * --------------------------------------------------------------------------
19  *
20  *
21  * This is part of the Guitarix Audio Engine
22  *
23  *
24  *
25  * --------------------------------------------------------------------------
26  */
27 
28 #include "engine.h"
29 #include "gx_faust_support.h"
30 
31 namespace gx_engine {
32 
33 /****************************************************************
34  ** class NoiseGate
35  */
36 
37 PluginDef NoiseGate::inputdef = PluginDef();
38 float NoiseGate::fnglevel = 0;
39 float NoiseGate::ngate = 1;
40 bool NoiseGate::off = true;
43 
45 
46  inputdef.version = PLUGINDEF_VERSION;
47  inputdef.flags = PGN_SNOOP;
48  inputdef.id = "noise_gate";
49  inputdef.name = N_("Noise Gate");
50  inputdef.mono_audio = inputlevel_compute;
51  inputdef.register_params = noisegate_register;
52 
53  inputlevel.set_pdef(&inputdef);
54 
56  outputgate.id = "noiseshut";
57  outputgate.name = "?noiseshut";
58  outputgate.mono_audio = outputgate_compute;
59  outputgate.activate_plugin = outputgate_activate;
60 
61 }
62 
63 inline float sqrf(float x) {
64  return x * x;
65 }
66 
67 void NoiseGate::inputlevel_compute(int count, float *input, float *output, PluginDef*) {
68  float sumnoise = 0;
69  for (int i = 0; i < count; i++) {
70  sumnoise += sqrf(input[i]);
71  }
72  if (sumnoise/count > sqrf(fnglevel * 0.01)) {
73  ngate = 1; // -75db 0.001 = 65db
74  } else if (ngate > 0.01) {
75  ngate *= 0.996;
76  }
77 }
78 
79 int NoiseGate::noisegate_register(const ParamReg& reg) {
80  reg.registerVar("noise_gate.threshold", N_("Threshold"), "S", "", &fnglevel,
81  0.017f, 0.01f, 0.31f, 0.001f);
82  return 0;
83 }
84 
85 void NoiseGate::outputgate_compute(int count, float *input, float *output, PluginDef*) {
86  if (off) {
87  return;
88  }
89  while (count--) {
90  *output++ = ngate * *input++;
91  }
92 }
93 
94 int NoiseGate::outputgate_activate(bool start, PluginDef *pdef) {
95  if (start) {
96  off = !inputlevel.get_on_off();
97  }
98  return 0;
99 }
100 
101 /****************************************************************
102  ** class GxSeqSettings
103  */
104 
106  : seqline() {
107 }
108 
110  seqline = seqset.seqline;
111  return *this;
112 }
113 
115  w.begin_object(true);
116  w.write_key("seq.seqline");
117  w.begin_array();
118  for (unsigned int i = 0; i < seqline.size(); i++) {
119  w.write(seqline[i]);
120  }
121  w.end_array(true);
122  w.end_object(true);
123 }
124 
125 bool GxSeqSettings::operator==(const GxSeqSettings& seqset) const {
126  if (seqline != seqset.seqline) {
127  return false;
128  }
129  return true;
130 }
131 
132 void GxSeqSettings::read_seqline(gx_system::JsonParser& jp) {
133  seqline.clear();
135  while (jp.peek() == gx_system::JsonParser::value_number) {
137  int p = jp.current_value_int();
138  seqline.push_back(p);
139  }
141 }
142 
145  do {
147  if (jp.current_value() == "seq.seqline") {
148  read_seqline(jp);
149  } else {
150  gx_print_warning("seq settings", "unknown key: " + jp.current_value());
151  jp.skip_object();
152  }
153  } while (jp.peek() == gx_system::JsonParser::value_key);
155 }
156 
157 /****************************************************************
158  ** class SeqParameter
159  */
160 
162  : Parameter(id, "", tp_special, None, true, false),
163  json_value(),
164  value(v),
165  std_value(),
166  value_storage(),
167  changed() {
168  std_value.seqline = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
169 }
170 
172  ParamMap &pmap, const string& id, GxSeqSettings *v) {
173  SeqParameter *p = new SeqParameter(id, v);
174  pmap.insert(p);
175  return p;
176 }
177 
179 }
180 
182  : Parameter(jp_next(jp, "Parameter")),
183  json_value(),
184  value(&value_storage),
185  std_value() {
186  while (jp.peek() != gx_system::JsonParser::end_object) {
188  if (jp.current_value() == "value") {
189  value->readJSON(jp);
190  } else if (jp.current_value() == "std_value") {
191  std_value.readJSON(jp);
192  } else {
194  "SeqParameter", Glib::ustring::compose("%1: unknown key: %2", _id, jp.current_value()));
195  jp.skip_object();
196  }
197  }
199 }
200 
202  jw.begin_object();
203  jw.write_key("Parameter"); Parameter::serializeJSON(jw);
204  jw.write_key("value"); value->writeJSON(jw);
205  jw.write_key("std_value"); std_value.writeJSON(jw);
206  jw.end_object();
207 }
208 
210  assert(false);
211  return false;
212 }
213 
215  json_value = std_value;
216 }
217 
219  jw.write_key(_id.c_str());
220  value->writeJSON(jw);
221 }
222 
224  json_value.readJSON(jp);
225 }
226 
228  return json_value == *value;
229 }
230 
231 bool SeqParameter::set(const GxSeqSettings& val) const {
232  if (val == *value) {
233  return false;
234  }
235  *value = val;
236  changed(value);
237  return true;
238 }
239 
241  set(json_value);
242 }
243 
244 /****************************************************************
245  ** class GxJConvSettings
246  */
247 
249  : fIRFile(),
250  fIRDir(),
251  fGain(0),
252  fOffset(0),
253  fLength(0),
254  fDelay(0),
255  gainline(),
256  fGainCor(false) {
257 }
258 
260  fIRFile = jcset.fIRFile;
261  fIRDir = jcset.fIRDir;
262  fGain = jcset.fGain;
263  fOffset = jcset.fOffset;
264  fLength = jcset.fLength;
265  fDelay = jcset.fDelay;
266  gainline = jcset.gainline;
267  fGainCor = jcset.fGainCor;
268  return *this;
269 }
270 
271 std::string GxJConvSettings::getFullIRPath() const {
272  if (fIRFile.empty()) {
273  return fIRFile;
274  } else {
275  return Glib::build_filename(fIRDir, fIRFile);
276  }
277 }
278 
280  fIRDir = Glib::path_get_dirname(name);
281  fIRFile= Glib::path_get_basename(name);
282 }
283 
285  w.begin_object(true);
286  w.write_kv("jconv.IRFile", fIRFile);
287  w.write_kv("jconv.IRDir", gx_system::get_options().get_IR_prefixmap().replace_path(fIRDir));
288  w.write_kv("jconv.Gain", fGain);
289  w.write_kv("jconv.GainCor", fGainCor);
290  w.write_kv("jconv.Offset", fOffset);
291  w.write_kv("jconv.Length", fLength);
292  w.write_kv("jconv.Delay", fDelay);
293  w.write_key("jconv.gainline");
294  w.begin_array();
295  for (unsigned int i = 0; i < gainline.size(); i++) {
296  w.begin_array();
297  w.write(gainline[i].i);
298  w.write(gainline[i].g);
299  w.end_array();
300  }
301  w.end_array(true);
302  w.end_object(true);
303 }
304 
306  if (fIRFile != jcset.fIRFile || fIRDir != jcset.fIRDir) {
307  return false;
308  }
309  if (fOffset != jcset.fOffset || fLength != jcset.fLength || fDelay != jcset.fDelay) {
310  return false;
311  }
312  if (fGainCor != jcset.fGainCor) {
313  return false;
314  }
315  if (fGainCor && std::abs(fGain - jcset.fGain) > 1e-4 * (fGain + jcset.fGain)) {
316  return false;
317  }
318  if (gainline == jcset.gainline) {
319  return false;
320  }
321  return true;
322 }
323 
324 void GxJConvSettings::read_gainline(gx_system::JsonParser& jp) {
325  gainline.clear();
327  while (jp.peek() == gx_system::JsonParser::begin_array) {
328  jp.next();
330  gain_points p;
331  p.i = jp.current_value_int();
333  p.g = jp.current_value_float();
335  gainline.push_back(p);
336  }
338 }
339 
342  do {
344  if (jp.read_kv("jconv.IRFile", fIRFile) ||
345  jp.read_kv("jconv.IRDir", fIRDir) ||
346  jp.read_kv("jconv.Gain", fGain) ||
347  jp.read_kv("jconv.GainCor", fGainCor) ||
348  jp.read_kv("jconv.Offset", fOffset) ||
349  jp.read_kv("jconv.Length", fLength) ||
350  jp.read_kv("jconv.Delay", fDelay)) {
351  } else if (jp.current_value() == "jconv.gainline") {
352  read_gainline(jp);
353  } else if (jp.current_value() == "jconv.favorits") {
354  jp.skip_object();
355  } else {
356  gx_print_warning("jconv settings", "unknown key: " + jp.current_value());
357  jp.skip_object();
358  }
359  } while (jp.peek() == gx_system::JsonParser::value_key);
361  if (!fIRFile.empty()) {
362  if (fIRDir.empty()) {
363  gx_system::get_options().get_IR_pathlist().find_dir(&fIRDir, fIRFile);
364  } else {
366  }
367  }
368 }
369 
370 
371 /****************************************************************
372  ** class JConvParameter
373  */
374 
376  : Parameter(id, "", tp_special, None, true, false),
377  json_value(),
378  value(v),
379  std_value(),
380  value_storage(),
381  changed() {
382  std_value.setFullIRPath(gx_system::get_options().get_IR_prefixmap().replace_symbol("%S/greathall.wav"));
383  std_value.fGainCor = true;
384  std_value.fGain = 0.598717;
385  const int ir_len = 112561;
386  std_value.fLength = ir_len;
387  static gain_points g[2] = {{0, 0}, {ir_len-1, 0}};
388  std_value.gainline = Gainline(g, sizeof(g) / sizeof(g[0]));
389 }
390 
392  ParamMap &pmap, const string& id, ConvolverAdapter &conv, GxJConvSettings *v) {
393  JConvParameter *p = new JConvParameter(id, conv, v);
394  pmap.insert(p);
395  return p;
396 }
397 
399 }
400 
402  : Parameter(jp_next(jp, "Parameter")),
403  searchpath(0),
404  pfx_conv(0),
405  json_value(),
406  value(&value_storage),
407  std_value() {
408  while (jp.peek() != gx_system::JsonParser::end_object) {
410  if (jp.current_value() == "value") {
411  value->readJSON(jp);
412  } else if (jp.current_value() == "std_value") {
413  std_value.readJSON(jp);
414  } else {
416  "JConvParameter", Glib::ustring::compose("%1: unknown key: %2", _id, jp.current_value()));
417  jp.skip_object();
418  }
419  }
421 }
422 
424  jw.begin_object();
425  jw.write_key("Parameter"); Parameter::serializeJSON(jw);
426  jw.write_key("value"); value->writeJSON(jw);
427  jw.write_key("std_value"); std_value.writeJSON(jw);
428  jw.end_object();
429 }
430 
432  assert(false);
433  return false;
434 }
435 
437  json_value = std_value;
438 }
439 
441  jw.write_key(_id.c_str());
442  value->writeJSON(jw);
443 }
444 
446  json_value.readJSON(jp);
447 }
448 
450  return json_value == *value;
451 }
452 
453 bool JConvParameter::set(const GxJConvSettings& val) const {
454  if (val == *value) {
455  return false;
456  }
457  *value = val;
458  changed(value);
459  return true;
460 }
461 
463  set(json_value);
464 }
465 
466 
467 /****************************************************************
468  ** class ConvolverAdapter
469  */
470 
471 #include "faust/jconv_post.cc"
472 #include "faust/jconv_post_mono.cc"
473 
475  EngineControl& engine_, sigc::slot<void> sync_, ParamMap& param_)
476  : PluginDef(),
477  conv(),
478  activate_mutex(),
479  engine(engine_),
480  sync(sync_),
481  param(param_),
482  activated(false),
483  jcset(),
484  jcp(0),
485  plugin() {
487  category = N_("Reverb");
488  //FIXME: add clear_state
489  plugin = this;
491  sigc::mem_fun(*this, &ConvolverAdapter::change_buffersize));
492 }
493 
495 }
496 
497 void ConvolverAdapter::change_buffersize(unsigned int size) {
498  boost::mutex::scoped_lock lock(activate_mutex);
499  if (activated) {
500  conv.stop_process();
501  while (conv.is_runnable()) {
502  conv.checkstate();
503  }
504  conv.set_buffersize(size);
505  if (size) {
506  conv_start();
507  }
508  } else {
509  conv.set_buffersize(size);
510  }
511 }
512 
514  if (!plugin.get_on_off()) {
515  return;
516  }
517  conv.set_not_runnable();
518  sync();
519  conv.stop_process();
520  while (!conv.checkstate());
521  float gain;
522  if (jcset.getGainCor()) {
523  gain = jcset.getGain();
524  } else {
525  gain = 1.0;
526  }
527  bool rc = conv.configure(
528  jcset.getFullIRPath(), gain, gain, jcset.getDelay(), jcset.getDelay(),
530  int policy, priority;
531  engine.get_sched_priority(policy, priority);
532  if (!rc || !conv.start(policy, priority)) {
533  plugin.set_on_off(false);
534  }
535 }
536 
538  if (!conv.get_buffersize() || !conv.get_samplerate()) {
539  return false;
540  }
541  string path = jcset.getFullIRPath();
542  if (path.empty()) {
543  gx_print_warning(_("convolver"), _("no impulseresponse file"));
544  plugin.set_on_off(false);
545  return false;
546  }
547  while (!conv.checkstate());
548  if (conv.is_runnable()) {
549  return true;
550  }
551  float gain;
552  if (jcset.getGainCor()) {
553  gain = jcset.getGain();
554  } else {
555  gain = 1.0;
556  }
557  if (!conv.configure(
558  path, gain, gain, jcset.getDelay(), jcset.getDelay(),
559  jcset.getOffset(), jcset.getLength(), 0, 0, jcset.getGainline())) {
560  return false;
561  }
562  int policy, priority;
563  engine.get_sched_priority(policy, priority);
564  return conv.start(policy, priority);
565 }
566 
567 
568 /****************************************************************
569  ** class ConvolverStereoAdapter
570  */
571 
573  EngineControl& engine_, sigc::slot<void> sync_, ParamMap& param_)
574  : ConvolverAdapter(engine_, sync_, param_) {
575  id = "jconv";
576  name = N_("Convolver");
577  register_params = convolver_register;
578  set_samplerate = convolver_init;
579  activate_plugin = activate;
580  stereo_audio = convolver;
581 }
582 
584 }
585 
586 void ConvolverStereoAdapter::convolver(int count, float *input0, float *input1,
587  float *output0, float *output1, PluginDef* plugin) {
588  ConvolverStereoAdapter& self = *static_cast<ConvolverStereoAdapter*>(plugin);
589  if (self.conv.is_runnable()) {
590  float conv_out0[count];
591  float conv_out1[count];
592  if (self.conv.compute(count, input0, input1, conv_out0, conv_out1)) {
593  self.jc_post.compute(count, input0, input1,
594  conv_out0, conv_out1, output0, output1);
595  return;
596  }
597  self.engine.overload(EngineControl::ov_Convolver, self.id);
598  }
599  if (input0 != output0) {
600  memcpy(output0, input0, count * sizeof(float));
601  }
602  if (input1 != output1) {
603  memcpy(output1, input1, count * sizeof(float));
604  }
605 }
606 
607 int ConvolverStereoAdapter::convolver_register(const ParamReg& reg) {
608  ConvolverStereoAdapter& self = *static_cast<ConvolverStereoAdapter*>(reg.plugin);
609  self.jcp = JConvParameter::insert_param(self.param, "jconv.convolver", self, &self.jcset);
610  self.jcp->signal_changed().connect(
611  sigc::hide(
612  sigc::mem_fun(self, &ConvolverStereoAdapter::restart)));
613  return self.jc_post.register_par(reg);
614 }
615 
616 void ConvolverStereoAdapter::convolver_init(unsigned int samplingFreq, PluginDef *p) {
617  ConvolverStereoAdapter& self = *static_cast<ConvolverStereoAdapter*>(p);
618  boost::mutex::scoped_lock lock(self.activate_mutex);
619  if (self.activated) {
620  self.conv.stop_process();
621  self.conv.set_samplerate(samplingFreq);
622  self.jc_post.init(samplingFreq);
623  while (self.conv.is_runnable()) {
624  self.conv.checkstate();
625  }
626  self.conv_start();
627  } else {
628  self.conv.set_samplerate(samplingFreq);
629  self.jc_post.init(samplingFreq);
630  }
631 }
632 
633 int ConvolverStereoAdapter::activate(bool start, PluginDef *p) {
634  ConvolverStereoAdapter& self = *static_cast<ConvolverStereoAdapter*>(p);
635  boost::mutex::scoped_lock lock(self.activate_mutex);
636  if (start) {
637  if (self.activated && self.conv.is_runnable()) {
638  return 0;
639  }
640  } else {
641  if (!self.activated) {
642  return 0;
643  }
644  }
645  self.activated = start;
646  if (start) {
647  if (self.jc_post.activate(true) != 0) {
648  gx_print_error(_("convolver"), "jconv post activate error?!");
649  return -1;
650  }
651  if (!self.conv_start()) {
652  return -1;
653  }
654  } else {
655  self.conv.stop_process();
656  self.jc_post.activate(false);
657  }
658  return 0;
659 }
660 
661 
662 /****************************************************************
663  ** class ConvolverMonoAdapter
664  */
665 
667  EngineControl& engine_, sigc::slot<void> sync_, ParamMap& param_)
668  : ConvolverAdapter(engine_, sync_, param_) {
669  id = "jconv_mono";
670  name = N_("Convolver");
671  register_params = convolver_register;
672  set_samplerate = convolver_init;
673  activate_plugin = activate;
674  mono_audio = convolver;
675 }
676 
678 }
679 
680 void ConvolverMonoAdapter::convolver(int count, float *input, float *output, PluginDef* plugin) {
681  ConvolverMonoAdapter& self = *static_cast<ConvolverMonoAdapter*>(plugin);
682  if (self.conv.is_runnable()) {
683  float conv_out[count];
684  if (self.conv.compute(count, input, conv_out)) {
685  self.jc_post_mono.compute(count, output, conv_out, output);
686  return;
687  }
688  self.engine.overload(EngineControl::ov_Convolver, self.id);
689  }
690  if (input != output) {
691  memcpy(output, input, count * sizeof(float));
692  }
693 }
694 
695 int ConvolverMonoAdapter::convolver_register(const ParamReg& reg) {
696  ConvolverMonoAdapter& self = *static_cast<ConvolverMonoAdapter*>(reg.plugin);
697  self.jcp = JConvParameter::insert_param(self.param, "jconv_mono.convolver", self, &self.jcset);
698  self.jcp->signal_changed().connect(
699  sigc::hide(
700  sigc::mem_fun(self, &ConvolverMonoAdapter::restart)));
701  return self.jc_post_mono.register_par(reg);;
702 }
703 
704 void ConvolverMonoAdapter::convolver_init(unsigned int samplingFreq, PluginDef *p) {
705  ConvolverMonoAdapter& self = *static_cast<ConvolverMonoAdapter*>(p);
706  boost::mutex::scoped_lock lock(self.activate_mutex);
707  if (self.activated) {
708  self.conv.stop_process();
709  self.conv.set_samplerate(samplingFreq);
710  while (self.conv.is_runnable()) {
711  self.conv.checkstate();
712  }
713  self.conv_start();
714  } else {
715  self.conv.set_samplerate(samplingFreq);
716  }
717 }
718 
719 int ConvolverMonoAdapter::activate(bool start, PluginDef *p) {
720  ConvolverMonoAdapter& self = *static_cast<ConvolverMonoAdapter*>(p);
721  boost::mutex::scoped_lock lock(self.activate_mutex);
722  if (start) {
723  if (self.activated && self.conv.is_runnable()) {
724  return 0;
725  }
726  } else {
727  if (!self.activated) {
728  return 0;
729  }
730  }
731  self.activated = start;
732  if (start) {
733  if (!self.conv_start()) {
734  return -1;
735  }
736  } else {
737  self.conv.stop_process();
738  }
739  return 0;
740 }
741 
742 /****************************************************************
743  ** class BaseConvolver
744  */
745 
746 
748  : PluginDef(),
749  conv(resamp),
750  activate_mutex(),
751  engine(engine_),
752  sync(sync_),
753  activated(false),
754  plugin() {
758  plugin = this;
760  sigc::mem_fun(*this, &BaseConvolver::change_buffersize));
761 }
762 
764  update_conn.disconnect();
765 }
766 
767 void BaseConvolver::change_buffersize(unsigned int bufsize) {
768  boost::mutex::scoped_lock lock(activate_mutex);
769  conv.set_buffersize(bufsize);
770  if (activated) {
771  if (!bufsize) {
772  conv.stop_process();
773  } else {
774  start(true);
775  }
776  }
777 }
778 
779 void BaseConvolver::init(unsigned int samplingFreq, PluginDef *p) {
780  BaseConvolver& self = *static_cast<BaseConvolver*>(p);
781  boost::mutex::scoped_lock lock(self.activate_mutex);
782  self.conv.set_samplerate(samplingFreq);
783  if (self.activated) {
784  self.start(true);
785  }
786 }
787 
789  if (!activated || !plugin.get_on_off()) {
790  return false;
791  }
792  check_update();
793  return true;
794 }
795 
796 int BaseConvolver::activate(bool start, PluginDef *p) {
797  BaseConvolver& self = *static_cast<BaseConvolver*>(p);
798  boost::mutex::scoped_lock lock(self.activate_mutex);
799  if (start) {
800  if (!self.conv.get_buffersize()) {
801  start = false;
802  }
803  }
804  if (start == self.activated) {
805  return 0;
806  }
807  if (start) {
808  if (!self.start()) {
809  return -1;
810  }
811  self.update_conn = Glib::signal_timeout().connect(
812  sigc::mem_fun(self, &BaseConvolver::check_update_timeout), 200);
813  } else {
814  self.conv.stop_process();
815  }
816  self.activated = start;
817  return 0;
818 }
819 
821  int policy, priority;
822  engine.get_sched_priority(policy, priority);
823  return conv.start(policy, priority);
824 }
825 
826 /****************************************************************
827  ** class FixedBaseConvolver
828  */
829 
830 
832  : PluginDef(),
833  conv(resamp),
834  activate_mutex(),
835  engine(engine_),
836  sync(sync_),
837  activated(false),
838  SamplingFreq(0),
839  buffersize(0),
840  bz(0.0),
841  plugin() {
845  plugin = this;
847  sigc::mem_fun(*this, &FixedBaseConvolver::change_buffersize));
848 }
849 
851  update_conn.disconnect();
852 }
853 
854 void FixedBaseConvolver::change_buffersize(unsigned int bufsize) {
855  boost::mutex::scoped_lock lock(activate_mutex);
856  buffersize = bufsize;
857  conv.set_buffersize(static_cast<int>(ceil((bufsize*bz))));
858  if (activated) {
859  if (!bufsize) {
860  conv.stop_process();
861  } else {
862  start(true);
863  }
864  }
865 }
866 
867 void FixedBaseConvolver::init(unsigned int samplingFreq, PluginDef *p) {
868  FixedBaseConvolver& self = *static_cast<FixedBaseConvolver*>(p);
869  boost::mutex::scoped_lock lock(self.activate_mutex);
870  self.SamplingFreq = samplingFreq;
871  self.bz = 96000/samplingFreq;
872  self.conv.set_buffersize(static_cast<int>(ceil((self.buffersize*self.bz))));
873  self.conv.set_samplerate(self.bz*self.SamplingFreq);
874  if (self.activated) {
875  self.start(true);
876  }
877 }
878 
880  if (!activated || !plugin.get_on_off()) {
881  return false;
882  }
883  check_update();
884  return true;
885 }
886 
888  FixedBaseConvolver& self = *static_cast<FixedBaseConvolver*>(p);
889  boost::mutex::scoped_lock lock(self.activate_mutex);
890  if (start) {
891  if (!self.conv.get_buffersize()) {
892  start = false;
893  }
894  }
895  if (start == self.activated) {
896  return 0;
897  }
898  if (start) {
899  if (!self.start()) {
900  return -1;
901  }
902  self.update_conn = Glib::signal_timeout().connect(
903  sigc::mem_fun(self, &FixedBaseConvolver::check_update_timeout), 200);
904  } else {
905  self.conv.stop_process();
906  }
907  self.activated = start;
908  return 0;
909 }
910 
912  int policy, priority;
913  engine.get_sched_priority(policy, priority);
914  return conv.start(policy, priority);
915 }
916 
917 /****************************************************************
918  ** class CabinetConvolver
919  */
920 
921 struct CabDesc {
922  int ir_count;
923  int ir_sr;
924  float ir_data[];
925 };
926 
927 template <int tab_size>
928 struct CabDesc_imp {
929  int ir_count;
930  int ir_sr;
931  float ir_data[tab_size];
932  operator CabDesc&() { return *(CabDesc*)this; }
933 };
934 
935 #include "gx_cabinet_data.cc"
936 
937 struct CabEntry {
938  const char *value_id;
939  const char *value_label;
941 } cab_table[] = {
942  { "4x12", N_("4x12"), &static_cast<CabDesc&>(cab_data_4x12) },
943  { "2x12", N_("2x12"), &static_cast<CabDesc&>(cab_data_2x12) },
944  { "1x12", N_("1x12"), &static_cast<CabDesc&>(cab_data_1x12) },
945  { "4x10", N_("4x10"), &static_cast<CabDesc&>(cab_data_4x10) },
946  { "2x10", N_("2x10"), &static_cast<CabDesc&>(cab_data_2x10) },
947  { "HighGain", N_("HighGain Style"), &static_cast<CabDesc&>(cab_data_HighGain) },
948  { "Twin", N_("Twin Style"), &static_cast<CabDesc&>(cab_data_Twin) },
949  { "Bassman", N_("Bassman Style"), &static_cast<CabDesc&>(cab_data_Bassman) },
950  { "Marshall", N_("Marshall Style"), &static_cast<CabDesc&>(cab_data_Marshall) },
951  { "AC-30", N_("AC-30 Style"), &static_cast<CabDesc&>(cab_data_AC30) },
952  { "Princeton", N_("Princeton Style"), &static_cast<CabDesc&>(cab_data_Princeton) },
953  { "A2", N_("A2 Style"), &static_cast<CabDesc&>(cab_data_A2) },
954  { "1x15", N_("1x15"), &static_cast<CabDesc&>(cab_data_1x15) },
955  { "Mesa Boogie", N_("Mesa Boogie Style"), &static_cast<CabDesc&>(cab_data_mesa) },
956  { "Briliant", N_("Briliant"), &static_cast<CabDesc&>(cab_data_briliant) },
957  { "Vitalize", N_("Vitalize"), &static_cast<CabDesc&>(cab_data_vitalize) },
958  { "Charisma", N_("Charisma"), &static_cast<CabDesc&>(cab_data_charisma) },
959 };
960 static const unsigned int cab_table_size = sizeof(cab_table) / sizeof(cab_table[0]);
961 
962 static CabEntry& getCabEntry(unsigned int n) {
963  if (n >= cab_table_size) {
964  n = cab_table_size - 1;
965  }
966  return cab_table[n];
967 }
968 
969 static const float no_sum = 1e10;
970 
971 #include "faust/cabinet_impulse_former.cc"
972 
973 static int cab_load_ui(const UiBuilder& builder, int format) {
974  if (format & UI_FORM_GLADE) {
975  builder.load_glade_file("cabinet_ui.glade");
976  return 0;
977  } else if (format & UI_FORM_STACK) {
978  builder.openHorizontalhideBox("");
979  builder.create_selector_no_caption("cab.select");
980  builder.closeBox();
981  builder.openVerticalBox("");
982  {
983  builder.openHorizontalBox("");
984  {
985  builder.insertSpacer();
986  builder.create_selector_no_caption("cab.select");
987  builder.create_small_rackknobr("cab.bass", "Bass");
988  builder.create_small_rackknobr("cab.treble", "Treble");
989  builder.create_mid_rackknob("cab.Level", "Level");
990  }
991  builder.closeBox();
992  }
993  builder.closeBox();
994  return 0;
995  } else {
996  return -1;
997  }
998 
999 }
1000 
1003  FixedBaseConvolver(engine, sync, resamp),
1004  current_cab(-1),
1005  level(0),
1006  cabinet(0),
1007  bass(0),
1008  treble(0),
1009  sum(no_sum),
1010  cab_names(new value_pair[cab_table_size+1]),
1011  impf(),
1012  smp() {
1013  for (unsigned int i = 0; i < cab_table_size; ++i) {
1014  CabEntry& cab = getCabEntry(i);
1015  cab_names[i].value_id = cab.value_id;
1016  cab_names[i].value_label = cab.value_label;
1017  }
1018  cab_names[cab_table_size].value_id = 0;
1019  cab_names[cab_table_size].value_label = 0;
1020  id = "cab";
1021  name = N_("Cabinet");
1022  category = N_("Tone Control");
1023  load_ui = cab_load_ui;
1024  mono_audio = run_cab_conf;
1025  register_params = register_cab;
1026 }
1027 
1029  delete[] cab_names;
1030 }
1031 
1032 bool CabinetConvolver::do_update() {
1033  bool configure = cabinet_changed();
1034  if (conv.is_runnable()) {
1035  conv.set_not_runnable();
1036  sync();
1037  conv.stop_process();
1038  }
1039  CabDesc& cab = *getCabEntry(cabinet).data;
1040  if (current_cab == -1) {
1041  unsigned int sr = getSamplingFreq();
1042  unsigned int sru = 96000;
1043  unsigned int fact = sru/sr;
1044 
1045  smp.setup(sr, fact*sr);
1046  impf.init(cab.ir_sr);
1047  }
1048  float cab_irdata_c[cab.ir_count];
1049  impf.clear_state_f();
1050  impf.compute(cab.ir_count,cab.ir_data,cab_irdata_c);
1051  while (!conv.checkstate());
1052  if (configure) {
1053  if (!conv.configure(cab.ir_count, cab_irdata_c, cab.ir_sr)) {
1054  return false;
1055  }
1056  } else {
1057  if (!conv.update(cab.ir_count, cab_irdata_c, cab.ir_sr)) {
1058  return false;
1059  }
1060  }
1061  update_cabinet();
1062  update_sum();
1063  return conv_start();
1064 }
1065 
1066 bool CabinetConvolver::start(bool force) {
1067  if (force) {
1068  current_cab = -1;
1069  }
1070  if (cabinet_changed() || sum_changed()) {
1071  return do_update();
1072  } else {
1073  while (!conv.checkstate());
1074  if (!conv.is_runnable()) {
1075  return conv_start();
1076  }
1077  return true;
1078  }
1079 }
1080 
1081 void CabinetConvolver::check_update() {
1082  if (cabinet_changed() || sum_changed()) {
1083  do_update();
1084  }
1085 }
1086 
1087 void CabinetConvolver::run_cab_conf(int count, float *input0, float *output0, PluginDef *p) {
1088  CabinetConvolver& self = *static_cast<CabinetConvolver*>(p);
1089  FAUSTFLOAT buf[self.smp.max_out_count(count)];
1090  int ReCount = self.smp.up(count, output0, buf);
1091  if (!self.conv.compute(ReCount,buf)) {
1092  self.engine.overload(EngineControl::ov_Convolver, "cab");
1093  }
1094  self.smp.down(buf, output0);
1095 }
1096 
1097 int CabinetConvolver::register_cab(const ParamReg& reg) {
1098  CabinetConvolver& cab = *static_cast<CabinetConvolver*>(reg.plugin);
1099  reg.registerIEnumVar("cab.select", "select", "B", "", cab.cab_names, &cab.cabinet, 0);
1100  reg.registerVar("cab.Level", N_("Level"), "S", N_("Level"), &cab.level, 1.0, 0.5, 5.0, 0.5);
1101  reg.registerVar("cab.bass", N_("Bass"), "S", N_("Bass"), &cab.bass, 0.0, -10.0, 10.0, 0.5);
1102  reg.registerVar("cab.treble", N_("Treble"), "S", N_("Treble"), &cab.treble, 0.0, -10.0, 10.0, 0.5);
1103  cab.impf.register_par(reg);
1104  return 0;
1105 }
1106 
1108 #include "faust/cabinet_impulse_former_st.cc"
1109 
1110 static int cab_load_stereo_ui(const UiBuilder& builder, int format) {
1111  if (format & UI_FORM_GLADE) {
1112  builder.load_glade_file("cabinet_stereo_ui.glade");
1113  return 0;
1114  } else if (format & UI_FORM_STACK) {
1115  builder.openHorizontalhideBox("");
1116  builder.create_selector_no_caption("cab_st.select");
1117  builder.closeBox();
1118  builder.openVerticalBox("");
1119  {
1120  builder.openHorizontalBox("");
1121  {
1122  builder.insertSpacer();
1123  builder.create_selector_no_caption("cab_st.select");
1124  builder.create_small_rackknobr("cab_st.bass", "Bass");
1125  builder.create_small_rackknobr("cab_st.treble", "Treble");
1126  builder.create_mid_rackknob("cab_st.Level", "Level");
1127  }
1128  builder.closeBox();
1129  }
1130  builder.closeBox();
1131  return 0;
1132  } else {
1133  return -1;
1134  }
1135 
1136 }
1137 
1140  FixedBaseConvolver(engine, sync, resamp),
1141  current_cab(-1),
1142  level(0),
1143  cabinet(0),
1144  bass(0),
1145  treble(0),
1146  sum(no_sum),
1147  cab_names(new value_pair[cab_table_size+1]),
1148  impf(),
1149  smp(),
1150  smps() {
1151  for (unsigned int i = 0; i < cab_table_size; ++i) {
1152  CabEntry& cab = getCabEntry(i);
1153  cab_names[i].value_id = cab.value_id;
1154  cab_names[i].value_label = cab.value_label;
1155  }
1156  cab_names[cab_table_size].value_id = 0;
1157  cab_names[cab_table_size].value_label = 0;
1158  id = "cab_st";
1159  name = N_("Cabinet");
1160  category = N_("Tone Control");
1161  load_ui = cab_load_stereo_ui;
1162  stereo_audio = run_cab_conf;
1163  register_params = register_cab;
1164 }
1165 
1167  delete[] cab_names;
1168 }
1169 
1170 bool CabinetStereoConvolver::do_update() {
1171  bool configure = cabinet_changed();
1172  if (conv.is_runnable()) {
1173  conv.set_not_runnable();
1174  sync();
1175  conv.stop_process();
1176  }
1177  CabDesc& cab = *getCabEntry(cabinet).data;
1178  if (current_cab == -1) {
1179  unsigned int sr = getSamplingFreq();
1180  unsigned int sru = 96000;
1181  unsigned int fact = sru/sr;
1182 
1183  smp.setup(sr, fact*sr);
1184  smps.setup(sr, fact*sr);
1185  impf.init(cab.ir_sr);
1186  }
1187  float cab_irdata_c[cab.ir_count];
1188  impf.clear_state_f();
1189  impf.compute(cab.ir_count,cab.ir_data,cab_irdata_c);
1190  while (!conv.checkstate());
1191  if (configure) {
1192  if (!conv.configure_stereo(cab.ir_count, cab_irdata_c, cab.ir_sr)) {
1193  return false;
1194  }
1195  } else {
1196  if (!conv.update_stereo(cab.ir_count, cab_irdata_c, cab.ir_sr)) {
1197  return false;
1198  }
1199  }
1200  update_cabinet();
1201  update_sum();
1202  return conv_start();
1203 }
1204 
1205 bool CabinetStereoConvolver::start(bool force) {
1206  if (force) {
1207  current_cab = -1;
1208  }
1209  if (cabinet_changed() || sum_changed()) {
1210  return do_update();
1211  } else {
1212  while (!conv.checkstate());
1213  if (!conv.is_runnable()) {
1214  return conv_start();
1215  }
1216  return true;
1217  }
1218 }
1219 
1220 void CabinetStereoConvolver::check_update() {
1221  if (cabinet_changed() || sum_changed()) {
1222  do_update();
1223  }
1224 }
1225 
1226 void CabinetStereoConvolver::run_cab_conf(int count, float *input0, float *input1, float *output0, float *output1, PluginDef *p) {
1227  CabinetStereoConvolver& self = *static_cast<CabinetStereoConvolver*>(p);
1228  FAUSTFLOAT buf[self.smp.max_out_count(count)];
1229  FAUSTFLOAT buf1[self.smps.max_out_count(count)];
1230  int ReCount = self.smp.up(count, output0, buf);
1231  self.smps.up(count, output1, buf1);
1232  if (!self.conv.compute_stereo(ReCount,buf,buf1)) {
1233  self.engine.overload(EngineControl::ov_Convolver, "cab_st");
1234  }
1235  self.smp.down(buf, output0);
1236  self.smps.down(buf1, output1);
1237 }
1238 
1239 int CabinetStereoConvolver::register_cab(const ParamReg& reg) {
1240  CabinetStereoConvolver& cab = *static_cast<CabinetStereoConvolver*>(reg.plugin);
1241  reg.registerIEnumVar("cab_st.select", "select", "B", "", cab.cab_names, &cab.cabinet, 0);
1242  reg.registerVar("cab_st.Level", N_("Level"), "S", N_("Level"), &cab.level, 1.0, 0.5, 5.0, 0.5);
1243  reg.registerVar("cab_st.bass", N_("Bass"), "S", N_("Bass"), &cab.bass, 0.0, -10.0, 10.0, 0.5);
1244  reg.registerVar("cab_st.treble", N_("Treble"), "S", N_("Treble"), &cab.treble, 0.0, -10.0, 10.0, 0.5);
1245  cab.impf.register_par(reg);
1246  return 0;
1247 }
1248 
1249 /****************************************************************
1250  ** class PreampConvolver
1251  */
1252 
1253 struct PreDesc {
1255  int ir_sr;
1256  float ir_data[];
1257 };
1258 
1259 template <int tab_size>
1260 struct PreDesc_imp {
1262  int ir_sr;
1263  float ir_data[tab_size];
1264  operator PreDesc&() { return *(PreDesc*)this; }
1265 };
1266 
1267 #include "gx_preamp_data.cc"
1268 
1269 struct PreEntry {
1270  const char *value_id;
1271  const char *value_label;
1273 } pre_table[] = {
1274  { "AC30", N_("AC30 Style"), &static_cast<PreDesc&>(pre_data_ac30) },
1275  { "Bassman", N_("Bassman Style"), &static_cast<PreDesc&>(pre_data_bassman) },
1276  { "Tube", N_("Tube Style"), &static_cast<PreDesc&>(pre_data_tube) },
1277  { "Fender", N_("Fender Style"), &static_cast<PreDesc&>(pre_data_fender) },
1278  { "JCM800", N_("JCM800 Style"), &static_cast<PreDesc&>(pre_data_jcm800) },
1279  { "JTM45", N_("JTM45 Style"), &static_cast<PreDesc&>(pre_data_jtm45) },
1280  { "Mesa Boogie", N_("Mesa Boogie Style"), &static_cast<PreDesc&>(pre_data_mesaboogie) },
1281  { "Boutique", N_("Boutique Style"), &static_cast<PreDesc&>(pre_data_boutique) },
1282  { "Ampeg", N_("Ampeg Style"), &static_cast<PreDesc&>(pre_data_ampeg) },
1283  { "Rectifier", N_("Rectifier Style"), &static_cast<PreDesc&>(pre_data_rectifier) },
1284 };
1285 static const unsigned int pre_table_size = sizeof(pre_table) / sizeof(pre_table[0]);
1286 
1287 static PreEntry& getPreEntry(unsigned int n) {
1288  if (n >= pre_table_size) {
1289  n = pre_table_size - 1;
1290  }
1291  return pre_table[n];
1292 }
1293 
1294 #include "faust/preamp_impulse_former.cc"
1295 
1296 static int pre_load_ui(const UiBuilder& builder, int format) {
1297  if (format & UI_FORM_GLADE) {
1298  builder.load_glade_file("ampimpulse_ui.glade");
1299  return 0;
1300  } else if (format & UI_FORM_STACK) {
1301  builder.openHorizontalhideBox("");
1302  builder.create_selector_no_caption("pre.select");
1303  builder.closeBox();
1304  builder.openVerticalBox("");
1305  {
1306  builder.openHorizontalBox("");
1307  {
1308  builder.insertSpacer();
1309  builder.create_selector_no_caption("pre.select");
1310  builder.create_small_rackknobr("pre.bass", "Bass");
1311  builder.create_small_rackknobr("pre.treble", "Treble");
1312  builder.create_mid_rackknob("pre.Level", "Level");
1313  }
1314  builder.closeBox();
1315  }
1316  builder.closeBox();
1317  return 0;
1318  } else {
1319  return -1;
1320  }
1321 
1322 }
1323 
1326  FixedBaseConvolver(engine, sync, resamp),
1327  current_pre(-1),
1328  level(0),
1329  preamp(0),
1330  bass(0),
1331  treble(0),
1332  sum(no_sum),
1333  pre_names(new value_pair[pre_table_size+1]),
1334  impf(),
1335  smp() {
1336  for (unsigned int i = 0; i < pre_table_size; ++i) {
1337  PreEntry& pre = getPreEntry(i);
1338  pre_names[i].value_id = pre.value_id;
1339  pre_names[i].value_label = pre.value_label;
1340  }
1341  pre_names[pre_table_size].value_id = 0;
1342  pre_names[pre_table_size].value_label = 0;
1343  id = "pre";
1344  name = N_("Amp Impulse");
1345  category = N_("Tone Control");
1346  load_ui = pre_load_ui;
1347  mono_audio = run_pre_conf;
1348  register_params = register_pre;
1349 }
1350 
1352  delete[] pre_names;
1353 }
1354 
1355 bool PreampConvolver::do_update() {
1356  bool configure = preamp_changed();
1357  if (conv.is_runnable()) {
1358  conv.set_not_runnable();
1359  sync();
1360  conv.stop_process();
1361  }
1362  PreDesc& pre = *getPreEntry(preamp).data;
1363  if (current_pre == -1) {
1364  unsigned int sr = getSamplingFreq();
1365  unsigned int sru = 96000;
1366  unsigned int fact = sru/sr;
1367 
1368  smp.setup(sr, fact*sr);
1369  impf.init(pre.ir_sr);
1370  }
1371  float pre_irdata_c[pre.ir_count];
1372  impf.clear_state_f();
1373  impf.compute(pre.ir_count,pre.ir_data,pre_irdata_c);
1374  while (!conv.checkstate());
1375  if (configure) {
1376  if (!conv.configure(pre.ir_count, pre_irdata_c, pre.ir_sr)) {
1377  return false;
1378  }
1379  } else {
1380  if (!conv.update(pre.ir_count, pre_irdata_c, pre.ir_sr)) {
1381  return false;
1382  }
1383  }
1384  update_preamp();
1385  update_sum();
1386  return conv_start();
1387 }
1388 
1389 bool PreampConvolver::start(bool force) {
1390  if (force) {
1391  current_pre = -1;
1392  }
1393  if (preamp_changed() || sum_changed()) {
1394  return do_update();
1395  } else {
1396  while (!conv.checkstate());
1397  if (!conv.is_runnable()) {
1398  return conv_start();
1399  }
1400  return true;
1401  }
1402 }
1403 
1404 void PreampConvolver::check_update() {
1405  if (preamp_changed() || sum_changed()) {
1406  do_update();
1407  }
1408 }
1409 
1410 void PreampConvolver::run_pre_conf(int count, float *input0, float *output0, PluginDef *p) {
1411  PreampConvolver& self = *static_cast<PreampConvolver*>(p);
1412  FAUSTFLOAT buf[self.smp.max_out_count(count)];
1413  int ReCount = self.smp.up(count, output0, buf);
1414  if (!self.conv.compute(ReCount, buf)) {
1415  self.engine.overload(EngineControl::ov_Convolver, "pre");
1416  }
1417  self.smp.down(buf, output0);
1418 }
1419 
1420 int PreampConvolver::register_pre(const ParamReg& reg) {
1421  PreampConvolver& pre = *static_cast<PreampConvolver*>(reg.plugin);
1422  reg.registerIEnumVar("pre.select", "select", "B", "", pre.pre_names, &pre.preamp, 0);
1423  reg.registerVar("pre.Level", N_("Level"), "S", N_("Level"), &pre.level, 1.0, 0.1, 2.1, 0.1);
1424  reg.registerVar("pre.bass", N_("Bass"), "S", N_("Bass"), &pre.bass, 0.0, -10.0, 10.0, 0.5);
1425  reg.registerVar("pre.treble", N_("Treble"), "S", N_("Treble"), &pre.treble, 0.0, -10.0, 10.0, 0.5);
1426  pre.impf.register_par(reg);
1427  return 0;
1428 }
1429 
1430 /****************************************************************
1431  ** class ContrastConvolver
1432  */
1433 
1434 #include "faust/presence_level.cc"
1435 
1438  FixedBaseConvolver(engine, sync, resamp),
1439  level(0),
1440  sum(no_sum),
1441  presl(),
1442  smp() {
1443  id = "con";
1444  name = N_("Contrast convolver");
1445  mono_audio = run_contrast;
1446  register_params = register_con;
1447 }
1448 
1450 }
1451 
1452 bool ContrastConvolver::do_update() {
1453  bool configure = (sum == no_sum);
1454  if (conv.is_runnable()) {
1455  conv.set_not_runnable();
1456  sync();
1457  conv.stop_process();
1458  }
1459  if (configure) {
1460  unsigned int sr = getSamplingFreq();
1461  unsigned int sru = 96000;
1462  unsigned int fact = sru/sr;
1463 
1464  smp.setup(sr, fact*sr);
1465  presl.init(contrast_ir_desc.ir_sr);
1466  }
1467  float contrast_irdata_c[contrast_ir_desc.ir_count];
1468  presl.compute(contrast_ir_desc.ir_count,contrast_ir_desc.ir_data,contrast_irdata_c);
1469  while (!conv.checkstate());
1470  if (configure) {
1471  if (!conv.configure(contrast_ir_desc.ir_count, contrast_irdata_c, contrast_ir_desc.ir_sr)) {
1472  return false;
1473  }
1474  } else {
1475  if (!conv.update(contrast_ir_desc.ir_count, contrast_irdata_c, contrast_ir_desc.ir_sr)) {
1476  return false;
1477  }
1478  }
1479  update_sum();
1480  return conv_start();
1481 }
1482 
1483 bool ContrastConvolver::start(bool force) {
1484  if (force) {
1485  sum = no_sum;
1486  }
1487  if (sum_changed()) {
1488  return do_update();
1489  } else {
1490  while (!conv.checkstate());
1491  if (!conv.is_runnable()) {
1492  return conv_start();
1493  }
1494  return true;
1495  }
1496 }
1497 
1498 void ContrastConvolver::check_update() {
1499  if (sum_changed()) {
1500  do_update();
1501  }
1502 }
1503 
1504 int ContrastConvolver::register_con(const ParamReg& reg) {
1505  ContrastConvolver& self = *static_cast<ContrastConvolver*>(reg.plugin);
1506  reg.registerVar("con.Level", "", "S", "", &self.level, 1.0, 0.5, 5.0, 0.5);
1507  self.presl.register_par(reg);
1508  return 0;
1509 }
1510 
1511 void ContrastConvolver::run_contrast(int count, float *input0, float *output0, PluginDef *p) {
1512  ContrastConvolver& self = *static_cast<ContrastConvolver*>(p);
1513  FAUSTFLOAT buf[self.smp.max_out_count(count)];
1514  int ReCount = self.smp.up(count, output0, buf);
1515  if (!self.conv.compute(ReCount,buf)) {
1516  self.engine.overload(EngineControl::ov_Convolver, "contrast");
1517  }
1518  self.smp.down(buf, output0);
1519 
1520 }
1521 
1522 /****************************************************************
1523  ** class smbPitchShift
1524  */
1525 
1526 #include "gx_livelooper.cc"
1527 
1528 /****************************************************************
1529  ** class SCapture
1530  */
1531 
1532 #include "gx_record.cc"
1533 
1534 /****************************************************************
1535  ** class DrumSequencer
1536  */
1537 
1538 #include "faust/drumseq.cc"
1539 
1540 static const char* seq_groups[] = {
1541  "hat_closed.dsp", N_("DrumSequencer"),
1542  "kick.dsp", N_("DrumSequencer"),
1543  "snare.dsp", N_("DrumSequencer"),
1544  "tom.dsp", N_("DrumSequencer"),
1545  "sequencer", N_("DrumSequencer"),
1546  0
1547 };
1548 
1550  : PluginDef(),
1551  Vectom(0),
1552  Vectom1(0),
1553  Vectom2(0),
1554  Veckick(0),
1555  Vecsnare(0),
1556  Vechat(0),
1557  param(param_),
1558  tomset(),
1559  tomp(0),
1560  tomset1(),
1561  tomp1(0),
1562  tomset2(),
1563  tomp2(0),
1564  snareset(),
1565  snarep(0),
1566  hatset(),
1567  hatp(0),
1568  kickset(),
1569  kickp(0),
1570  plugin() {
1572  flags = 0;
1573  id = "seq";
1574  name = N_("DrumSequencer");
1575  groups = seq_groups;
1576  description = N_("Simple Drum Step Sequencer"); // description (tooltip)
1577  category = N_("Misc"); // category
1578  shortname = N_("Drum"); // shortname
1579  mono_audio = compute_static;
1580  stereo_audio = 0;
1581  set_samplerate = init_static;
1582  activate_plugin = 0;
1583  register_params = register_params_static;
1584  delete_instance = del_instance;
1585  plugin = this;
1586 }
1587 
1589 }
1590 
1591 inline void DrumSequencer::init(unsigned int samplingFreq)
1592 {
1593  fSamplingFreq = samplingFreq;
1594  counter = 0;
1595  step = 0;
1596  step_orig = 0;
1597  fSlow1 = 0.0;
1598  fSlow3 = 0.0;
1599  fSlow5 = 0.0;
1600  fSlow7 = 0.0;
1601  fSlow18 = 150.0;
1602  position = 0.0;
1603  drums.init(samplingFreq);
1604 }
1605 
1606 void DrumSequencer::init_static(unsigned int samplingFreq, PluginDef *p)
1607 {
1608  static_cast<DrumSequencer*>(p)->init(samplingFreq);
1609 }
1610 
1611 int DrumSequencer::min_seq_size(){
1612  int i = min(min(min(Vectom.size(),Veckick.size()),min(Vechat.size(),Vecsnare.size())),min(Vectom1.size(),Vectom2.size()));
1613  return i-1;
1614 }
1615 
1616 void DrumSequencer::reset_tom() {
1617  Vectom = tomset.getseqline() ;
1618  seq_size = min_seq_size();
1619 }
1620 
1621 void DrumSequencer::reset_tom1() {
1622  Vectom1 = tomset1.getseqline() ;
1623  seq_size = min_seq_size();
1624 }
1625 
1626 void DrumSequencer::reset_tom2() {
1627  Vectom2 = tomset2.getseqline() ;
1628  seq_size = min_seq_size();
1629 }
1630 
1631 void DrumSequencer::reset_kick() {
1632  Veckick = kickset.getseqline() ;
1633  seq_size = min_seq_size();
1634 }
1635 
1636 void DrumSequencer::reset_hat() {
1637  Vechat = hatset.getseqline() ;
1638  seq_size = min_seq_size();
1639 }
1640 
1641 void DrumSequencer::reset_snare() {
1642  Vecsnare = snareset.getseqline() ;
1643  seq_size = min_seq_size();
1644 }
1645 
1646 void always_inline DrumSequencer::compute(int count, FAUSTFLOAT *input0, FAUSTFLOAT *output0)
1647 {
1648  double fSlow15 = (60.0/double(fsliderbpm*ftact))*fSamplingFreq;
1649  counter += count;
1650  int iSlow15 = (int)fSlow15;
1651  // beat
1652  if (counter >= iSlow15) {
1653  int istep = (int)step;
1654  fSlow1 = double(Vecsnare[istep]);
1655  // disable hat when sequencer runs to fast
1656  if (iSlow15 > 4800) {
1657  fSlow3 = double(Vechat[istep]);
1658  }
1659  fSlow5 = double(Veckick[istep]);
1660  // only one tom at time
1661  if (Vectom2[istep]) {
1662  fSlow7 = double(Vectom2[istep]);
1663  fSlow18 = 150.0;
1664  fSlow20 = fSlow16;
1665  } else if (Vectom1[istep]) {
1666  fSlow7 = double(Vectom1[istep]);
1667  fSlow18 = 128.0;
1668  fSlow20 = fSlow14;
1669  } else if(Vectom[istep]) {
1670  fSlow7 = double(Vectom[istep]);
1671  fSlow18 = 90.0;
1672  fSlow20 = fSlow12;
1673  }
1674  int m = ftact;
1675  int r = rand()%(m+1 - (-m))+ (-m);
1676  counter = 0; //int(r*fsliderhum);
1677 
1678  if (step<seq_size) step = fmin(seq_size,fmax(0,step + 1.0 + int(r*fsliderhum)));
1679  else step = 0.0;
1680  if (step_orig<seq_size) step_orig += 1.0;
1681  else step_orig = 0.0;
1682  double ph1 = 2300.0/seq_size;
1683  position = fmin(2300,fmax(0,(step*ph1)));
1684  } else {
1685  fSlow1 = 0.0;
1686  fSlow3 = 0.0;
1687  fSlow5 = 0.0;
1688  fSlow7 = 0.0;
1689  }
1690  drums.compute(count,input0,output0);
1691 }
1692 
1693 void __rt_func DrumSequencer::compute_static(int count, FAUSTFLOAT *input0, FAUSTFLOAT *output0, PluginDef *p)
1694 {
1695  static_cast<DrumSequencer*>(p)->compute(count, input0, output0);
1696 }
1697 
1698 int DrumSequencer::register_par(const ParamReg& reg)
1699 {
1700  reg.registerNonMidiFloatVar("seq.hat_closed.dsp.gate",&fSlow3, false, true, 0.0, 0.0, 1.0, 1.0);
1701  reg.registerNonMidiFloatVar("seq.kick.dsp.gate",&fSlow5, false, true, 0.0, 0.0, 1.0, 1.0);
1702  reg.registerNonMidiFloatVar("seq.snare.dsp.gate",&fSlow1, false, true, 0.0, 0.0, 1.0, 1.0);
1703  reg.registerNonMidiFloatVar("seq.tom.dsp.gate",&fSlow7, false, true, 0.0, 0.0, 1.0, 1.0);
1704  reg.registerNonMidiSharedVar("seq.tom.dsp.Gainf",&fSlow20, false, true, -2e+01, -6e+01, 4e+01, 0.1);
1705  reg.registerVar("seq.tom.dsp.Gain","","S",N_("Volume level in decibels"),&fSlow12, -2e+01, -6e+01, 4e+01, 0.1);
1706  reg.registerVar("seq.tom.dsp.Gain1","","S",N_("Volume level in decibels"),&fSlow14, -2e+01, -6e+01, 4e+01, 0.1);
1707  reg.registerVar("seq.tom.dsp.Gain2","","S",N_("Volume level in decibels"),&fSlow16, -2e+01, -6e+01, 4e+01, 0.1);
1708  reg.registerNonMidiFloatVar("seq.tom.dsp.freq",&fSlow18, false, true, 9e+01, 9e+01, 1.5e+02, 1.0);
1709  reg.registerVar("seq.bpm","","S",N_("Beats per Minute"),&fsliderbpm, 120, 24, 360, 1);
1710  static const value_pair ftact_values[] = {{"1/4"},{"2/4"},{"3/4"},{"4/4"},{0}};
1711  reg.registerEnumVar("seq.tact","","S",N_("select tact"),ftact_values,&ftact, 4.0, 1.0, 4.0, 1.0);
1712  reg.registerVar("seq.asequences","","S",N_("Number of Sequences"),&fsec, 24.0, 24.0, 240.0, 4.0);
1713  reg.registerVar("seq.hum","","B",N_("Randomize Sequence"),&fsliderhum, 0.0, 0.0, 1.0, 1.0);
1714  reg.registerVar("seq.npreset","","BO",N_("Load next unit preset"),0, 0.0, 0.0, 1.0, 1.0);
1715  reg.registerVar("seq.ppreset","","BO",N_("Load previous unit preset"),0, 0.0, 0.0, 1.0, 1.0);
1716  reg.registerNonMidiFloatVar("seq.pos",&position, false, true, 0.0, 0.0, 2300.0, 1.0);
1717  reg.registerNonMidiFloatVar("seq.step",&step, false, true, 0.0, 0.0, 240.0, 1.0);
1718  reg.registerNonMidiFloatVar("seq.step_orig",&step_orig, false, true, 0.0, 0.0, 240.0, 1.0);
1719  reg.registerVar("seq.set_step","","BO",N_("Set stepper one Beat back"),0, 0.0, 0.0, 1.0, 1.0);
1720  reg.registerVar("seq.set_fstep","","BO",N_("Set stepper one Beat forward"),0, 0.0, 0.0, 1.0, 1.0);
1721  reg.registerVar("seq.set_sync","","BO",N_("Set stepper back on Beat "),0, 0.0, 0.0, 1.0, 1.0);
1722  reg.registerVar("seq.reset_step","","BO",N_("Set stepper one Start"),0, 0.0, 0.0, 1.0, 1.0);
1723  reg.registerVar("seq.follow","","BO",N_("follow playhead"),0, 0.0, 0.0, 1.0, 1.0);
1724  for (int i=0; i<24; i++) Vectom.push_back(0);
1725  for (int i=0; i<24; i++) Vectom1.push_back(0);
1726  for (int i=0; i<24; i++) Vectom2.push_back(0);
1727  for (int i=0; i<24; i++) Veckick.push_back(0);
1728  for (int i=0; i<24; i++) Vechat.push_back(0);
1729  for (int i=0; i<24; i++) Vecsnare.push_back(0);
1730  seq_size = min_seq_size();
1731  tomp = SeqParameter::insert_param(param, "seq.sequencer.tom", &tomset);
1732  tomp1 = SeqParameter::insert_param(param, "seq.sequencer.tom1", &tomset1);
1733  tomp2 = SeqParameter::insert_param(param, "seq.sequencer.tom2", &tomset2);
1734  snarep = SeqParameter::insert_param(param, "seq.sequencer.snare", &snareset);
1735  hatp = SeqParameter::insert_param(param, "seq.sequencer.hat", &hatset);
1736  kickp = SeqParameter::insert_param(param, "seq.sequencer.kick", &kickset);
1737  tomp->signal_changed().connect(
1738  sigc::hide(
1739  sigc::mem_fun(this, &DrumSequencer::reset_tom)));
1740  tomp1->signal_changed().connect(
1741  sigc::hide(
1742  sigc::mem_fun(this, &DrumSequencer::reset_tom1)));
1743  tomp2->signal_changed().connect(
1744  sigc::hide(
1745  sigc::mem_fun(this, &DrumSequencer::reset_tom2)));
1746  snarep->signal_changed().connect(
1747  sigc::hide(
1748  sigc::mem_fun(this, &DrumSequencer::reset_snare)));
1749  hatp->signal_changed().connect(
1750  sigc::hide(
1751  sigc::mem_fun(this, &DrumSequencer::reset_hat)));
1752  kickp->signal_changed().connect(
1753  sigc::hide(
1754  sigc::mem_fun(this, &DrumSequencer::reset_kick)));
1755 
1756  drums.register_par(reg);
1757  return 0;
1758 }
1759 
1760 int DrumSequencer::register_params_static(const ParamReg& reg)
1761 {
1762  return static_cast<DrumSequencer*>(reg.plugin)->register_par(reg);
1763 }
1764 
1765 void DrumSequencer::del_instance(PluginDef *p)
1766 {
1767  delete static_cast<DrumSequencer*>(p);
1768 }
1769 
1770 /****************************************************************************
1771 *
1772 * NAME: smbPitchShift.cpp
1773 * VERSION: 1.2
1774 * HOME URL: http://www.dspdimension.com
1775 * KNOWN BUGS: none
1776 *
1777 *
1778 * COPYRIGHT 1999-2009 Stephan M. Bernsee <smb [AT] dspdimension [DOT] com>
1779 *
1780 * Modified for guitarix by Hermann Meyer 2014
1781 *
1782 * The Wide Open License (WOL)
1783 *
1784 * Permission to use, copy, modify, distribute and sell this software and its
1785 * documentation for any purpose is hereby granted without fee, provided that
1786 * the above copyright notice and this license appear in all source copies.
1787 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF
1788 * ANY KIND. See http://www.dspguru.com/wol.htm for more information.
1789 *
1790 *****************************************************************************/
1791 
1792 bool smbPitchShift::setParameters(int sampleRate_)
1793 {
1794  numSampsToProcess = int(engine.get_buffersize());
1795  fftFrameSize = numSampsToProcess/4;
1796  sampleRate = int(sampleRate_);
1797  assert(sampleRate>0);
1798  osamp = 8;
1799  osamp1 = 1./osamp;
1800  osamp2 = 2.*M_PI*osamp1;
1801  mpi = (1./(2.*M_PI)) * osamp;
1802  mpi1 = 1./M_PI;
1803  fpb = 0;
1804  expect = 0;
1805  hanning = 0;
1806  hanningd = 0;
1807  resampin = 0;
1808  resampout = 0;
1809  indata2 = 0;
1810  resamp.setup(sampleRate,4);
1811  gRover = inFifoLatency;
1812  return true;
1813 }
1814 
1815 smbPitchShift::smbPitchShift(ParamMap& param_, EngineControl& engine_, sigc::slot<void> sync_):
1816  PluginDef(),
1817  engine(engine_),
1818  mem_allocated(false),
1819  sync(sync_),
1820  ready(false),
1821  param(param_),
1822  ftPlanForward(0),
1823  ftPlanInverse(0),
1824  plugin() {
1825  memset(gInFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
1826  memset(gOutFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
1827  memset(gLastPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
1828  memset(gSumPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
1829  memset(gOutputAccum, 0, 2*MAX_FRAME_LENGTH*sizeof(float));
1830  memset(gAnaFreq, 0, MAX_FRAME_LENGTH*sizeof(float));
1831  memset(gAnaMagn, 0, MAX_FRAME_LENGTH*sizeof(float));
1833  id = "smbPitchShift";
1834  name = N_("Detune");
1835  groups = 0;
1836  description = N_("detune and pitch shift up"); // description (tooltip)
1837  category = N_("Misc"); // category
1838  mono_audio = compute_static;
1839  stereo_audio = 0;
1840  set_samplerate = init;
1841  activate_plugin = activate_static;
1842  register_params = registerparam;
1843  delete_instance = del_instance;
1844  load_ui = load_ui_f_static;
1845  plugin = this;
1846  engine.signal_buffersize_change().connect(
1847  sigc::mem_fun(*this, &smbPitchShift::change_buffersize));
1848 }
1849 
1850 void smbPitchShift::init(unsigned int samplingFreq, PluginDef *plugin) {
1851  static_cast<smbPitchShift*>(plugin)->setParameters(samplingFreq);
1852 
1853 }
1854 
1855 void smbPitchShift::clear_state()
1856 {
1857  stepSize = fftFrameSize/osamp;
1858  freqPerBin = (double)(sampleRate/4)/(double)fftFrameSize;
1859  freqPerBin1 = (1/freqPerBin)*osamp2;
1860  freqPerBin2 = freqPerBin*mpi;
1861  expct = 2.*M_PI*(double)stepSize/(double)fftFrameSize;
1862  inFifoLatency = fftFrameSize-stepSize;
1863  fftFrameSize3 = 2. * (1./ ((double)(fftFrameSize2)*osamp));
1864  fftFrameSize4 = 1./(double)fftFrameSize;
1865  ai = 0;
1866  aio = 0;
1867  ii = 0;
1868  tone =0;
1869  memset(gInFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
1870  memset(gOutFIFO, 0, MAX_FRAME_LENGTH*sizeof(float));
1871  memset(gLastPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
1872  memset(gSumPhase, 0, (MAX_FRAME_LENGTH/2+1)*sizeof(float));
1873  memset(gOutputAccum, 0, 2*MAX_FRAME_LENGTH*sizeof(float));
1874  memset(gAnaFreq, 0, MAX_FRAME_LENGTH*sizeof(float));
1875  memset(gAnaMagn, 0, MAX_FRAME_LENGTH*sizeof(float));
1876  for (k = 0; k < fftFrameSize2;k++) {
1877  fpb[k] = (double)k*freqPerBin;
1878  }
1879  for (k = 0; k < fftFrameSize2;k++) {
1880  expect[k] = (double)k*expct;
1881  }
1882  for (k = 0; k < fftFrameSize;k++) {
1883  hanning[k] = 0.5*(1-cos(2.*M_PI*(double)k/((double)fftFrameSize)));
1884  }
1885  for (k = 0; k < fftFrameSize;k++) {
1886  hanningd[k] = 0.5*(1-cos(2.*M_PI*(double)k * fftFrameSize4)) * fftFrameSize3;
1887  }
1888  for (k = 0; k < fftFrameSize;k++) {
1889  resampin[k] = 0.0;
1890  }
1891  for (k = 0; k < fftFrameSize;k++) {
1892  resampin2[k] = 0.0;
1893  }
1894  for (k = 0; k < fftFrameSize*4;k++) {
1895  resampout[k] = 0.0;
1896  }
1897  for (k = 0; k < fftFrameSize*4;k++) {
1898  indata2[k] = 0.0;
1899  }
1900  gRover = inFifoLatency;
1901  mem_allocated = true;
1902  ready = true;
1903 }
1904 
1905 void smbPitchShift::mem_alloc()
1906 {
1907  numSampsToProcess = int(engine.get_buffersize());
1908  assert(numSampsToProcess>0);
1909  numSampsToResamp = numSampsToProcess/4;
1910  sampleRate = int(engine.get_samplerate());
1911  assert(sampleRate>0);
1912 
1913  switch(latency) {
1914  case(0):
1915  if (numSampsToProcess <= 2048) {
1916  fftFrameSize = 512 ;
1917  } else {
1918  fftFrameSize = numSampsToProcess*0.25 ;
1919  }
1920  break;
1921  case(1):
1922  fftFrameSize = numSampsToProcess;
1923  break;
1924  case(2):
1925  fftFrameSize = numSampsToProcess*0.25;
1926  break;
1927  default:
1928  if (numSampsToProcess <= 2048) {
1929  fftFrameSize = 512 ;
1930  } else {
1931  fftFrameSize = numSampsToProcess*0.25 ;
1932  }
1933  break;
1934  }
1935  fftFrameSize2 = fftFrameSize/2;
1936 
1937  try {
1938  //create FFTW plan
1939  ftPlanForward = fftwf_plan_dft_1d(fftFrameSize, fftw_in, fftw_out, FFTW_FORWARD, FFTW_ESTIMATE);
1940  ftPlanInverse = fftwf_plan_dft_1d(fftFrameSize, fftw_in, fftw_out, FFTW_BACKWARD, FFTW_ESTIMATE);
1941  // alloc buffers
1942  fpb = new float[fftFrameSize2];
1943  expect = new float[fftFrameSize2];
1944  hanning = new float[fftFrameSize];
1945  hanningd = new float[fftFrameSize];
1946  resampin = new float[fftFrameSize];
1947  resampin2 = new float[fftFrameSize];
1948  resampout = new float[fftFrameSize*4];
1949  indata2 = new float[fftFrameSize*4];
1950  } catch(...) {
1951  gx_print_error("detune", "cant allocate memory pool");
1952  return;
1953  }
1954  clear_state();
1955 }
1956 
1957 void smbPitchShift::mem_free()
1958 {
1959  ready = false;
1960  mem_allocated = false;
1961  if (fpb) { delete fpb; fpb = 0; }
1962  if (expect) { delete expect; expect = 0; }
1963  if (hanning) { delete hanning; hanning = 0; }
1964  if (hanningd) { delete hanningd; hanningd = 0; }
1965  if (resampin) { delete resampin; resampin = 0; }
1966  if (resampin2) { delete resampin2; resampin2 = 0; }
1967  if (resampout) { delete resampout; resampout = 0; }
1968  if (indata2) { delete indata2; indata2 = 0; }
1969  if (ftPlanForward)
1970  {fftwf_destroy_plan(ftPlanForward);ftPlanForward = 0; }
1971  if (ftPlanInverse)
1972  { fftwf_destroy_plan(ftPlanInverse);ftPlanInverse = 0; }
1973 }
1974 
1975 int smbPitchShift::activate(bool start)
1976 {
1977  if (start) {
1978  if (!mem_allocated) {
1979  mem_alloc();
1980  }
1981  } else if (mem_allocated) {
1982  mem_free();
1983  }
1984  return 0;
1985 }
1986 
1987 void smbPitchShift::change_buffersize(unsigned int size)
1988 {
1989  sync();
1990  ready = false;
1991  if (mem_allocated) {
1992  mem_free();
1993  mem_alloc();
1994  }
1995 }
1996 
1997 void smbPitchShift::change_latency()
1998 {
1999  sync();
2000  ready = false;
2001  if (mem_allocated) {
2002  mem_free();
2003  mem_alloc();
2004  }
2005 }
2006 
2008 {
2009  if (mem_allocated) {
2010  mem_free();
2011  }
2012 }
2013 
2014 // -----------------------------------------------------------------------------------------------------------------
2015 void __rt_func smbPitchShift::compute_static(int count, float *input0, float *output0, PluginDef *p)
2016 {
2017  static_cast<smbPitchShift*>(p)->PitchShift(count, input0, output0);
2018 }
2019 
2020 
2021 void always_inline smbPitchShift::PitchShift(int count, float *indata, float *outdata)
2022 {
2023 
2024  if (!ready || count != numSampsToProcess) {
2025  if (indata != outdata)
2026  {
2027  memcpy(outdata,indata,count*sizeof(float));
2028  }
2029  return;
2030  }
2031 
2032  resamp.down(numSampsToResamp,indata,resampin);
2033  double fSlow0 = (0.01 * wet);
2034  double fSlow1 = (0.01 * dry);
2035 
2036  // collect data for latency compensation
2037  for (i = 0; i < count; i++){
2038  indata2[ii] = indata[i];
2039  ii++;
2040  }
2041  // collect data for fft
2042  for (i = 0; i < numSampsToResamp; i++){
2043  resampin2[ai] = resampin[i];
2044  ai++;
2045  }
2046  // now we have enough data
2047  if (ai>=fftFrameSize) {
2048  ai = 0;
2049  ii = 0;
2050  switch(octave) {
2051  case(0):
2052  tone =0;
2053  break;
2054  case(1):
2055  tone =12;
2056  break;
2057  case(2):
2058  tone =-12;
2059  break;
2060  default:
2061  tone =0;
2062  break;
2063  }
2064  float pitchShift = pow(2., (semitones+tone)*0.0833333333);
2065  /* main processing loop */
2066  for (i = 0; i < fftFrameSize; i++){
2067 
2068  /* As long as we have not yet collected enough data just read in */
2069  float fTemp = resampin2[i];
2070  gInFIFO[gRover] = fTemp;
2071  resampin2[i] = gOutFIFO[gRover-inFifoLatency];
2072  gRover++;
2073 
2074  /* now we have enough data for processing */
2075  if (gRover >= fftFrameSize) {
2076  gRover = inFifoLatency;
2077 
2078  /* do windowing and re,im interleave */
2079  for (k = 0; k < fftFrameSize;k++) {
2080  fftw_in[k][0] = gInFIFO[k] * hanning[k];
2081  fftw_in[k][1] = 0.0;
2082  }
2083 
2084 
2085  /* ***************** ANALYSIS ******************* */
2086  /* do transform */
2087  fftwf_execute(ftPlanForward);
2088 
2089  /* this is the analysis step */
2090  for (k = 0; k < fftFrameSize2; k++) {
2091 
2092  /* de-interlace FFT buffer */
2093  real = fftw_out[k][0];
2094  imag = fftw_out[k][1];
2095 
2096  /* compute magnitude and phase */
2097  magn = 2.*sqrt(real*real + imag*imag);
2098  phase = atan2(imag,real);
2099 
2100  /* compute phase difference */
2101  tmp = phase - gLastPhase[k];
2102  gLastPhase[k] = phase;
2103 
2104  /* subtract expected phase difference */
2105  tmp -= expect[k];
2106 
2107  /* map delta phase into +/- Pi interval */
2108  qpd = tmp*mpi1;
2109  if (qpd >= 0) qpd += qpd&1;
2110  else qpd -= qpd&1;
2111  tmp -= M_PI*(double)qpd;
2112 
2113  /* get deviation from bin frequency from the +/- Pi interval */
2114  /* compute the k-th partials' true frequency */
2115  tmp = fpb[k] + tmp*freqPerBin2;
2116 
2117  /* store magnitude and true frequency in analysis arrays */
2118  gAnaMagn[k] = magn;
2119  gAnaFreq[k] = tmp;
2120 
2121  }
2122 
2123  /* ***************** PROCESSING ******************* */
2124  /* this does the actual pitch shifting */
2125  memset(gSynMagn, 0, fftFrameSize*sizeof(float));
2126  memset(gSynFreq, 0, fftFrameSize*sizeof(float));
2127  for (k = 1; k < fftFrameSize2-2; k++) {
2128  index = k*pitchShift;
2129  if (index < fftFrameSize2) {
2130  if (index < fftFrameSize2*0.20)
2131  gSynMagn[index] += gAnaMagn[k]*a;
2132  else if (index < fftFrameSize2*0.45)
2133  gSynMagn[index] += gAnaMagn[k]*b;
2134  else if (index < fftFrameSize2*0.667)
2135  gSynMagn[index] += gAnaMagn[k]*c;
2136  else
2137  gSynMagn[index] += gAnaMagn[k]*d;
2138  gSynFreq[index] = gAnaFreq[k] * pitchShift;
2139  }
2140  }
2141 
2142  /* ***************** SYNTHESIS ******************* */
2143  /* this is the synthesis step */
2144  for (k = 0; k < fftFrameSize2; k++) {
2145 
2146  /* get magnitude and true frequency from synthesis arrays */
2147  magn = gSynMagn[k];
2148  //tmp = gSynFreq[k];
2149 
2150  /* subtract bin mid frequency */
2151  /* get bin deviation from freq deviation */
2152  /* take osamp into account */
2153  /* add the overlap phase advance back in */
2154  tmp = ((gSynFreq[k] - fpb[k]) * freqPerBin1) + expect[k];
2155 
2156  /* accumulate delta phase to get bin phase */
2157  gSumPhase[k] += tmp;
2158  phase = gSumPhase[k];
2159  if (magn == 0.0) continue;
2160 
2161  /* get real and imag part and re-interleave */
2162  fftw_in[k][0] = magn * cos (phase);
2163  fftw_in[k][1] = magn * sin (phase);
2164  }
2165 
2166  /* do inverse transform */
2167  fftwf_execute(ftPlanInverse);
2168  /* do windowing and add to output accumulator */
2169  for(k=0; k < fftFrameSize; k++) {
2170  gOutputAccum[k] += hanningd[k] * fftw_out[ k][0] ;
2171  }
2172  for (k = 0; k < stepSize; k++) gOutFIFO[k] = gOutputAccum[k];
2173 
2174  /* shift accumulator */
2175  memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
2176 
2177  /* move input FIFO */
2178  for (k = 0; k < inFifoLatency; k++) gInFIFO[k] = gInFIFO[k+stepSize];
2179  }
2180  }
2181  resamp.up(fftFrameSize,resampin2,resampout);
2182  aio = 0;
2183  }
2184  if(l) {
2185  for (i = 0; i < count; i++){
2186  outdata[i] = ((fSlow0 * resampout[aio]) + (fSlow1 *indata2[aio]));
2187  aio++;
2188  }
2189  } else {
2190  for (i = 0; i < count; i++){
2191  outdata[i] = ((fSlow0 * resampout[aio]) + (fSlow1 *indata[i]));
2192  aio++;
2193  }
2194  }
2195 }
2196 
2197 int smbPitchShift::register_par(const ParamReg& reg)
2198 {
2199  reg.registerVar("smbPitchShift.semitone", N_("Detune"), "S", "", &semitones, 0.0, -12., 12., 0.1);
2200  static const value_pair octave_values[] = {{"unison"},{"octave up"},{"octave down"},{0}};
2201  reg.registerIEnumVar("smbPitchShift.octave",N_("add harmonics"),"B",N_("add harmonics"),octave_values,&octave, 0);
2202  static const value_pair latency_values[] = {{"latency "},{"compensate"},{0}};
2203  reg.registerEnumVar("smbPitchShift.l",N_("compensate latency"),"S",N_("compensate latency"),latency_values,&l, 0.0f, 0.0f, 1.0f, 1.0f);
2204  static const value_pair latency_set[] = {{"high quality"},{"low quality"},{"realtime"},{0}};
2205  reg.registerIEnumVar("smbPitchShift.latency",N_("latency settings"),"B",N_("latency settings"),latency_set,&latency, 0);
2206  reg.registerVar("smbPitchShift.wet", N_("Wet"), "S", N_("Wet amount"), &wet, 50.0, 0.0, 100.0, 1);
2207  reg.registerVar("smbPitchShift.dry", N_("Dry"), "S", N_("Dry amount"), &dry, 50.0, 0.0, 100.0, 1);
2208  reg.registerVar("smbPitchShift.a", N_("low"), "S", N_("Sub"), &a, 1.0, 0.0, 2.0, 0.01);
2209  reg.registerVar("smbPitchShift.b", N_("middle low"), "S", N_("Low"), &b, 1.0, 0.0, 2.0, 0.01);
2210  reg.registerVar("smbPitchShift.c", N_("middle treble"), "S", N_("Mid"), &c, 1.0, 0.0, 2.0, 0.01);
2211  reg.registerVar("smbPitchShift.d", N_("treble"), "S", N_("Hi"), &d, 1.0, 0.0, 2.0, 0.01);
2212  param["smbPitchShift.latency"].signal_changed_int().connect(
2213  sigc::hide(sigc::mem_fun(this, &smbPitchShift::change_latency)));
2214  return 0;
2215 }
2216 
2217 int smbPitchShift::registerparam(const ParamReg& reg)
2218 {
2219  return static_cast<smbPitchShift*>(reg.plugin)->register_par(reg);
2220 }
2221 
2222 int smbPitchShift::load_ui_f(const UiBuilder& b, int form)
2223 {
2224  if (form & UI_FORM_GLADE) {
2225  b.load_glade_file("gx_detune_ui.glade");
2226  return 0;
2227  }
2228  if (form & UI_FORM_STACK) {
2229  b.openHorizontalhideBox("");
2230  {
2231  b.create_master_slider("smbPitchShift.semitone",N_("Detune"));
2232  }
2233  b.closeBox();
2234  b.openVerticalBox("");
2235  {
2236  b.openHorizontalBox("");
2237  {
2238  b.openVerticalBox("");
2239  {
2240  b.insertSpacer();
2241  b.create_selector_no_caption("smbPitchShift.octave");
2242  b.create_selector_no_caption("smbPitchShift.l");
2243  b.create_selector_no_caption("smbPitchShift.latency");
2244  b.insertSpacer();
2245  }
2246  b.closeBox();
2247  b.create_mid_rackknob("smbPitchShift.semitone",N_("Detune"));
2248  b.create_small_rackknobr("smbPitchShift.dry",N_("Dry"));
2249  b.create_small_rackknobr("smbPitchShift.wet",N_("Wet"));
2250  }
2251  b.closeBox();
2252  b.insertSpacer();
2253  b.openHorizontalBox("");
2254  {
2256  b.create_small_rackknobr("smbPitchShift.a",N_("Lo"));
2258  b.create_small_rackknobr("smbPitchShift.b",N_("LoMid"));
2260  b.create_small_rackknobr("smbPitchShift.c",N_("HiMid"));
2262  b.create_small_rackknobr("smbPitchShift.d",N_("Hi"));
2263  }
2264  b.closeBox();
2265  }
2266  b.closeBox();
2267  return 0;
2268  }
2269  return -1;
2270 }
2271 
2272 int smbPitchShift::activate_static(bool start, PluginDef *p)
2273 {
2274  return static_cast<smbPitchShift*>(p)->activate(start);
2275 }
2276 
2277 int smbPitchShift::load_ui_f_static(const UiBuilder& b, int form)
2278 {
2279  return static_cast<smbPitchShift*>(b.plugin)->load_ui_f(b, form);
2280 }
2281 
2282 void smbPitchShift::del_instance(PluginDef *p)
2283 {
2284  delete static_cast<smbPitchShift*>(p);
2285 }
2286 
2287 
2288 } // namespace gx_engine
bool operator==(const GxSeqSettings &seqset) const
ParameterV< GxSeqSettings > SeqParameter
#define always_inline
void write_kv(const char *key, float v)
Definition: gx_json.h:81
static void init(unsigned int samplingFreq, PluginDef *p)
CmdConnection::msg_type start
Definition: jsonrpc.cpp:255
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
void get_sched_priority(int &policy, int &priority, int prio_dim=0)
void up(int count, float *input, float *output)
void readJSON(gx_system::JsonParser &jp)
void(* insertSpacer)()
Definition: gx_plugin.h:78
float sqrf(float x)
const std::vector< int > & getseqline() const
BasicOptions & get_options()
Definition: gx_system.h:511
ParameterV< GxJConvSettings > JConvParameter
PluginDef * plugin
Definition: gx_plugin.h:64
const Gainline & getGainline() const
void end_array(bool nl=false)
Definition: gx_json.cpp:192
bool operator==(const GxJConvSettings &jcset) const
static int activate(bool start, PluginDef *pdef)
struct gx_engine::CabEntry cab_table[]
virtual void check_update()=0
const char * value_id
Definition: gx_plugin.h:118
PluginDef * plugin
Definition: gx_plugin.h:123
void set_pdef(PluginDef *p)
#define N_(String)
const char * name
Definition: gx_plugin.h:188
bool set(const GxJConvSettings &val) const
#define __rt_func
Definition: gx_compiler.h:4
bool get_on_off() const
float *(* registerNonMidiSharedVar)(const char *id, float *var, bool preset, bool nosave, float val, float low, float up, float step)
Definition: gx_plugin.h:140
#define UI_LABEL_INVERSE
Definition: gx_plugin.h:45
float *(* registerVar)(const char *id, const char *name, const char *tp, const char *tooltip, float *var, float val, float low, float up, float step)
Definition: gx_plugin.h:124
void(* registerEnumVar)(const char *id, const char *name, const char *tp, const char *tooltip, const value_pair *values, float *var, float val, float low, float up, float step)
Definition: gx_plugin.h:132
#define UI_FORM_GLADE
Definition: gx_plugin.h:61
const char * description
Definition: gx_plugin.h:191
ParameterV(const string &id, ConvolverAdapter &conv, GxJConvSettings *v)
void change_buffersize(unsigned int size)
void(* closeBox)()
Definition: gx_plugin.h:77
void change_buffersize(unsigned int)
void write_key(const char *p, bool nl=false)
Definition: gx_json.cpp:200
bool set(const GxSeqSettings &val) const
#define M_PI
const char ** groups
Definition: gx_plugin.h:189
void(* load_glade_file)(const char *fname)
Definition: gx_plugin.h:66
#define FAUSTFLOAT
const char * shortname
Definition: gx_plugin.h:193
CabDesc * data
const char * category
Definition: gx_plugin.h:192
virtual void readJSON_value(gx_system::JsonParser &jp)
void(* registerIEnumVar)(const char *id, const char *name, const char *tp, const char *tooltip, const value_pair *values, int *var, int val)
Definition: gx_plugin.h:138
deletefunc delete_instance
Definition: gx_plugin.h:206
virtual bool start(bool force=false)=0
ParameterV(const string &id, GxSeqSettings *v)
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
bool read_kv(const char *key, float &v)
Definition: gx_json.cpp:511
ConvolverMonoAdapter(EngineControl &engine, sigc::slot< void > sync, ParamMap &param)
smbPitchShift(ParamMap &param_, EngineControl &engine, sigc::slot< void > sync)
const char * value_id
CabinetConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
int setup(int _inputRate, int _outputRate)
GxSeqSettings & operator=(GxSeqSettings const &seqset)
#define PLUGINDEF_VERSION
Definition: gx_plugin.h:181
void(* openHorizontalBox)(const char *label)
Definition: gx_plugin.h:71
registerfunc register_params
Definition: gx_plugin.h:202
bool find_dir(std::string *d, const std::string &filename) const
Definition: gx_system.cpp:264
#define min(x, y)
PreampConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
static PluginDef outputgate
CabinetStereoConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
const char * id
Definition: gx_plugin.h:187
virtual void serializeJSON(gx_system::JsonWriter &jw)
virtual void readJSON_value(gx_system::JsonParser &jp)
static void init(unsigned int samplingFreq, PluginDef *p)
const char * value_label
Definition: gx_plugin.h:119
BaseConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
void(* create_small_rackknobr)(const char *id, const char *label)
Definition: gx_plugin.h:98
void down(int count, float *input, float *output)
void(* create_mid_rackknob)(const char *id, const char *label)
Definition: gx_plugin.h:103
int flags
Definition: gx_plugin.h:185
void writeJSON(gx_system::JsonWriter &w) const
virtual void writeJSON(gx_system::JsonWriter &jw) const
#define MAX_FRAME_LENGTH
const PathList & get_IR_pathlist() const
Definition: gx_system.h:377
ContrastConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
#define UI_FORM_STACK
Definition: gx_plugin.h:60
const char * value_id
void writeJSON(gx_system::JsonWriter &w) const
FixedBaseConvolver(EngineControl &engine, sigc::slot< void > sync, gx_resample::BufferResampler &resamp)
PreDesc * data
void gx_print_warning(const char *, const std::string &)
Definition: gx_logging.cpp:161
void(* openHorizontalhideBox)(const char *label)
Definition: gx_plugin.h:72
ConvolverAdapter(EngineControl &engine, sigc::slot< void > sync, ParamMap &param)
activatefunc activate_plugin
Definition: gx_plugin.h:201
const char * value_label
virtual void check_update()=0
process_stereo_audio stereo_audio
Definition: gx_plugin.h:198
std::string replace_symbol(const std::string &dir) const
Definition: gx_system.cpp:287
void readJSON(gx_system::JsonParser &jp)
string current_value() const
Definition: gx_json.h:143
void(* set_next_flags)(int flags)
Definition: gx_plugin.h:79
void(* registerNonMidiFloatVar)(const char *id, float *var, bool preset, bool nosave, float val, float low, float up, float step)
Definition: gx_plugin.h:130
inifunc set_samplerate
Definition: gx_plugin.h:200
process_mono_audio mono_audio
Definition: gx_plugin.h:197
virtual void serializeJSON(gx_system::JsonWriter &jw)
sigc::signal< void, const GxSeqSettings * > & signal_changed()
void set_on_off(bool v) const
GxJConvSettings & operator=(GxJConvSettings const &jcset)
float current_value_float()
Definition: gx_json.h:146
virtual void serializeJSON(gx_system::JsonWriter &jw)
token next(token expect=no_token)
Definition: gx_json.cpp:496
const char * value_label
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
struct gx_engine::PreEntry pre_table[]
int version
Definition: gx_plugin.h:184
const PrefixConverter & get_IR_prefixmap() const
Definition: gx_system.h:378
uiloader load_ui
Definition: gx_plugin.h:203
static ParameterV< GxJConvSettings > * insert_param(ParamMap &pmap, const string &id, ConvolverAdapter &conv, GxJConvSettings *v)
virtual bool start(bool force=false)=0
static ParameterV< GxSeqSettings > * insert_param(ParamMap &pmap, const string &id, GxSeqSettings *v)
void(* create_master_slider)(const char *id, const char *label)
Definition: gx_plugin.h:84
void end_object(bool nl=false)
Definition: gx_json.cpp:176
ConvolverStereoAdapter(EngineControl &engine, sigc::slot< void > sync, ParamMap &param)
void(* create_selector_no_caption)(const char *id)
Definition: gx_plugin.h:88
void(* openVerticalBox)(const char *label)
Definition: gx_plugin.h:68
virtual void writeJSON(gx_system::JsonWriter &jw) const
static int activate(bool start, PluginDef *pdef)
sigc::signal< void, unsigned int > & signal_buffersize_change()