diff --git a/calf.desktop.in b/calf.desktop.in index a69e966cd..534e02a4b 100644 --- a/calf.desktop.in +++ b/calf.desktop.in @@ -1,15 +1,22 @@ [Desktop Entry] +Categories=Application;AudioVideo;Audio;GNOME +Exec=calfjackhost +Icon=calf +Terminal=false +Type=Application +Version=@VERSION@ + Name=Calf Plugin Pack for JACK +Name[fr]=Ensemble de greffons Calf pour JACK Name[pl]=Zestaw wtyczek Calf +Name[pt_BR]=Conjunto de Ferramentas e Efeitos do Calf para o JACK Name[ru]=Набор эффектов и инструментов Calf для JACK -Name[fr]=Ensemble de greffons Calf pour JACK -Version=@VERSION@ + Comment=Process and produce sounds using a set of plugins with JACK interface +Comment[fr]=Traitement et production de sons utilisant un ensemble de greffons avec une interface JACK Comment[pl]=Przetwarzaj i generuj dźwięk używając zestawu wtyczek zgodnych z JACK +Comment[pt_BR]=O ‘Calf Plugin Pack for JACK’ ou ‘Calf Studio Gear’ é um conjunto de ferramentas que possui efeitos sonoros e instrumentos musicais conectável através do servidor de áudio Jack ou como um módulo de extensão em qualquer hospedeiro de áudio capaz de iniciar dispositivos compiladores LV2, por exemplo, é altamente recomendado para a estação de trabalho de áudio digital Ardour e Rosegarden Comment[ru]=Обработка и создание музыки при помощи эффектов и инструментов через JACK -Comment[fr]=Traitement et production de sons utilisant un ensemble de greffons avec une interface JACK -Exec=calfjackhost -Terminal=false -Type=Application -Categories=Application;AudioVideo;Audio;GNOME -Icon=calf + +Keywords=Audio,Plug-in;Effect;Instrument; +Keywords[pt_BR]=Áudio,Complementos;Módulo;Extensão,Efeitos;Instrumentos;Música,Som; diff --git a/src/Makefile.am b/src/Makefile.am index 2c4f13a97..6844d5a1b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,11 +39,7 @@ calfbenchmark_LDADD = libcalf.la libcalf_la_SOURCES = audio_fx.cpp analyzer.cpp lv2wrap.cpp metadata.cpp modules_tools.cpp modules_delay.cpp modules_comp.cpp modules_limit.cpp modules_dist.cpp modules_filter.cpp modules_mod.cpp modules_pitch.cpp fluidsynth.cpp giface.cpp monosynth.cpp organ.cpp osctl.cpp plugin.cpp preset.cpp synth.cpp utils.cpp wavetable.cpp modmatrix.cpp pffft.c shaping_clipper.cpp libcalf_la_LIBADD = $(FLUIDSYNTH_DEPS_LIBS) $(GLIB_DEPS_LIBS) -if USE_DEBUG libcalf_la_LDFLAGS = -rpath $(pkglibdir) -avoid-version -module -lexpat -disable-static -else -libcalf_la_LDFLAGS = -rpath $(pkglibdir) -avoid-version -module -lexpat -disable-static -export-symbols-regex "lv2_descriptor" -endif if USE_LV2_GUI @@ -55,9 +51,9 @@ pkglib_LTLIBRARIES += libcalflv2gui.la libcalflv2gui_la_SOURCES = gui.cpp gui_config.cpp gui_controls.cpp ctl_curve.cpp ctl_keyboard.cpp ctl_knob.cpp ctl_led.cpp ctl_tube.cpp ctl_vumeter.cpp ctl_frame.cpp ctl_fader.cpp ctl_buttons.cpp ctl_notebook.cpp ctl_meterscale.cpp ctl_combobox.cpp ctl_tuner.cpp ctl_phasegraph.cpp ctl_pattern.cpp metadata.cpp giface.cpp plugin_gui_window.cpp preset.cpp preset_gui.cpp lv2gui.cpp osctl.cpp utils.cpp ctl_linegraph.cpp drawingutils.cpp if USE_DEBUG -libcalflv2gui_la_LDFLAGS = -rpath $(lv2dir) -avoid-version -module -lexpat $(GUI_DEPS_LIBS) -disable-static +libcalflv2gui_la_LDFLAGS = -rpath $(pkglibdir) -avoid-version -module -lexpat $(GUI_DEPS_LIBS) -disable-static else -libcalflv2gui_la_LDFLAGS = -rpath $(lv2dir) -avoid-version -module -lexpat -export-symbols-regex "lv2ui_descriptor" $(GUI_DEPS_LIBS) -disable-static +libcalflv2gui_la_LDFLAGS = -rpath $(pkglibdir) -avoid-version -module -lexpat -export-symbols-regex "lv2ui_descriptor" $(GUI_DEPS_LIBS) -disable-static endif if HAVE_LD_NODELETE @@ -84,7 +80,10 @@ if USE_GUI endif if USE_LV2 install -d -m 755 $(DESTDIR)$(lv2dir) - ln -sf $(pkglibdir)/calf.so $(DESTDIR)$(lv2dir)/calf.so + ln -sf $(pkglibdir)/libcalf.so $(DESTDIR)$(lv2dir)/calf.so +if USE_LV2_GUI + ln -sf $(pkglibdir)/libcalflv2gui.so $(DESTDIR)$(lv2dir)/calflv2gui.so +endif rm -f $(DESTDIR)$(lv2dir)/*.ttl $(top_builddir)/src/calfmakerdf -m ttl -p $(DESTDIR)$(lv2dir)/ -d $(DESTDIR)$(pkgdatadir)/ if USE_SORDI diff --git a/src/calf/modules_filter.h b/src/calf/modules_filter.h index 2671752a6..e1a54292a 100644 --- a/src/calf/modules_filter.h +++ b/src/calf/modules_filter.h @@ -235,8 +235,8 @@ public frequency_response_line_graph float values[] = {0,0,0,0}; for (uint32_t i = offset; i < offset + numsamples; i++) { outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; - //float values[] = {ins[0][i],ins[1][i],outs[0][i],outs[1][i]}; + if(outs[1]) + outs[1][i] = ins[ins[1]?1:0][i]; meters.process(values); ostate = -1; } @@ -250,19 +250,24 @@ public frequency_response_line_graph if (outputs_mask & 1) { ostate |= FilterClass::process_channel(0, ins[0] + offset, outs[0] + offset, numnow, inputs_mask & 1, *params[Metadata::param_level_in], *params[Metadata::param_level_out]); } - if (outputs_mask & 2) { - ostate |= FilterClass::process_channel(1, ins[1] + offset, outs[1] + offset, numnow, inputs_mask & 2, *params[Metadata::param_level_in], *params[Metadata::param_level_out]); + if (outputs_mask & 2 && outs[1]) { + ostate |= FilterClass::process_channel(1, ins[(ins[1] ? 1 : 0)] + offset, outs[1] + offset, numnow, inputs_mask & 2, *params[Metadata::param_level_in], *params[Metadata::param_level_out]); } if (timer.elapsed()) { on_timer(); } for (uint32_t i = offset; i < offset + numnow; i++) { - float values[] = {ins[0][i] * *params[Metadata::param_level_in], ins[1][i] * *params[Metadata::param_level_in], outs[0][i], outs[1][i]}; + float values[] = { + ins[0][i] * *params[Metadata::param_level_in], + (ins[ins[1]?1:0][i]) * *params[Metadata::param_level_in], + outs[0][i], + (outs[outs[1]?1:0][i]) + }; meters.process(values); } offset += numnow; } - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); } meters.fall(orig_numsamples); return ostate; diff --git a/src/calf/orfanidis_eq.h b/src/calf/orfanidis_eq.h index 47abf5bea..61e51ec76 100644 --- a/src/calf/orfanidis_eq.h +++ b/src/calf/orfanidis_eq.h @@ -748,7 +748,7 @@ class EllipticTypeBPFilter : public BPFilter { std::vector v = landen(k, tol); std::transform(v.begin(), v.end(), v.begin(), - bind2nd(std::plus(), 1.0)); + bind(std::plus(), std::placeholders::_1, 1.0)); K = std::accumulate(v.begin(), v.end(), 1, std::multiplies()) * M_PI/2.0; @@ -764,7 +764,7 @@ class EllipticTypeBPFilter : public BPFilter { std::vector vp = landen(kp, tol); std::transform(vp.begin(), vp.end(), vp.begin(), - bind2nd(std::plus(), 1.0)); + bind(std::plus(), std::placeholders::_1, 1.0)); Kprime = std::accumulate(vp.begin(), vp.end(), 1.0, std::multiplies()) * M_PI/2.0; diff --git a/src/giface.cpp b/src/giface.cpp index ae7bce6e1..ed31ead3c 100644 --- a/src/giface.cpp +++ b/src/giface.cpp @@ -324,7 +324,7 @@ char *calf_plugins::load_gui_xml(const std::string &plugin_id) try { return strdup(calf_utils::load_file((std::string(PKGLIBDIR) + "/" + plugin_id + ".xml").c_str()).c_str()); } - catch(file_exception e) + catch(const file_exception &e) { return NULL; } diff --git a/src/gui.cpp b/src/gui.cpp index 8283971b9..42f4d4101 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -502,10 +502,32 @@ bool window_update_controller::check_redraw(GtkWidget *toplevel) gui_environment::gui_environment() { keyfile = g_key_file_new(); + + string filename; - gchar *fn = g_build_filename(getenv("HOME"), ".calfrc", NULL); - string filename = fn; - g_free(fn); + gchar *fn_under_home = g_build_filename(getenv("HOME"), ".calfrc", NULL); + char *xdg_conf = getenv("XDG_CONFIG_HOME"); + gchar *calf_conf_dir = g_build_filename(xdg_conf, "calf", NULL); + gchar *fn_under_conf = g_build_filename(calf_conf_dir, "calfrc", NULL); + + //if $HOME/.calfrc exists or XDG_CONFIG_HOME is not set use $HOME/.calfrc + if(g_file_test(fn_under_home, G_FILE_TEST_IS_REGULAR) || xdg_conf == NULL) { + filename = fn_under_home; + } else { + //if $XDG_CONFIG_HOME/calf does not exist, create it + if(!g_file_test(calf_conf_dir, G_FILE_TEST_EXISTS)) + g_mkdir_with_parents(calf_conf_dir, 0755); + + if(g_file_test(calf_conf_dir, G_FILE_TEST_IS_DIR)) + filename = fn_under_conf; + else + filename = fn_under_home; //failed creating directory: fall back to $HOME/.calfrc + } + + g_free(calf_conf_dir); + g_free(fn_under_conf); + g_free(fn_under_home); + g_key_file_load_from_file(keyfile, filename.c_str(), (GKeyFileFlags)(G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS), NULL); config_db = new calf_utils::gkeyfile_config_db(keyfile, filename.c_str(), "gui"); diff --git a/src/modules_comp.cpp b/src/modules_comp.cpp index 044e5584a..3a2cf2f17 100644 --- a/src/modules_comp.cpp +++ b/src/modules_comp.cpp @@ -785,7 +785,8 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, // everything bypassed while(offset < numsamples) { outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; + if(outs[1]) + outs[1][offset] = ins[ins[1]?1:0][offset]; float values[] = {0, 0, 1}; meters.process(values); ++offset; @@ -802,9 +803,9 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, float outL = 0.f; float outR = 0.f; float inL = ins[0][offset]; - float inR = ins[1][offset]; + float inR = ins[ins[1]?1:0][offset]; float Lin = ins[0][offset]; - float Rin = ins[1][offset]; + float Rin = ins[ins[1]?1:0][offset]; // in level inR *= *params[param_level_in]; @@ -824,7 +825,8 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, // send to output outs[0][offset] = outL; - outs[1][offset] = outR; + if(outs[1]) + outs[1][offset] = outR; float values[] = {std::max(inL, inR), std::max(outL, outR), compressor.get_comp_level()}; meters.process(values); @@ -832,7 +834,7 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, // next sample ++offset; } // cycle trough samples - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); } meters.fall(numsamples); return outputs_mask; @@ -2561,7 +2563,7 @@ uint32_t transientdesigner_audio_module::process(uint32_t offset, uint32_t numsa bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples); for(uint32_t i = offset; i < offset + numsamples; i++) { float L = ins[0][i]; - float R = ins[1][i]; + float R = ins[ins[1]?1:0][i]; meter_inL = 0.f; meter_inR = 0.f; meter_outL = 0.f; @@ -2569,8 +2571,8 @@ uint32_t transientdesigner_audio_module::process(uint32_t offset, uint32_t numsa float s = (fabs(L) + fabs(R)) / 2; if(bypassed) { outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; - + if(outs[1]) + outs[1][i] = ins[ins[1]?1:0][i]; } else { // levels in L *= *params[param_level_in]; @@ -2600,10 +2602,12 @@ uint32_t transientdesigner_audio_module::process(uint32_t offset, uint32_t numsa // output if (*params[param_listen] > 0.5) { outs[0][i] = s; - outs[1][i] = s; + if(outs[1]) + outs[1][i] = s; } else { outs[0][i] = L; - outs[1][i] = R; + if(outs[1]) + outs[1][i] = R; } meter_outL = L; meter_outR = R; @@ -2677,7 +2681,7 @@ uint32_t transientdesigner_audio_module::process(uint32_t offset, uint32_t numsa meters.process(mval); } if (!bypassed) - bypass.crossfade(ins, outs, 2, orig_offset, numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, numsamples); meters.fall(numsamples); return outputs_mask; } diff --git a/src/modules_delay.cpp b/src/modules_delay.cpp index cee4cd13b..b2b626271 100644 --- a/src/modules_delay.cpp +++ b/src/modules_delay.cpp @@ -432,7 +432,7 @@ void comp_delay_audio_module::set_sample_rate(uint32_t sr) uint32_t comp_delay_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { bool bypassed = bypass.update(*params[param_bypass] > 0.5f, numsamples); - bool stereo = ins[1]; + bool stereo = ins[1] && outs[1]; uint32_t w_ptr = write_ptr; uint32_t b_mask = buf_size - 2; uint32_t end = offset + numsamples; @@ -472,7 +472,7 @@ uint32_t comp_delay_audio_module::process(uint32_t offset, uint32_t numsamples, w_ptr = (w_ptr + 2) & b_mask; r_ptr = (r_ptr + 2) & b_mask; - float values[] = {L, R, outs[0][i], outs[1][i]}; + float values[] = {L, R, outs[0][i], outs[(int)stereo][i]}; meters.process(values); } } diff --git a/src/modules_dist.cpp b/src/modules_dist.cpp index f87e07f14..aff9b92f3 100644 --- a/src/modules_dist.cpp +++ b/src/modules_dist.cpp @@ -158,12 +158,12 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u if(bypassed) { // everything bypassed while(offset < numsamples) { - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { outs[0][offset] = ins[0][offset]; outs[1][offset] = ins[1][offset]; - } else if(in_count > 1) { + } else if(ins[1]) { outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2; - } else if(out_count > 1) { + } else if(outs[1]) { outs[0][offset] = ins[0][offset]; outs[1][offset] = ins[0][offset]; } else { @@ -181,7 +181,7 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u // cycle through samples float out[2], in[2] = {0.f, 0.f}; int c = 0; - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { // stereo in/stereo out // handle full stereo in[0] = ins[0][offset]; @@ -225,13 +225,13 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u proc[i] *= 1 + (*params[param_level_in] - 1) / 32; } - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { // full stereo out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; outs[0][offset] = out[0]; out[1] = ((proc[1] * *params[param_mix]) + in[1] * (1 - *params[param_mix])) * *params[param_level_out]; outs[1][offset] = out[1]; - } else if(out_count > 1) { + } else if(outs[1]) { // mono -> pseudo stereo out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; outs[0][offset] = out[0]; @@ -243,7 +243,7 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u out[0] = ((proc[0] * *params[param_mix]) + in[0] * (1 - *params[param_mix])) * *params[param_level_out]; outs[0][offset] = out[0]; } - float values[] = {in[0], in[1], out[0], out[1]}; + float values[] = {in[0], in[1], out[0], out[1]}; meters.process(values); // next sample @@ -269,7 +269,7 @@ uint32_t saturator_audio_module::process(uint32_t offset, uint32_t numsamples, u hp[1][3].sanitize(); p[0].sanitize(); p[1].sanitize(); - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); } meters.fall(numsamples); return outputs_mask; @@ -350,12 +350,12 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin if(bypassed) { // everything bypassed while(offset < numsamples) { - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { outs[0][offset] = ins[0][offset]; outs[1][offset] = ins[1][offset]; - } else if(in_count > 1) { + } else if(ins[1]) { outs[0][offset] = (ins[0][offset] + ins[1][offset]) / 2; - } else if(out_count > 1) { + } else if(outs[1]) { outs[0][offset] = ins[0][offset]; outs[1][offset] = ins[0][offset]; } else { @@ -381,7 +381,7 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin float maxDrive = 0.f; int c = 0; - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { // stereo in/stereo out // handle full stereo in[0] = ins[0][offset]; @@ -420,14 +420,14 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin } maxDrive = dist[0].get_distortion_level() * *params[param_amount]; - if(in_count > 1 && out_count > 1) { + if(ins[1] && outs[1]) { maxDrive = std::max(maxDrive, dist[1].get_distortion_level() * *params[param_amount]); // full stereo out[0] = (proc[0] * *params[param_amount] + in2out * in[0]) * *params[param_level_out]; out[1] = (proc[1] * *params[param_amount] + in2out * in[1]) * *params[param_level_out]; outs[0][offset] = out[0]; outs[1][offset] = out[1]; - } else if(out_count > 1) { + } else if(outs[1]) { // mono -> pseudo stereo out[1] = out[0] = (proc[0] * *params[param_amount] + in2out * in[0]) * *params[param_level_out]; outs[0][offset] = out[0]; @@ -443,7 +443,7 @@ uint32_t exciter_audio_module::process(uint32_t offset, uint32_t numsamples, uin // next sample ++offset; } // cycle trough samples - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); // clean up hp[0][0].sanitize(); hp[1][0].sanitize(); @@ -611,7 +611,8 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples out[1] = proc[1] * *params[param_amount] * *params[param_level_out]; else out[1] = (proc[1] * *params[param_amount] + in[1]) * *params[param_level_out]; - outs[1][offset] = out[1]; + if(outs[1]) + outs[1][offset] = out[1]; maxDrive = std::max(dist[0].get_distortion_level() * *params[param_amount], dist[1].get_distortion_level() * *params[param_amount]); } else if(out_count > 1) { @@ -622,7 +623,8 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples out[0] = (proc[0] * *params[param_amount] + in[0]) * *params[param_level_out]; outs[0][offset] = out[0]; out[1] = out[0]; - outs[1][offset] = out[1]; + if(outs[1]) + outs[1][offset] = out[1]; maxDrive = dist[0].get_distortion_level() * *params[param_amount]; } else { // stereo -> mono @@ -640,7 +642,7 @@ uint32_t bassenhancer_audio_module::process(uint32_t offset, uint32_t numsamples // next sample ++offset; } // cycle trough samples - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); // clean up lp[0][0].sanitize(); lp[1][0].sanitize(); @@ -742,10 +744,11 @@ uint32_t vinyl_audio_module::process(uint32_t offset, uint32_t numsamples, uint3 } for(uint32_t i = offset; i < offset + numsamples; i++) { float L = ins[0][i]; - float R = ins[1][i]; + float R = ins[ins[1]?1:0][i]; if(bypassed) { outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; + if(outs[1]) + outs[1][i] = ins[ins[1]?1:0][i]; float values[] = {0, 0, 0, 0}; meters.process(values); } else { @@ -791,7 +794,8 @@ uint32_t vinyl_audio_module::process(uint32_t offset, uint32_t numsamples, uint3 // output outs[0][i] = L; - outs[1][i] = R; + if(outs[1]) + outs[1][i] = R; // sanitize filters if (*params[param_aging] > 0.f) { @@ -801,12 +805,12 @@ uint32_t vinyl_audio_module::process(uint32_t offset, uint32_t numsamples, uint3 } } - float values[] = {inL, inR, outs[0][i], outs[1][i]}; + float values[] = {inL, inR, outs[0][i], outs[1] ? outs[1][i]: outs[0][i]}; meters.process(values); } } if (bypassed) - bypass.crossfade(ins, outs, 2, orig_offset, numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, numsamples); meters.fall(numsamples); return outputs_mask; } @@ -832,7 +836,7 @@ void vinyl_audio_module::post_instantiate(uint32_t sr) settings = new_fluid_settings(); fluid_settings_setnum(settings, "synth.sample-rate", sr); fluid_settings_setint(settings, "synth.polyphony", 32); - fluid_settings_setint(settings, "synth.midi-channels", _synths); + fluid_settings_setint(settings, "synth.midi-channels", _synths > 16 ? _synths : 16); // = max(16, _synths) fluid_settings_setint(settings, "synth.reverb.active", 0); fluid_settings_setint(settings, "synth.chorus.active", 0); @@ -944,12 +948,13 @@ uint32_t tapesimulator_audio_module::process(uint32_t offset, uint32_t numsample uint32_t orig_offset = offset; for(uint32_t i = offset; i < offset + numsamples; i++) { float L = ins[0][i]; - float R = ins[1][i]; + float R = ins[ins[1]?1:0][i]; float Lin = ins[0][i]; - float Rin = ins[1][i]; + float Rin = ins[ins[1]?1:0][i]; if(bypassed) { outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; + if(outs[1]) + outs[1][i] = ins[ins[1]?1:0][i]; float values[] = {0, 0, 0, 0}; meters.process(values); } else { @@ -1042,7 +1047,8 @@ uint32_t tapesimulator_audio_module::process(uint32_t offset, uint32_t numsample // output outs[0][i] = L; - outs[1][i] = R; + if(outs[1]) + outs[1][i] = R; // sanitize filters lp[0][0].sanitize(); @@ -1058,12 +1064,12 @@ uint32_t tapesimulator_audio_module::process(uint32_t offset, uint32_t numsample rms = std::max((double)rms, (double)((fabs(Lo) + fabs(Ro)) / 2)); input = std::max((double)input, (double)((fabs(Lc) + fabs(Rc)) / 2)); - float values[] = {inL, inR, outs[0][i], outs[1][i]}; + float values[] = {inL, inR, outs[0][i], outs[outs[1]?1:0][i]}; meters.process(values); } } if (bypassed) - bypass.crossfade(ins, outs, 2, orig_offset, numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, numsamples); meters.fall(numsamples); return outputs_mask; } @@ -1229,7 +1235,8 @@ uint32_t crusher_audio_module::process(uint32_t offset, uint32_t numsamples, uin // everything bypassed while(offset < numsamples) { outs[0][offset] = ins[0][offset]; - outs[1][offset] = ins[1][offset]; + if(outs[1]) + outs[1][offset] = ins[ins[1]?1:0][offset]; float values[] = {0, 0, 0, 0}; meters.process(values); ++offset; @@ -1245,19 +1252,27 @@ uint32_t crusher_audio_module::process(uint32_t offset, uint32_t numsamples, uin samplereduction[1].set_params(smin + sdiff * (lfo.get_value() + 0.5)); } outs[0][offset] = samplereduction[0].process(ins[0][offset] * *params[param_level_in]); - outs[1][offset] = samplereduction[1].process(ins[1][offset] * *params[param_level_in]); outs[0][offset] = outs[0][offset] * *params[param_morph] + ins[0][offset] * (*params[param_morph] * -1 + 1) * *params[param_level_in]; - outs[1][offset] = outs[1][offset] * *params[param_morph] + ins[1][offset] * (*params[param_morph] * -1 + 1) * *params[param_level_in]; outs[0][offset] = bitreduction.process(outs[0][offset]) * *params[param_level_out]; - outs[1][offset] = bitreduction.process(outs[1][offset]) * *params[param_level_out]; - float values[] = {ins[0][offset], ins[1][offset], outs[0][offset], outs[1][offset]}; + if(outs[1] && ins[1]) { + const float* ins1 = ins[1] ? ins[1] : ins[0]; + outs[1][offset] = samplereduction[1].process(ins1[offset] * *params[param_level_in]); + outs[1][offset] = outs[1][offset] * *params[param_morph] + ins1[offset] * (*params[param_morph] * -1 + 1) * *params[param_level_in]; + outs[1][offset] = bitreduction.process(outs[1][offset]) * *params[param_level_out]; + } + float values[] = { + ins[0][offset], + ins[ins[1]?1:0][offset], + outs[0][offset], + outs[outs[1]?1:0][offset] + }; meters.process(values); // next sample ++offset; if (*params[param_lforate]) lfo.advance(1); } // cycle trough samples - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); } meters.fall(numsamples); return outputs_mask; diff --git a/src/modules_limit.cpp b/src/modules_limit.cpp index 08e86bc7b..42ddf7ddf 100644 --- a/src/modules_limit.cpp +++ b/src/modules_limit.cpp @@ -116,6 +116,8 @@ uint32_t limiter_audio_module::process(uint32_t offset, uint32_t numsamples, uin } else { asc_led -= std::min(asc_led, numsamples); + // allocate fickdich on the stack before entering loop + STACKALLOC(float, fickdich, limiter.overall_buffer_size); while(offset < numsamples) { // cycle through samples float inL = ins[0][offset]; @@ -135,7 +137,6 @@ uint32_t limiter_audio_module::process(uint32_t offset, uint32_t numsamples, uin float tmpR; // process gain reduction - STACKALLOC(float, fickdich, limiter.overall_buffer_size); for (int i = 0; i < *params[param_oversampling]; i ++) { tmpL = samplesL[i]; tmpR = samplesR[i]; @@ -356,6 +357,8 @@ uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsam } else { // process all strips asc_led -= std::min(asc_led, numsamples); + // allocate fickdich on the stack before entering loop to avoid buffer overflow + STACKALLOC(float, fickdich, broadband.overall_buffer_size); while(offset < numsamples) { float inL = 0.f; // input float inR = 0.f; @@ -465,7 +468,6 @@ uint32_t multibandlimiter_audio_module::process(uint32_t offset, uint32_t numsam } // process broadband limiter - STACKALLOC(float, fickdich, broadband.overall_buffer_size); tmpL = resL[o]; tmpR = resR[o]; broadband.process(tmpL, tmpR, fickdich); @@ -754,6 +756,8 @@ uint32_t sidechainlimiter_audio_module::process(uint32_t offset, uint32_t numsam } else { // process all strips asc_led -= std::min(asc_led, numsamples); + // allocate fickdich on the stack before loops to avoid buffer overflow + STACKALLOC(float, fickdich, broadband.overall_buffer_size); while(offset < numsamples) { float inL = 0.f; // input float inR = 0.f; @@ -850,7 +854,6 @@ uint32_t sidechainlimiter_audio_module::process(uint32_t offset, uint32_t numsam } // process broadband limiter - STACKALLOC(float, fickdich, broadband.overall_buffer_size); tmpL = resL[o]; tmpR = resR[o]; broadband.process(tmpL, tmpR, fickdich); diff --git a/src/modules_tools.cpp b/src/modules_tools.cpp index 72a208fcb..ab6220b77 100644 --- a/src/modules_tools.cpp +++ b/src/modules_tools.cpp @@ -80,7 +80,8 @@ uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint for(uint32_t i = offset; i < offset + numsamples; i++) { if(bypassed) { outs[0][i] = ins[0][i]; - outs[1][i] = ins[1][i]; + if(outs[1]) + outs[1][i] = ins[ins[1]?1:0][i]; meter_inL = 0.f; meter_inR = 0.f; meter_outL = 0.f; @@ -92,7 +93,7 @@ uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint meter_outR = 0.f; float L = ins[0][i]; - float R = ins[1][i]; + float R = ins[ins[1]?1:0][i]; // levels in L *= *params[param_level_in]; @@ -221,7 +222,8 @@ uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint //output outs[0][i] = L; - outs[1][i] = R; + if(outs[1]) + outs[1][i] = R; meter_outL = L; meter_outR = R; @@ -237,7 +239,7 @@ uint32_t stereo_audio_module::process(uint32_t offset, uint32_t numsamples, uint meters.process(values); } if (!bypassed) - bypass.crossfade(ins, outs, 2, orig_offset, numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, numsamples); meters.fall(numsamples); return outputs_mask; } @@ -475,7 +477,7 @@ uint32_t analyzer_audio_module::process(uint32_t offset, uint32_t numsamples, ui meter_R = 0.f; float L = ins[0][i]; - float R = ins[1][i]; + float R = ins[ins[1]?1:0][i]; // GUI stuff if(L > 1.f) clip_L = srate >> 3; @@ -513,7 +515,8 @@ uint32_t analyzer_audio_module::process(uint32_t offset, uint32_t numsamples, ui //output outs[0][i] = L; - outs[1][i] = R; + if(outs[1]) + outs[1][i] = R; } // draw meters SET_IF_CONNECTED(clip_L); @@ -867,7 +870,7 @@ uint32_t multispread_audio_module::process(uint32_t offset, uint32_t numsamples, // everything bypassed while(offset < numsamples) { outs[0][offset] = ins[0][offset]; - outs[1][offset] = *params[param_mono] > 0.5 ? ins[0][offset] : ins[1][offset]; + outs[1][offset] = *params[param_mono] > 0.5 ? ins[0][offset] : ins[ins[1]?1:0][offset]; float values[] = {0, 0, 0, 0}; meters.process(values); // phase buffer handling @@ -882,7 +885,7 @@ uint32_t multispread_audio_module::process(uint32_t offset, uint32_t numsamples, // process all strips while(offset < numsamples) { float inL = ins[0][offset]; // input - float inR = *params[param_mono] > 0.5 ? ins[0][offset] : ins[1][offset]; + float inR = *params[param_mono] > 0.5 ? ins[0][offset] : ins[ins[1]?1:0][offset]; float outL = 0.f; // final output float outR = 0.f; @@ -927,7 +930,7 @@ uint32_t multispread_audio_module::process(uint32_t offset, uint32_t numsamples, float values[] = {inL, inR, outL, outR}; meters.process(values); } // cycle trough samples - bypass.crossfade(ins, outs, 2, orig_offset, orig_numsamples); + bypass.crossfade(ins, outs, 1 + (int)(ins[1] && outs[1]), orig_offset, orig_numsamples); } // process (no bypass) meters.fall(numsamples); return outputs_mask;