From 5e7a61fba39b0693de0a5925f880a836d3132c92 Mon Sep 17 00:00:00 2001 From: falkTX Date: Tue, 19 Aug 2014 15:38:13 +0100 Subject: [PATCH] Add openav roomy test example --- Makefile | 2 + avtk/README | 7 + avtk/delaygraph.h | 349 +++++++++++ avtk/dial.h | 183 ++++++ avtk/filtergraph.h | 356 +++++++++++ avtk/image.h | 113 ++++ avtk/masher.h | 253 ++++++++ avtk/parameteric.h | 284 +++++++++ avtk/reverb.h | 221 +++++++ avtk/sidechain_gain.h | 286 +++++++++ avtk/waveshaper.h | 296 ++++++++++ plugins/Makefile.ntk.mk | 130 ++++ plugins/Parameters/DistrhoPluginInfo.h | 1 + plugins/States/DistrhoPluginInfo.h | 1 + plugins/openav-rommy/ArtyFxPluginRoomy.cpp | 204 +++++++ plugins/openav-rommy/ArtyFxUiRoomy.cpp | 93 +++ plugins/openav-rommy/DistrhoPluginInfo.h | 39 ++ plugins/openav-rommy/Makefile | 35 ++ plugins/openav-rommy/README.md | 4 + plugins/openav-rommy/dsp/dsp_reverb.hxx | 511 ++++++++++++++++ plugins/openav-rommy/gui/avtk.h | 28 + plugins/openav-rommy/gui/header.c | 652 +++++++++++++++++++++ plugins/openav-rommy/gui/roomy_widget.cxx | 153 +++++ plugins/openav-rommy/gui/roomy_widget.fl | 110 ++++ plugins/openav-rommy/gui/roomy_widget.h | 66 +++ 25 files changed, 4377 insertions(+) create mode 100644 avtk/README create mode 100644 avtk/delaygraph.h create mode 100644 avtk/dial.h create mode 100644 avtk/filtergraph.h create mode 100644 avtk/image.h create mode 100644 avtk/masher.h create mode 100644 avtk/parameteric.h create mode 100644 avtk/reverb.h create mode 100644 avtk/sidechain_gain.h create mode 100644 avtk/waveshaper.h create mode 100644 plugins/Makefile.ntk.mk create mode 100644 plugins/openav-rommy/ArtyFxPluginRoomy.cpp create mode 100644 plugins/openav-rommy/ArtyFxUiRoomy.cpp create mode 100644 plugins/openav-rommy/DistrhoPluginInfo.h create mode 100644 plugins/openav-rommy/Makefile create mode 100644 plugins/openav-rommy/README.md create mode 100644 plugins/openav-rommy/dsp/dsp_reverb.hxx create mode 100644 plugins/openav-rommy/gui/avtk.h create mode 100644 plugins/openav-rommy/gui/header.c create mode 100644 plugins/openav-rommy/gui/roomy_widget.cxx create mode 100644 plugins/openav-rommy/gui/roomy_widget.fl create mode 100644 plugins/openav-rommy/gui/roomy_widget.h diff --git a/Makefile b/Makefile index 59d6358..ed947d5 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ libs: $(MAKE) -C dpf/dgl plugins: libs + $(MAKE) all -C plugins/openav-rommy $(MAKE) all -C plugins/Parameters $(MAKE) all -C plugins/States @@ -26,6 +27,7 @@ dpf/utils/lv2_ttl_generator: clean: $(MAKE) clean -C dpf/dgl $(MAKE) clean -C dpf/utils/lv2-ttl-generator + $(MAKE) clean -C plugins/openav-rommy $(MAKE) clean -C plugins/Parameters $(MAKE) clean -C plugins/States diff --git a/avtk/README b/avtk/README new file mode 100644 index 0000000..b2823ed --- /dev/null +++ b/avtk/README @@ -0,0 +1,7 @@ + + AVTK : + +These files are AVTK widgets. + +They're included in this repo for convinience. +Details on www.openavproductions.com/avtk diff --git a/avtk/delaygraph.h b/avtk/delaygraph.h new file mode 100644 index 0000000..998ad26 --- /dev/null +++ b/avtk/delaygraph.h @@ -0,0 +1,349 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_DELAY_GRAPH_H +#define AVTK_DELAY_GRAPH_H + +#include +#include + +#include + +#include +#include + +namespace Avtk +{ + +class Delaygraph : public Fl_Slider +{ + public: + Delaygraph(int _x, int _y, int _w, int _h, const char *_label = 0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + mouseClickedX = 0; + mouseClickedY = 0; + mouseClicked = false; + + active = true; + highlight = false; + + volume = 0.5; + waveshapeType = 0.f; + + feedback = 0.0; + } + + /// holds the preset: used from callback() to write value + float waveshapeType; + + void type(float t) {waveshapeType = t; redraw();} + + bool active; + bool highlight; + int x, y, w, h; + const char* label; + + int mouseClickedX; + int mouseClickedY; + bool mouseClicked; + bool mouseRightClicked; + + float feedback; + + float volume; + + void setFeedback(float f) + { + feedback = f; + redraw(); + } + + void setVolume(float e) + { + volume = e; + redraw(); + } + + float getVolume() + { + return volume; + } + + void setActive(bool a) + { + active = a; + redraw(); + } + + bool getActive() + { + return active; + } + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + cairo_set_line_width(cr, 1.5); + + + // fill background + cairo_rectangle( cr, x, y, w, h); + cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill_preserve( cr ); + cairo_clip( cr ); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + cairo_set_line_width( cr, 1.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + + // curved waveshape + /* + float distort = value(); + cairo_move_to( cr, x , y + h ); + cairo_curve_to( cr, x + w * distort, y+h, // control point 1 + x + w - (w * distort), y, // control point 2 + x + w, y ); // end of curve 1, start curve 2 + + cairo_line_to ( cr, x + w, y + h ); + cairo_close_path(cr); + + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_line_width(cr, 2.0); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke(cr); + */ + + float delay = 0; + int delTimeQuantized = int(value() * 3.99f); + switch( delTimeQuantized ) + { + case 0: + delay = 0.125; + break; + case 1: + delay = 0.25; + break; + case 2: + delay = 0.5; + break; + case 3: + delay = 1; + break; + } + + // Actual audio bar + cairo_move_to( cr, x + w/4, y + h - 2 ); + cairo_line_to( cr, x + w/4, y + h - h * 0.75 ); + + cairo_set_line_width(cr, 18); + cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND ); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + //cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke(cr); + + // feedback pointer + cairo_move_to( cr, x + w/4 + w/2*delay, y + h * 3.5 / 4 ); + cairo_line_to( cr, x + w*3.5/4 , y + h * 3.5 / 4 ); + cairo_line_to( cr, x + w*3.5/4 , y + h * 1.0 / 4 ); + + cairo_line_to( cr, x + w*3.5/4 - ((w/2.)*feedback), y + h * 1.0 / 4 ); + + cairo_set_source_rgba( cr, 255 / 255.f, 0 / 255.f , 0 / 255.f , 1 ); + cairo_set_line_width(cr, 1.5); + cairo_stroke( cr ); + + cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-10, y + h * 1.0 / 4 ); + cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-2 , (y + h * 1.0 / 4)+8 ); + cairo_line_to( cr, x + w*3.5/4 - ((w/2)*feedback)-2 , (y + h * 1.0 / 4)-8 ); + cairo_close_path( cr ); + cairo_fill( cr ); + + // changing delay bar + cairo_move_to( cr, x + w/4 + w/2*delay, y + h - 2 ); + cairo_line_to( cr, x + w/4 + w/2*delay, y + h*7/8 - (h*1.5/3.0 * volume) ); + + cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND ); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_line_width(cr, 18); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke(cr); + + + + // stroke outline + cairo_rectangle(cr, x+1, y+1, w-2, h-2); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) + { + case FL_PUSH: + highlight = 0; + mouseRightClicked = false; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + mouseRightClicked = true; + do_callback(); + } + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + float deltaX = mouseClickedX - Fl::event_x(); + float deltaY = mouseClickedY - Fl::event_y(); + + float valX = value() ; + valX -= deltaX / 100.f; + float valY = volume; + valY += deltaY / 100.f; + + if ( valX > 1.0 ) valX = 1.0; + if ( valX < 0.0 ) valX = 0.0; + + if ( valY > 1.0 ) valY = 1.0; + if ( valY < 0.0 ) valY = 0.0; + + //handle_drag( value + deltaY ); + set_value( valX ); + volume = valY; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); + } + } + return 1; + case FL_RELEASE: + mouseRightClicked = false; + if (highlight) { + highlight = 0; + redraw(); + do_callback(); + } + mouseClicked = false; + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + + return 0; + } + + private: +}; + +} // Avtk + +#endif // AVTK_DELAY_GRAPH_H diff --git a/avtk/dial.h b/avtk/dial.h new file mode 100644 index 0000000..b3b2894 --- /dev/null +++ b/avtk/dial.h @@ -0,0 +1,183 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_DIAL_H +#define AVTK_DIAL_H + +#include +#include + +namespace Avtk +{ + +class Dial : public Fl_Slider +{ + public: + Dial(int _x, int _y, int _w, int _h, const char* _label=0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + // * 0.9 for line width to remain inside redraw area + if ( w > h ) + radius = (h / 2.f)*0.9; + else + radius = (w / 2.f)*0.9; + + lineWidth = 1.4 + radius / 12.f; + + mouseClickedY = 0; + mouseClicked = false; + + highlight = false; + label = _label; + } + + bool highlight; + int x, y, w, h; + const char* label; + bool drawLab; + void drawLabel(bool b){drawLab = b; redraw();} + + float radius; + float lineWidth; + + int mouseClickedY; + bool mouseClicked; + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + // label behind value + draw_label(); + + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + + cairo_set_line_width(cr, lineWidth-0.2); + cairo_move_to( cr, x+w/2,y+h/2); + cairo_line_to( cr, x+w/2,y+h/2); + cairo_set_source_rgba(cr, 0.5, 0.5, 0.5, 0.4 ); + + // draw dash guide + double dashes[2]; + cairo_set_line_width(cr, 1.7); + dashes[0] = 3.0; + dashes[1] = 3.0; + cairo_set_dash ( cr, dashes, 2, 0.0); + cairo_stroke(cr); + + cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, 0.75 ); + //cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + float angle = 2.46 + ( 4.54 * value() ); + cairo_set_line_width(cr, lineWidth); + cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, angle ); + cairo_line_to(cr, x+w/2,y+h/2); + cairo_set_source_rgba(cr, 1.0, 0.48, 0, 1.0); + cairo_stroke(cr); + + cairo_restore( cr ); + + if ( drawLab ) + { + //draw_label(); + } + + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Slider::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + //cout << "handle event type = " << event << " value = " << value() << endl; + + //Fl_Slider::handle( event ); + + switch(event) { + case FL_PUSH: + highlight = 1; + redraw(); + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + float deltaY = mouseClickedY - Fl::event_y(); + + float val = value(); + val += deltaY / 100.f; + + if ( val > 1.0 ) val = 1.0; + if ( val < 0.0 ) val = 0.0; + + set_value( val ); + + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); // makes FLTK call "extra" code entered in FLUID + } + } + return 1; + case FL_RELEASE: + if (highlight) { + highlight = 0; + redraw(); + // never do anything after a callback, as the callback + // may delete the widget! + } + mouseClicked = false; + return 1; + default: + return Fl_Widget::handle(event); + } + } +}; + +} // Avtk + +#endif // AVTK_DIAL_H diff --git a/avtk/filtergraph.h b/avtk/filtergraph.h new file mode 100644 index 0000000..b4fc4c6 --- /dev/null +++ b/avtk/filtergraph.h @@ -0,0 +1,356 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_FILTERGRAPH_H +#define AVTK_FILTERGRAPH_H + +#include +#include +#include +#include + +namespace Avtk +{ + +class Filtergraph : public Fl_Slider +{ + public: + enum Type { + FILTER_LOWPASS = 0, + FILTER_HIGHPASS, + FILTER_FLAT, + }; + + Filtergraph(int _x, int _y, int _w, int _h, const char *_label = 0, Type _type = FILTER_LOWPASS): + Fl_Slider(_x, _y, _w, _h, _label) + { + graphType = _type; + + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + mouseClickedX = 0; + mouseClickedY = 0; + mouseClicked = false; + + active = true; + highlight = false; + + value( 0.5 ); + freq = value(); + + gain = 0; + bandwidth = 0; + } + + void setGain(float g) {gain = g; redraw();} + void setBandwidth(float b) {bandwidth = b; redraw();} + float getGain() {return gain;} + float getBandwidth() {return bandwidth;} + + void setType(Type t) + { + graphType = t; + redraw(); + } + + void setActive(bool a) + { + active = a; + redraw(); + } + + bool getActive() + { + return active; + } + + Type graphType; + bool active; + bool highlight; + int x, y, w, h; + const char* label; + + int mouseClickedX; + int mouseClickedY; + bool mouseClicked; + + float freq; + float gain; + float bandwidth; + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + cairo_set_line_width(cr, 1.5); + + + // fill background + cairo_rectangle( cr, x, y, w, h); + cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill( cr ); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + cairo_set_line_width( cr, 1.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + + + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + // change filter type (low|high) based on value: + // 0 to < 0.5 = lowpass + // 0.5 == no change + // 0.5 < 1.0 == highpass + if ( value() < 0.45 ) + { + graphType = FILTER_LOWPASS; + freq = value()*2.f; + } + else if ( value() > 0.55 ) + { + graphType = FILTER_HIGHPASS; + freq = (value()-0.5)*2.f; + } + else + { + graphType = FILTER_FLAT; + } + + switch( graphType ) + { + case FILTER_LOWPASS : drawLowpass(cr); break; + case FILTER_HIGHPASS: drawHighpass(cr); break; + case FILTER_FLAT : drawFlat(cr); break; + default: + cout << "Filtergraph: unknown filter type selected!" << endl; + } + + // stroke outline + cairo_rectangle(cr, x, y, w, h); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.9); + cairo_stroke( cr ); + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) + { + case FL_PUSH: + highlight = 0; + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + do_callback(); + } + redraw(); + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + float deltaX = mouseClickedX - Fl::event_x(); + float deltaY = mouseClickedY - Fl::event_y(); + + float valX = value(); + valX -= deltaX / 100.f; + float valY = gain; + valY += deltaY / 100.f; + + if ( valX > 1.0 ) valX = 1.0; + if ( valX < 0.0 ) valX = 0.0; + + if ( valY > 1.0 ) valY = 1.0; + if ( valY < 0.0 ) valY = 0.0; + + //handle_drag( value + deltaY ); + set_value( valX ); + gain = valY; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); + } + } + return 1; + case FL_RELEASE: + if (highlight) { + highlight = 0; + redraw(); + do_callback(); + } + mouseClicked = false; + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + } + + private: + void drawLowpass(cairo_t* cr) + { + // draw the cutoff line: + // move to bottom left, draw line to middle left + cairo_move_to( cr, x , y + h ); + cairo_line_to( cr, x , y + (h*0.47)); + + float cutoff = 0.1 + freq * 0.85; + + // Curve + cairo_curve_to( cr, x + w * cutoff , y+(h*0.5) , // control point 1 + x + w * cutoff , y+(h * 0.3), // control point 2 + x + w * cutoff + 5, y+ h ); // end of curve 1 + + cairo_close_path(cr); + + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_line_width(cr, 1.5); + cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke( cr ); + } + + void drawHighpass(cairo_t* cr) + { + // draw the cutoff line: + float cutoff = 0.95 - (freq*0.8); + + // move to bottom right + cairo_move_to( cr, x + w, y + h ); + cairo_line_to( cr, x + w, y + (h*0.47)); + + // Curve + cairo_curve_to( cr, x + w - (w*cutoff) , y+(h*0.5) , // control point 1 + x + w - (w*cutoff) , y+(h * 0.3), // control point 2 + x + w - (w*cutoff) - 5, y+ h ); // end of curve 1 + + cairo_close_path(cr); + + // stroke + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_line_width(cr, 1.5); + cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke( cr ); + } + + void drawFlat(cairo_t* cr) + { + // move to bottom right + cairo_move_to( cr, x + w, y + h ); + cairo_line_to( cr, x + w, y + (h*0.47)); + cairo_line_to( cr, x , y + (h*0.47)); + cairo_line_to( cr, x , y + h ); + cairo_close_path(cr); + + // stroke + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_line_width(cr, 1.5); + cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke( cr ); + } + +}; + +} // Avtk + +#endif // AVTK_FILTERGRAPH_H diff --git a/avtk/image.h b/avtk/image.h new file mode 100644 index 0000000..6301bfc --- /dev/null +++ b/avtk/image.h @@ -0,0 +1,113 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_IMAGE_H +#define AVTK_IMAGE_H + +#include +#include +#include +#include +#include + +#include + +using namespace std; + +namespace Avtk +{ + +class Image : public Fl_Widget +{ + public: + Image(int _x, int _y, int _w, int _h, const char *_label=0 ): + Fl_Widget(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + bits = -1; + imageDataPtr = 0; + } + + void setPixbuf(const unsigned char* data, int b ) + { + bits = b; + imageDataPtr = data; + } + + int x, y, w, h; + const char* label; + + int bits; + const unsigned char* imageDataPtr; + + void draw() + { + if ( damage() & FL_DAMAGE_ALL && imageDataPtr != 0 ) + { + fl_draw_image((const uchar*)imageDataPtr, x, y, w, h, bits, w*bits); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) + { + case FL_PUSH: + do_callback(); + return 1; + case FL_DRAG: + return 1; + case FL_RELEASE: + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + } +}; + +} // Avtk + +#endif + diff --git a/avtk/masher.h b/avtk/masher.h new file mode 100644 index 0000000..7dcca4f --- /dev/null +++ b/avtk/masher.h @@ -0,0 +1,253 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_MASHER_H +#define AVTK_MASHER_H + +#include + +namespace Avtk +{ + +class Masher : public Fl_Slider +{ + public: + Masher(int _x, int _y, int _w, int _h, const char *_label =0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + _duration = 0.5; + _volume = 1.0; + _replace = 1.0; + + active = true; + + label = _label; + + highlight = false; + mouseOver = false; + } + + void volume(float v){ _volume = v; redraw(); } + void replace(float r){ _replace = r; redraw(); } + void duration(float d){ _duration = d; redraw(); } + + bool getActive(){return active;} + void setActive(bool a){active = a; redraw();} + + float _volume; + float _duration; + float _replace; + + bool active; + + bool mouseOver; + bool highlight; + int x, y, w, h; + const char* label; + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + // graph + cairo_rectangle( cr, x, y, w, h ); + cairo_set_source_rgb( cr,28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill(cr); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + + // check that its a new "segment" to redraw + int newAngle = ( _duration * 4.9f); + + int xc = (w) / 2.f; + int yc = (h) / 2.f; + + float angle = 0.f; + + if ( newAngle == 0 ) + angle = 0.06; + else if ( newAngle == 1 ) + angle = 0.125; + else if ( newAngle <= 2 ) + angle = 0.25; + else if ( newAngle <= 3 ) + angle = 0.5; + else + angle = 1; + + // replace: middle arc + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND ); + cairo_arc( cr, x + xc, y + yc, xc * 6.5 / 14, -(3.1415/2), _replace * 6.28 - (3.1415/2) ); + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8 ); + cairo_set_line_width(cr, 9); + cairo_stroke(cr); + + if ( newAngle == 0 ) + cairo_set_source_rgba (cr, 1.0, 0.0 , 0.0, 1 ); + else if ( newAngle == 1 ) + cairo_set_source_rgba (cr, 1.0, 0.48, 0.0, 1 ); + else if ( newAngle <= 2 ) + cairo_set_source_rgba (cr, 0.0, 1.0 , 0.0, 0.8 ); + else if ( newAngle <= 3 ) + cairo_set_source_rgba (cr, 0.0, 0.48, 1.0, 1 ); + else + cairo_set_source_rgba (cr, 1.0, 0.0, 1.0, 0.7 ); + + + // duration : outside arc + cairo_arc( cr, x + xc, y + yc, xc * 9.5 / 14, -(3.1415/2), angle * 6.28 - (3.1415/2) ); + cairo_set_line_width(cr, 11); + cairo_stroke(cr); + + + // volume: inside circle + cairo_set_source_rgba(cr,0.3,0.3,0.3, 0.5); + cairo_arc(cr, x + xc, y + yc, 25 * _volume, 0, 2 * 3.1415); + cairo_set_line_width(cr, 4.2); + cairo_fill_preserve(cr); + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8 ); + cairo_set_line_width(cr, 2); + cairo_stroke(cr); + + // stroke rim + cairo_rectangle(cr, x, y, w, h); + //cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + + draw_label(); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) { + case FL_PUSH: + + highlight = 1; + + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + do_callback(); + } + return 1; + case FL_DRAG: { + int t = Fl::event_inside(this); + if (t != highlight) { + highlight = t; + redraw(); + } + } + return 1; + case FL_ENTER: + mouseOver = true; + redraw(); + return 1; + case FL_LEAVE: + mouseOver = false; + redraw(); + return 1; + case FL_RELEASE: + if (highlight) { + highlight = 0; + redraw(); + } + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + } +}; + +} // Avtk + +#endif // AVTK_ADSR_H + diff --git a/avtk/parameteric.h b/avtk/parameteric.h new file mode 100644 index 0000000..af00822 --- /dev/null +++ b/avtk/parameteric.h @@ -0,0 +1,284 @@ +/* + * Author: Harry van Haaren 2014 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_PARAMETERIC_H +#define AVTK_PARAMETERIC_H + +#include +#include + +#include + +#include +#include + +namespace Avtk +{ + +class Parameteric : public Fl_Slider +{ + public: + Parameteric(int _x, int _y, int _w, int _h, const char *_label = 0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + mouseClickedX = 0; + mouseClickedY = 0; + mouseClicked = false; + + active = true; + highlight = false; + + gains[0] = 0.f; + gains[1] = 0.f; + gains[2] = 0.f; + gains[3] = 0.f; + gains[4] = 0.f; + } + + bool active; + bool highlight; + int x, y, w, h; + const char* label; + + int mouseClickedX; + int mouseClickedY; + bool mouseClicked; + bool mouseRightClicked; + + float gains[5]; + + void setGain( int s, float g) + { + gains[s] = g; + redraw(); + } + + float getVolume() + { + return gains[0]; + } + + void setActive(bool a) + { + active = a; + redraw(); + } + + bool getActive() + { + return active; + } + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + cairo_set_line_width(cr, 1.5); + + + // fill background + cairo_rectangle( cr, x, y, w, h); + cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill_preserve( cr ); + cairo_clip( cr ); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + cairo_set_line_width( cr, 1.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + // draw frequency/amplitude rectangles + for(int i = 0; i < 4; i ++) + { + int startY = y + h/2; + int heightY = h/4 * ( ( (1-gains[i+1])*2)-1 ); + + cairo_rectangle( cr, x + (w/4)*i, startY, w/4, heightY ); + } + + cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND ); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_line_width(cr, 1.8); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke(cr); + + // draw "master gain line + + cairo_move_to( cr, x , y + h/2 + (h/4 *-(gains[0]*2-1)) ); + cairo_line_to( cr, x+w, y + h/2 + (h/4 *-(gains[0]*2-1)) ); + cairo_set_line_width(cr, 2.1); + cairo_set_source_rgba( cr, 255 / 255.f, 0 / 255.f , 0 / 255.f , 1 ); + cairo_stroke(cr); + + // stroke outline + cairo_rectangle(cr, x+1, y+1, w-2, h-2); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) + { + case FL_PUSH: + highlight = 0; + mouseRightClicked = false; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + mouseRightClicked = true; + do_callback(); + } + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + //float deltaX = mouseClickedX - Fl::event_x(); + float deltaY = mouseClickedY - Fl::event_y(); + + //float valX = value() ; + //valX -= deltaX / 100.f; + float valY = gains[0]; + valY += deltaY / 100.f; + + //if ( valX > 1.0 ) valX = 1.0; + //if ( valX < 0.0 ) valX = 0.0; + + if ( valY > 1.0 ) valY = 1.0; + if ( valY < 0.0 ) valY = 0.0; + + //handle_drag( value + deltaY ); + //set_value( valX ); + gains[0] = valY; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); + } + } + return 1; + case FL_RELEASE: + mouseRightClicked = false; + if (highlight) { + highlight = 0; + redraw(); + do_callback(); + } + mouseClicked = false; + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + + return 0; + } + + private: +}; + +} // Avtk + +#endif // AVTK_WAVESHAPER_H diff --git a/avtk/reverb.h b/avtk/reverb.h new file mode 100644 index 0000000..7a1c086 --- /dev/null +++ b/avtk/reverb.h @@ -0,0 +1,221 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_REVERB_H +#define AVTK_REVERB_H + +#include + +namespace Avtk +{ + +class Reverb : public Fl_Slider +{ + public: + Reverb(int _x, int _y, int _w, int _h, const char *_label =0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + amp = 0.5; + s = 0.5; + damp= 0.5; + + active = true; + + label = _label; + + highlight = false; + mouseOver = false; + } + + void size(float v) { s = v; redraw(); } + void wet(float v) { amp = v; redraw(); } + void damping(float v){damp = v; redraw();} + + bool getActive(){return active;} + void setActive(bool a){active = a; redraw();} + + float s; + float amp; + float damp; + + bool active; + + bool mouseOver; + bool highlight; + int x, y, w, h; + const char* label; + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + // graph + cairo_rectangle( cr, x, y, w, h ); + cairo_set_source_rgb( cr,28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill(cr); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + // draw "damping" control + cairo_move_to( cr, x+w*0.1 , y + h*0.85 - (h*0.7*amp)); + cairo_line_to( cr, x+w*0.1 + (w-20)*damp, y + h*0.85 - (h*0.7*amp)); + cairo_set_source_rgba(cr, 1.0, 0.48, 0, 1); + cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width(cr, 1.9); + cairo_stroke( cr ); + + // draw reverb triangle + cairo_move_to( cr, x , y + h*0.99 ); + cairo_line_to( cr, x + w*0.1, y + h*0.85 - (h*0.7*amp)); + cairo_line_to( cr, x + w*0.3+w*0.7*s, y + (h*0.99)); + + // stroke + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_line_width(cr, 1.5); + cairo_stroke( cr ); + + // stroke rim + cairo_rectangle(cr, x+1, y+1, w-2, h-2); + //cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + + draw_label(); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) { + case FL_PUSH: + + highlight = 1; + /* + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + do_callback(); + } + */ + return 1; + case FL_DRAG: { + int t = Fl::event_inside(this); + if (t != highlight) { + highlight = t; + redraw(); + } + } + return 1; + case FL_ENTER: + mouseOver = true; + redraw(); + return 1; + case FL_LEAVE: + mouseOver = false; + redraw(); + return 1; + case FL_RELEASE: + if (highlight) { + highlight = 0; + redraw(); + } + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + } +}; + +} // Avtk + +#endif // AVTK_ADSR_H + diff --git a/avtk/sidechain_gain.h b/avtk/sidechain_gain.h new file mode 100644 index 0000000..d0579c2 --- /dev/null +++ b/avtk/sidechain_gain.h @@ -0,0 +1,286 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_SIDECHAIN_GAIN_H +#define AVTK_SIDECHAIN_GAIN_H + +#include +#include +#include +#include + +namespace Avtk +{ + +class SidechainGain : public Fl_Slider +{ + public: + SidechainGain(int _x, int _y, int _w, int _h, const char *_label = 0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + mouseClickedX = 0; + mouseClickedY = 0; + mouseClicked = false; + + active = true; + highlight = false; + + _threshold = 1.0; + _target = 1.f; + _reduce = 1.f; + _release = 0.5; + + _sidechainAmp = 0; + } + + void threshold(float t) {_threshold = t; redraw();} + void reduce (float r) {_reduce = r; redraw();} + void release (float r) {_release = r; redraw();} + + /// sets the sidechain amplitude + void sidechain(float s) {_sidechainAmp = s; redraw();} + + bool active; + bool highlight; + int x, y, w, h; + const char* label; + + int mouseClickedX; + int mouseClickedY; + bool mouseClicked; + bool mouseRightClicked; + + float _threshold; + float _target; + float _reduce; + float _release; + + float _sidechainAmp; + + void set_active(bool a) + { + active = a; + redraw(); + } + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + cairo_set_line_width(cr, 1.5); + + + // fill background + cairo_rectangle( cr, x, y, w, h); + cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill_preserve( cr ); + cairo_clip( cr ); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + cairo_set_line_width( cr, 1.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + + // draw threshold / ducked line + cairo_move_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)), y ); + + cairo_line_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)) + _sidechainAmp* _reduce*( w * 0.5 ), y + h / 2 ); + + cairo_line_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)), y + h ); + + cairo_line_to( cr, x + w , y + h ); + cairo_line_to( cr, x + w , y ); + cairo_close_path( cr ); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve( cr ); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke( cr ); + + // _sidechainAmp => arrow + cairo_move_to( cr, x + w * 0.00 * _sidechainAmp, y + h * 0.4 - (h*0.1*_sidechainAmp) ); + cairo_line_to( cr, x + w * 0.65 * _sidechainAmp, y + h * 0.4 ); + cairo_line_to( cr, x + w * 0.1 + w * 0.65 * _sidechainAmp, y + h * 0.5 ); + cairo_line_to( cr, x + w * 0.65 * _sidechainAmp, y + h * 0.6 ); + cairo_line_to( cr, x + w * 0.00 * _sidechainAmp, y + h * 0.6 + (h*0.1*_sidechainAmp) ); + cairo_close_path( cr ); + cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 0.21 ); + cairo_fill_preserve( cr ); + cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 1 ); + cairo_stroke( cr ); + + + // _release horizontal line + cairo_move_to( cr, x , y + h * 0.25 + h/2 * _release ); + cairo_line_to( cr, x + w, y + h * 0.25 + h/2 * _release ); + cairo_set_source_rgba( cr, 1.0, 0.0, 0.f , 1 ); + cairo_stroke( cr ); + + + // stroke outline + cairo_rectangle(cr, x+1, y+1, w-2, h-2); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + /* + switch(event) + { + case FL_PUSH: + highlight = 0; + mouseRightClicked = false; + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + mouseRightClicked = true; + do_callback(); + } + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + float deltaX = mouseClickedX - Fl::event_x(); + float deltaY = mouseClickedY - Fl::event_y(); + + float valX = value(); + valX -= deltaX / 100.f; + float valY = makeupGain; + valY += deltaY / 100.f; + + if ( valX > 1.0 ) valX = 1.0; + if ( valX < 0.0 ) valX = 0.0; + + if ( valY > 1.0 ) valY = 1.0; + if ( valY < 0.0 ) valY = 0.0; + + //handle_drag( value + deltaY ); + set_value( valX ); + makeupGain = valY; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); + } + } + return 1; + case FL_RELEASE: + mouseRightClicked = false; + if (highlight) { + highlight = 0; + redraw(); + do_callback(); + } + mouseClicked = false; + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + */ + return 0; + } + + private: +}; + +} // Avtk + +#endif // AVTK_SIDECHAIN_GAIN_H diff --git a/avtk/waveshaper.h b/avtk/waveshaper.h new file mode 100644 index 0000000..e9dbe7d --- /dev/null +++ b/avtk/waveshaper.h @@ -0,0 +1,296 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#ifndef AVTK_WAVESHAPER_H +#define AVTK_WAVESHAPER_H + +#include +#include + +#include + +#include +#include + +namespace Avtk +{ + +class Waveshaper : public Fl_Slider +{ + public: + Waveshaper(int _x, int _y, int _w, int _h, const char *_label = 0): + Fl_Slider(_x, _y, _w, _h, _label) + { + x = _x; + y = _y; + w = _w; + h = _h; + + label = _label; + + mouseClickedX = 0; + mouseClickedY = 0; + mouseClicked = false; + + active = true; + highlight = false; + + envelope = 0.5; + waveshapeType = 0.f; + } + + /// holds the preset: used from callback() to write value + float waveshapeType; + + void type(float t) {waveshapeType = t; redraw();} + + bool active; + bool highlight; + int x, y, w, h; + const char* label; + + int mouseClickedX; + int mouseClickedY; + bool mouseClicked; + bool mouseRightClicked; + + float _threshold; + + float _sidechainAmp; + + float envelope; + + void setEnvelope(float e) + { + envelope = e; + redraw(); + } + + float getEnvelope() + { + return envelope; + } + + void setActive(bool a) + { + active = a; + redraw(); + } + + bool getActive() + { + return active; + } + + void draw() + { + if (damage() & FL_DAMAGE_ALL) + { + cairo_t *cr = Fl::cairo_cc(); + + cairo_save( cr ); + + cairo_set_line_width(cr, 1.5); + + + // fill background + cairo_rectangle( cr, x, y, w, h); + cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); + cairo_fill_preserve( cr ); + cairo_clip( cr ); + + + // set up dashed lines, 1 px off, 1 px on + double dashes[1]; + dashes[0] = 2.0; + + cairo_set_dash ( cr, dashes, 1, 0.0); + cairo_set_line_width( cr, 1.0); + + // loop over each 2nd line, drawing dots + cairo_set_line_width(cr, 1.0); + cairo_set_source_rgb(cr, 0.4,0.4,0.4); + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x + ((w / 4.f)*i), y ); + cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); + } + for ( int i = 0; i < 4; i++ ) + { + cairo_move_to( cr, x , y + ((h / 4.f)*i) ); + cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); + } + + cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); + cairo_stroke(cr); + cairo_set_dash ( cr, dashes, 0, 0.0); + + + // curved waveshape + float distort = value(); + cairo_move_to( cr, x , y + h ); + cairo_curve_to( cr, x + w * distort, y+h, // control point 1 + x + w - (w * distort), y, // control point 2 + x + w, y ); // end of curve 1, start curve 2 + + cairo_line_to ( cr, x + w, y + h ); + cairo_close_path(cr); + + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); + cairo_fill_preserve(cr); + cairo_set_line_width(cr, 2.0); + cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); + cairo_stroke(cr); + + // Tone bars + cairo_move_to( cr, x + w/4, y + 2 ); + cairo_line_to( cr, x + w/4, y + h / 2 * envelope ); + + cairo_move_to( cr, x + w - w/4, y + h - 2 ); + cairo_line_to( cr, x + w - w/4, y + h - (h / 2 * envelope) ); + + //cairo_set_source_rgba (cr, 0.0, 0.48, 1.0, 0.6 ); + cairo_set_source_rgba (cr, 0,0,0, 0.7 ); + cairo_set_line_width(cr, 21.5); + cairo_set_line_cap( cr, CAIRO_LINE_CAP_ROUND ); + cairo_stroke( cr ); + + // stroke outline + cairo_rectangle(cr, x+1, y+1, w-2, h-2); + cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); + cairo_set_line_width(cr, 1.0); + cairo_stroke( cr ); + + + if ( !active ) + { + // big grey X + cairo_set_line_width(cr, 20.0); + cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); + + cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); + + cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); + cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); + cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); + cairo_stroke( cr ); + } + + cairo_restore( cr ); + } + } + + void resize(int X, int Y, int W, int H) + { + Fl_Widget::resize(X,Y,W,H); + x = X; + y = Y; + w = W; + h = H; + redraw(); + } + + int handle(int event) + { + switch(event) + { + case FL_PUSH: + highlight = 0; + mouseRightClicked = false; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + + if ( Fl::event_button() == FL_RIGHT_MOUSE ) + { + active = !active; + redraw(); + mouseRightClicked = true; + do_callback(); + } + return 1; + case FL_DRAG: + { + if ( Fl::event_state(FL_BUTTON1) ) + { + if ( mouseClicked == false ) // catch the "click" event + { + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + mouseClicked = true; + } + + float deltaX = mouseClickedX - Fl::event_x(); + float deltaY = mouseClickedY - Fl::event_y(); + + float valX = envelope; + valX -= deltaX / 100.f; + float valY = value(); + valY += deltaY / 100.f; + + if ( valX > 1.0 ) valX = 1.0; + if ( valX < 0.0 ) valX = 0.0; + + if ( valY > 1.0 ) valY = 1.0; + if ( valY < 0.0 ) valY = 0.0; + + //handle_drag( value + deltaY ); + set_value( valY ); + envelope = valX; + + mouseClickedX = Fl::event_x(); + mouseClickedY = Fl::event_y(); + redraw(); + do_callback(); + } + } + return 1; + case FL_RELEASE: + mouseRightClicked = false; + if (highlight) { + highlight = 0; + redraw(); + do_callback(); + } + mouseClicked = false; + return 1; + case FL_SHORTCUT: + if ( test_shortcut() ) + { + do_callback(); + return 1; + } + return 0; + default: + return Fl_Widget::handle(event); + } + + return 0; + } + + private: +}; + +} // Avtk + +#endif // AVTK_WAVESHAPER_H diff --git a/plugins/Makefile.ntk.mk b/plugins/Makefile.ntk.mk new file mode 100644 index 0000000..242cfee --- /dev/null +++ b/plugins/Makefile.ntk.mk @@ -0,0 +1,130 @@ +#!/usr/bin/make -f +# Makefile for DISTRHO Plugins # +# ---------------------------- # +# Created by falkTX +# + +# NAME, OBJS_DSP and OBJS_UI have been defined before + +include ../../Makefile.mk + +# -------------------------------------------------------------- +# Basic setup + +TARGET_DIR = ../../bin + +BUILD_C_FLAGS += -I. +BUILD_CXX_FLAGS += -I. -I../../dpf/distrho -I../../dpf/dgl + +# -------------------------------------------------------------- +# Set plugin binary file targets + +jack = $(TARGET_DIR)/$(NAME) +ladspa_dsp = $(TARGET_DIR)/$(NAME)-ladspa.$(EXT) +dssi_dsp = $(TARGET_DIR)/$(NAME)-dssi.$(EXT) +dssi_ui = $(TARGET_DIR)/$(NAME)-dssi/$(NAME)_ui +lv2 = $(TARGET_DIR)/$(NAME).lv2/$(NAME).$(EXT) +lv2_dsp = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_dsp.$(EXT) +lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui.$(EXT) +vst = $(TARGET_DIR)/$(NAME)-vst.$(EXT) + +ifeq ($(WIN32),true) +dssi_ui += .exe +endif + +# TODO: MacOS VST bundle + +# -------------------------------------------------------------- +# Set distrho code files + +DISTRHO_PLUGIN_FILES = ../../dpf/distrho/DistrhoPluginMain.cpp +DISTRHO_UI_FILES = ../../dpf/distrho/DistrhoUIMain.cpp ../../dpf/libdgl.a + +# -------------------------------------------------------------- +# Handle plugins without UI + +ifeq ($(TARGET_NOUI),true) +dssi_ui = +lv2_ui = +DISTRHO_UI_FILES = +DGL_LIBS = +OBJS_UI = +endif + +# -------------------------------------------------------------- +# all needs to be first + +all: + +# -------------------------------------------------------------- +# Common + +%.c.o: %.c + $(CC) $< $(BUILD_C_FLAGS) -c -o $@ + +%.cpp.o: %.cpp ../../dpf/distrho/* + $(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags ntk_images ntk) -c -o $@ + +clean: + rm -f *.o + rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2/ + +# -------------------------------------------------------------- +# JACK + +jack: $(jack) + +$(jack): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs jack ntk_images ntk) -DDISTRHO_PLUGIN_TARGET_JACK -o $@ + +# -------------------------------------------------------------- +# LADSPA + +ladspa: $(ladspa_dsp) + +$(ladspa_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LADSPA -o $@ + +# -------------------------------------------------------------- +# DSSI + +dssi: $(dssi_dsp) $(dssi_ui) + +$(dssi_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@ + +$(dssi_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs liblo ntk_images ntk) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@ + +# -------------------------------------------------------------- +# LV2 + +lv2_one: $(lv2) +lv2_sep: $(lv2_dsp) $(lv2_ui) + +$(lv2): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs ntk_images ntk) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ + +$(lv2_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ + +$(lv2_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs ntk_images ntk) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ + +# -------------------------------------------------------------- +# VST + +vst: $(vst) + +$(vst): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) + mkdir -p $(shell dirname $@) + $(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs ntk_images ntk) $(SHARED) -DDISTRHO_PLUGIN_TARGET_VST -o $@ + +# -------------------------------------------------------------- diff --git a/plugins/Parameters/DistrhoPluginInfo.h b/plugins/Parameters/DistrhoPluginInfo.h index 060acee..8a77e6b 100644 --- a/plugins/Parameters/DistrhoPluginInfo.h +++ b/plugins/Parameters/DistrhoPluginInfo.h @@ -20,6 +20,7 @@ #define DISTRHO_PLUGIN_NAME "Parameters" #define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 #define DISTRHO_PLUGIN_IS_SYNTH 0 #define DISTRHO_PLUGIN_NUM_INPUTS 2 diff --git a/plugins/States/DistrhoPluginInfo.h b/plugins/States/DistrhoPluginInfo.h index 1e9cba0..eee86a6 100644 --- a/plugins/States/DistrhoPluginInfo.h +++ b/plugins/States/DistrhoPluginInfo.h @@ -20,6 +20,7 @@ #define DISTRHO_PLUGIN_NAME "States" #define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 #define DISTRHO_PLUGIN_IS_SYNTH 0 #define DISTRHO_PLUGIN_NUM_INPUTS 2 diff --git a/plugins/openav-rommy/ArtyFxPluginRoomy.cpp b/plugins/openav-rommy/ArtyFxPluginRoomy.cpp new file mode 100644 index 0000000..095c1c1 --- /dev/null +++ b/plugins/openav-rommy/ArtyFxPluginRoomy.cpp @@ -0,0 +1,204 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "DistrhoPlugin.hpp" + +#include "dsp/dsp_reverb.hxx" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +class ArtyFxPluginRoomy : public Plugin +{ +public: + ArtyFxPluginRoomy() + : Plugin(3, 0, 0), // 3 parameters, 0 programs, 0 states + dspReverb(d_getSampleRate()) + { + // Initialize all our parameters to their defaults. + controlTime = 0.5f; + controlDamping = 0.5f; + controlDryWet = 0.5f; + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers. + */ + const char* d_getLabel() const override + { + return "roomy"; + } + + /** + Get the plugin author/maker. + */ + const char* d_getMaker() const override + { + return "OpenAV Productions"; + } + + /** + Get the plugin license name (a single line of text). + */ + const char* d_getLicense() const override + { + return "ISC"; + } + + /** + Get the plugin version, in hexadecimal. + TODO format to be defined + */ + uint32_t d_getVersion() const override + { + return 0x1000; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t d_getUniqueId() const override + { + return d_cconst('O', 'V', 'r', 'm'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void d_initParameter(uint32_t index, Parameter& parameter) override + { + parameter.hints = kParameterIsAutomable; + parameter.ranges.def = 0.5f; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 1.0f; + + switch (index) + { + case 0: + parameter.name = "Time"; + parameter.symbol = "time"; + break; + case 1: + parameter.name = "Damping"; + parameter.symbol = "damping"; + break; + case 2: + parameter.name = "Dry Wet Mix"; + parameter.symbol = "dry_wet"; + break; + } + } + + /* -------------------------------------------------------------------------------------------------------- + * Internal data */ + + /** + Get the current value of a parameter. + */ + float d_getParameterValue(uint32_t index) const override + { + switch (index) + { + case 0: return controlTime; + case 1: return controlDamping; + case 2: return controlDryWet; + } + + return 0.0f; + } + + /** + Change a parameter value. + */ + void d_setParameterValue(uint32_t index, float value) override + { + switch (index) + { + case 0: + controlTime = value; + break; + case 1: + controlDamping = value; + break; + case 2: + controlDryWet = value; + break; + } + } + + /* -------------------------------------------------------------------------------------------------------- + * Process */ + + /** + Run/process function for plugins without MIDI input. + */ + void d_run(const float** inputs, float** outputs, uint32_t frames) override + { + dspReverb.rt60 ( controlTime ); + dspReverb.damping ( controlDamping ); + dspReverb.dryWet ( controlDryWet ); + + dspReverb.process(frames, inputs, outputs); + } + + /* -------------------------------------------------------------------------------------------------------- + * Callbacks */ + + /** + Optional callback to inform the plugin about a sample rate change. + This function will only be called when the plugin is deactivated. + */ + void d_sampleRateChanged(double /*newSampleRate*/) override + { + // TODO - reinit dspReverb + } + + // ------------------------------------------------------------------------------------------------------- + +private: + // our parameters + float controlTime; + float controlDamping; + float controlDryWet; + + // the reverb + Reverb dspReverb; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ArtyFxPluginRoomy) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Plugin entry point, called by DPF to create a new plugin instance. */ + +Plugin* createPlugin() +{ + return new ArtyFxPluginRoomy(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-rommy/ArtyFxUiRoomy.cpp b/plugins/openav-rommy/ArtyFxUiRoomy.cpp new file mode 100644 index 0000000..f2ecb7b --- /dev/null +++ b/plugins/openav-rommy/ArtyFxUiRoomy.cpp @@ -0,0 +1,93 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "DistrhoUI.hpp" + +// include full file here for convenience +#include "gui/roomy_widget.cxx" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +class ArtyFxUiRoomy : public UI +{ +public: + ArtyFxUiRoomy() + : UI(), + fUI(this) + { + // ntk method to add sub-window + add(fUI.window); + fUI.window->show(); + + // start widgets on their default values + fUI.graph->size(0.5f); + fUI.graph->damping(0.5f); + fUI.graph->wet(0.5f); + fUI.time->value(0.5f); + fUI.damping->value(0.5f); + fUI.dryWet->value(0.5f); + + setSize(fUI.getWidth(), fUI.getHeight()); + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * DSP/Plugin Callbacks */ + + /** + A parameter has changed on the plugin side. + This is called by the host to inform the UI about parameter changes. + */ + void d_parameterChanged(uint32_t index, float value) override + { + switch (index) + { + case 0: + fUI.graph->size(value); + fUI.time->value(value); + break; + case 1: + fUI.graph->damping(value); + fUI.damping->value(value); + break; + case 2: + fUI.graph->wet(value); + fUI.dryWet->value(value); + break; + } + } + + // ------------------------------------------------------------------------------------------------------- + +private: + RoomyUI fUI; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ArtyFxUiRoomy) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * UI entry point, called by DPF to create a new UI instance. */ + +UI* createUI() +{ + return new ArtyFxUiRoomy(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-rommy/DistrhoPluginInfo.h b/plugins/openav-rommy/DistrhoPluginInfo.h new file mode 100644 index 0000000..abd6b71 --- /dev/null +++ b/plugins/openav-rommy/DistrhoPluginInfo.h @@ -0,0 +1,39 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_NAME "Roomy" + +#define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 + +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 + +#define DISTRHO_PLUGIN_WANT_LATENCY 0 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 +#define DISTRHO_PLUGIN_WANT_STATE 0 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 + +#define DISTRHO_PLUGIN_URI "http://www.openavproductions.com/artyfx#roomy" +#define DISTRHO_UI_URI "http://www.openavproductions.com/artyfx#roomy/gui" + +#define DISTRHO_UI_USE_NTK 1 + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/plugins/openav-rommy/Makefile b/plugins/openav-rommy/Makefile new file mode 100644 index 0000000..744cee2 --- /dev/null +++ b/plugins/openav-rommy/Makefile @@ -0,0 +1,35 @@ +#!/usr/bin/make -f +# Makefile for DISTRHO Plugins # +# ---------------------------- # +# Created by falkTX +# + +# -------------------------------------------------------------- +# Project name, used for binaries + +NAME = roomy + +# -------------------------------------------------------------- +# Files to build + +OBJS_DSP = \ + ArtyFxPluginRoomy.cpp.o + +OBJS_UI = \ + ArtyFxUiRoomy.cpp.o + +# -------------------------------------------------------------- +# Do some magic + +include ../Makefile.ntk.mk + +# -------------------------------------------------------------- +# Enable all possible plugin types + +ifeq ($(LINUX),true) +all: jack ladspa dssi lv2_sep vst +else +all: ladspa dssi lv2_sep vst +endif + +# -------------------------------------------------------------- diff --git a/plugins/openav-rommy/README.md b/plugins/openav-rommy/README.md new file mode 100644 index 0000000..17bdb73 --- /dev/null +++ b/plugins/openav-rommy/README.md @@ -0,0 +1,4 @@ +# OpenAV / NTK example + +This example will show an OpenAV based plugin working with DPF.
+The UI uses NTK instead of OpenGL.
diff --git a/plugins/openav-rommy/dsp/dsp_reverb.hxx b/plugins/openav-rommy/dsp/dsp_reverb.hxx new file mode 100644 index 0000000..37e9b9c --- /dev/null +++ b/plugins/openav-rommy/dsp/dsp_reverb.hxx @@ -0,0 +1,511 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +/* + The DSP code in this file was generated using FAUST. + The FAUST code used is under the following licenses: + + effect.lib/name Faust Audio Effect Library + effect.lib/author Julius O. Smith (jos at ccrma.stanford.edu) + effect.lib/copyright Julius O. Smith III + effect.lib/version 1.33 + effect.lib/license STK-4.3 + effect.lib/reference https://ccrma.stanford.edu/realsimple/faust_strings/ + + filter.lib/author Julius O. Smith (jos at ccrma.stanford.edu) + filter.lib/name Faust Filter Library + filter.lib/copyright Julius O. Smith III + filter.lib/version 1.29 + filter.lib/license STK-4.3 + filter.lib/reference https://ccrma.stanford.edu/~jos/filters/ + + music.lib/name Music Library + music.lib/author GRAME + music.lib/copyright GRAME + music.lib/version 1.0 + music.lib/license LGPL + + math.lib/name Math Library + math.lib/author GRAME + math.lib/copyright GRAME + math.lib/version 1.0 + math.lib/license LGPL +*/ + + +#ifndef OPENAV_DSP_REVERB_H +#define OPENAV_DSP_REVERB_H + +#include +#include +#include + +template const T& max (const T& a, const T& b) { + return (a const T& min (const T& a, const T& b) { + return !(b inline float faustpower(float x) { return powf(x,N); } +template inline double faustpower(double x) { return pow(x,N); } +template inline int faustpower(int x) { return faustpower(x) * faustpower(x); } +template <> inline int faustpower<0>(int x) { return 1; } +template <> inline int faustpower<1>(int x) { return x; } + +class Reverb // : Effect +{ + public: + Reverb(int sr) + { + init( sr ); + } + + int getNumInputs() { return 2; } + int getNumOutputs(){ return 2; } + + void damping(float d) + { + if( d > 1.0 ) d = 1.0f; + if( d < 0.0 ) d = 0.0f; + + fslider1 = (1-d) * 18500 + 1500.f; + } + + void rt60(float rt) + { + if( rt > 1.0 ) rt = 1.0f; + if( rt < 0.0 ) rt = 0.0f; + + fslider0 = 1 + rt * 5; + } + + void dryWet(float dw) + { + if( dw > 1.0 ) dw = 1.0f; + if( dw < 0.0 ) dw = 0.0f; + _dryWet = dw; + } + + void process (int count, const float** input, float** output) + { + float fSlow0 = fslider0; + float fSlow1 = expf((fConst2 / fSlow0)); + float fSlow2 = faustpower<2>(fSlow1); + float fSlow3 = (1.0f - fSlow2); + float fSlow4 = cosf((fConst3 * fslider1)); + float fSlow5 = (1.0f - (fSlow4 * fSlow2)); + float fSlow6 = sqrtf(max(0.f, ((faustpower<2>(fSlow5) / faustpower<2>(fSlow3)) - 1.0f))); + float fSlow7 = (fSlow5 / fSlow3); + float fSlow8 = (fSlow7 - fSlow6); + float fSlow9 = (fSlow0 - 0.5f); + float fSlow10 = ((expf((fConst2 / fSlow9)) / fSlow1) - 1); + float fSlow11 = (fSlow1 * ((1.0f + fSlow6) - fSlow7)); + float fSlow12 = expf((fConst12 / fSlow0)); + float fSlow13 = faustpower<2>(fSlow12); + float fSlow14 = (1.0f - fSlow13); + float fSlow15 = (1.0f - (fSlow4 * fSlow13)); + float fSlow16 = sqrtf(max(0.f, ((faustpower<2>(fSlow15) / faustpower<2>(fSlow14)) - 1.0f))); + float fSlow17 = (fSlow15 / fSlow14); + float fSlow18 = (fSlow17 - fSlow16); + float fSlow19 = ((expf((fConst12 / fSlow9)) / fSlow12) - 1); + float fSlow20 = (fSlow12 * ((1.0f + fSlow16) - fSlow17)); + float fSlow21 = expf((fConst17 / fSlow0)); + float fSlow22 = faustpower<2>(fSlow21); + float fSlow23 = (1.0f - fSlow22); + float fSlow24 = (1.0f - (fSlow4 * fSlow22)); + float fSlow25 = sqrtf(max(0.f, ((faustpower<2>(fSlow24) / faustpower<2>(fSlow23)) - 1.0f))); + float fSlow26 = (fSlow24 / fSlow23); + float fSlow27 = (fSlow26 - fSlow25); + float fSlow28 = ((expf((fConst17 / fSlow9)) / fSlow21) - 1); + float fSlow29 = (fSlow21 * ((1.0f + fSlow25) - fSlow26)); + float fSlow30 = expf((fConst22 / fSlow0)); + float fSlow31 = faustpower<2>(fSlow30); + float fSlow32 = (1.0f - fSlow31); + float fSlow33 = (1.0f - (fSlow4 * fSlow31)); + float fSlow34 = sqrtf(max(0.f, ((faustpower<2>(fSlow33) / faustpower<2>(fSlow32)) - 1.0f))); + float fSlow35 = (fSlow33 / fSlow32); + float fSlow36 = (fSlow35 - fSlow34); + float fSlow37 = ((expf((fConst22 / fSlow9)) / fSlow30) - 1); + float fSlow38 = (fSlow30 * ((1.0f + fSlow34) - fSlow35)); + float fSlow39 = expf((fConst27 / fSlow0)); + float fSlow40 = faustpower<2>(fSlow39); + float fSlow41 = (1.0f - fSlow40); + float fSlow42 = (1.0f - (fSlow4 * fSlow40)); + float fSlow43 = sqrtf(max(0.f, ((faustpower<2>(fSlow42) / faustpower<2>(fSlow41)) - 1.0f))); + float fSlow44 = (fSlow42 / fSlow41); + float fSlow45 = (fSlow44 - fSlow43); + float fSlow46 = ((expf((fConst27 / fSlow9)) / fSlow39) - 1); + float fSlow47 = (fSlow39 * ((1.0f + fSlow43) - fSlow44)); + float fSlow48 = expf((fConst32 / fSlow0)); + float fSlow49 = faustpower<2>(fSlow48); + float fSlow50 = (1.0f - fSlow49); + float fSlow51 = (1.0f - (fSlow4 * fSlow49)); + float fSlow52 = sqrtf(max(0.f, ((faustpower<2>(fSlow51) / faustpower<2>(fSlow50)) - 1.0f))); + float fSlow53 = (fSlow51 / fSlow50); + float fSlow54 = (fSlow53 - fSlow52); + float fSlow55 = ((expf((fConst32 / fSlow9)) / fSlow48) - 1); + float fSlow56 = (fSlow48 * ((1.0f + fSlow52) - fSlow53)); + float fSlow57 = expf((fConst37 / fSlow0)); + float fSlow58 = faustpower<2>(fSlow57); + float fSlow59 = (1.0f - fSlow58); + float fSlow60 = (1.0f - (fSlow4 * fSlow58)); + float fSlow61 = sqrtf(max(0.f, ((faustpower<2>(fSlow60) / faustpower<2>(fSlow59)) - 1.0f))); + float fSlow62 = (fSlow60 / fSlow59); + float fSlow63 = (fSlow62 - fSlow61); + float fSlow64 = ((expf((fConst37 / fSlow9)) / fSlow57) - 1); + float fSlow65 = (fSlow57 * ((1.0f + fSlow61) - fSlow62)); + float fSlow66 = expf((fConst42 / fSlow0)); + float fSlow67 = faustpower<2>(fSlow66); + float fSlow68 = (1.0f - fSlow67); + float fSlow69 = (1.0f - (fSlow67 * fSlow4)); + float fSlow70 = sqrtf(max(0.f, ((faustpower<2>(fSlow69) / faustpower<2>(fSlow68)) - 1.0f))); + float fSlow71 = (fSlow69 / fSlow68); + float fSlow72 = (fSlow71 - fSlow70); + float fSlow73 = ((expf((fConst42 / fSlow9)) / fSlow66) - 1); + float fSlow74 = (fSlow66 * ((1.0f + fSlow70) - fSlow71)); + const float* input0 = input[0]; + const float* input1 = input[1]; + float* output0 = output[0]; + float* output1 = output[1]; + for (int i=0; i\11\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\215>\11\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\24\24" + "\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\24\24\24\377\24\24\24\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\24\24\24\377\24\24\24\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\215>\11\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377", +}; + diff --git a/plugins/openav-rommy/gui/roomy_widget.cxx b/plugins/openav-rommy/gui/roomy_widget.cxx new file mode 100644 index 0000000..27dd63e --- /dev/null +++ b/plugins/openav-rommy/gui/roomy_widget.cxx @@ -0,0 +1,153 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#include "roomy_widget.h" + +START_NAMESPACE_DISTRHO + +void RoomyUI::cb_headerImage_i(Avtk::Image*, void*) { + //system("xdg-open http://www.openavproductions.com/artyfx#ducka"); +} +void RoomyUI::cb_headerImage(Avtk::Image* o, void* v) { + ((RoomyUI*)(o->parent()->user_data()))->cb_headerImage_i(o,v); +} + +void RoomyUI::cb_graph_i(Avtk::Reverb* o, void*) { + //cutoff = o->value(); +//float g = o->getGain(); +//gainDial->value( g ); +//freq->value( cutoff ); // update dial +//writePort(CUTOFF_FREQ, cutoff); +//writePort(CUTOFF_GAIN, g); +} +void RoomyUI::cb_graph(Avtk::Reverb* o, void* v) { + ((RoomyUI*)(o->parent()->user_data()))->cb_graph_i(o,v); +} + +void RoomyUI::cb_time_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->size( tmp ); + setHostParameter( 0, tmp ); +} +void RoomyUI::cb_time(Avtk::Dial* o, void* v) { + ((RoomyUI*)(o->parent()->user_data()))->cb_time_i(o,v); +} + +void RoomyUI::cb_damping_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->damping( tmp ); + setHostParameter( 1, tmp ); +} +void RoomyUI::cb_damping(Avtk::Dial* o, void* v) { + ((RoomyUI*)(o->parent()->user_data()))->cb_damping_i(o,v); +} + +void RoomyUI::cb_dryWet_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->wet( tmp ); + setHostParameter( 2, tmp ); +} +void RoomyUI::cb_dryWet(Avtk::Dial* o, void* v) { + ((RoomyUI*)(o->parent()->user_data()))->cb_dryWet_i(o,v); +} + +/** + if the type of filter changes, this function will highlight the right button +*/ +void RoomyUI::update_button(int button) { +} + +RoomyUI::RoomyUI(UI* uic) : ui(uic) { + { Fl_Double_Window* o = window = new Fl_Double_Window(160, 220); + window->user_data((void*)(this)); + { headerImage = new Avtk::Image(0, 0, 160, 29, "header.png"); + headerImage->box(FL_NO_BOX); + headerImage->color(FL_BACKGROUND_COLOR); + headerImage->selection_color(FL_BACKGROUND_COLOR); + headerImage->labeltype(FL_NORMAL_LABEL); + headerImage->labelfont(0); + headerImage->labelsize(14); + headerImage->labelcolor((Fl_Color)20); + headerImage->callback((Fl_Callback*)cb_headerImage); + headerImage->align(Fl_Align(FL_ALIGN_CENTER)); + headerImage->when(FL_WHEN_RELEASE_ALWAYS); + headerImage->setPixbuf(header.pixel_data,4); + } // Avtk::Image* headerImage + { graph = new Avtk::Reverb(5, 36, 150, 126, "graph"); + graph->box(FL_UP_BOX); + graph->color((Fl_Color)179); + graph->selection_color(FL_INACTIVE_COLOR); + graph->labeltype(FL_NO_LABEL); + graph->labelfont(0); + graph->labelsize(14); + graph->labelcolor(FL_FOREGROUND_COLOR); + graph->callback((Fl_Callback*)cb_graph); + graph->align(Fl_Align(FL_ALIGN_BOTTOM)); + graph->when(FL_WHEN_CHANGED); + } // Avtk::Reverb* graph + { time = new Avtk::Dial(10, 169, 37, 37, "Time"); + time->box(FL_NO_BOX); + time->color((Fl_Color)90); + time->selection_color(FL_INACTIVE_COLOR); + time->labeltype(FL_NORMAL_LABEL); + time->labelfont(0); + time->labelsize(10); + time->labelcolor(FL_FOREGROUND_COLOR); + time->callback((Fl_Callback*)cb_time); + time->align(Fl_Align(FL_ALIGN_BOTTOM)); + time->when(FL_WHEN_CHANGED); + } // Avtk::Dial* time + { damping = new Avtk::Dial(62, 169, 37, 37, "Damping"); + damping->box(FL_NO_BOX); + damping->color((Fl_Color)90); + damping->selection_color(FL_INACTIVE_COLOR); + damping->labeltype(FL_NORMAL_LABEL); + damping->labelfont(0); + damping->labelsize(10); + damping->labelcolor(FL_FOREGROUND_COLOR); + damping->callback((Fl_Callback*)cb_damping); + damping->align(Fl_Align(FL_ALIGN_BOTTOM)); + damping->when(FL_WHEN_CHANGED); + } // Avtk::Dial* damping + { dryWet = new Avtk::Dial(113, 168, 37, 37, "Dry / Wet"); + dryWet->box(FL_NO_BOX); + dryWet->color((Fl_Color)90); + dryWet->selection_color(FL_INACTIVE_COLOR); + dryWet->labeltype(FL_NORMAL_LABEL); + dryWet->labelfont(0); + dryWet->labelsize(10); + dryWet->labelcolor(FL_FOREGROUND_COLOR); + dryWet->callback((Fl_Callback*)cb_dryWet); + dryWet->align(Fl_Align(FL_ALIGN_BOTTOM)); + dryWet->when(FL_WHEN_CHANGED); + } // Avtk::Dial* dryWet + window->color( fl_rgb_color( 17, 17, 17) ); + close_cb(o, 0); + window->end(); + } // Fl_Double_Window* window +} + +int RoomyUI::getWidth() { + return window->w(); +} + +int RoomyUI::getHeight() { + return window->h(); +} + +void RoomyUI::setHostParameter(uint32_t index, float value) { + //cout << "port " << port << " value " << value << endl; + ui->d_setParameterValue(index, value); +} + +void close_cb(Fl_Widget* o, void*) { + if ((Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape) + { + return; // ignore ESC + } + else + { + o->hide(); + } +} + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-rommy/gui/roomy_widget.fl b/plugins/openav-rommy/gui/roomy_widget.fl new file mode 100644 index 0000000..eb04a9b --- /dev/null +++ b/plugins/openav-rommy/gui/roomy_widget.fl @@ -0,0 +1,110 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0300 +header_name {.h} +code_name {.cxx} +class RoomyUI {open +} { + Function {update_button(int button)} { + comment {if the type of filter changes, this function will highlight the right button} open return_type void + } { + code {} {} + } + Function {RoomyUI()} {open + } { + Fl_Window window {open selected + xywh {1024 378 160 220} type Double + code0 {\#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"} + code1 {window->color( fl_rgb_color( 17, 17, 17) );} + code2 {close_cb(o, 0);} + code3 {\#include "../dsp/roomy.hxx"} visible + } { + Fl_Box headerImage { + label {header.png} + callback {//system("xdg-open http://www.openavproductions.com/artyfx\#ducka");} + xywh {0 0 160 29} labelcolor 20 when 6 + code0 {\#include "avtk.h"} + code1 {\#include } + code2 {\#include "header.c"} + code3 {headerImage->setPixbuf(header.pixel_data,4);} + class {Avtk::Image} + } + Fl_Dial graph { + label graph + callback {//cutoff = o->value(); +//float g = o->getGain(); +//gainDial->value( g ); +//freq->value( cutoff ); // update dial +//writePort(CUTOFF_FREQ, cutoff); +//writePort(CUTOFF_GAIN, g);} + xywh {5 36 150 126} box UP_BOX color 179 labeltype NO_LABEL + code1 {using namespace std;} + code2 {\#include } + class {Avtk::Reverb} + } + Fl_Dial time { + label Time + callback {float tmp = o->value(); +graph->size( tmp ); +writePort( int(ROOMY_TIME), tmp );} + xywh {10 169 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + Fl_Dial damping { + label Damping + callback {float tmp = o->value(); +graph->damping( tmp ); +writePort( int(ROOMY_DAMPING), tmp );} + xywh {62 169 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + Fl_Dial dryWet { + label {Dry / Wet} + callback {float tmp = o->value(); +graph->wet( tmp ); +writePort( int(ROOMY_DRY_WET),tmp );} + xywh {113 168 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + } + } + decl {LV2UI_Write_Function write_function;} {public local + } + decl {LV2UI_Controller controller;} {public local + } + Function {idle()} {open return_type void + } { + code {Fl::check(); +Fl::flush();} {} + } + Function {getWidth()} {open return_type int + } { + code {return window->w();} {} + } + Function {getHeight()} {open return_type int + } { + code {return window->h();} {} + } + decl {float gain;} {private local + } + decl {float cutoff;} {private local + } + decl {float Q;} {private local + } + Function {writePort(int port, float& value)} {open + } { + code {//cout << "port " << port << " value " << value << endl; +write_function(controller, port, sizeof(float), 0, &value);} {} + } +} + +Function {close_cb(Fl_Widget* o, void*)} {open +} { + code {if ((Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape) + { + return; // ignore ESC + } + else + { + o->hide(); + }} {} +} diff --git a/plugins/openav-rommy/gui/roomy_widget.h b/plugins/openav-rommy/gui/roomy_widget.h new file mode 100644 index 0000000..fa3fb9f --- /dev/null +++ b/plugins/openav-rommy/gui/roomy_widget.h @@ -0,0 +1,66 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#ifndef roomy_widget_h +#define roomy_widget_h + +#include +#include +//#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" +//#include "../dsp/roomy.hxx" +#include "DistrhoUI.hpp" + +#include "avtk.h" +#include +#include "header.c" + +using namespace std; +#include + +// keep things inside the namespace to prevent issues with public symbols +START_NAMESPACE_DISTRHO + +class RoomyUI { +public: + void update_button(int button); + RoomyUI(UI* ui); + Fl_Double_Window *window; + Avtk::Image *headerImage; +private: + void cb_headerImage_i(Avtk::Image*, void*); + static void cb_headerImage(Avtk::Image*, void*); +public: + Avtk::Reverb *graph; +private: + void cb_graph_i(Avtk::Reverb*, void*); + static void cb_graph(Avtk::Reverb*, void*); +public: + Avtk::Dial *time; +private: + void cb_time_i(Avtk::Dial*, void*); + static void cb_time(Avtk::Dial*, void*); +public: + Avtk::Dial *damping; +private: + void cb_damping_i(Avtk::Dial*, void*); + static void cb_damping(Avtk::Dial*, void*); +public: + Avtk::Dial *dryWet; +private: + void cb_dryWet_i(Avtk::Dial*, void*); + static void cb_dryWet(Avtk::Dial*, void*); +public: + int getWidth(); + int getHeight(); +private: + UI* const ui; + float gain; + float cutoff; + float Q; +public: + void setHostParameter(uint32_t index, float value); +}; +void close_cb(Fl_Widget* o, void*); + +END_NAMESPACE_DISTRHO + +#endif