astyle: global restyle of codebase (fixes #153)

This to bring common fomatting to the whole project,
including submissions. To format a file to this style:

astyle --style=linux -t8 <file>

Future patches / pull-requests should be in this format.
This commit is contained in:
Harry van Haaren 2016-12-27 12:47:19 +00:00
parent 0020d9a672
commit 01f71ec5e4
93 changed files with 11792 additions and 11466 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@ src/*.o
luppp luppp
*.zip *.zip
*.orig
build/* build/*
buildTest/* buildTest/*

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -22,95 +22,94 @@
AudioBuffer::AudioBuffer() AudioBuffer::AudioBuffer()
{ {
ID = privateID++; ID = privateID++;
init(); init();
} }
AudioBuffer::AudioBuffer(unsigned long size) AudioBuffer::AudioBuffer(unsigned long size)
{ {
// FIXME recorded buffers don't get an ID, using garbage IDs // FIXME recorded buffers don't get an ID, using garbage IDs
/// no ID assigned: it *takes* the one from the previous buffer! /// no ID assigned: it *takes* the one from the previous buffer!
init(); init();
buffer.resize(size); buffer.resize(size);
} }
void AudioBuffer::init() void AudioBuffer::init()
{ {
numBeats = 0; numBeats = 0;
audioFrames = 0; audioFrames = 0;
memset( name, 0, sizeof(char)*20 ); memset( name, 0, sizeof(char)*20 );
//sprintf( name, "%i", ID ); //sprintf( name, "%i", ID );
} }
/// this function is used for "resizing" an exisiting buffer, and should /// this function is used for "resizing" an exisiting buffer, and should
/// not be called for any other reason. /// not be called for any other reason.
void AudioBuffer::setID(int id) void AudioBuffer::setID(int id)
{ {
ID = id; ID = id;
} }
int AudioBuffer::getID() int AudioBuffer::getID()
{ {
return ID; return ID;
} }
void AudioBuffer::setName(const char* n) void AudioBuffer::setName(const char* n)
{ {
memcpy( name, n, sizeof(char)* 19 ); memcpy( name, n, sizeof(char)* 19 );
if ( strlen(n) > 19 ) if ( strlen(n) > 19 ) {
{
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
cout << "AudioBuffer setName too long, truncating." << endl; cout << "AudioBuffer setName too long, truncating." << endl;
#endif #endif
return; return;
} }
} }
char* AudioBuffer::getName() char* AudioBuffer::getName()
{ {
return name; return name;
} }
int AudioBuffer::getBeats() int AudioBuffer::getBeats()
{ {
return numBeats; return numBeats;
} }
void AudioBuffer::setBeats(int b) void AudioBuffer::setBeats(int b)
{ {
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
cout << "AudioBuffer now has " << b << " beats\n" << endl; cout << "AudioBuffer now has " << b << " beats\n" << endl;
#endif #endif
numBeats = b; numBeats = b;
} }
void AudioBuffer::setAudioFrames(long af) void AudioBuffer::setAudioFrames(long af)
{ {
audioFrames = af; audioFrames = af;
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
cout << "AudioBuffer " << ID << " has " << audioFrames << " audioFrames\n" << endl; cout << "AudioBuffer " << ID << " has " << audioFrames << " audioFrames\n" << endl;
#endif #endif
} }
long AudioBuffer::getAudioFrames() long AudioBuffer::getAudioFrames()
{ {
return audioFrames; return audioFrames;
} }
std::vector<float>& AudioBuffer::getData() std::vector<float>& AudioBuffer::getData()
{ {
return buffer; return buffer;
} }
void AudioBuffer::nonRtSetSample(std::vector<float>& sample) void AudioBuffer::nonRtSetSample(std::vector<float>& sample)
{ {
buffer.swap(sample); buffer.swap(sample);
} }
void AudioBuffer::nonRtResize(unsigned long size) void AudioBuffer::nonRtResize(unsigned long size)
{ {
buffer.resize(size); buffer.resize(size);
} }
/* /*

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -30,49 +30,49 @@ using namespace std;
/// AudioBuffer stores float samples in a big vector. /// AudioBuffer stores float samples in a big vector.
class AudioBuffer class AudioBuffer
{ {
public: public:
AudioBuffer(); AudioBuffer();
AudioBuffer(unsigned long size); AudioBuffer(unsigned long size);
void init(); void init();
/// this function is used for "resizing" an exisiting buffer, and should /// this function is used for "resizing" an exisiting buffer, and should
/// not be called for any other reason. /// not be called for any other reason.
void setID(int id); void setID(int id);
int getID(); int getID();
void setName(const char* n); void setName(const char* n);
char* getName(); char* getName();
int getBeats(); int getBeats();
void setBeats(int b); void setBeats(int b);
void setAudioFrames(long af); void setAudioFrames(long af);
long getAudioFrames(); long getAudioFrames();
std::vector<float>& getData(); std::vector<float>& getData();
void nonRtSetSample(std::vector<float>& sample); void nonRtSetSample(std::vector<float>& sample);
void nonRtResize(unsigned long size); void nonRtResize(unsigned long size);
//friend ostream& operator<<(ostream& o, const AudioBuffer& a); //friend ostream& operator<<(ostream& o, const AudioBuffer& a);
protected: protected:
static int privateID; static int privateID;
int ID; int ID;
int numBeats; int numBeats;
/// holds the number of samples that are usable audio, as opposed to /// holds the number of samples that are usable audio, as opposed to
/// buffer.size(), which also has non-used space at the end. /// buffer.size(), which also has non-used space at the end.
long audioFrames; long audioFrames;
char name[20]; char name[20];
std::vector<float> buffer; std::vector<float> buffer;
}; };
#endif #endif

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -25,25 +25,28 @@
class AudioProcessor class AudioProcessor
{ {
public: public:
AudioProcessor(){} AudioProcessor() {}
/// copies the track output to master buffer, sidechain & post-side buffer /// copies the track output to master buffer, sidechain & post-side buffer
virtual void process(unsigned int nframes, Buffers* buffers){printf("AudioProcessor::process() not derived\n");} virtual void process(unsigned int nframes, Buffers* buffers)
{
/// set main mix, 0-1 printf("AudioProcessor::process() not derived\n");
virtual void setMaster(float value){} }
/// set sidechain mix, 0-1 /// set main mix, 0-1
virtual void setSidechain(float value){} virtual void setMaster(float value) {}
/// set post sidechain mix, 0-1 /// set sidechain mix, 0-1
virtual void setPostSidechain(float value){} virtual void setSidechain(float value) {}
/// set reverb mix, 0-1 /// set post sidechain mix, 0-1
virtual void setReverb(float value){} virtual void setPostSidechain(float value) {}
virtual ~AudioProcessor(){}; /// set reverb mix, 0-1
virtual void setReverb(float value) {}
virtual ~AudioProcessor() {};
}; };
#endif // LUPPP_AUDIO_PROCESSOR_H #endif // LUPPP_AUDIO_PROCESSOR_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,134 +32,129 @@ namespace Avtk
// FIXME: Refactor to .hxx .cxx // FIXME: Refactor to .hxx .cxx
class Background : public Fl_Widget class Background : public Fl_Widget
{ {
public: public:
Background(int _x, int _y, int _w, int _h, const char *_label = 0): Background(int _x, int _y, int _w, int _h, const char *_label = 0):
Fl_Widget(_x, _y, _w, _h, _label) Fl_Widget(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = strdup(_label); label = strdup(_label);
highlight = false; highlight = false;
} }
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
void setLabel(const char* l) void setLabel(const char* l)
{ {
if( label ) if( label )
free( (char*) label); free( (char*) label);
label = strdup( l ); label = strdup( l );
redraw(); redraw();
} }
const char* getLabel() const char* getLabel()
{ {
return label; return label;
} }
void draw() void draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ cairo_t *cr = Fl::cairo_cc();
cairo_t *cr = Fl::cairo_cc();
cairo_save( cr );
cairo_save( cr );
cairo_set_line_width(cr, 1.5);
cairo_set_line_width(cr, 1.5);
// fill background
// fill background cairo_rectangle( cr, x, y, w, h);
cairo_rectangle( cr, x, y, w, h); cairo_set_source_rgba( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f , 1 );
cairo_set_source_rgba( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f , 1 ); cairo_fill( cr );
cairo_fill( cr );
// draw header
// draw header // backing
// backing cairo_rectangle(cr, x, y, w, 20);
cairo_rectangle(cr, x, y, w, 20); cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f );
cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); cairo_fill( cr );
cairo_fill( cr );
// text
// text cairo_move_to( cr, x + 10, y + 14 );
cairo_move_to( cr, x + 10, y + 14 ); cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); cairo_set_font_size( cr, 10 );
cairo_set_font_size( cr, 10 ); cairo_show_text( cr, label );
cairo_show_text( cr, label );
// lower stripe
// lower stripe cairo_move_to( cr, x , y + 20 );
cairo_move_to( cr, x , y + 20 ); cairo_line_to( cr, x + w, y + 20 );
cairo_line_to( cr, x + w, y + 20 ); cairo_stroke( cr );
cairo_stroke( cr );
// stroke rim
// stroke rim cairo_rectangle(cr, x, y, w, h);
cairo_rectangle(cr, x, y, w, h); cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 1 );
cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 1 ); cairo_stroke( cr );
cairo_stroke( cr );
cairo_restore( cr );
cairo_restore( cr ); }
} }
}
void resize(int X, int Y, int W, int H)
void resize(int X, int Y, int W, int H) {
{ Fl_Widget::resize(X,Y,W,H);
Fl_Widget::resize(X,Y,W,H); x = X;
x = X; y = Y;
y = Y; w = W;
w = W; h = H;
h = H; redraw();
redraw(); }
}
int handle(int event)
int handle(int event) {
{ switch(event) {
switch(event) case FL_PUSH:
{ if ( Fl::event_state(FL_BUTTON3) && Fl::event_y() < y + 20 ) {
case FL_PUSH: const char* name = fl_input( "Track name: ", "" );
if ( Fl::event_state(FL_BUTTON3) && Fl::event_y() < y + 20 ) if ( name ) {
{ free( (char*) label );
const char* name = fl_input( "Track name: ", "" ); label = strdup( name );
if ( name ) redraw();
{ }
free( (char*) label ); return 1;
label = strdup( name ); }
redraw();
} redraw();
return 1; return 1;
} case FL_DRAG: {
int t = Fl::event_inside(this);
redraw(); if (t != highlight) {
return 1; redraw();
case FL_DRAG: { }
int t = Fl::event_inside(this); }
if (t != highlight) { return 1;
redraw(); case FL_RELEASE:
} if (highlight) {
} highlight = 0;
return 1; redraw();
case FL_RELEASE: do_callback();
if (highlight) { }
highlight = 0; return 1;
redraw(); case FL_SHORTCUT:
do_callback(); if ( test_shortcut() ) {
} do_callback();
return 1; return 1;
case FL_SHORTCUT: }
if ( test_shortcut() ) return 0;
{ default:
do_callback(); return Fl_Widget::handle(event);
return 1; }
} }
return 0;
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -28,84 +28,83 @@ namespace Avtk
// FIXME: Refactor to .hxx .cxx // FIXME: Refactor to .hxx .cxx
class Box : public Fl_Widget class Box : public Fl_Widget
{ {
public: public:
Box(int _x, int _y, int _w, int _h, const char *_label = 0): Box(int _x, int _y, int _w, int _h, const char *_label = 0):
Fl_Widget(_x, _y, _w, _h, _label) Fl_Widget(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
r = g = b = 0; r = g = b = 0;
label = strdup(_label); label = strdup(_label);
highlight = false; highlight = false;
} }
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
int r,g,b; int r,g,b;
void setLabel(const char* l) void setLabel(const char* l)
{ {
if( label ) if( label )
free( (char*) label); free( (char*) label);
label = strdup( l ); label = strdup( l );
redraw(); redraw();
} }
const char* getLabel() const char* getLabel()
{ {
return label; return label;
} }
void setColor( int red, int green, int blue ) void setColor( int red, int green, int blue )
{ {
r = red; r = red;
g = green; g = green;
b = blue; b = blue;
redraw(); redraw();
} }
void draw() void draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ cairo_t *cr = Fl::cairo_cc();
cairo_t *cr = Fl::cairo_cc();
cairo_save( cr );
cairo_save( cr );
cairo_set_line_width(cr, 1.5);
cairo_set_line_width(cr, 1.5);
// fill background
// fill background cairo_rectangle( cr, x, y, w, h);
cairo_rectangle( cr, x, y, w, h); cairo_set_source_rgba( cr, r, g, b, 1 );
cairo_set_source_rgba( cr, r, g, b, 1 ); cairo_fill( cr );
cairo_fill( cr );
/*
/* // stroke rim
// stroke rim cairo_rectangle(cr, x, y, w, h);
cairo_rectangle(cr, x, y, w, h); cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 1 );
cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 1 ); cairo_stroke( cr );
cairo_stroke( cr ); */
*/
cairo_restore( cr );
cairo_restore( cr ); }
} }
}
void resize(int X, int Y, int W, int H)
void resize(int X, int Y, int W, int H) {
{ Fl_Widget::resize(X,Y,W,H);
Fl_Widget::resize(X,Y,W,H); x = X;
x = X; y = Y;
y = Y; w = W;
w = W; h = H;
h = H; redraw();
redraw(); }
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,174 +27,170 @@ namespace Avtk
class Button : public Fl_Button class Button : public Fl_Button
{ {
public: public:
Button(int _x, int _y, int _w, int _h, const char *_label): Button(int _x, int _y, int _w, int _h, const char *_label):
Fl_Button(_x, _y, _w, _h, _label) Fl_Button(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
labelMe = _label; labelMe = _label;
setLabel( labelMe ); setLabel( labelMe );
_r = 1.0; _r = 1.0;
_g = 0.48; _g = 0.48;
_b = 0.0; _b = 0.0;
_bgr = 0.11; _bgr = 0.11;
_bgg = 0.11; _bgg = 0.11;
_bgb = 0.11; _bgb = 0.11;
highlight = false; highlight = false;
mouseOver = false; mouseOver = false;
greyedOut = false; greyedOut = false;
} }
void setGreyOut( bool g ) void setGreyOut( bool g )
{ {
greyedOut = g; greyedOut = g;
} }
bool greyedOut; bool greyedOut;
bool mouseOver; bool mouseOver;
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* labelMe; const char* labelMe;
void setLabel( const char* l) void setLabel( const char* l)
{ {
labelMe = l; labelMe = l;
label( labelMe ); label( labelMe );
redraw(); redraw();
} }
float _r, _g, _b; // foreground colour float _r, _g, _b; // foreground colour
float _bgr, _bgg, _bgb; // background colour float _bgr, _bgg, _bgb; // background colour
float _outr, _outg, _outb; // outline colour float _outr, _outg, _outb; // outline colour
void setColor(float r, float g, float b) void setColor(float r, float g, float b)
{ {
_r = r; _r = r;
_g = g; _g = g;
_b = b; _b = b;
} }
void setBgColor(float r, float g, float b) void setBgColor(float r, float g, float b)
{ {
_bgr = r; _bgr = r;
_bgg = g; _bgg = g;
_bgb = b; _bgb = b;
} }
void setHighlight(bool b) void setHighlight(bool b)
{ {
highlight = b; redraw(); highlight = b;
} redraw();
}
void draw()
{ void draw()
if (damage() & FL_DAMAGE_ALL) {
{ if (damage() & FL_DAMAGE_ALL) {
cairo_t *cr = Fl::cairo_cc(); cairo_t *cr = Fl::cairo_cc();
cairo_save( cr ); cairo_save( cr );
cairo_rectangle( cr, x+1, y+1, w-2, h-2 ); cairo_rectangle( cr, x+1, y+1, w-2, h-2 );
if ( !greyedOut ) if ( !greyedOut )
cairo_set_source_rgb( cr, _bgr, _bgg, _bgb ); cairo_set_source_rgb( cr, _bgr, _bgg, _bgb );
else else {
{ float grey = (_bgr + _bgg + _bgb) / 3;
float grey = (_bgr + _bgg + _bgb) / 3; cairo_set_source_rgb( cr, grey, grey, grey );
cairo_set_source_rgb( cr, grey, grey, grey ); }
} cairo_fill_preserve(cr);
cairo_fill_preserve(cr);
cairo_set_line_width(cr, 1.3);
cairo_set_line_width(cr, 1.3); cairo_rectangle( cr, x+1, y+1, w-2, h-2 );
cairo_rectangle( cr, x+1, y+1, w-2, h-2 );
if ( highlight && !greyedOut ) {
if ( highlight && !greyedOut ) cairo_set_source_rgba(cr, _r, _g, _b, 0.4);
{ cairo_fill_preserve(cr);
cairo_set_source_rgba(cr, _r, _g, _b, 0.4); }
cairo_fill_preserve(cr);
} float alpha = 0.6;
if (mouseOver)
float alpha = 0.6; alpha = 1;
if (mouseOver)
alpha = 1; if ( !greyedOut )
cairo_set_source_rgba(cr, _r, _g, _b, alpha);
if ( !greyedOut ) else {
cairo_set_source_rgba(cr, _r, _g, _b, alpha); float grey = (_r + _g + _b) / 3;
else cairo_set_source_rgb( cr, grey, grey, grey );
{ }
float grey = (_r + _g + _b) / 3;
cairo_set_source_rgb( cr, grey, grey, grey ); if ( highlight && !greyedOut )
} cairo_set_line_width(cr, 2.2);
cairo_stroke(cr);
if ( highlight && !greyedOut )
cairo_set_line_width(cr, 2.2); cairo_restore( cr );
cairo_stroke(cr);
draw_label();
cairo_restore( cr ); }
}
draw_label();
} void resize(int X, int Y, int W, int H)
} {
Fl_Widget::resize(X,Y,W,H);
void resize(int X, int Y, int W, int H) x = X;
{ y = Y;
Fl_Widget::resize(X,Y,W,H); w = W;
x = X; h = H;
y = Y; redraw();
w = W; }
h = H;
redraw(); int handle(int event)
} {
switch(event) {
int handle(int event) case FL_PUSH:
{ highlight = 1;
switch(event) { redraw();
case FL_PUSH: return 1;
highlight = 1; case FL_DRAG: {
redraw(); int t = Fl::event_inside(this);
return 1; if (t != highlight) {
case FL_DRAG: { highlight = t;
int t = Fl::event_inside(this); redraw();
if (t != highlight) { }
highlight = t; }
redraw(); return 1;
} case FL_ENTER:
} mouseOver = true;
return 1; redraw();
case FL_ENTER: return 1;
mouseOver = true; case FL_LEAVE:
redraw(); mouseOver = false;
return 1; redraw();
case FL_LEAVE: return 1;
mouseOver = false; case FL_RELEASE:
redraw(); if (highlight) {
return 1; highlight = 0;
case FL_RELEASE: redraw();
if (highlight) { do_callback();
highlight = 0; }
redraw(); return 1;
do_callback(); case FL_SHORTCUT:
} if ( test_shortcut() ) {
return 1; do_callback();
case FL_SHORTCUT: return 1;
if ( test_shortcut() ) }
{ return 0;
do_callback(); default:
return 1; return Fl_Widget::handle(event);
} }
return 0; }
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,174 +29,168 @@ namespace Avtk
class Dial : public Fl_Slider class Dial : public Fl_Slider
{ {
public: public:
Dial(int _x, int _y, int _w, int _h, const char* _lab=0): Dial(int _x, int _y, int _w, int _h, const char* _lab=0):
Fl_Slider(_x, _y, _w, _h, _lab) Fl_Slider(_x, _y, _w, _h, _lab)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
drawLabel = true; drawLabel = true;
mouseClickedY = 0; mouseClickedY = 0;
mouseClicked = false; mouseClicked = false;
highlight = false; highlight = false;
_label = strdup( _lab ); _label = strdup( _lab );
} }
~Dial() ~Dial()
{ {
if( _label ) if( _label )
free( _label ); free( _label );
} }
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
char* _label; char* _label;
float radius; float radius;
float lineWidth; float lineWidth;
int mouseClickedY; int mouseClickedY;
bool mouseClicked; bool mouseClicked;
bool drawLabel; bool drawLabel;
void setLabel( const char* newLabel ) void setLabel( const char* newLabel )
{ {
if( _label ) if( _label )
free( _label ); free( _label );
_label = strdup( newLabel ); _label = strdup( newLabel );
label( _label ); label( _label );
redraw(); redraw();
} }
void draw() void draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ if ( drawLabel ) {
if ( drawLabel ) draw_label();
{ }
draw_label();
} // * 0.9 for line width to remain inside redraw area
if ( w > h )
// * 0.9 for line width to remain inside redraw area radius = (h / 2.f)*0.9;
if ( w > h ) else
radius = (h / 2.f)*0.9; radius = (w / 2.f)*0.9;
else
radius = (w / 2.f)*0.9; lineWidth = 1.4 + radius / 12.f;
lineWidth = 1.4 + radius / 12.f; cairo_t *cr = Fl::cairo_cc();
cairo_t *cr = Fl::cairo_cc(); cairo_save( cr );
cairo_save( cr ); cairo_rectangle( cr, x, y, w, h );
cairo_set_source_rgba(cr, 1.1, 0.1, 0.1, 0 );
cairo_rectangle( cr, x, y, w, h ); cairo_fill(cr);
cairo_set_source_rgba(cr, 1.1, 0.1, 0.1, 0 );
cairo_fill(cr); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
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_set_line_width(cr, lineWidth-0.2); cairo_line_to( cr, x+w/2,y+h/2);
cairo_move_to( cr, x+w/2,y+h/2); cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0 );
cairo_line_to( cr, x+w/2,y+h/2); cairo_stroke(cr);
cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0 );
cairo_stroke(cr); cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, 0.75 );
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1 );
cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, 0.75 ); cairo_stroke(cr);
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1 );
cairo_stroke(cr); float angle = 2.46 + ( 4.54 * value() );
cairo_set_line_width(cr, lineWidth);
float angle = 2.46 + ( 4.54 * value() ); cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, angle );
cairo_set_line_width(cr, lineWidth); cairo_line_to(cr, x+w/2,y+h/2);
cairo_arc(cr, x+w/2,y+h/2, radius, 2.46, angle ); cairo_set_source_rgba(cr, 1.0, 0.48, 0, 0.8);
cairo_line_to(cr, x+w/2,y+h/2); cairo_stroke(cr);
cairo_set_source_rgba(cr, 1.0, 0.48, 0, 0.8);
cairo_stroke(cr); cairo_restore( cr );
}
cairo_restore( cr ); }
}
} void resize(int X, int Y, int W, int H)
{
void resize(int X, int Y, int W, int H) Fl_Slider::resize(X,Y,W,H);
{ x = X;
Fl_Slider::resize(X,Y,W,H); y = Y;
x = X; w = W;
y = Y; h = H;
w = W; redraw();
h = H; }
redraw();
} int handle(int event)
{
int handle(int event) //cout << "handle event type = " << event << " value = " << value() << endl;
{
//cout << "handle event type = " << event << " value = " << value() << endl; //Fl_Slider::handle( event );
//Fl_Slider::handle( event ); switch(event) {
case FL_PUSH:
switch(event) { highlight = 1;
case FL_PUSH: redraw();
highlight = 1; return 1;
redraw(); case FL_DRAG: {
return 1; if ( Fl::event_state(FL_BUTTON1) ) {
case FL_DRAG: if ( mouseClicked == false ) { // catch the "click" event
{ mouseClickedY = Fl::event_y();
if ( Fl::event_state(FL_BUTTON1) ) mouseClicked = true;
{ }
if ( mouseClicked == false ) // catch the "click" event
{ float deltaY = mouseClickedY - Fl::event_y();
mouseClickedY = Fl::event_y();
mouseClicked = true; float val = value();
} val += deltaY / 100.f;
float deltaY = mouseClickedY - Fl::event_y(); if ( val > 1.0 ) val = 1.0;
if ( val < 0.0 ) val = 0.0;
float val = value();
val += deltaY / 100.f; set_value( val );
if ( val > 1.0 ) val = 1.0; mouseClickedY = Fl::event_y();
if ( val < 0.0 ) val = 0.0; redraw();
do_callback(); // makes FLTK call "extra" code entered in FLUID
set_value( val ); }
}
mouseClickedY = Fl::event_y(); return 1;
redraw(); case FL_MOUSEWHEEL: {
do_callback(); // makes FLTK call "extra" code entered in FLUID float val = value() - Fl::event_dy() * 0.1;
} //printf("dial scroll event: %f\n", val);
} if ( val > 1.0 ) val = 1.0;
return 1; if ( val < 0.0 ) val = 0.0;
case FL_MOUSEWHEEL: set_value( val );
{ redraw();
float val = value() - Fl::event_dy() * 0.1; do_callback();
//printf("dial scroll event: %f\n", val); return 1;
if ( val > 1.0 ) val = 1.0; }
if ( val < 0.0 ) val = 0.0; break;
set_value( val ); case FL_RELEASE:
redraw(); if (highlight) {
do_callback(); highlight = 0;
return 1; redraw();
} // never do anything after a callback, as the callback
break; // may delete the widget!
case FL_RELEASE: }
if (highlight) { mouseClicked = false;
highlight = 0; return 1;
redraw(); default:
// never do anything after a callback, as the callback return Fl_Widget::handle(event);
// may delete the widget! }
} }
mouseClicked = false;
return 1;
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -38,78 +38,74 @@ namespace Avtk
class Image : public Fl_Widget class Image : public Fl_Widget
{ {
public: public:
Image(int _x, int _y, int _w, int _h, const char *_label=0 ): Image(int _x, int _y, int _w, int _h, const char *_label=0 ):
Fl_Widget(_x, _y, _w, _h, _label) Fl_Widget(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
bits = -1; bits = -1;
imageDataPtr = 0; imageDataPtr = 0;
stickToRight = false; stickToRight = false;
} }
// used to keep images on the right hand side of the window // used to keep images on the right hand side of the window
bool stickToRight; bool stickToRight;
void setPixbuf(const unsigned char* data, int b ) void setPixbuf(const unsigned char* data, int b )
{ {
bits = b; bits = b;
imageDataPtr = data; imageDataPtr = data;
} }
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
int bits; int bits;
const unsigned char* imageDataPtr; const unsigned char* imageDataPtr;
void draw() void draw()
{ {
if ( damage() & FL_DAMAGE_ALL && imageDataPtr != 0 ) if ( damage() & FL_DAMAGE_ALL && imageDataPtr != 0 ) {
{ fl_draw_image((const uchar*)imageDataPtr, x, y, w, h, bits, w*bits);
fl_draw_image((const uchar*)imageDataPtr, x, y, w, h, bits, w*bits); }
} }
}
void resize(int X, int Y, int W, int H)
void resize(int X, int Y, int W, int H) {
{ if ( stickToRight ) {
if ( stickToRight ) x = gui->getWindowWidth() - w;
{ }
x = gui->getWindowWidth() - w;
} redraw();
}
redraw();
} int handle(int event)
{
int handle(int event) switch(event) {
{ case FL_PUSH:
switch(event) do_callback();
{ return 1;
case FL_PUSH: case FL_DRAG:
do_callback(); return 1;
return 1; case FL_RELEASE:
case FL_DRAG: return 1;
return 1; case FL_SHORTCUT:
case FL_RELEASE: if ( test_shortcut() ) {
return 1; do_callback();
case FL_SHORTCUT: return 1;
if ( test_shortcut() ) }
{ return 0;
do_callback(); default:
return 1; return Fl_Widget::handle(event);
} }
return 0; }
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,152 +27,144 @@ namespace Avtk
class LightButton : public Fl_Button class LightButton : public Fl_Button
{ {
public: public:
LightButton(int _x, int _y, int _w, int _h, const char *_label): LightButton(int _x, int _y, int _w, int _h, const char *_label):
Fl_Button(_x, _y, _w, _h, _label) Fl_Button(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
_r = 1.0; _r = 1.0;
_g = 0.48; _g = 0.48;
_b = 0.0; _b = 0.0;
_bgr = 0.11; _bgr = 0.11;
_bgg = 0.11; _bgg = 0.11;
_bgb = 0.11; _bgb = 0.11;
_outr = _r; _outr = _r;
_outg = _g; _outg = _g;
_outb = _b; _outb = _b;
label = _label; label = _label;
_highlight = false; _highlight = false;
mouseOver = false; mouseOver = false;
} }
bool mouseOver; bool mouseOver;
bool _highlight; bool _highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
float _r, _g, _b; // foreground colour float _r, _g, _b; // foreground colour
float _bgr, _bgg, _bgb; // background colour float _bgr, _bgg, _bgb; // background colour
float _outr, _outg, _outb; // outline colour float _outr, _outg, _outb; // outline colour
void setColor(float r, float g, float b) void setColor(float r, float g, float b)
{ {
_r = r; _r = r;
_g = g; _g = g;
_b = b; _b = b;
} }
void setBgColor(float r, float g, float b) void setBgColor(float r, float g, float b)
{ {
_bgr = r; _bgr = r;
_bgg = g; _bgg = g;
_bgb = b; _bgb = b;
} }
void draw() void draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ if ( value() ) {
if ( value() ) _highlight = true;
{ } else {
_highlight = true; _highlight = false;
} }
else
{ cairo_t *cr = Fl::cairo_cc();
_highlight = false;
} cairo_save( cr );
cairo_t *cr = Fl::cairo_cc(); cairo_rectangle( cr, x+1, y+1, w-2, h-2 );
cairo_set_source_rgba( cr, _bgr, _bgg, _bgb, 0.4 );
cairo_save( cr ); cairo_fill_preserve(cr);
cairo_rectangle( cr, x+1, y+1, w-2, h-2 ); cairo_set_line_width(cr, 1.5);
cairo_set_source_rgba( cr, _bgr, _bgg, _bgb, 0.4 ); cairo_rectangle( cr, x+1, y+1, w-2, h-2 );
cairo_fill_preserve(cr);
if ( _highlight ) {
cairo_set_line_width(cr, 1.5); cairo_set_source_rgba(cr, _r, _g, _b, 0.4);
cairo_rectangle( cr, x+1, y+1, w-2, h-2 ); cairo_fill_preserve(cr);
}
if ( _highlight )
{ float alpha = 0.7;
cairo_set_source_rgba(cr, _r, _g, _b, 0.4); if (mouseOver)
cairo_fill_preserve(cr); alpha = 1;
} cairo_set_source_rgba(cr, _r, _g, _b, alpha);
cairo_stroke(cr);
float alpha = 0.7;
if (mouseOver) cairo_restore( cr );
alpha = 1;
cairo_set_source_rgba(cr, _r, _g, _b, alpha); draw_label();
cairo_stroke(cr); }
}
cairo_restore( cr );
void resize(int X, int Y, int W, int H)
draw_label(); {
} Fl_Widget::resize(X,Y,W,H);
} x = X;
y = Y;
void resize(int X, int Y, int W, int H) w = W;
{ h = H;
Fl_Widget::resize(X,Y,W,H); redraw();
x = X; }
y = Y;
w = W;
h = H;
redraw(); int handle(int event)
} {
switch(event) {
case FL_ACTIVATE: {
}
int handle(int event) case FL_DEACTIVATE: {
{ }
switch(event) { return 1;
case FL_ACTIVATE: case FL_PUSH:
{
} do_callback();
case FL_DEACTIVATE: return 1;
{ case FL_DRAG: {
} int t = Fl::event_inside(this);
return 1; if (t != _highlight) {
case FL_PUSH: _highlight = t;
redraw();
do_callback(); }
return 1; }
case FL_DRAG: { return 1;
int t = Fl::event_inside(this); case FL_ENTER:
if (t != _highlight) { mouseOver = true;
_highlight = t; redraw();
redraw(); return 1;
} case FL_LEAVE:
} mouseOver = false;
return 1; redraw();
case FL_ENTER: return 1;
mouseOver = true; case FL_RELEASE:
redraw(); return 1;
return 1; case FL_SHORTCUT:
case FL_LEAVE: if ( test_shortcut() ) {
mouseOver = false; do_callback();
redraw(); return 1;
return 1; }
case FL_RELEASE: return 0;
return 1; default:
case FL_SHORTCUT: return Fl_Widget::handle(event);
if ( test_shortcut() ) }
{ }
do_callback();
return 1;
}
return 0;
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,173 +27,172 @@ namespace Avtk
class RadialStatus : public Fl_Slider class RadialStatus : public Fl_Slider
{ {
public: public:
RadialStatus(int _x, int _y, int _w, int _h, const char *_label = 0): RadialStatus(int _x, int _y, int _w, int _h, const char *_label = 0):
Fl_Slider(_x, _y, _w, _h, _label) Fl_Slider(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
previousAngle = -1; previousAngle = -1;
_r = 1.0; _r = 1.0;
_g = 0.48; _g = 0.48;
_b = 0.0; _b = 0.0;
_bgr = 0.11; _bgr = 0.11;
_bgg = 0.11; _bgg = 0.11;
_bgb = 0.11; _bgb = 0.11;
highlight = false; highlight = false;
mouseOver = false; mouseOver = false;
_recording = false; _recording = false;
} }
bool _recording; bool _recording;
void recording(bool r){_recording = r; redraw();} void recording(bool r)
{
bool mouseOver; _recording = r;
bool highlight; redraw();
int x, y, w, h; }
const char* label;
bool mouseOver;
int previousAngle; bool highlight;
int x, y, w, h;
float _r, _g, _b; // foreground colour const char* label;
float _bgr, _bgg, _bgb; // background colour
float _outr, _outg, _outb; // outline colour int previousAngle;
void setColor(float r, float g, float b) float _r, _g, _b; // foreground colour
{ float _bgr, _bgg, _bgb; // background colour
_r = r; float _outr, _outg, _outb; // outline colour
_g = g;
_b = b; void setColor(float r, float g, float b)
} {
_r = r;
void setBgColor(float r, float g, float b) _g = g;
{ _b = b;
_bgr = r; }
_bgg = g;
_bgb = b; void setBgColor(float r, float g, float b)
} {
_bgr = r;
void draw() _bgg = g;
{ _bgb = b;
// check that its a new "segment" to redraw }
int newAngle = (value() * 16);
void draw()
if (damage() & FL_DAMAGE_ALL && {
previousAngle != newAngle ) // check that its a new "segment" to redraw
{ int newAngle = (value() * 16);
cairo_t *cr = Fl::cairo_cc();
if (damage() & FL_DAMAGE_ALL &&
cairo_save( cr ); previousAngle != newAngle ) {
cairo_t *cr = Fl::cairo_cc();
int xc = (w) / 2.f;
int yc = (h) / 2.f; cairo_save( cr );
int radius = xc > yc ? yc : xc; int xc = (w) / 2.f;
radius -= 10; int yc = (h) / 2.f;
float angle = newAngle / 16.f; int radius = xc > yc ? yc : xc;
radius -= 10;
cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND );
//cairo_move_to( cr, x + xc, y + yc ); float angle = newAngle / 16.f;
cairo_arc( cr, x + xc, y + yc, radius, -(3.1415/2), angle * 6.28 - (3.1415/2) );
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5 ); cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND );
cairo_set_line_width(cr, 12); //cairo_move_to( cr, x + xc, y + yc );
cairo_stroke_preserve(cr); cairo_arc( cr, x + xc, y + yc, radius, -(3.1415/2), angle * 6.28 - (3.1415/2) );
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5 );
cairo_set_source_rgba (cr, 1.0, 0.48, 0.0, 1 ); cairo_set_line_width(cr, 12);
cairo_set_line_width(cr, 8.2); cairo_stroke_preserve(cr);
cairo_stroke(cr);
cairo_set_source_rgba (cr, 1.0, 0.48, 0.0, 1 );
cairo_set_line_width(cr, 8.2);
// recording? cairo_stroke(cr);
if ( _recording )
{
cairo_set_source_rgba(cr,1.0,0.0,0.0, 0.8); // recording?
cairo_arc(cr, x + xc, y + yc, radius-4, 0, 2 * 3.1415); if ( _recording ) {
cairo_fill_preserve(cr); cairo_set_source_rgba(cr,1.0,0.0,0.0, 0.8);
cairo_set_source_rgba(cr,0.0,0.0,0.0, 0.8); cairo_arc(cr, x + xc, y + yc, radius-4, 0, 2 * 3.1415);
cairo_set_line_width(cr, 2.2); cairo_fill_preserve(cr);
cairo_stroke(cr); cairo_set_source_rgba(cr,0.0,0.0,0.0, 0.8);
cairo_set_line_width(cr, 2.2);
// color of internal dot depending on rec state cairo_stroke(cr);
cairo_set_source_rgba(cr,0.0,0.0,0.0, 1);
} // color of internal dot depending on rec state
else cairo_set_source_rgba(cr,0.0,0.0,0.0, 1);
{ } else {
cairo_set_source_rgba(cr,0.3,0.3,0.3, 1); cairo_set_source_rgba(cr,0.3,0.3,0.3, 1);
} }
// inside circle // inside circle
cairo_arc(cr, x + xc, y + yc, 10, 0, 2 * 3.1415); cairo_arc(cr, x + xc, y + yc, 10, 0, 2 * 3.1415);
cairo_set_line_width(cr, 4.2); cairo_set_line_width(cr, 4.2);
cairo_fill(cr); cairo_fill(cr);
cairo_restore( cr ); cairo_restore( cr );
draw_label(); draw_label();
} }
} }
void resize(int X, int Y, int W, int H) void resize(int X, int Y, int W, int H)
{ {
Fl_Widget::resize(X,Y,W,H); Fl_Widget::resize(X,Y,W,H);
x = X; x = X;
y = Y; y = Y;
w = W; w = W;
h = H; h = H;
redraw(); redraw();
} }
int handle(int event) int handle(int event)
{ {
switch(event) { switch(event) {
case FL_PUSH: case FL_PUSH:
highlight = 1; highlight = 1;
redraw(); redraw();
return 1; return 1;
case FL_DRAG: { case FL_DRAG: {
int t = Fl::event_inside(this); int t = Fl::event_inside(this);
if (t != highlight) { if (t != highlight) {
highlight = t; highlight = t;
redraw(); redraw();
} }
} }
return 1; return 1;
case FL_ENTER: case FL_ENTER:
mouseOver = true; mouseOver = true;
redraw(); redraw();
return 1; return 1;
case FL_LEAVE: case FL_LEAVE:
mouseOver = false; mouseOver = false;
redraw(); redraw();
return 1; return 1;
case FL_RELEASE: case FL_RELEASE:
if (highlight) { if (highlight) {
highlight = 0; highlight = 0;
redraw(); redraw();
do_callback(); do_callback();
} }
return 1; return 1;
case FL_SHORTCUT: case FL_SHORTCUT:
if ( test_shortcut() ) if ( test_shortcut() ) {
{ do_callback();
do_callback(); return 1;
return 1; }
} return 0;
return 0; default:
default: return Fl_Widget::handle(event);
return Fl_Widget::handle(event); }
} }
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,190 +27,212 @@ namespace Avtk
class Reverb : public Fl_Slider class Reverb : public Fl_Slider
{ {
public: public:
Reverb(int _x, int _y, int _w, int _h, const char *_label =0): Reverb(int _x, int _y, int _w, int _h, const char *_label =0):
Fl_Slider(_x, _y, _w, _h, _label) Fl_Slider(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
amp = 0.5; amp = 0.5;
s = 0.5; s = 0.5;
damp= 0.5; damp= 0.5;
active = false; active = false;
label = _label; label = _label;
highlight = false; highlight = false;
mouseOver = false; mouseOver = false;
} }
void size(float v) { s = v; redraw(); } void size(float v)
void wet(float v) { amp = v; redraw(); } {
void damping(float v){damp = v; redraw();} s = v;
redraw();
float size(){return s;} }
float wet (){return amp;} void wet(float v)
float damping(){return damp;} {
amp = v;
bool getActive(){return active;} redraw();
void setActive(bool a){active = a; redraw();} }
void damping(float v)
float s; {
float amp; damp = v;
float damp; redraw();
}
bool active;
float size()
bool mouseOver; {
bool highlight; return s;
int x, y, w, h; }
const char* label; float wet ()
{
void draw() return amp;
{ }
if (damage() & FL_DAMAGE_ALL) float damping()
{ {
cairo_t *cr = Fl::cairo_cc(); return damp;
}
cairo_save( cr );
bool getActive()
// graph {
cairo_rectangle( cr, x, y, w, h ); return active;
cairo_set_source_rgb( cr,28 / 255.f, 28 / 255.f , 28 / 255.f ); }
cairo_fill(cr); void setActive(bool a)
{
active = a;
// set up dashed lines, 1 px off, 1 px on redraw();
double dashes[1]; }
dashes[0] = 2.0;
float s;
cairo_set_dash ( cr, dashes, 1, 0.0); float amp;
float damp;
// loop over each 2nd line, drawing dots
cairo_set_line_width(cr, 1.0); bool active;
cairo_set_source_rgb(cr, 0.4,0.4,0.4);
for ( int i = 0; i < 4; i++ ) bool mouseOver;
{ bool highlight;
cairo_move_to( cr, x + ((w / 4.f)*i), y ); int x, y, w, h;
cairo_line_to( cr, x + ((w / 4.f)*i), y + h ); const char* label;
}
for ( int i = 0; i < 4; i++ ) void draw()
{ {
cairo_move_to( cr, x , y + ((h / 4.f)*i) ); if (damage() & FL_DAMAGE_ALL) {
cairo_line_to( cr, x + w, y + ((h / 4.f)*i) ); cairo_t *cr = Fl::cairo_cc();
}
cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); cairo_save( cr );
cairo_stroke(cr);
cairo_set_dash ( cr, dashes, 0, 0.0); // graph
cairo_rectangle( cr, x, y, w, h );
// draw "damping" control cairo_set_source_rgb( cr,28 / 255.f, 28 / 255.f , 28 / 255.f );
cairo_move_to( cr, x+w*0.1 , y + h*0.85 - (h*0.7*amp)); cairo_fill(cr);
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); // set up dashed lines, 1 px off, 1 px on
cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND); double dashes[1];
cairo_set_line_width(cr, 1.9); dashes[0] = 2.0;
cairo_stroke( cr );
cairo_set_dash ( cr, dashes, 1, 0.0);
// draw reverb triangle
cairo_move_to( cr, x , y + h*0.99 ); // loop over each 2nd line, drawing dots
cairo_line_to( cr, x + w*0.1, y + h*0.85 - (h*0.7*amp)); cairo_set_line_width(cr, 1.0);
cairo_line_to( cr, x + w*0.3+w*0.7*s, y + (h*0.99)); cairo_set_source_rgb(cr, 0.4,0.4,0.4);
for ( int i = 0; i < 4; i++ ) {
// stroke cairo_move_to( cr, x + ((w / 4.f)*i), y );
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); cairo_line_to( cr, x + ((w / 4.f)*i), y + h );
cairo_fill_preserve(cr); }
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); for ( int i = 0; i < 4; i++ ) {
cairo_set_line_width(cr, 1.2); cairo_move_to( cr, x , y + ((h / 4.f)*i) );
cairo_stroke( cr ); cairo_line_to( cr, x + w, y + ((h / 4.f)*i) );
}
// stroke rim cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 );
cairo_rectangle(cr, x, y, w, h); cairo_stroke(cr);
//cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); cairo_set_dash ( cr, dashes, 0, 0.0);
cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 );
cairo_set_line_width(cr, 0.9); // draw "damping" control
cairo_stroke( cr ); 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));
if ( !active ) cairo_set_source_rgba(cr, 1.0, 0.48, 0, 1);
{ cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND);
// big grey X cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width(cr, 12.0); cairo_set_line_width(cr, 1.9);
cairo_set_source_rgba(cr, 0.0,0.0,0.0, 1.0); cairo_stroke( cr );
cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) ); // draw reverb triangle
cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) ); 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_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); cairo_line_to( cr, x + w*0.3+w*0.7*s, y + (h*0.99));
cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) );
cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); // stroke
cairo_stroke( 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_restore( cr ); cairo_set_line_width(cr, 1.2);
cairo_stroke( cr );
draw_label();
} // stroke rim
} cairo_rectangle(cr, x, y, w, h);
//cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
void resize(int X, int Y, int W, int H) cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 );
{ cairo_set_line_width(cr, 0.9);
Fl_Widget::resize(X,Y,W,H); cairo_stroke( cr );
x = X;
y = Y; if ( !active ) {
w = W; // big grey X
h = H; cairo_set_line_width(cr, 12.0);
redraw(); cairo_set_source_rgba(cr, 0.0,0.0,0.0, 1.0);
}
cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) );
int handle(int event) cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) );
{
switch(event) { cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) );
case FL_PUSH: cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) );
highlight = 1; cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT);
if ( Fl::event_button() == FL_RIGHT_MOUSE ) cairo_stroke( cr );
{ }
active = !active;
redraw(); cairo_restore( cr );
do_callback();
} draw_label();
return 1; }
case FL_DRAG: { }
int t = Fl::event_inside(this);
if (t != highlight) { void resize(int X, int Y, int W, int H)
highlight = t; {
redraw(); Fl_Widget::resize(X,Y,W,H);
} x = X;
} y = Y;
return 1; w = W;
case FL_ENTER: h = H;
mouseOver = true; redraw();
redraw(); }
return 1;
case FL_LEAVE: int handle(int event)
mouseOver = false; {
redraw(); switch(event) {
return 1; case FL_PUSH:
case FL_RELEASE: highlight = 1;
if (highlight) { if ( Fl::event_button() == FL_RIGHT_MOUSE ) {
highlight = 0; active = !active;
redraw(); redraw();
} do_callback();
return 1; }
case FL_SHORTCUT: return 1;
if ( test_shortcut() ) case FL_DRAG: {
{ int t = Fl::event_inside(this);
do_callback(); if (t != highlight) {
return 1; highlight = t;
} redraw();
return 0; }
default: }
return Fl_Widget::handle(event); 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 } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,185 +29,198 @@
namespace Avtk namespace Avtk
{ {
class SidechainGain : public Fl_Slider class SidechainGain : public Fl_Slider
{ {
public: public:
SidechainGain(int _x, int _y, int _w, int _h, const char *_label = 0): SidechainGain(int _x, int _y, int _w, int _h, const char *_label = 0):
Fl_Slider(_x, _y, _w, _h, _label) Fl_Slider(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
mouseClickedX = 0; mouseClickedX = 0;
mouseClickedY = 0; mouseClickedY = 0;
mouseClicked = false; mouseClicked = false;
active = true; active = true;
highlight = false; highlight = false;
_threshold = 1.0; _threshold = 1.0;
_target = 1.f; _target = 1.f;
_reduce = 1.f; _reduce = 1.f;
_release = 0.5; _release = 0.5;
_sidechainAmp = 0; _sidechainAmp = 0;
} }
void threshold(float t) {_threshold = t; redraw();} void threshold(float t)
void reduce (float r) {_reduce = r; redraw();} {
void release (float r) {_release = r; redraw();} _threshold = t;
redraw();
/// sets the sidechain amplitude }
void sidechain(float s) {_sidechainAmp = s; redraw();} void reduce (float r)
{
bool active; _reduce = r;
bool highlight; redraw();
int x, y, w, h; }
const char* label; void release (float r)
{
int mouseClickedX; _release = r;
int mouseClickedY; redraw();
bool mouseClicked; }
bool mouseRightClicked;
/// sets the sidechain amplitude
float _threshold; void sidechain(float s)
float _target; {
float _reduce; _sidechainAmp = s;
float _release; redraw();
}
float _sidechainAmp;
bool active;
void set_active(bool a) bool highlight;
{ int x, y, w, h;
active = a; const char* label;
redraw();
} int mouseClickedX;
int mouseClickedY;
void draw() bool mouseClicked;
{ bool mouseRightClicked;
if (damage() & FL_DAMAGE_ALL)
{ float _threshold;
cairo_t *cr = Fl::cairo_cc(); float _target;
float _reduce;
cairo_save( cr ); float _release;
cairo_set_line_width(cr, 1.5); float _sidechainAmp;
void set_active(bool a)
// fill background {
cairo_rectangle( cr, x, y, w, h); active = a;
cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); redraw();
cairo_fill_preserve( cr ); }
cairo_clip( cr );
void draw()
{
// set up dashed lines, 1 px off, 1 px on if (damage() & FL_DAMAGE_ALL) {
double dashes[1]; cairo_t *cr = Fl::cairo_cc();
dashes[0] = 2.0;
cairo_save( cr );
cairo_set_dash ( cr, dashes, 1, 0.0);
cairo_set_line_width( cr, 1.0); cairo_set_line_width(cr, 1.5);
// loop over each 2nd line, drawing dots
cairo_set_line_width(cr, 1.0); // fill background
cairo_set_source_rgb(cr, 0.4,0.4,0.4); cairo_rectangle( cr, x, y, w, h);
for ( int i = 0; i < 4; i++ ) cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f );
{ cairo_fill_preserve( cr );
cairo_move_to( cr, x + ((w / 4.f)*i), y ); cairo_clip( cr );
cairo_line_to( cr, x + ((w / 4.f)*i), y + h );
}
for ( int i = 0; i < 4; i++ ) // set up dashed lines, 1 px off, 1 px on
{ double dashes[1];
cairo_move_to( cr, x , y + ((h / 4.f)*i) ); dashes[0] = 2.0;
cairo_line_to( cr, x + w, y + ((h / 4.f)*i) );
} cairo_set_dash ( cr, dashes, 1, 0.0);
cairo_set_line_width( cr, 1.0);
cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 );
cairo_stroke(cr); // loop over each 2nd line, drawing dots
cairo_set_dash ( cr, dashes, 0, 0.0); 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++ ) {
// draw threshold / ducked line cairo_move_to( cr, x + ((w / 4.f)*i), y );
cairo_move_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)), y ); cairo_line_to( cr, x + ((w / 4.f)*i), y + h );
}
cairo_line_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)) + _sidechainAmp* _reduce*( w * 0.5 ), y + h / 2 ); for ( int i = 0; i < 4; i++ ) {
cairo_move_to( cr, x , y + ((h / 4.f)*i) );
cairo_line_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)), y + h ); cairo_line_to( cr, x + w, y + ((h / 4.f)*i) );
}
cairo_line_to( cr, x + w , y + h );
cairo_line_to( cr, x + w , y ); cairo_set_source_rgba( cr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 );
cairo_close_path( cr ); cairo_stroke(cr);
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); cairo_set_dash ( cr, dashes, 0, 0.0);
cairo_fill_preserve( cr );
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_stroke( cr ); // draw threshold / ducked line
cairo_move_to( cr, x + w * 0.750 - (w * 0.5 * (1-_threshold)), y );
// _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.750 - (w * 0.5 * (1-_threshold)) + _sidechainAmp* _reduce*( w * 0.5 ), y + h / 2 );
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.750 - (w * 0.5 * (1-_threshold)), y + h );
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_line_to( cr, x + w , y + h );
cairo_close_path( cr ); cairo_line_to( cr, x + w , y );
cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 0.21 ); cairo_close_path( cr );
cairo_fill_preserve( cr ); cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 1 ); cairo_fill_preserve( cr );
cairo_stroke( cr ); cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_stroke( cr );
// _release horizontal line // _sidechainAmp => arrow
cairo_move_to( cr, x , y + h * 0.25 + h/2 * _release ); cairo_move_to( cr, x + w * 0.00 * _sidechainAmp, y + h * 0.4 - (h*0.1*_sidechainAmp) );
cairo_line_to( cr, x + w, y + h * 0.25 + h/2 * _release ); cairo_line_to( cr, x + w * 0.65 * _sidechainAmp, y + h * 0.4 );
cairo_set_source_rgba( cr, 1.0, 0.0, 0.f , 1 ); cairo_line_to( cr, x + w * 0.1 + w * 0.65 * _sidechainAmp, y + h * 0.5 );
cairo_stroke( cr ); 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) );
// stroke outline cairo_close_path( cr );
cairo_rectangle(cr, x, y, w, h); cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 0.21 );
cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 ); cairo_fill_preserve( cr );
cairo_set_line_width(cr, 1.9); cairo_set_source_rgba( cr, 1.0, 0.48, 0.f , 1 );
cairo_stroke( cr ); cairo_stroke( cr );
if ( !active )
{ // _release horizontal line
// big grey X cairo_move_to( cr, x , y + h * 0.25 + h/2 * _release );
cairo_set_line_width(cr, 20.0); cairo_line_to( cr, x + w, y + h * 0.25 + h/2 * _release );
cairo_set_source_rgba(cr, 0.4,0.4,0.4, 0.7); cairo_set_source_rgba( cr, 1.0, 0.0, 0.f , 1 );
cairo_stroke( cr );
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 ) ); // stroke outline
cairo_rectangle(cr, x, y, w, h);
cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) ); cairo_set_source_rgba( cr, 126 / 255.f, 126 / 255.f , 126 / 255.f , 0.8 );
cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) ); cairo_set_line_width(cr, 1.9);
cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT); cairo_stroke( cr );
cairo_stroke( cr );
} if ( !active ) {
// big grey X
cairo_restore( cr ); 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 ) );
void resize(int X, int Y, int W, int H) cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) );
{
Fl_Widget::resize(X,Y,W,H); cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) );
x = X; cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) );
y = Y; cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT);
w = W; cairo_stroke( cr );
h = H; }
redraw();
} cairo_restore( cr );
}
int handle(int event) }
{ //TODO needed?
void resize(int X, int Y, int W, int H)
return 0; {
} Fl_Widget::resize(X,Y,W,H);
x = X;
private: y = Y;
w = W;
h = H;
redraw();
}
int handle(int event)
{
//TODO needed?
return 0;
}
private:
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,171 +29,166 @@ namespace Avtk
class UnitState class UnitState
{ {
public: public:
enum State { enum State {
UNIT_EMPTY = 0, UNIT_EMPTY = 0,
UNIT_LOADED, UNIT_LOADED,
UNIT_QUEUED, UNIT_QUEUED,
UNIT_PLAYING, UNIT_PLAYING,
UNIT_RECORDING, UNIT_RECORDING,
UNIT_STOPPING, UNIT_STOPPING,
}; };
UnitState() UnitState()
{ {
state = UNIT_EMPTY; state = UNIT_EMPTY;
name = "Clip"; name = "Clip";
} }
UnitState(std::string n) UnitState(std::string n)
{ {
state = UNIT_EMPTY; state = UNIT_EMPTY;
name = n; name = n;
} }
State state; State state;
std::string name; std::string name;
}; };
class Unit : public Fl_Button class Unit : public Fl_Button
{ {
public: public:
Unit(int _x, int _y, int _w, int _h, const char *_label): Unit(int _x, int _y, int _w, int _h, const char *_label):
Fl_Button(_x, _y, _w, _h, _label) Fl_Button(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
highlight = false; highlight = false;
mouseOver = false; mouseOver = false;
clips[0].state = UnitState::UNIT_EMPTY; clips[0].state = UnitState::UNIT_EMPTY;
clips[1].state = UnitState::UNIT_LOADED; clips[1].state = UnitState::UNIT_LOADED;
clips[2].state = UnitState::UNIT_QUEUED; clips[2].state = UnitState::UNIT_QUEUED;
clips[3].state = UnitState::UNIT_PLAYING; clips[3].state = UnitState::UNIT_PLAYING;
clips[4].state = UnitState::UNIT_RECORDING; clips[4].state = UnitState::UNIT_RECORDING;
clips[5].state = UnitState::UNIT_STOPPING; clips[5].state = UnitState::UNIT_STOPPING;
} }
static const int numClips = 10; static const int numClips = 10;
UnitState clips[numClips]; UnitState clips[numClips];
bool mouseOver; bool mouseOver;
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
void draw() void draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ if ( value() ) {
if ( value() ) highlight = true;
{ } else {
highlight = true; highlight = false;
} }
else
{ cairo_t *cr = Fl::cairo_cc();
highlight = false;
} cairo_save( cr );
cairo_t *cr = Fl::cairo_cc(); cairo_rectangle( cr, x+2, y + 2, w - 2, h - 2 );
cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4);
cairo_save( cr ); cairo_fill(cr);
cairo_rectangle( cr, x+2, y + 2, w - 2, h - 2 ); //cairo_rectangle( cr, x+1, drawY, clipHeight - 2, clipHeight - 2 );
cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4); /*
cairo_fill(cr); cairo_rectangle( cr, x+1, drawY, clipWidth, clipHeight - 2 );
//cairo_rectangle( cr, x+1, drawY, clipHeight - 2, clipHeight - 2 ); float alpha = 0.7;
/* if (mouseOver) { alpha = 1; }
cairo_rectangle( cr, x+1, drawY, clipWidth, clipHeight - 2 ); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha);
cairo_set_line_width( cr, 1.4);
float alpha = 0.7; cairo_move_to( cr, x+clipHeight-1, drawY );
if (mouseOver) { alpha = 1; } cairo_line_to( cr, x+clipHeight-1, drawY + clipHeight - 2);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha); cairo_stroke(cr);
cairo_set_line_width( cr, 1.4);
cairo_move_to( cr, x+clipHeight-1, drawY ); // clip name
cairo_line_to( cr, x+clipHeight-1, drawY + clipHeight - 2); cairo_move_to( cr, x+clipHeight-1+ 10, drawY + 15 );
cairo_stroke(cr); cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 );
cairo_set_font_size( cr, 10 );
// clip name cairo_show_text( cr, label );
cairo_move_to( cr, x+clipHeight-1+ 10, drawY + 15 ); */
cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 );
cairo_set_font_size( cr, 10 ); // outline
cairo_show_text( cr, label ); float alpha = 0.7;
*/ if (mouseOver) {
alpha = 1;
// outline }
float alpha = 0.7; cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha);
if (mouseOver) { alpha = 1; } cairo_rectangle( cr, x+2, y + 2, w - 2, h - 2 );
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha); cairo_set_line_width( cr, 1.4);
cairo_rectangle( cr, x+2, y + 2, w - 2, h - 2 ); cairo_stroke( cr );
cairo_set_line_width( cr, 1.4);
cairo_stroke( cr ); cairo_restore( cr );
cairo_restore( cr ); draw_label();
}
draw_label(); }
}
} void resize(int X, int Y, int W, int H)
{
void resize(int X, int Y, int W, int H) Fl_Widget::resize(X,Y,W,H);
{ x = X;
Fl_Widget::resize(X,Y,W,H); y = Y;
x = X; w = W;
y = Y; h = H;
w = W; redraw();
h = H; }
redraw();
}
int handle(int event)
{
int handle(int event) switch(event) {
{ case FL_ACTIVATE: {
switch(event) { }
case FL_ACTIVATE: case FL_DEACTIVATE: {
{ }
} return 1;
case FL_DEACTIVATE: case FL_PUSH:
{ highlight = 1;
} do_callback();
return 1; return 1;
case FL_PUSH: case FL_DRAG: {
highlight = 1; int t = Fl::event_inside(this);
do_callback(); if (t != highlight) {
return 1; highlight = t;
case FL_DRAG: { redraw();
int t = Fl::event_inside(this); }
if (t != highlight) { }
highlight = t; return 1;
redraw(); case FL_ENTER:
} mouseOver = true;
} redraw();
return 1; return 1;
case FL_ENTER: case FL_LEAVE:
mouseOver = true; mouseOver = false;
redraw(); redraw();
return 1; return 1;
case FL_LEAVE: case FL_RELEASE:
mouseOver = false; return 1;
redraw(); case FL_SHORTCUT:
return 1; if ( test_shortcut() ) {
case FL_RELEASE: do_callback();
return 1; return 1;
case FL_SHORTCUT: }
if ( test_shortcut() ) return 0;
{ default:
do_callback(); return Fl_Widget::handle(event);
return 1; }
} }
return 0;
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,132 +27,130 @@ namespace Avtk
{ {
Bindings::Bindings( int _x, int _y, int _w, int _h, const char *_label ) : Bindings::Bindings( int _x, int _y, int _w, int _h, const char *_label ) :
Fl_Button(_x, _y, _w, _h, _label) Fl_Button(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
bindYPx = 25; bindYPx = 25;
highlight = false; highlight = false;
mouseOver = false; mouseOver = false;
} }
void Bindings::draw() void Bindings::draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ cairo_t *cr = Fl::cairo_cc();
cairo_t *cr = Fl::cairo_cc(); cairo_save( cr );
cairo_save( cr );
cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 );
cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 ); cairo_set_font_size( cr, 11 );
cairo_set_font_size( cr, 11 ); cairo_move_to( cr, x + 7, y+15 );
cairo_move_to( cr, x + 7, y+15 ); cairo_show_text( cr, "Action:" );
cairo_show_text( cr, "Action:" );
cairo_move_to( cr, x + 140, y+15 );
cairo_move_to( cr, x + 140, y+15 ); cairo_show_text( cr, "T:" );
cairo_show_text( cr, "T:" ); cairo_move_to( cr, x + 160, y+15 );
cairo_move_to( cr, x + 160, y+15 ); cairo_show_text( cr, "S:" );
cairo_show_text( cr, "S:" );
cairo_move_to( cr, x + 200, y+15 );
cairo_move_to( cr, x + 200, y+15 ); cairo_show_text( cr, "B1:" );
cairo_show_text( cr, "B1:" ); cairo_move_to( cr, x + 230, y+15 );
cairo_move_to( cr, x + 230, y+15 ); cairo_show_text( cr, "B2:" );
cairo_show_text( cr, "B2:" );
int drawY = y + bindYPx;
int drawY = y + bindYPx; for(unsigned int i = 0; i < binds.size(); i++) { // draw each binding
for(unsigned int i = 0; i < binds.size(); i++) // draw each binding cairo_rectangle( cr, x+2, drawY, 179, 23 );
{ cairo_set_source_rgba(cr, 0 / 255.f, 0 / 255.f , 0 / 255.f, 0.4);
cairo_rectangle( cr, x+2, drawY, 179, 23 ); cairo_fill(cr);
cairo_set_source_rgba(cr, 0 / 255.f, 0 / 255.f , 0 / 255.f, 0.4);
cairo_fill(cr); // action
cairo_move_to( cr, x + 7, drawY+15 );
// action cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 );
cairo_move_to( cr, x + 7, drawY+15 ); cairo_set_font_size( cr, 11 );
cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 1 ); const char* action = Event::getPrettyName( binds.at(i)->action );
cairo_set_font_size( cr, 11 ); if ( action )
const char* action = Event::getPrettyName( binds.at(i)->action ); cairo_show_text( cr, action );
if ( action )
cairo_show_text( cr, action ); // track
cairo_move_to( cr, x + 140, drawY+15 );
// track {
cairo_move_to( cr, x + 140, drawY+15 ); std::stringstream s;
{ s << binds.at(i)->track;
std::stringstream s; cairo_show_text( cr, s.str().c_str() );
s << binds.at(i)->track; }
cairo_show_text( cr, s.str().c_str() ); // scene
} cairo_move_to( cr, x + 150, drawY+15 );
// scene {
cairo_move_to( cr, x + 150, drawY+15 ); std::stringstream s;
{ s << binds.at(i)->scene;
std::stringstream s; cairo_show_text( cr, s.str().c_str() );
s << binds.at(i)->scene; }
cairo_show_text( cr, s.str().c_str() );
} // status
cairo_move_to( cr, x + 165, drawY+15 );
// status {
cairo_move_to( cr, x + 165, drawY+15 ); std::stringstream s;
{ s << binds.at(i)->status;
std::stringstream s; cairo_show_text( cr, s.str().c_str() );
s << binds.at(i)->status; }
cairo_show_text( cr, s.str().c_str() ); // data
} cairo_move_to( cr, x + 175, drawY+15 );
// data {
cairo_move_to( cr, x + 175, drawY+15 ); std::stringstream s;
{ s << binds.at(i)->data;
std::stringstream s; cairo_show_text( cr, s.str().c_str() );
s << binds.at(i)->data; }
cairo_show_text( cr, s.str().c_str() ); // move to next line
} drawY += bindYPx;
// move to next line }
drawY += bindYPx;
} //printf("done drawing\n");
//printf("done drawing\n"); cairo_restore( cr );
}
cairo_restore( cr );
}
} }
void Bindings::add( Binding* b ) void Bindings::add( Binding* b )
{ {
// FIXME: Refactor to use copy-constructor? // FIXME: Refactor to use copy-constructor?
Binding* tmp = new Binding(); Binding* tmp = new Binding();
tmp->action = b->action; tmp->action = b->action;
tmp->status = b->status; tmp->status = b->status;
tmp->data = b->data; tmp->data = b->data;
tmp->active = b->active; tmp->active = b->active;
tmp->track = b->track; tmp->track = b->track;
tmp->scene = b->scene; tmp->scene = b->scene;
tmp->send = b->send; tmp->send = b->send;
binds.push_back( tmp ); binds.push_back( tmp );
/* /*
int height = binds.size() * bindYPx; int height = binds.size() * bindYPx;
printf("resize to %i, %i, %i, %i\n", x, y, w, height ); printf("resize to %i, %i, %i, %i\n", x, y, w, height );
resize( x, y, w, height ); resize( x, y, w, height );
*/ */
redraw(); redraw();
} }
void Bindings::resize(int X, int Y, int W, int H) void Bindings::resize(int X, int Y, int W, int H)
{ {
Fl_Widget::resize(X,Y,W,H); Fl_Widget::resize(X,Y,W,H);
x = X; x = X;
y = Y; y = Y;
w = W; w = W;
h = H; h = H;
redraw(); redraw();
} }
} // namespace Avtk } // namespace Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -31,23 +31,23 @@ namespace Avtk
class Bindings : public Fl_Button class Bindings : public Fl_Button
{ {
public: public:
Bindings( int _x, int _y, int _w, int _h, const char *_label = 0 ); Bindings( int _x, int _y, int _w, int _h, const char *_label = 0 );
bool mouseOver; bool mouseOver;
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
void add( Binding* b ); void add( Binding* b );
void draw(); void draw();
//int handle(int event); //int handle(int event);
void resize(int X, int Y, int W, int H); void resize(int X, int Y, int W, int H);
int bindYPx; int bindYPx;
std::vector<Binding*> binds; std::vector<Binding*> binds;
}; };
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,38 +32,36 @@ namespace Avtk
ClipSelector::ClipSelector( int _x, int _y, int _w, int _h, ClipSelector::ClipSelector( int _x, int _y, int _w, int _h,
const char *_label, bool master ) : const char *_label, bool master ) :
Fl_Button(_x, _y, _w, _h, _label) Fl_Button(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
special = -1; special = -1;
label = _label; label = _label;
_master = master; _master = master;
if ( _master ) if ( _master ) {
{ for(int i = 0; i < 10; i++ ) {
for(int i = 0; i < 10; i++ ) stringstream s;
{ s << "Scene " << i + 1;
stringstream s; clips[i].setName( s.str() );
s << "Scene " << i + 1; }
clips[i].setName( s.str() );
} }
} highlight = false;
mouseOver = false;
highlight = false;
mouseOver = false;
} }
void ClipSelector::setID( int id ) void ClipSelector::setID( int id )
{ {
ID = id; ID = id;
} }
@ -71,366 +69,320 @@ void ClipSelector::setID( int id )
void ClipSelector::setState( int clipNum, GridLogic::State s ) void ClipSelector::setState( int clipNum, GridLogic::State s )
{ {
#ifdef DEBUG_CLIP #ifdef DEBUG_CLIP
//cout << "ClipSelector::setState() t = " << ID << " clipNum = " << clipNum << " state = " << s << endl; //cout << "ClipSelector::setState() t = " << ID << " clipNum = " << clipNum << " state = " << s << endl;
#endif #endif
clips[clipNum].setState( s ); clips[clipNum].setState( s );
if ( s == GridLogic::STATE_EMPTY ) if ( s == GridLogic::STATE_EMPTY ) {
{ clips[clipNum].setName("");
clips[clipNum].setName(""); }
}
redraw();
redraw();
} }
std::string ClipSelector::clipName(int clip) std::string ClipSelector::clipName(int clip)
{ {
return clips[clip].getName(); return clips[clip].getName();
} }
void ClipSelector::clipName(int clip, std::string name) void ClipSelector::clipName(int clip, std::string name)
{ {
clips[clip].setName( name ); clips[clip].setName( name );
redraw(); redraw();
} }
void ClipSelector::setSpecial(int scene) void ClipSelector::setSpecial(int scene)
{ {
if ( special == -1 && scene == -1 ) if ( special == -1 && scene == -1 ) {
{ // no change
// no change return;
return; }
}
special = scene;
special = scene; redraw();
redraw();
} }
void ClipSelector::draw() void ClipSelector::draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ if ( value() ) {
if ( value() ) highlight = true;
{ } else {
highlight = true; highlight = false;
} }
else
{ cairo_t *cr = Fl::cairo_cc();
highlight = false;
} cairo_save( cr );
cairo_t *cr = Fl::cairo_cc(); int clipWidth = w - 2;
int clipHeight = (h / numClips);
cairo_save( cr );
// text height adjustment based on clip size
int clipWidth = w - 2; // small 22, 13
int clipHeight = (h / numClips); // start 29, 17
//printf("clipHeight %i\n", clipHeight);
// text height adjustment based on clip size int textHeight = 13 + ((clipHeight - 22) * 0.66 );
// small 22, 13
// start 29, 17
//printf("clipHeight %i\n", clipHeight);
int textHeight = 13 + ((clipHeight - 22) * 0.66 ); int xOff = x+clipHeight/2;
int drawY = y + 1;
for( int i = 0; i < numClips; i++) { // draw each clip
int xOff = x+clipHeight/2; int yOff = drawY+ clipHeight/2 -1;
int drawY = y + 1; cairo_rectangle( cr, x+2, drawY, clipWidth-1, clipHeight - 4 );
for( int i = 0; i < numClips; i++) // draw each clip cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4);
{ cairo_fill(cr);
int yOff = drawY+ clipHeight/2 -1;
cairo_rectangle( cr, x+2, drawY, clipHeight-4, clipHeight - 4 );
cairo_rectangle( cr, x+2, drawY, clipWidth-1, clipHeight - 4 );
cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4); if ( clips[i].getState() == GridLogic::STATE_RECORDING ) {
cairo_fill(cr); cairo_set_source_rgba(cr, 1.f, 0 / 255.f , 0 / 255.f, 1.f);
cairo_fill(cr);
cairo_rectangle( cr, x+2, drawY, clipHeight-4, clipHeight - 4 ); //cairo_arc( cr, x+14, drawY+13, 4.3, 0, 6.29 );
cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 );
if ( clips[i].getState() == GridLogic::STATE_RECORDING ) cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
{ cairo_fill(cr);
cairo_set_source_rgba(cr, 1.f, 0 / 255.f , 0 / 255.f, 1.f); } else if ( clips[i].getState() == GridLogic::STATE_PLAYING ) {
cairo_fill(cr); cairo_set_source_rgba(cr, 0.0, 1.0, 0, 1.f );
//cairo_arc( cr, x+14, drawY+13, 4.3, 0, 6.29 ); cairo_fill(cr);
cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 ); cairo_move_to( cr, xOff-4, yOff-5 );
cairo_set_source_rgba(cr, 0, 0, 0, 1.f); cairo_line_to( cr, xOff+5, yOff );
cairo_fill(cr); cairo_line_to( cr, xOff-4, yOff+5 );
} cairo_close_path(cr);
else if ( clips[i].getState() == GridLogic::STATE_PLAYING ) cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
{ cairo_fill(cr);
cairo_set_source_rgba(cr, 0.0, 1.0, 0, 1.f ); } else if ( clips[i].getState() == GridLogic::STATE_PLAY_QUEUED ) {
cairo_fill(cr); cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_move_to( cr, xOff-4, yOff-5 ); cairo_fill(cr);
cairo_line_to( cr, xOff+5, yOff ); cairo_move_to( cr, xOff-4, yOff-5 );
cairo_line_to( cr, xOff-4, yOff+5 ); cairo_line_to( cr, xOff+5, yOff );
cairo_close_path(cr); cairo_line_to( cr, xOff-4, yOff +5 );
cairo_set_source_rgba(cr, 0, 0, 0, 1.f); cairo_close_path(cr);
cairo_fill(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
} cairo_fill(cr);
else if ( clips[i].getState() == GridLogic::STATE_PLAY_QUEUED ) } else if ( clips[i].getState() == GridLogic::STATE_STOP_QUEUED ) {
{ cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); cairo_fill(cr);
cairo_fill(cr); cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 );
cairo_move_to( cr, xOff-4, yOff-5 ); cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
cairo_line_to( cr, xOff+5, yOff ); cairo_set_line_width(cr, 2.2f);
cairo_line_to( cr, xOff-4, yOff +5 ); cairo_stroke(cr);
cairo_close_path(cr); } else if ( clips[i].getState() == GridLogic::STATE_RECORD_QUEUED ) {
cairo_set_source_rgba(cr, 0, 0, 0, 1.f); cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_fill(cr); cairo_fill(cr);
} cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 );
else if ( clips[i].getState() == GridLogic::STATE_STOP_QUEUED ) cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
{ cairo_fill(cr);
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); } else if ( clips[i].getState() == GridLogic::STATE_STOPPED ) {
cairo_fill(cr); cairo_set_source_rgba(cr, 1.0, 0.6, 0, 1.f);
cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 ); cairo_fill(cr);
cairo_set_source_rgba(cr, 0, 0, 0, 1.f); cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 );
cairo_set_line_width(cr, 2.2f); cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
cairo_stroke(cr); cairo_set_line_width(cr, 2.2f);
} cairo_stroke(cr);
else if ( clips[i].getState() == GridLogic::STATE_RECORD_QUEUED ) } else {
{ cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 1.f);
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); cairo_fill(cr);
cairo_fill(cr); }
cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 );
cairo_set_source_rgba(cr, 0, 0, 0, 1.f); cairo_rectangle( cr, x+2, drawY, clipWidth -1, clipHeight - 3 );
cairo_fill(cr);
} float alpha = 1;
else if ( clips[i].getState() == GridLogic::STATE_STOPPED ) cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha);
{ cairo_set_line_width( cr, 1.3);
cairo_set_source_rgba(cr, 1.0, 0.6, 0, 1.f); cairo_move_to( cr, x+clipHeight-1, drawY );
cairo_fill(cr); cairo_line_to( cr, x+clipHeight-1, drawY + clipHeight - 2);
cairo_arc( cr, xOff, yOff, 4.3, 0, 6.29 ); cairo_stroke(cr);
cairo_set_source_rgba(cr, 0, 0, 0, 1.f);
cairo_set_line_width(cr, 2.2f); // clip name
cairo_stroke(cr); cairo_move_to( cr, x + clipHeight + 5, drawY + textHeight );
} cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 0.9 );
else cairo_set_font_size( cr, 11 );
{
cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 1.f); std::string tmp = clips[i].getName().substr(0,8);
cairo_fill(cr);
} cairo_show_text( cr, tmp.c_str() );
cairo_rectangle( cr, x+2, drawY, clipWidth -1, clipHeight - 3 ); // special indicator?
if ( i == special ) {
float alpha = 1; cairo_rectangle( cr, x+2, drawY, clipWidth -1, clipHeight - 3 );
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, alpha); cairo_set_source_rgba(cr, 0.0, 153 / 255.f, 1.0, alpha);
cairo_set_line_width( cr, 1.3); cairo_stroke( cr );
cairo_move_to( cr, x+clipHeight-1, drawY ); }
cairo_line_to( cr, x+clipHeight-1, drawY + clipHeight - 2);
cairo_stroke(cr); drawY += clipHeight;
// clip name }
cairo_move_to( cr, x + clipHeight + 5, drawY + textHeight );
cairo_set_source_rgba( cr, 255 / 255.f, 255 / 255.f , 255 / 255.f , 0.9 ); cairo_restore( cr );
cairo_set_font_size( cr, 11 );
//draw_label();
std::string tmp = clips[i].getName().substr(0,8); }
cairo_show_text( cr, tmp.c_str() );
// special indicator?
if ( i == special )
{
cairo_rectangle( cr, x+2, drawY, clipWidth -1, clipHeight - 3 );
cairo_set_source_rgba(cr, 0.0, 153 / 255.f, 1.0, alpha);
cairo_stroke( cr );
}
drawY += clipHeight;
}
cairo_restore( cr );
//draw_label();
}
} }
void ClipSelector::resize(int X, int Y, int W, int H) void ClipSelector::resize(int X, int Y, int W, int H)
{ {
Fl_Widget::resize(X,Y,W,H); Fl_Widget::resize(X,Y,W,H);
x = X; x = X;
y = Y; y = Y;
w = W; w = W;
h = H; h = H;
redraw(); redraw();
} }
int ClipSelector::handle(int event) int ClipSelector::handle(int event)
{ {
switch(event) { switch(event) {
case FL_ACTIVATE: case FL_ACTIVATE: {
{ }
} case FL_DEACTIVATE: {
case FL_DEACTIVATE: }
{ return 1;
} case FL_PUSH:
return 1; highlight = 1;
case FL_PUSH: {
highlight = 1; // calculate the clicked clip number
{ int clipHeight = (h / numClips);
// calculate the clicked clip number int clipNum = ( (Fl::event_y() ) - y ) / clipHeight;
int clipHeight = (h / numClips); if (clipNum >= numClips)
int clipNum = ( (Fl::event_y() ) - y ) / clipHeight; clipNum = numClips -1; // fix for clicking the lowest pixel
if (clipNum >= numClips)
clipNum = numClips -1; // fix for clicking the lowest pixel // handle right clicks: popup menu
if ( Fl::event_state(FL_BUTTON3) ) {
// handle right clicks: popup menu if ( _master ) {
if ( Fl::event_state(FL_BUTTON3) ) // ask new name for clip, then
{ const char* name = fl_input( "Scene name: ", clips[clipNum].getName().c_str() );
if ( _master ) if ( name )
{ clips[clipNum].setName( name );
// ask new name for clip, then
const char* name = fl_input( "Scene name: ", clips[clipNum].getName().c_str() ); redraw();
if ( name ) return 1;
clips[clipNum].setName( name ); }
redraw();
return 1; Fl_Menu_Item rclick_menu[] = {
} { "Load" },
{ "Save" },
{ "Special"},
Fl_Menu_Item rclick_menu[] = { "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER },
{ {"1 "},
{ "Load" }, {"2"},
{ "Save" }, {"4"},
{ "Special"}, {"8"},
{ "Beats", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER }, {"16"},
{"1 "}, {"32"},
{"2"}, {"64"},
{"4"}, {0},
{"8"}, //{ "Record" },
{"16"}, { "Use as tempo" },
{"32"}, { "Rename", 0, 0, 0, FL_MENU_DIVIDER},
{"64"}, { "Clear" },
{0}, { 0 }
//{ "Record" }, };
{ "Use as tempo" }, Fl_Menu_Item *m = (Fl_Menu_Item*) rclick_menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
{ "Rename", 0, 0, 0, FL_MENU_DIVIDER}, if ( !m ) {
{ "Clear" }, return 0;
{ 0 } } else if ( strcmp(m->label(), "Load") == 0 ) {
}; gui->selectLoadSample( ID, clipNum );
Fl_Menu_Item *m = (Fl_Menu_Item*) rclick_menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0); } else if ( strcmp(m->label(), "Save") == 0 ) {
if ( !m ) //gui->saveBufferPath = "/tmp/test.wav";
{ char* tmp = gui->selectSavePath();
return 0; if(tmp && strlen(tmp)) {
} if( access( tmp, F_OK ) != -1 ) {
else if ( strcmp(m->label(), "Load") == 0 ) int overwrite = fl_choice("Overwrite file?","Cancel","Overwrite",0);
{ if (!overwrite) {
gui->selectLoadSample( ID, clipNum ); return 0;
} }
else if ( strcmp(m->label(), "Save") == 0 ) }
{ gui->saveBufferPath = tmp;
//gui->saveBufferPath = "/tmp/test.wav"; free(tmp);
char* tmp = gui->selectSavePath(); gui->selectSaveSample( ID, clipNum );
if(tmp && strlen(tmp)) { }
if( access( tmp, F_OK ) != -1 ) { } else if ( strcmp(m->label(), "1 ") == 0 ) {
int overwrite = fl_choice("Overwrite file?","Cancel","Overwrite",0); EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,1);
if (!overwrite) { writeToDspRingbuffer( &e );
return 0; } else if ( strcmp(m->label(), "2") == 0 ) {
} EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,2);
} writeToDspRingbuffer( &e );
gui->saveBufferPath = tmp; } else if ( strcmp(m->label(), "4") == 0 ) {
free(tmp); EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,4);
gui->selectSaveSample( ID, clipNum ); writeToDspRingbuffer( &e );
} } else if ( strcmp(m->label(), "8") == 0 ) {
} EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,8);
else if ( strcmp(m->label(), "1 ") == 0 ) { writeToDspRingbuffer( &e );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,1); } else if ( strcmp(m->label(), "16") == 0 ) {
writeToDspRingbuffer( &e ); EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,16);
} else if ( strcmp(m->label(), "2") == 0 ) { writeToDspRingbuffer( &e );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,2); } else if ( strcmp(m->label(), "32") == 0 ) {
writeToDspRingbuffer( &e ); EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,32);
} else if ( strcmp(m->label(), "4") == 0 ) { writeToDspRingbuffer( &e );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,4); } else if ( strcmp(m->label(), "64") == 0 ) {
writeToDspRingbuffer( &e ); EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,64);
} else if ( strcmp(m->label(), "8") == 0 ) { writeToDspRingbuffer( &e );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,8); } else if ( strcmp(m->label(), "Use as tempo") == 0 ) {
writeToDspRingbuffer( &e ); EventLooperUseAsTempo e (ID, clipNum);
} else if ( strcmp(m->label(), "16") == 0 ) { writeToDspRingbuffer( &e );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,16); } else if ( strcmp(m->label(), "Special") == 0 ) {
writeToDspRingbuffer( &e ); //printf("special selected %i, %i\n", ID, clipNum );
} else if ( strcmp(m->label(), "32") == 0 ) { EventGridSelectNewChosen e( ID, clipNum);
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,32); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); } else if ( strcmp(m->label(), "Rename") == 0 ) {
} else if ( strcmp(m->label(), "64") == 0 ) { const char* name = fl_input( "Clip name: ", clips[clipNum].getName().c_str() );
EventLooperLoopLength e = EventLooperLoopLength(ID, clipNum ,64); if ( name )
writeToDspRingbuffer( &e ); clips[clipNum].setName( name );
} } else if ( strcmp(m->label(), "Clear") == 0 ) {
else if ( strcmp(m->label(), "Use as tempo") == 0 ) // for a clip to become 0
{ EventGridState e( ID, clipNum, GridLogic::STATE_EMPTY );
EventLooperUseAsTempo e (ID, clipNum); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); }
} } else {
else if ( strcmp(m->label(), "Special") == 0 ) if ( _master ) {
{ EventGridLaunchScene e( clipNum );
//printf("special selected %i, %i\n", ID, clipNum ); writeToDspRingbuffer( &e );
EventGridSelectNewChosen e( ID, clipNum); redraw();
writeToDspRingbuffer( &e ); return 1;
} }
else if ( strcmp(m->label(), "Rename") == 0 )
{ // write "pressed" event for this track,scene
const char* name = fl_input( "Clip name: ", clips[clipNum].getName().c_str() ); EventGridEvent e( ID, clipNum, true );
if ( name ) writeToDspRingbuffer( &e );
clips[clipNum].setName( name ); }
} }
else if ( strcmp(m->label(), "Clear") == 0 ) redraw();
{ do_callback();
// for a clip to become 0 return 1;
EventGridState e( ID, clipNum, GridLogic::STATE_EMPTY ); case FL_DRAG: {
writeToDspRingbuffer( &e ); int t = Fl::event_inside(this);
} if (t != highlight) {
} highlight = t;
else redraw();
{ }
if ( _master ) }
{ return 1;
EventGridLaunchScene e( clipNum ); case FL_ENTER:
writeToDspRingbuffer( &e ); mouseOver = true;
redraw();
return 1; redraw();
} return 1;
case FL_LEAVE:
// write "pressed" event for this track,scene mouseOver = false;
EventGridEvent e( ID, clipNum, true ); redraw();
writeToDspRingbuffer( &e ); return 1;
} case FL_RELEASE:
} return 1;
redraw(); case FL_SHORTCUT:
do_callback(); if ( test_shortcut() ) {
return 1; do_callback();
case FL_DRAG: return 1;
{ }
int t = Fl::event_inside(this); return 0;
if (t != highlight) default:
{ return Fl_Widget::handle(event);
highlight = t; }
redraw();
}
}
return 1;
case FL_ENTER:
mouseOver = true;
redraw();
return 1;
case FL_LEAVE:
mouseOver = false;
redraw();
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 } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -38,73 +38,73 @@ namespace Avtk
class ClipState class ClipState
{ {
public: public:
ClipState() : ClipState() :
state(GridLogic::STATE_EMPTY), state(GridLogic::STATE_EMPTY),
name("") name("")
{} {}
void setName(std::string n) void setName(std::string n)
{ {
name = n; name = n;
} }
void setState(GridLogic::State s) void setState(GridLogic::State s)
{ {
state = s; state = s;
} }
std::string getName() std::string getName()
{ {
return name; return name;
} }
GridLogic::State getState() GridLogic::State getState()
{ {
return state; return state;
} }
private: private:
GridLogic::State state; GridLogic::State state;
std::string name; std::string name;
}; };
class ClipSelector : public Fl_Button class ClipSelector : public Fl_Button
{ {
public: public:
ClipSelector( int _x, int _y, int _w, int _h, ClipSelector( int _x, int _y, int _w, int _h,
const char *_label, bool master = false); const char *_label, bool master = false);
int ID; int ID;
// FIXME: NSCENES? // FIXME: NSCENES?
static const int numClips = 10; static const int numClips = 10;
ClipState clips[numClips]; ClipState clips[numClips];
/// indicates if a clip is the "special" clip /// indicates if a clip is the "special" clip
void setSpecial(int scene); void setSpecial(int scene);
int special; int special;
bool _master; bool _master;
bool mouseOver; bool mouseOver;
bool highlight; bool highlight;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
void setID( int id ); void setID( int id );
/** converts the Looper::State into the UI represnted ClipSelector state. /** converts the Looper::State into the UI represnted ClipSelector state.
* It puts some of the data into clips[], and stores unique state into the class. * It puts some of the data into clips[], and stores unique state into the class.
**/ **/
void setState( int clipNum, GridLogic::State s ); void setState( int clipNum, GridLogic::State s );
void clipName(int clip, std::string name); void clipName(int clip, std::string name);
std::string clipName(int clip); std::string clipName(int clip);
void draw(); void draw();
int handle(int event); int handle(int event);
void resize(int X, int Y, int W, int H); void resize(int X, int Y, int W, int H);
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -21,218 +21,206 @@
using namespace Avtk; using namespace Avtk;
Volume::Volume(int _x, int _y, int _w, int _h, const char *_label ): Volume::Volume(int _x, int _y, int _w, int _h, const char *_label ):
Fl_Slider(_x, _y, _w, _h, _label) Fl_Slider(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label;
mouseClickedX = 0;
mouseClickedY = 0;
mouseClicked = false;
active = true;
highlight = false;
ampL = 0;
ampR = 0;
compress = 0;
value( 0.78f );
orientationHorizontal = false; label = _label;
mouseClickedX = 0;
mouseClickedY = 0;
mouseClicked = false;
active = true;
highlight = false;
ampL = 0;
ampR = 0;
compress = 0;
value( 0.78f );
orientationHorizontal = false;
} }
void Volume::fader( float f ) void Volume::fader( float f )
{ {
// redraw on larger value change // redraw on larger value change
//if ( fabsf( value() - f ) > 0.025 ) //if ( fabsf( value() - f ) > 0.025 )
value( f ); value( f );
} }
void Volume::amplitude (float aL, float aR) void Volume::amplitude (float aL, float aR)
{ {
if ( aL < 0.1 ) aL = 0.f; if ( aL < 0.1 ) aL = 0.f;
if ( aR < 0.1 ) aR = 0.f; if ( aR < 0.1 ) aR = 0.f;
// only redraw if changed more than X amount // only redraw if changed more than X amount
if ( fabsf(ampL - aL) > 0.025 || if ( fabsf(ampL - aL) > 0.025 ||
fabsf(ampR - aR) > 0.025 ) fabsf(ampR - aR) > 0.025 ) {
{ ampL = aL;
ampL = aL; ampR = aR;
ampR = aR; redraw();
redraw(); }
}
} }
void Volume::compression(float c) void Volume::compression(float c)
{ {
compress = c; compress = c;
redraw(); redraw();
} }
void Volume::setOrientationHorizontal() void Volume::setOrientationHorizontal()
{ {
orientationHorizontal = true; orientationHorizontal = true;
redraw(); redraw();
} }
void Volume::set_active(bool a) void Volume::set_active(bool a)
{ {
active = a; active = a;
redraw(); redraw();
} }
void Volume::draw() void Volume::draw()
{ {
if (damage() & FL_DAMAGE_ALL) if (damage() & FL_DAMAGE_ALL) {
{ cairo_t *cr = Fl::cairo_cc();
cairo_t *cr = Fl::cairo_cc();
cairo_save( cr );
cairo_save( cr );
cairo_set_line_width(cr, 1.5);
cairo_set_line_width(cr, 1.5);
// fill background
// fill background cairo_rectangle( cr, x, y, w, h);
cairo_rectangle( cr, x, y, w, h); cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4);
cairo_set_source_rgba(cr, 66 / 255.f, 66 / 255.f , 66 / 255.f, 0.4); //cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f );
//cairo_set_source_rgb( cr, 28 / 255.f, 28 / 255.f , 28 / 255.f ); cairo_fill( cr );
cairo_fill( cr );
//cairo_set_dash ( cr, dashes, 1, 0.0);
//cairo_set_dash ( cr, dashes, 1, 0.0); cairo_set_line_width( cr, 1.0);
cairo_set_line_width( cr, 1.0);
// loop over each 2nd line, drawing dots
// loop over each 2nd line, drawing dots cairo_set_line_width(cr, 1.0);
cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 0.4,0.4,0.4);
cairo_set_source_rgb(cr, 0.4,0.4,0.4); for ( int i = 0; i < 2; i++ ) {
for ( int i = 0; i < 2; i++ ) cairo_move_to( cr, x + ((w / 2.f)*i), y );
{ cairo_line_to( cr, x + ((w / 2.f)*i), y + h );
cairo_move_to( cr, x + ((w / 2.f)*i), y ); }
cairo_line_to( cr, x + ((w / 2.f)*i), y + h ); for ( int i = 0; i < 4; i++ ) {
} cairo_move_to( cr, x , y + ((h / 4.f)*i) );
for ( int i = 0; i < 4; i++ ) cairo_line_to( cr, x + w, y + ((h / 4.f)*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);
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); // audio level
if ( orientationHorizontal ) {
cairo_rectangle(cr, x, y+h*0.15, w * ampL, 9.9 );
// audio level cairo_rectangle(cr, x, y+h*0.56, w * ampR, 9.9 );
if ( orientationHorizontal ) } else {
{ cairo_rectangle(cr, x+w*0.15, y+h*(1-ampL), 9.9, h - h*(1-ampL) );
cairo_rectangle(cr, x, y+h*0.15, w * ampL, 9.9 ); cairo_rectangle(cr, x+w*0.56, y+h*(1-ampR), 9.9, h - h*(1-ampR) );
cairo_rectangle(cr, x, y+h*0.56, w * ampR, 9.9 ); }
} cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
else cairo_fill_preserve( cr );
{ cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
cairo_rectangle(cr, x+w*0.15, y+h*(1-ampL), 9.9, h - h*(1-ampL) ); cairo_stroke(cr);
cairo_rectangle(cr, x+w*0.56, y+h*(1-ampR), 9.9, h - h*(1-ampR) );
} // fader
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 ); if ( orientationHorizontal )
cairo_fill_preserve( cr ); cairo_rectangle(cr, x+2+(w-24)*(value()), y+5, 20, h-10);
cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 ); else
cairo_stroke(cr); cairo_rectangle(cr, x+5, y+2+(h-24)*(1-value()), w-10, 20);
// fader cairo_set_source_rgba( cr, 1.0f, 0.48, 0.f, 1);
if ( orientationHorizontal ) cairo_set_line_width(cr, 1.9);
cairo_rectangle(cr, x+2+(w-24)*(value()), y+5, 20, h-10); cairo_stroke( cr );
else
cairo_rectangle(cr, x+5, y+2+(h-24)*(1-value()), w-10, 20); // stroke outline
cairo_rectangle(cr, x, y, w, h);
cairo_set_source_rgba( cr, 1.0f, 0.48, 0.f, 1); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 1.9); cairo_set_line_width(cr, 1.9);
cairo_stroke( cr ); cairo_stroke( cr );
// stroke outline cairo_restore( cr );
cairo_rectangle(cr, x, y, w, h); }
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 1.9);
cairo_stroke( cr );
cairo_restore( cr );
}
} }
void Volume::resize(int X, int Y, int W, int H) void Volume::resize(int X, int Y, int W, int H)
{ {
Fl_Widget::resize(X,Y,W,H); Fl_Widget::resize(X,Y,W,H);
x = X; x = X;
y = Y; y = Y;
w = W; w = W;
h = H; h = H;
redraw(); redraw();
} }
int Volume::handle(int event) int Volume::handle(int event)
{ {
switch(event) switch(event) {
{ case FL_PUSH:
case FL_PUSH: highlight = 0;
highlight = 0; redraw();
redraw(); return 1;
return 1; case FL_DRAG: {
case FL_DRAG: if ( Fl::event_state(FL_BUTTON1) ) {
{ if ( mouseClicked == false ) { // catch the "click" event
if ( Fl::event_state(FL_BUTTON1) ) mouseClickedX = Fl::event_x();
{ mouseClickedY = Fl::event_y();
if ( mouseClicked == false ) // catch the "click" event mouseClicked = true;
{ }
mouseClickedX = Fl::event_x();
mouseClickedY = Fl::event_y(); float delta = (mouseClickedY - Fl::event_y() ) / float(h);
mouseClicked = true; // handle the x / y swap, and the inverting of direction (mouseX / Y relative)
} if ( orientationHorizontal )
delta = ( Fl::event_x() - mouseClickedX ) / float(w);
float delta = (mouseClickedY - Fl::event_y() ) / float(h);
// handle the x / y swap, and the inverting of direction (mouseX / Y relative) float valY = value();
if ( orientationHorizontal ) valY += delta;
delta = ( Fl::event_x() - mouseClickedX ) / float(w);
if ( valY > 1.0 ) valY = 1.0;
float valY = value(); if ( valY < 0.0 ) valY = 0.0;
valY += delta;
set_value( valY );
if ( valY > 1.0 ) valY = 1.0;
if ( valY < 0.0 ) valY = 0.0; mouseClickedX = Fl::event_x();
mouseClickedY = Fl::event_y();
set_value( valY ); redraw();
do_callback();
mouseClickedX = Fl::event_x(); }
mouseClickedY = Fl::event_y(); }
redraw(); return 1;
do_callback(); case FL_ENTER:
} return 1;
} case FL_MOUSEWHEEL:
return 1; //printf("no scroll on faders\n");
case FL_ENTER: return 1;
return 1; case FL_RELEASE:
case FL_MOUSEWHEEL: if (highlight) {
//printf("no scroll on faders\n"); highlight = 0;
return 1; redraw();
case FL_RELEASE: do_callback();
if (highlight) { }
highlight = 0; mouseClicked = false;
redraw(); return 1;
do_callback(); case FL_SHORTCUT:
} if ( test_shortcut() ) {
mouseClicked = false; do_callback();
return 1; return 1;
case FL_SHORTCUT: }
if ( test_shortcut() ) return 0;
{ default:
do_callback(); return Fl_Widget::handle(event);
return 1; }
}
return 0;
default:
return Fl_Widget::handle(event);
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -28,39 +28,39 @@
namespace Avtk namespace Avtk
{ {
class Volume : public Fl_Slider class Volume : public Fl_Slider
{ {
public: public:
Volume(int _x, int _y, int _w, int _h, const char *_label = 0); Volume(int _x, int _y, int _w, int _h, const char *_label = 0);
void set_active(bool a); void set_active(bool a);
void setOrientationHorizontal(); void setOrientationHorizontal();
void fader( float f ); void fader( float f );
void compression(float c); void compression(float c);
void amplitude (float aL, float aR); void amplitude (float aL, float aR);
void draw(); void draw();
int handle(int event); int handle(int event);
void resize(int X, int Y, int W, int H); void resize(int X, int Y, int W, int H);
private: private:
bool active; bool active;
bool highlight; bool highlight;
bool orientationHorizontal; bool orientationHorizontal;
int x, y, w, h; int x, y, w, h;
const char* label; const char* label;
int mouseClickedX; int mouseClickedX;
int mouseClickedY; int mouseClickedY;
bool mouseClicked; bool mouseClicked;
float ampL, ampR; float ampL, ampR;
float compress; float compress;
}; };
} // Avtk } // Avtk
#endif // AVTK_VOLUME_H #endif // AVTK_VOLUME_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,276 +33,259 @@ namespace Avtk
class Waveform : public Fl_Widget class Waveform : public Fl_Widget
{ {
public: public:
Waveform(int _x, int _y, int _w, int _h, const char *_label=0 ): Waveform(int _x, int _y, int _w, int _h, const char *_label=0 ):
Fl_Widget(_x, _y, _w, _h, _label) Fl_Widget(_x, _y, _w, _h, _label)
{ {
x = _x; x = _x;
y = _y; y = _y;
w = _w; w = _w;
h = _h; h = _h;
label = _label; label = _label;
highlight = false; highlight = false;
newWaveform = false; newWaveform = false;
waveformCr = 0; waveformCr = 0;
waveformSurf = 0; waveformSurf = 0;
data = (float*)malloc( sizeof(float) * w ); data = (float*)malloc( sizeof(float) * w );
srand (time(NULL)); srand (time(NULL));
for (int i = 0; i < _w; i++) for (int i = 0; i < _w; i++) {
{ data[i] = rand() / RAND_MAX / 0.75;
data[i] = rand() / RAND_MAX / 0.75; }
}
newWaveform = true;
newWaveform = true;
strokeRim = true;
strokeRim = true; }
}
bool strokeRim;
bool strokeRim; bool highlight;
bool highlight; int x, y, w, h;
int x, y, w, h; const char* label;
const char* label;
cairo_t* waveformCr;
cairo_t* waveformCr; cairo_surface_t* waveformSurf;
cairo_surface_t* waveformSurf;
bool newWaveform;
bool newWaveform;
long dataSize;
long dataSize; float* data;
float* data;
void setData( float* d, long size )
void setData( float* d, long size ) {
{ //cout << "AvtkWaveform: setDataPtr = " << data << endl;
//cout << "AvtkWaveform: setDataPtr = " << data << endl; dataSize = size;
dataSize = size; data = d;
data = d; newWaveform = true;
newWaveform = true;
damage(FL_DAMAGE_ALL);
damage(FL_DAMAGE_ALL); }
}
void draw()
void draw() {
{ if (damage() & FL_DAMAGE_ALL) {
if (damage() & FL_DAMAGE_ALL) cairo_t *cr = Fl::cairo_cc();
{ cairo_save(cr);
cairo_t *cr = Fl::cairo_cc();
cairo_save(cr); // clear the surface
cairo_rectangle(cr, x, y, w, h);
// clear the surface cairo_set_source_rgb (cr, 0.1,0.1,0.1);
cairo_rectangle(cr, x, y, w, h); cairo_fill( cr );
cairo_set_source_rgb (cr, 0.1,0.1,0.1);
cairo_fill( cr ); if ( newWaveform ) {
if ( !waveformCr ) {
if ( newWaveform ) // create the waveform surface and context
{ //cout << "waveform draw() creating new objects" << endl;
if ( !waveformCr ) waveformSurf= cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, w, h);
{ waveformCr = cairo_create ( waveformSurf );
// create the waveform surface and context //cout << "waveform draw() creating objects done" << endl;
//cout << "waveform draw() creating new objects" << endl; }
waveformSurf= cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, w, h);
waveformCr = cairo_create ( waveformSurf ); // clear the surface
//cout << "waveform draw() creating objects done" << endl; cairo_rectangle(waveformCr, 0, 0, w, h);
} cairo_set_source_rgb (waveformCr, 0.1,0.1,0.1);
cairo_fill( waveformCr );
// clear the surface
cairo_rectangle(waveformCr, 0, 0, w, h); // set up dashed lines, 1 px off, 1 px on
cairo_set_source_rgb (waveformCr, 0.1,0.1,0.1); double dashes[1];
cairo_fill( waveformCr ); dashes[0] = 2.0;
// set up dashed lines, 1 px off, 1 px on cairo_set_dash ( waveformCr, dashes, 1, 0.0);
double dashes[1]; cairo_set_line_width( waveformCr, 1.0);
dashes[0] = 2.0;
// loop over each 2nd line, drawing dots
cairo_set_dash ( waveformCr, dashes, 1, 0.0); cairo_set_line_width(waveformCr, 1.0);
cairo_set_line_width( waveformCr, 1.0); cairo_set_source_rgb(waveformCr, 0.4,0.4,0.4);
for ( int i = 1; i < 4; i++ ) {
// loop over each 2nd line, drawing dots cairo_move_to( waveformCr, ((w / 4.f)*i), 0);
cairo_set_line_width(waveformCr, 1.0); cairo_line_to( waveformCr, ((w / 4.f)*i), h );
cairo_set_source_rgb(waveformCr, 0.4,0.4,0.4); }
for ( int i = 1; i < 4; i++ ) for ( int i = 1; i < 4; i++ ) {
{ cairo_move_to( waveformCr, 0, ((h / 4.f)*i) );
cairo_move_to( waveformCr, ((w / 4.f)*i), 0); cairo_line_to( waveformCr, w, ((h / 4.f)*i) );
cairo_line_to( waveformCr, ((w / 4.f)*i), h ); }
}
for ( int i = 1; i < 4; i++ ) cairo_set_source_rgba( waveformCr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 );
{ cairo_stroke(waveformCr);
cairo_move_to( waveformCr, 0, ((h / 4.f)*i) ); cairo_set_dash ( waveformCr, dashes, 0, 0.0);
cairo_line_to( waveformCr, w, ((h / 4.f)*i) );
}
if ( !data ) {
cairo_set_source_rgba( waveformCr, 66 / 255.f, 66 / 255.f , 66 / 255.f , 0.5 ); // draw X
cairo_stroke(waveformCr); cairo_move_to( cr, 0 , 0 );
cairo_set_dash ( waveformCr, dashes, 0, 0.0); cairo_line_to( cr, 0 + w, 0 + h );
cairo_move_to( cr, 0 , 0 + h );
cairo_line_to( cr, 0 + w, 0 );
if ( !data ) cairo_set_source_rgb ( cr, 0.2,0.2,0.2);
{ cairo_stroke(cr);
// draw X
cairo_move_to( cr, 0 , 0 ); // draw text
cairo_line_to( cr, 0 + w, 0 + h ); cairo_move_to( cr, 0 + (w/2.f) - 65, 0 + (h/2.f) + 10 );
cairo_move_to( cr, 0 , 0 + h ); cairo_set_source_rgb ( cr, 0.6,0.6,0.6);
cairo_line_to( cr, 0 + w, 0 ); cairo_set_font_size( cr, 20 );
cairo_set_source_rgb ( cr, 0.2,0.2,0.2); cairo_show_text( cr, "No data loaded" );
cairo_stroke(cr); } else {
// don't draw every sample
// draw text int sampleCountForDrawing = -1;
cairo_move_to( cr, 0 + (w/2.f) - 65, 0 + (h/2.f) + 10 );
cairo_set_source_rgb ( cr, 0.6,0.6,0.6); float currentTop = 0.f;
cairo_set_font_size( cr, 20 ); float previousTop = 0.f;
cairo_show_text( cr, "No data loaded" ); float currentSample = 0.f;
}
else // find how many samples per pixel
{ int samplesPerPix = int(dataSize / float(w));
// don't draw every sample //cout << "width = " << w << " sampsPerPx " << samplesPerPix << endl;
int sampleCountForDrawing = -1;
// loop over each pixel value we need
float currentTop = 0.f; for( int p = 0; p < w; p++ ) {
float previousTop = 0.f; float averageMax = 0.f;
float currentSample = 0.f; float averageMin = 0.f;
// find how many samples per pixel // calc value for this pixel
int samplesPerPix = int(dataSize / float(w)); for( int i = 0; i < samplesPerPix; i++ ) {
//cout << "width = " << w << " sampsPerPx " << samplesPerPix << endl; float tmp = data[i + (p * samplesPerPix)];
if ( tmp < 0 ) {
// loop over each pixel value we need averageMin -= tmp;
for( int p = 0; p < w; p++ ) } else {
{ averageMax += tmp;
float averageMax = 0.f; }
float averageMin = 0.f; }
// calc value for this pixel // - 0.1 to keep in bounds of square
for( int i = 0; i < samplesPerPix; i++ ) averageMin = (averageMin / samplesPerPix);
{ averageMax = (averageMax / samplesPerPix);
float tmp = data[i + (p * samplesPerPix)];
if ( tmp < 0 ) // don't use to the *very* top of the widget, only 0.8 (top & bottom)
{ float dH = h * 0.4;
averageMin -= tmp;
} // emulate log shape
else float tmpMin = log( 0.1 + (averageMin*4.9) );
{ float tmpMax = log( 0.1 + (averageMax*4.9) );
averageMax += tmp;
} // logMin range == -2.3 -> 1.6: add 2.3, then / 3.9
} float logMin = -((tmpMin + 2.3) / 3.9);
float logMax = ((tmpMax + 2.3) / 3.9);
// - 0.1 to keep in bounds of square
averageMin = (averageMin / samplesPerPix); //printf("input %f, output %f\n", averageMin, logMin );
averageMax = (averageMax / samplesPerPix);
// draw lines
// don't use to the *very* top of the widget, only 0.8 (top & bottom) cairo_move_to( waveformCr, p, h * 0.5 + (logMin * dH ) );
float dH = h * 0.4; cairo_line_to( waveformCr, p, h * 0.5 + (logMax * dH ) );
}
// emulate log shape
float tmpMin = log( 0.1 + (averageMin*4.9) ); // stroke the waveform
float tmpMax = log( 0.1 + (averageMax*4.9) ); cairo_set_source_rgb( waveformCr, 1.0,1.0,1.0);
cairo_stroke( waveformCr );
// logMin range == -2.3 -> 1.6: add 2.3, then / 3.9
float logMin = -((tmpMin + 2.3) / 3.9); newWaveform = false;
float logMax = ((tmpMax + 2.3) / 3.9); }
}
//printf("input %f, output %f\n", averageMin, logMin );
cairo_set_source_surface(cr, waveformSurf, x, y);
// draw lines cairo_rectangle( cr, x, y, w, h);
cairo_move_to( waveformCr, p, h * 0.5 + (logMin * dH ) ); cairo_paint(cr);
cairo_line_to( waveformCr, p, h * 0.5 + (logMax * dH ) );
} if ( strokeRim ) {
// stroke rim
// stroke the waveform cairo_set_line_width(cr, 1);
cairo_set_source_rgb( waveformCr, 1.0,1.0,1.0); cairo_rectangle(cr, x, y, w, h);
cairo_stroke( waveformCr ); cairo_set_source_rgba( cr, 100 / 255.f, 100 / 255.f , 100 / 255.f , 1 );
cairo_stroke( cr );
newWaveform = false; }
}
} //cout << "waveform draw() done" << endl;
cairo_set_source_surface(cr, waveformSurf, x, y); cairo_restore(cr);
cairo_rectangle( cr, x, y, w, h); }
cairo_paint(cr); }
if ( strokeRim ) void resize(int X, int Y, int W, int H)
{ {
// stroke rim Fl_Widget::resize(X,Y,W,H);
cairo_set_line_width(cr, 1);
cairo_rectangle(cr, x, y, w, h); // take the smaller value
cairo_set_source_rgba( cr, 100 / 255.f, 100 / 255.f , 100 / 255.f , 1 ); long newSize = W > w ? W : w;
cairo_stroke( cr ); printf("Waveform new size %li, from %i\n", newSize, w );
}
x = X;
//cout << "waveform draw() done" << endl; y = Y;
w = W;
cairo_restore(cr); h = H;
}
} // FIXME: needs to be resampled, not clipped at end
// delete old data, and resize it
void resize(int X, int Y, int W, int H) float* newData = (float*)malloc( sizeof(float) * w );
{
Fl_Widget::resize(X,Y,W,H); memcpy( newData, data, newSize );
free ( data );
// take the smaller value data = newData;
long newSize = W > w ? W : w;
printf("Waveform new size %li, from %i\n", newSize, w ); newWaveform = true;
x = X;
y = Y; redraw();
w = W; }
h = H;
int handle(int event)
// FIXME: needs to be resampled, not clipped at end {
// delete old data, and resize it return 0;
float* newData = (float*)malloc( sizeof(float) * w );
switch(event) {
memcpy( newData, data, newSize ); case FL_PUSH:
free ( data ); highlight = 0;
data = newData; redraw();
return 1;
newWaveform = true; case FL_DRAG: {
int t = Fl::event_inside(this);
if (t != highlight) {
redraw(); redraw();
} }
}
int handle(int event) return 1;
{ case FL_RELEASE:
return 0; if (highlight) {
highlight = 0;
switch(event) redraw();
{ do_callback();
case FL_PUSH: }
highlight = 0; return 1;
redraw(); case FL_SHORTCUT:
return 1; if ( test_shortcut() ) {
case FL_DRAG: { do_callback();
int t = Fl::event_inside(this); return 1;
if (t != highlight) { }
redraw(); return 0;
} default:
} return Fl_Widget::handle(event);
return 1; }
case FL_RELEASE: }
if (highlight) {
highlight = 0;
redraw();
do_callback();
}
return 1;
case FL_SHORTCUT:
if ( test_shortcut() )
{
do_callback();
return 1;
}
return 0;
default:
return Fl_Widget::handle(event);
}
}
}; };
} // Avtk } // Avtk

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -24,91 +24,91 @@
class Buffers class Buffers
{ {
public: public:
enum BUFFER {
// AUDIO
MASTER_INPUT = 0,
MASTER_OUT_L,
MASTER_OUT_R,
JACK_SEND_OUT,
JACK_MASTER_OUT_L,
JACK_MASTER_OUT_R,
JACK_SIDECHAIN_KEY,
JACK_SIDECHAIN_SIGNAL,
SEND,
SIDECHAIN_KEY,
SIDECHAIN_SIGNAL,
MASTER_RETURN_L,
MASTER_RETURN_R,
HEADPHONES_OUT,
// MIDI
MASTER_MIDI_INPUT,
// track buffers: they are the "working" buffers per track:
// the end result is mixed into the master output, while each
// stage along the way the amplitude etc can be analysed
TRACK_0,
TRACK_1,
TRACK_2,
TRACK_3,
TRACK_4,
TRACK_5,
TRACK_6,
TRACK_7,
//Per track sends/returns
SEND_TRACK_0,
SEND_TRACK_1,
SEND_TRACK_2,
SEND_TRACK_3,
SEND_TRACK_4,
SEND_TRACK_5,
SEND_TRACK_6,
SEND_TRACK_7,
RETURN_TRACK_0,
RETURN_TRACK_1,
RETURN_TRACK_2,
RETURN_TRACK_3,
RETURN_TRACK_4,
RETURN_TRACK_5,
RETURN_TRACK_6,
RETURN_TRACK_7,
JACK_TRACK_0, enum BUFFER {
JACK_TRACK_1, // AUDIO
JACK_TRACK_2, MASTER_INPUT = 0,
JACK_TRACK_3,
JACK_TRACK_4, MASTER_OUT_L,
JACK_TRACK_5, MASTER_OUT_R,
JACK_TRACK_6,
JACK_TRACK_7, JACK_SEND_OUT,
JACK_MASTER_OUT_L,
JACK_MASTER_OUT_R,
JACK_SIDECHAIN_KEY,
JACK_SIDECHAIN_SIGNAL,
SEND,
SIDECHAIN_KEY,
SIDECHAIN_SIGNAL,
MASTER_RETURN_L,
MASTER_RETURN_R,
HEADPHONES_OUT,
// MIDI
MASTER_MIDI_INPUT,
// track buffers: they are the "working" buffers per track:
// the end result is mixed into the master output, while each
// stage along the way the amplitude etc can be analysed
TRACK_0,
TRACK_1,
TRACK_2,
TRACK_3,
TRACK_4,
TRACK_5,
TRACK_6,
TRACK_7,
//Per track sends/returns
SEND_TRACK_0,
SEND_TRACK_1,
SEND_TRACK_2,
SEND_TRACK_3,
SEND_TRACK_4,
SEND_TRACK_5,
SEND_TRACK_6,
SEND_TRACK_7,
RETURN_TRACK_0,
RETURN_TRACK_1,
RETURN_TRACK_2,
RETURN_TRACK_3,
RETURN_TRACK_4,
RETURN_TRACK_5,
RETURN_TRACK_6,
RETURN_TRACK_7,
JACK_TRACK_0,
JACK_TRACK_1,
JACK_TRACK_2,
JACK_TRACK_3,
JACK_TRACK_4,
JACK_TRACK_5,
JACK_TRACK_6,
JACK_TRACK_7,
BUFFER_COUNT,
};
Buffers()
{
memset( audio, 0, sizeof(float*)*BUFFER_COUNT);
memset( midi , 0, sizeof(void *)*BUFFER_COUNT);
}
float* audio[BUFFER_COUNT];
void* midi [BUFFER_COUNT];
// Jack details
jack_nframes_t nframes;
jack_nframes_t samplerate;
jack_nframes_t transportFrame;
jack_position_t* transportPosition;
jack_transport_state_t* transportState;
BUFFER_COUNT,
};
Buffers()
{
memset( audio, 0, sizeof(float*)*BUFFER_COUNT);
memset( midi , 0, sizeof(void *)*BUFFER_COUNT);
}
float* audio[BUFFER_COUNT];
void* midi [BUFFER_COUNT];
// Jack details
jack_nframes_t nframes;
jack_nframes_t samplerate;
jack_nframes_t transportFrame;
jack_position_t* transportPosition;
jack_transport_state_t* transportState;
}; };
#endif // LUPPP_BUFFERS_H #endif // LUPPP_BUFFERS_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,32 +27,35 @@ typedef int LupppAction;
class Binding class Binding
{ {
public: public:
Binding() : status(0), data(0), action(0), active(-1), Binding() : status(0), data(0), action(0), active(-1),
track(-2),scene(-1),send(-1) { ID = privateID++; } track(-2),scene(-1),send(-1)
{
int ID; ID = privateID++;
}
unsigned char status;
unsigned char data; int ID;
/// the action this binding relates to: this is an integer based on the unsigned char status;
/// event.hxx enumeration of event types unsigned char data;
LupppAction action;
/// the action this binding relates to: this is an integer based on the
/// arguments to the event: track number, scene number etc /// event.hxx enumeration of event types
int active; LupppAction action;
int track;
int scene; /// arguments to the event: track number, scene number etc
int send; int active;
int track;
/// maps from Gridlogic::State to MIDI output value from binding int scene;
std::map<int,int> clipStateMap; int send;
private: /// maps from Gridlogic::State to MIDI output value from binding
/// static int counter to allow deleting this specific instance std::map<int,int> clipStateMap;
static int privateID;
private:
/// static int counter to allow deleting this specific instance
static int privateID;
}; };
#endif #endif

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,7 +29,7 @@ int Controller::privateID = 0;
Controller::Controller() Controller::Controller()
{ {
ID = privateID++; ID = privateID++;
} }
void Controller::reset() void Controller::reset()
@ -38,5 +38,5 @@ void Controller::reset()
int Controller::getID() int Controller::getID()
{ {
return ID; return ID;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -31,66 +31,72 @@
**/ **/
class Controller class Controller
{ {
public: public:
/// used to report the controller status /// used to report the controller status
enum STATUS { enum STATUS {
CONTROLLER_ERROR = 0, CONTROLLER_ERROR = 0,
CONTROLLER_OK, CONTROLLER_OK,
}; };
/// creates the controller instance: this is called in the non-RT thread
Controller();
/// controllers have a unique ID
int getID();
/// allows instance to register MIDI observer type functionality
virtual int registerComponents(){return 0;}
virtual ~Controller(){};
/// get the status of the controller
virtual STATUS status(){return CONTROLLER_OK;}
/// name string to show in UI
virtual std::string getName() = 0;
/// master
virtual void masterInputVol(float f){}
virtual void masterInputTo(int to,float f){}
virtual void masterInputToActive(int to,float f){}
virtual void masterVolume(float f){}
virtual void masterReturnVolume(float f){}
virtual void metronomeEnable(bool b){}
/// FX
virtual void trackSend(int t, int send, float v){}
virtual void trackSendActive(int t, int send, bool a){}
virtual void trackJackSend(int t, float v){} /// creates the controller instance: this is called in the non-RT thread
virtual void trackJackSendActivate(int t, bool a){} Controller();
/// Time /// controllers have a unique ID
virtual void bpm(int bpm){} int getID();
virtual void tapTempo(bool b){}
/// allows instance to register MIDI observer type functionality
/// Special virtual int registerComponents()
virtual void specialScene(int t, int scene){} {
return 0;
/// track functionality }
virtual void mute(int t, bool b){}
virtual void volume(int t, float f){} virtual ~Controller() {};
virtual void progress(int t, int s, float f){}
virtual void recordArm(int t, bool r){} /// get the status of the controller
virtual void setSceneState(int track, int scene, GridLogic::State s){} virtual STATUS status()
virtual void launchScene( int scene ){} {
return CONTROLLER_OK;
/// reset controller }
virtual void reset();
/// name string to show in UI
private: virtual std::string getName() = 0;
static int privateID;
int ID; /// master
virtual void masterInputVol(float f) {}
virtual void masterInputTo(int to,float f) {}
virtual void masterInputToActive(int to,float f) {}
virtual void masterVolume(float f) {}
virtual void masterReturnVolume(float f) {}
virtual void metronomeEnable(bool b) {}
/// FX
virtual void trackSend(int t, int send, float v) {}
virtual void trackSendActive(int t, int send, bool a) {}
virtual void trackJackSend(int t, float v) {}
virtual void trackJackSendActivate(int t, bool a) {}
/// Time
virtual void bpm(int bpm) {}
virtual void tapTempo(bool b) {}
/// Special
virtual void specialScene(int t, int scene) {}
/// track functionality
virtual void mute(int t, bool b) {}
virtual void volume(int t, float f) {}
virtual void progress(int t, int s, float f) {}
virtual void recordArm(int t, bool r) {}
virtual void setSceneState(int track, int scene, GridLogic::State s) {}
virtual void launchScene( int scene ) {}
/// reset controller
virtual void reset();
private:
static int privateID;
int ID;
}; };
#endif // LUPPP_CONTROLLER_H #endif // LUPPP_CONTROLLER_H

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -36,96 +36,96 @@
**/ **/
class GenericMIDI : public Controller, public MidiIO class GenericMIDI : public Controller, public MidiIO
{ {
public: public:
/// Creates a blank GenericMIDI instance, which can be bound dynamically /// Creates a blank GenericMIDI instance, which can be bound dynamically
GenericMIDI(int waste = 0, std::string name = "generic"); GenericMIDI(int waste = 0, std::string name = "generic");
/// Attempts to load a .ctlr file, pointed to by the string
GenericMIDI(std::string file);
int registerComponents();
Controller::STATUS status();
void setName(std::string );
std::string getName();
std::string getAuthor();
std::string getEmail();
/// track actions
//void mute(int t, bool b);
void metronomeEnable(bool b);
void launchScene( int scene );
void volume(int t, float f);
void recordArm(int t, bool b);
void setSceneState(int track, int clip, GridLogic::State s);
/*
void progress(int t, int s, float f);
void launchScene( int scene );
/// track FX
void trackSend(int t, int send, float v);
*/
void trackSend(int t, int send, float v);
void trackSendActive(int t, int send, bool a);
virtual void trackJackSend(int t, float v); /// Attempts to load a .ctlr file, pointed to by the string
virtual void trackJackSendActivate(int t, bool a); GenericMIDI(std::string file);
/// footswitch -> scene launch controls int registerComponents();
void setFootswitchToNextScene(int v);
bool footswitchNextScene; Controller::STATUS status();
bool footswitchPrevScene;
void setName(std::string );
std::string getName();
void reset(); std::string getAuthor();
std::string getEmail();
void midi(unsigned char* data);
/// track actions
void process(int nframes); //void mute(int t, bool b);
const std::vector<Binding*>& getMidiToAction(); void metronomeEnable(bool b);
// for adding bindings from MIDI / GUI event pair void launchScene( int scene );
void setupBinding( LupppAction eventType, int midiStatus, int midiData, int track, int scene, int send, int active );
void removeBinding( int bindingID ); void volume(int t, float f);
private:
STATUS stat; void recordArm(int t, bool b);
void setSceneState(int track, int clip, GridLogic::State s);
std::string name;
std::string author; /*
std::string email; void progress(int t, int s, float f);
void launchScene( int scene );
/// contains midi binding instances
std::vector<Binding*> midiToAction; /// track FX
std::vector<Binding*> actionToMidi; void trackSend(int t, int send, float v);
*/
int loadController(std::string controllerFile);
void trackSend(int t, int send, float v);
/// creates a binding from a cJSON inputBindings / outputBindings object void trackSendActive(int t, int send, bool a);
Binding* setupBinding( cJSON* bindings );
virtual void trackJackSend(int t, float v);
virtual void trackJackSendActivate(int t, bool a);
/// for "sampling" a clip in the grid, and applying events to it:
/// footpedal for example /// footswitch -> scene launch controls
bool shiftPressed; void setFootswitchToNextScene(int v);
int footpedalTrack; bool footswitchNextScene;
int footpedalScene; bool footswitchPrevScene;
/*
/// for handling events void reset();
void ccChange( int track, int cc, float value );
void noteOff( int track, int note, int vel ); void midi(unsigned char* data);
void noteOn( int track, int note, int vel );
*/ void process(int nframes);
const std::vector<Binding*>& getMidiToAction();
// for adding bindings from MIDI / GUI event pair
void setupBinding( LupppAction eventType, int midiStatus, int midiData, int track, int scene, int send, int active );
void removeBinding( int bindingID );
private:
STATUS stat;
std::string name;
std::string author;
std::string email;
/// contains midi binding instances
std::vector<Binding*> midiToAction;
std::vector<Binding*> actionToMidi;
int loadController(std::string controllerFile);
/// creates a binding from a cJSON inputBindings / outputBindings object
Binding* setupBinding( cJSON* bindings );
/// for "sampling" a clip in the grid, and applying events to it:
/// footpedal for example
bool shiftPressed;
int footpedalTrack;
int footpedalScene;
/*
/// for handling events
void ccChange( int track, int cc, float value );
void noteOff( int track, int note, int vel );
void noteOn( int track, int note, int vel );
*/
}; };
#endif // LUPPP_GENERIC_MIDI_H #endif // LUPPP_GENERIC_MIDI_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -30,120 +30,120 @@
extern Jack* jack; extern Jack* jack;
LupppGUI::LupppGUI() : LupppGUI::LupppGUI() :
Controller() Controller()
{ {
} }
void LupppGUI::masterInputVol(float f) void LupppGUI::masterInputVol(float f)
{ {
EventMasterInputVol e( f ); EventMasterInputVol e( f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::masterInputTo(int to,float f) void LupppGUI::masterInputTo(int to,float f)
{ {
EventMasterInputTo e( (Event::INPUT_TO)to, f ); EventMasterInputTo e( (Event::INPUT_TO)to, f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::masterInputToActive(int to,float f) void LupppGUI::masterInputToActive(int to,float f)
{ {
EventMasterInputToActive e( (Event::INPUT_TO)to, f ); EventMasterInputToActive e( (Event::INPUT_TO)to, f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::masterVolume(float f) void LupppGUI::masterVolume(float f)
{ {
EventMasterVol e( f ); EventMasterVol e( f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::masterReturnVolume(float f) void LupppGUI::masterReturnVolume(float f)
{ {
printf(" return %f ", f ); printf(" return %f ", f );
EventMasterReturn e( RETURN_MAIN, f ); EventMasterReturn e( RETURN_MAIN, f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::metronomeEnable(bool r) void LupppGUI::metronomeEnable(bool r)
{ {
EventMetronomeActive e( r ); EventMetronomeActive e( r );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::recordArm(int t, bool r) void LupppGUI::recordArm(int t, bool r)
{ {
EventTrackRecordArm e( t, r ); EventTrackRecordArm e( t, r );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::trackSend(int t, int send, float r) void LupppGUI::trackSend(int t, int send, float r)
{ {
EventTrackSend e( t, static_cast<Event::SEND_TYPE>(send), r ); EventTrackSend e( t, static_cast<Event::SEND_TYPE>(send), r );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::specialScene(int t, int s) void LupppGUI::specialScene(int t, int s)
{ {
EventGridSelectNewChosen e( t, s ); EventGridSelectNewChosen e( t, s );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::trackSendActive(int t, int send, bool a) void LupppGUI::trackSendActive(int t, int send, bool a)
{ {
EventTrackSendActive e( t, static_cast<Event::SEND_TYPE>(send), a ); EventTrackSendActive e( t, static_cast<Event::SEND_TYPE>(send), a );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::trackJackSend(int t, float v) void LupppGUI::trackJackSend(int t, float v)
{ {
EventTrackJackSend e(t,v); EventTrackJackSend e(t,v);
writeToGuiRingbuffer(&e); writeToGuiRingbuffer(&e);
} }
void LupppGUI::trackJackSendActivate(int t, bool a) void LupppGUI::trackJackSendActivate(int t, bool a)
{ {
EventTrackJackSendActivate e(t,a); EventTrackJackSendActivate e(t,a);
writeToGuiRingbuffer(&e); writeToGuiRingbuffer(&e);
} }
void LupppGUI::setSceneState(int t, int clip, GridLogic::State s) void LupppGUI::setSceneState(int t, int clip, GridLogic::State s)
{ {
EventGridState e( t, clip, s ); EventGridState e( t, clip, s );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::launchScene( int scene ) void LupppGUI::launchScene( int scene )
{ {
EventGridLaunchScene e( scene ); EventGridLaunchScene e( scene );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::mute(int t, bool b) void LupppGUI::mute(int t, bool b)
{ {
} }
void LupppGUI::tapTempo( bool b ) void LupppGUI::tapTempo( bool b )
{ {
EventTimeTempoTap e(b); EventTimeTempoTap e(b);
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::bpm(int bpm) void LupppGUI::bpm(int bpm)
{ {
EventTimeBPM e(bpm); EventTimeBPM e(bpm);
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::volume(int t, float f) void LupppGUI::volume(int t, float f)
{ {
EventTrackVol e( t, f ); EventTrackVol e( t, f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
void LupppGUI::progress(int t, int s, float f) void LupppGUI::progress(int t, int s, float f)
{ {
EventLooperProgress e( t, f ); EventLooperProgress e( t, f );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -26,37 +26,40 @@
class LupppGUI : public Controller class LupppGUI : public Controller
{ {
public: public:
LupppGUI(); LupppGUI();
std::string getName(){return "Luppp GUI";} std::string getName()
{
void masterVolume(float f); return "Luppp GUI";
void masterReturnVolume(float f); }
void masterInputVol(float v);
void masterInputTo(int to,float f); void masterVolume(float f);
void masterInputToActive(int to,float f); void masterReturnVolume(float f);
void masterInputVol(float v);
void metronomeEnable(bool b); void masterInputTo(int to,float f);
void masterInputToActive(int to,float f);
void trackSend(int t, int send, float r);
void trackSendActive(int t, int send, bool a); void metronomeEnable(bool b);
void trackSend(int t, int send, float r);
void trackSendActive(int t, int send, bool a);
virtual void trackJackSend(int t, float v);
virtual void trackJackSendActivate(int t, bool a);
void bpm(int bpm);
void tapTempo( bool b );
void specialScene(int t, int scene);
void mute(int t, bool b);
void volume(int t, float f);
void progress(int t, int s, float p);
void recordArm(int t, bool b);
void launchScene( int scene );
void setSceneState(int track, int clip, GridLogic::State s);
virtual void trackJackSend(int t, float v);
virtual void trackJackSendActivate(int t, bool a);
void bpm(int bpm);
void tapTempo( bool b );
void specialScene(int t, int scene);
void mute(int t, bool b);
void volume(int t, float f);
void progress(int t, int s, float p);
void recordArm(int t, bool b);
void launchScene( int scene );
void setSceneState(int track, int clip, GridLogic::State s);
}; };
#endif // LUPPP_CONTROLLER_GUI_H #endif // LUPPP_CONTROLLER_GUI_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -26,56 +26,56 @@
#include "../looperclip.hxx" #include "../looperclip.hxx"
NonSeq::NonSeq() : NonSeq::NonSeq() :
Controller(), Controller(),
MidiIO() MidiIO()
{ {
std::string name = "non-seq"; std::string name = "non-seq";
registerMidiPorts( name ); registerMidiPorts( name );
} }
void NonSeq::launchScene( int scene ) void NonSeq::launchScene( int scene )
{ {
unsigned char data[3]; unsigned char data[3];
data[0] = 176; data[0] = 176;
data[1] = 20; data[1] = 20;
data[2] = scene; data[2] = scene;
//LUPPP_NOTE("NonSeq::launchScene() %i, %i, %i\n", data[0],data[1],data[2] ); //LUPPP_NOTE("NonSeq::launchScene() %i, %i, %i\n", data[0],data[1],data[2] );
writeMidi( data ); writeMidi( data );
} }
std::string NonSeq::getName() std::string NonSeq::getName()
{ {
return "non-seq"; return "non-seq";
} }
void NonSeq::setSceneState(int track, int scene, GridLogic::State s) void NonSeq::setSceneState(int track, int scene, GridLogic::State s)
{ {
unsigned char data[3]; unsigned char data[3];
data[0] = 176; data[0] = 176;
data[1] = 22; // off data[1] = 22; // off
// check *actual* value of playing: *NOT* GridState::s, because it could be queued // check *actual* value of playing: *NOT* GridState::s, because it could be queued
// for something else, but we want the *actual* here, not "queued". This is a unique // for something else, but we want the *actual* here, not "queued". This is a unique
// use case because were trying to control non-seq as if it were part of Luppp. // use case because were trying to control non-seq as if it were part of Luppp.
if( jack->getLooper( track )->getClip( scene )->playing() ) if( jack->getLooper( track )->getClip( scene )->playing() )
data[1] = 21; data[1] = 21;
data[2] = track; data[2] = track;
//LUPPP_NOTE("NonSeq::setSceneState() %i, %i, %i\n", data[0],data[1],data[2] ); //LUPPP_NOTE("NonSeq::setSceneState() %i, %i, %i\n", data[0],data[1],data[2] );
writeMidi( data ); writeMidi( data );
} }
int NonSeq::registerComponents() int NonSeq::registerComponents()
{ {
// makes JACK add this controller to the midiObservers list: // makes JACK add this controller to the midiObservers list:
// note the static_cast<>() is *needed* here for multiple-inheritance // note the static_cast<>() is *needed* here for multiple-inheritance
MidiIO* m = static_cast<MidiIO*>(this); MidiIO* m = static_cast<MidiIO*>(this);
jack->registerMidiIO( m ); jack->registerMidiIO( m );
return LUPPP_RETURN_OK; return LUPPP_RETURN_OK;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,17 +29,17 @@
**/ **/
class NonSeq : public Controller, public MidiIO class NonSeq : public Controller, public MidiIO
{ {
public: public:
NonSeq(); NonSeq();
~NonSeq(){}; ~NonSeq() {};
std::string getName(); std::string getName();
int registerComponents(); int registerComponents();
void launchScene( int scene ); void launchScene( int scene );
void setSceneState(int track, int scene, GridLogic::State s); void setSceneState(int track, int scene, GridLogic::State s);
}; };
#endif // LUPPP_NON_SEQ_H #endif // LUPPP_NON_SEQ_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -22,167 +22,162 @@
ControllerUpdater::ControllerUpdater() ControllerUpdater::ControllerUpdater()
{ {
// CAREFUL size of controllers: otherwise malloc() called // CAREFUL size of controllers: otherwise malloc() called
c.reserve( CONTROLLERS_PREALLOC ); c.reserve( CONTROLLERS_PREALLOC );
} }
void ControllerUpdater::registerController( Controller* controller ) void ControllerUpdater::registerController( Controller* controller )
{ {
if (!controller) if (!controller) {
{ LUPPP_ERROR("Register Controller passed NULL controller!");
LUPPP_ERROR("Register Controller passed NULL controller!"); return;
return; }
}
//LUPPP_NOTE("Registering controller %s", controller->getName().c_str() );
//LUPPP_NOTE("Registering controller %s", controller->getName().c_str() );
// store the controller instance
// store the controller instance c.push_back( controller );
c.push_back( controller );
// and tell it to register itself (MidiObserver / AudioObserver etc)
// and tell it to register itself (MidiObserver / AudioObserver etc) controller->registerComponents();
controller->registerComponents();
} }
void ControllerUpdater::removeController( int id ) void ControllerUpdater::removeController( int id )
{ {
for( unsigned int i = 0; i < c.size(); i++) for( unsigned int i = 0; i < c.size(); i++) {
{ if ( c.at(i)->getID() == id ) {
if ( c.at(i)->getID() == id ) // keep pointer: otherwise we mem-leak
{ Controller* removed = c.at( i );
// keep pointer: otherwise we mem-leak
Controller* removed = c.at( i ); cout << "Removing item " << i << " with name " << removed->getName() << endl;
cout << "Removing item " << i << " with name " << removed->getName() << endl; // remove the instance at
c.erase( c.begin() + i );
// remove the instance at
c.erase( c.begin() + i ); // send it for de-allocation
EventControllerInstance e( removed );
// send it for de-allocation writeToGuiRingbuffer( &e );
EventControllerInstance e( removed ); }
writeToGuiRingbuffer( &e ); }
}
}
} }
Controller* ControllerUpdater::getController(int id) Controller* ControllerUpdater::getController(int id)
{ {
// search controllers for ID, if found return a pointer to it // search controllers for ID, if found return a pointer to it
for( unsigned int i = 0; i < c.size(); i++) for( unsigned int i = 0; i < c.size(); i++) {
{ if ( c.at(i)->getID() == id ) {
if ( c.at(i)->getID() == id ) LUPPP_NOTE("getController target ID: %i, found ID: %i, returning %s", id, i, c.at(i)->getName().c_str() );
{ return c.at(i);
LUPPP_NOTE("getController target ID: %i, found ID: %i, returning %s", id, i, c.at(i)->getName().c_str() ); }
return c.at(i); }
} return 0;
}
return 0;
} }
void ControllerUpdater::reset() void ControllerUpdater::reset()
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->reset(); c.at(i)->reset();
} }
void ControllerUpdater::mute(int t, bool b) void ControllerUpdater::mute(int t, bool b)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->mute(t,b); c.at(i)->mute(t,b);
} }
void ControllerUpdater::masterVolume(float v) void ControllerUpdater::masterVolume(float v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->masterVolume(v); c.at(i)->masterVolume(v);
} }
void ControllerUpdater::masterReturnVolume(float v) void ControllerUpdater::masterReturnVolume(float v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->masterReturnVolume( v ); c.at(i)->masterReturnVolume( v );
} }
void ControllerUpdater::setTrackSceneProgress(int t, int s, float p) void ControllerUpdater::setTrackSceneProgress(int t, int s, float p)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->progress(t,s,p); c.at(i)->progress(t,s,p);
} }
void ControllerUpdater::setTrackSendActive(int t, int send, bool v) void ControllerUpdater::setTrackSendActive(int t, int send, bool v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->trackSendActive(t, send, v); c.at(i)->trackSendActive(t, send, v);
} }
void ControllerUpdater::setTrackSend(int t, int send, float v) void ControllerUpdater::setTrackSend(int t, int send, float v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->trackSend(t, send, v); c.at(i)->trackSend(t, send, v);
} }
void ControllerUpdater::setTrackJackSendActive(int t, bool v) void ControllerUpdater::setTrackJackSendActive(int t, bool v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->trackJackSendActivate(t, v); c.at(i)->trackJackSendActivate(t, v);
} }
void ControllerUpdater::setTrackJackSend(int t, float v) void ControllerUpdater::setTrackJackSend(int t, float v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->trackJackSend(t, v); c.at(i)->trackJackSend(t, v);
} }
void ControllerUpdater::specialScene(int t, int scene) void ControllerUpdater::specialScene(int t, int scene)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->specialScene(t, scene); c.at(i)->specialScene(t, scene);
} }
void ControllerUpdater::masterInputToActive(int to, bool v) void ControllerUpdater::masterInputToActive(int to, bool v)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->masterInputToActive( to, v); c.at(i)->masterInputToActive( to, v);
} }
void ControllerUpdater::masterInputTo( int to, float v ) void ControllerUpdater::masterInputTo( int to, float v )
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->masterInputTo( to, v); c.at(i)->masterInputTo( to, v);
} }
void ControllerUpdater::masterInputVol( float v ) void ControllerUpdater::masterInputVol( float v )
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->masterInputVol( v ); c.at(i)->masterInputVol( v );
} }
void ControllerUpdater::launchScene( int scene ) void ControllerUpdater::launchScene( int scene )
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->launchScene(scene); c.at(i)->launchScene(scene);
} }
void ControllerUpdater::setSceneState(int t, int clip, GridLogic::State s) void ControllerUpdater::setSceneState(int t, int clip, GridLogic::State s)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->setSceneState(t,clip,s); c.at(i)->setSceneState(t,clip,s);
} }
void ControllerUpdater::recordArm(int t, bool r) void ControllerUpdater::recordArm(int t, bool r)
{ {
for(unsigned int i = 0; i < c.size(); i++) for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->recordArm(t,r); c.at(i)->recordArm(t,r);
} }
void ControllerUpdater::volume(int t, float v) void ControllerUpdater::volume(int t, float v)
{ {
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->volume(t,v); for(unsigned int i = 0; i < c.size(); i++) c.at(i)->volume(t,v);
} }
void ControllerUpdater::tapTempo(bool b) void ControllerUpdater::tapTempo(bool b)
{ {
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->tapTempo(b); for(unsigned int i = 0; i < c.size(); i++) c.at(i)->tapTempo(b);
} }
void ControllerUpdater::metronomeEnable(bool b) void ControllerUpdater::metronomeEnable(bool b)
{ {
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->metronomeEnable(b); for(unsigned int i = 0; i < c.size(); i++) c.at(i)->metronomeEnable(b);
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,60 +33,60 @@ using namespace std;
* Updates each registered controller when a certain event occurs. All output * Updates each registered controller when a certain event occurs. All output
* devices (MIDI controllers, GUI, OSC-UI's etc) are registered in order to * devices (MIDI controllers, GUI, OSC-UI's etc) are registered in order to
* stay up-to-date. * stay up-to-date.
* *
* This class does no scheduling, it passes the events to the Controllers * This class does no scheduling, it passes the events to the Controllers
* immidiatly. * immidiatly.
* *
* The Logic class is the opposite of this: it takes input and Luppp processes * The Logic class is the opposite of this: it takes input and Luppp processes
* it, pushing the relevant updates in state through ControllerUpdater to each * it, pushing the relevant updates in state through ControllerUpdater to each
* registered device. * registered device.
**/ **/
class ControllerUpdater class ControllerUpdater
{ {
public: public:
ControllerUpdater(); ControllerUpdater();
/// add a Controller* to Controllers that recieve updates
void registerController( Controller* controller );
/// removes a controller by ID
void removeController( int controllerID );
/// returns a Controller* from ID
Controller* getController(int id);
void reset();
void mute(int t, bool b);
void masterVolume(float v);
void masterReturnVolume(float v);
void masterInputToActive(int to, bool v);
void masterInputTo( int inputTo, float vol );
void masterInputVol( float vol );
void setTrackSceneProgress(int t, int s, float p);
void setTrackSendActive(int t, int send, bool v);
void setTrackSend(int t, int send, float v);
void setTrackJackSendActive(int t, bool v); /// add a Controller* to Controllers that recieve updates
void setTrackJackSend(int t, float v); void registerController( Controller* controller );
void specialScene(int t, int scene); /// removes a controller by ID
void removeController( int controllerID );
void launchScene( int scene );
/// returns a Controller* from ID
void setSceneState(int t, int clip, GridLogic::State s); Controller* getController(int id);
void recordArm(int t, bool r); void reset();
void mute(int t, bool b);
void volume(int t, float v);
void masterVolume(float v);
void tapTempo(bool b); void masterReturnVolume(float v);
void masterInputToActive(int to, bool v);
void metronomeEnable(bool b); void masterInputTo( int inputTo, float vol );
void masterInputVol( float vol );
private:
std::vector<Controller*> c; void setTrackSceneProgress(int t, int s, float p);
void setTrackSendActive(int t, int send, bool v);
void setTrackSend(int t, int send, float v);
void setTrackJackSendActive(int t, bool v);
void setTrackJackSend(int t, float v);
void specialScene(int t, int scene);
void launchScene( int scene );
void setSceneState(int t, int clip, GridLogic::State s);
void recordArm(int t, bool r);
void volume(int t, float v);
void tapTempo(bool b);
void metronomeEnable(bool b);
private:
std::vector<Controller*> c;
}; };
#endif // LUPPP_CONTROLLER_UPDATER_H #endif // LUPPP_CONTROLLER_UPDATER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -24,34 +24,26 @@
void luppp_debug( int warnLevel, const char* name, const char* file, const char* func, int line, void luppp_debug( int warnLevel, const char* name, const char* file, const char* func, int line,
const char* format, ... ) const char* format, ... )
{ {
if ( warnLevel == DEBUG_LEVEL_ERROR ) if ( warnLevel == DEBUG_LEVEL_ERROR ) {
{ printf( "[\033[1;31m%s\033[0m] %s:%i: ", name, func, line );
printf( "[\033[1;31m%s\033[0m] %s:%i: ", name, func, line ); } else if ( warnLevel == DEBUG_LEVEL_WARN ) {
} printf( "[\033[1;33m%s\033[0m] %s:%i: ", name, func, line );
else if ( warnLevel == DEBUG_LEVEL_WARN ) } else if ( warnLevel == DEBUG_LEVEL_TEST ) {
{
printf( "[\033[1;33m%s\033[0m] %s:%i: ", name, func, line );
}
else if ( warnLevel == DEBUG_LEVEL_TEST )
{
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
printf( "[\033[1;33m%s\033[0m] %s:%i: ", name, func, line ); printf( "[\033[1;33m%s\033[0m] %s:%i: ", name, func, line );
#endif #endif
} } else { // NOTE
else // NOTE printf( "[\033[1;32m%s\033[0m] %s:%i: ", name, func, line );
{ }
printf( "[\033[1;32m%s\033[0m] %s:%i: ", name, func, line ); printf( "\033[0m" );
}
printf( "\033[0m" ); if ( format ) {
va_list args;
if ( format ) va_start( args, format );
{ vfprintf( stdout, format, args );
va_list args; va_end( args );
va_start( args, format ); }
vfprintf( stdout, format, args ); printf( "\n" );
va_end( args );
}
printf( "\n" );
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,10 +29,10 @@ LUPPP_KILL( "%s", "MessageHere" );
*/ */
enum DEBUG_LEVEL { enum DEBUG_LEVEL {
DEBUG_LEVEL_NOTE = 0, DEBUG_LEVEL_NOTE = 0,
DEBUG_LEVEL_WARN, DEBUG_LEVEL_WARN,
DEBUG_LEVEL_ERROR, DEBUG_LEVEL_ERROR,
DEBUG_LEVEL_TEST DEBUG_LEVEL_TEST
}; };
void luppp_debug( int warnLevel, const char* name, const char* file, const char* func, int line, void luppp_debug( int warnLevel, const char* name, const char* file, const char* func, int line,

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,23 +29,23 @@
#include <pmmintrin.h> #include <pmmintrin.h>
inline void AVOIDDENORMALS() inline void AVOIDDENORMALS()
{ {
//LUPPP_NOTE("Denormals: FZ DAZ using SSE3"); //LUPPP_NOTE("Denormals: FZ DAZ using SSE3");
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
} }
#else #else
#include <xmmintrin.h> #include <xmmintrin.h>
inline void AVOIDDENORMALS() inline void AVOIDDENORMALS()
{ {
//LUPPP_NOTE("Denormals: FZ"); //LUPPP_NOTE("Denormals: FZ");
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
} }
#endif //__SSE3__ #endif //__SSE3__
#else #else
inline void AVOIDDENORMALS() inline void AVOIDDENORMALS()
{ {
LUPPP_NOTE( "Denormals: Warning! No protection" ); LUPPP_NOTE( "Denormals: Warning! No protection" );
} }
#endif //__SSE__ #endif //__SSE__

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -28,51 +28,51 @@ class AudioBuffer;
/** DiskReader /** DiskReader
* This class reads a previously saved session from disk, restoring Luppp's * This class reads a previously saved session from disk, restoring Luppp's
* internal state to that of when the save took place. * internal state to that of when the save took place.
* *
* The directory <sessionDir> is the main point of loading. The user selects * The directory <sessionDir> is the main point of loading. The user selects
* that directory to load the session from. <sessionDir>.luppp is the name of * that directory to load the session from. <sessionDir>.luppp is the name of
* the session file: it contains all info about the session: Volumes, loaded * the session file: it contains all info about the session: Volumes, loaded
* samples etc. * samples etc.
* *
* Samples are read from the directory <sessionDir>/samples, in which there is a * Samples are read from the directory <sessionDir>/samples, in which there is a
* sample.cfg file, which can be parsed to get sample metadata. * sample.cfg file, which can be parsed to get sample metadata.
**/ **/
class DiskReader class DiskReader
{ {
public: public:
DiskReader(); DiskReader();
/// loads default settings for Luppp: controller instances etc /// loads default settings for Luppp: controller instances etc
int loadPreferences(); int loadPreferences();
/// loads a sample into a new AudioBuffer, returning the buffer /// loads a sample into a new AudioBuffer, returning the buffer
int loadSample( int track, int scene, std::string path ); int loadSample( int track, int scene, std::string path );
std::string getLastLoadedSamplePath(); std::string getLastLoadedSamplePath();
/// reads a session from disk, parsing and restoring state /// reads a session from disk, parsing and restoring state
int readSession( std::string path ); int readSession( std::string path );
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
int runTests(); int runTests();
#endif #endif
private: private:
cJSON* sessionJson; cJSON* sessionJson;
std::string sessionName; std::string sessionName;
std::string sessionPath; std::string sessionPath;
// convinience functions // convinience functions
int readTracks(); int readTracks();
int readMaster(); int readMaster();
int readScenes(int t, cJSON* track); int readScenes(int t, cJSON* track);
// ui show editor // ui show editor
int showAudioEditor(AudioBuffer* ); int showAudioEditor(AudioBuffer* );
// sample load dialog // sample load dialog
int resampleQuality; int resampleQuality;
std::string lastLoadedSamplePath; std::string lastLoadedSamplePath;
}; };
#endif // LUPPP_DISK_READER_H #endif // LUPPP_DISK_READER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -43,498 +43,451 @@ using namespace std;
DiskWriter::DiskWriter() DiskWriter::DiskWriter()
{ {
sessionJson = cJSON_CreateObject(); sessionJson = cJSON_CreateObject();
audioJson = cJSON_CreateObject(); audioJson = cJSON_CreateObject();
// setup default controller name / author etc // setup default controller name / author etc
controllerInfo[CONTROLLER_NAME] = "no name"; controllerInfo[CONTROLLER_NAME] = "no name";
controllerInfo[CONTROLLER_AUTHOR] = "no author"; controllerInfo[CONTROLLER_AUTHOR] = "no author";
controllerInfo[CONTROLLER_LINK] = "no link"; controllerInfo[CONTROLLER_LINK] = "no link";
sessionDir = getenv("HOME"); sessionDir = getenv("HOME");
sessionName = "session"; sessionName = "session";
foldersCreated = false; foldersCreated = false;
// create .config/openAV/luppp/ directory // create .config/openAV/luppp/ directory
stringstream dotConfig; stringstream dotConfig;
dotConfig << getenv("HOME") << "/.config/openAV/"; dotConfig << getenv("HOME") << "/.config/openAV/";
int dotConfigDir = mkdir( dotConfig.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); int dotConfigDir = mkdir( dotConfig.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
if ( errno == EEXIST ) if ( errno == EEXIST ) {
{ //LUPPP_NOTE("dotConfigDir exists");
//LUPPP_NOTE("dotConfigDir exists"); } else if ( dotConfigDir ) {
} LUPPP_WARN("Error creating dotConfigDir: %s", strerror(errno));
else if ( dotConfigDir ) } else {
{ LUPPP_NOTE("Creating .config/openAV/ directory");
LUPPP_WARN("Error creating dotConfigDir: %s", strerror(errno)); }
}
else stringstream dotConfigLuppp;
{ dotConfigLuppp << getenv("HOME") << "/.config/openAV/luppp";
LUPPP_NOTE("Creating .config/openAV/ directory"); int dotConfigLupppDir = mkdir( dotConfigLuppp.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
} if ( errno == EEXIST ) {
//LUPPP_NOTE("dotConfigLupppDir exists");
stringstream dotConfigLuppp; } else if ( dotConfigLupppDir ) {
dotConfigLuppp << getenv("HOME") << "/.config/openAV/luppp"; LUPPP_WARN("Error creating dotConfigLupppDir: %s", strerror(errno));
int dotConfigLupppDir = mkdir( dotConfigLuppp.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); } else {
if ( errno == EEXIST ) LUPPP_NOTE("Creating .config/openAV/luppp directory");
{ }
//LUPPP_NOTE("dotConfigLupppDir exists");
} stringstream dotConfigCtlr;
else if ( dotConfigLupppDir ) dotConfigCtlr << getenv("HOME") << "/.config/openAV/luppp/controllers/";
{ int dotConfigCtlrDir = mkdir( dotConfigCtlr.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
LUPPP_WARN("Error creating dotConfigLupppDir: %s", strerror(errno)); if ( errno == EEXIST ) {
} //LUPPP_NOTE("dotConfigCtlrDir exists");
else } else if ( dotConfigCtlrDir ) {
{ LUPPP_WARN("Error creating dotConfigCtlrDir: %s", strerror(errno));
LUPPP_NOTE("Creating .config/openAV/luppp directory"); } else {
} LUPPP_NOTE("Creating .config/openAV/luppp directory");
}
stringstream dotConfigCtlr;
dotConfigCtlr << getenv("HOME") << "/.config/openAV/luppp/controllers/";
int dotConfigCtlrDir = mkdir( dotConfigCtlr.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
if ( errno == EEXIST )
{
//LUPPP_NOTE("dotConfigCtlrDir exists");
}
else if ( dotConfigCtlrDir )
{
LUPPP_WARN("Error creating dotConfigCtlrDir: %s", strerror(errno));
}
else
{
LUPPP_NOTE("Creating .config/openAV/luppp directory");
}
}; };
void DiskWriter::initialize(std::string path, std::string name ) void DiskWriter::initialize(std::string path, std::string name )
{ {
sessionName = name; sessionName = name;
sessionPath = path; sessionPath = path;
// write session.luppp JSON node to <path>/<sessionName>.luppp // write session.luppp JSON node to <path>/<sessionName>.luppp
stringstream sessionDirStream; stringstream sessionDirStream;
sessionDirStream << path; sessionDirStream << path;
if ( !gui->getNsm() ) if ( !gui->getNsm() )
sessionDirStream << "/" << sessionName << ".luppp"; sessionDirStream << "/" << sessionName << ".luppp";
sessionDir = sessionDirStream.str(); sessionDir = sessionDirStream.str();
LUPPP_NOTE( "Creating session dir %s", sessionDir.c_str() ); LUPPP_NOTE( "Creating session dir %s", sessionDir.c_str() );
int sessionDirError = mkdir( sessionDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); int sessionDirError = mkdir( sessionDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
if ( sessionDirError ) if ( sessionDirError ) {
{ // handle by using different filename?
// handle by using different filename? LUPPP_WARN("Error creating session directory. Does the path: %s exist?",path.c_str());
LUPPP_WARN("Error creating session directory. Does the path: %s exist?",path.c_str()); }
}
stringstream audioDirStream;
stringstream audioDirStream; audioDirStream << sessionDir << "/audio";
audioDirStream << sessionDir << "/audio"; audioDir = audioDirStream.str();
audioDir = audioDirStream.str(); LUPPP_NOTE("Creating audio dir %s", audioDir.c_str() );
LUPPP_NOTE("Creating audio dir %s", audioDir.c_str() );
int audioDirError = mkdir( audioDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
int audioDirError = mkdir( audioDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ); if ( audioDirError ) {
if ( audioDirError ) LUPPP_WARN("Error creating sample directory");
{ }
LUPPP_WARN("Error creating sample directory");
} foldersCreated = true;
foldersCreated = true;
} }
std::string DiskWriter::getLastSaveName() std::string DiskWriter::getLastSaveName()
{ {
return sessionName; return sessionName;
} }
std::string DiskWriter::getLastSavePath() std::string DiskWriter::getLastSavePath()
{ {
return sessionPath; return sessionPath;
} }
void DiskWriter::writeControllerInfo( CONTROLLER_INFO c, std::string s ) void DiskWriter::writeControllerInfo( CONTROLLER_INFO c, std::string s )
{ {
controllerInfo[c] = s; controllerInfo[c] = s;
} }
int DiskWriter::writeControllerFile( Controller* c ) int DiskWriter::writeControllerFile( Controller* c )
{ {
if ( c ) if ( c ) {
{ LUPPP_NOTE("DiskWriter Controller* id: %i", c->getID() );
LUPPP_NOTE("DiskWriter Controller* id: %i", c->getID() ); } else {
} LUPPP_ERROR("DiskWriter Controller* passed NULL" );
else return LUPPP_RETURN_ERROR;
{ }
LUPPP_ERROR("DiskWriter Controller* passed NULL" );
return LUPPP_RETURN_ERROR; // check if controller of ID is actually a GenericMIDI controller
} GenericMIDI* g = dynamic_cast<GenericMIDI*>( c );
// check if controller of ID is actually a GenericMIDI controller if ( g ) {
GenericMIDI* g = dynamic_cast<GenericMIDI*>( c ); LUPPP_NOTE("Creating JSON for .ctlr file...");
if ( g ) cJSON* controllerJson = cJSON_CreateObject();
{
LUPPP_NOTE("Creating JSON for .ctlr file..."); cJSON_AddItemToObject( controllerJson, "name",
cJSON_CreateString( controllerInfo[CONTROLLER_NAME].c_str() ) );
cJSON* controllerJson = cJSON_CreateObject(); cJSON_AddItemToObject( controllerJson, "author",
cJSON_CreateString( controllerInfo[CONTROLLER_AUTHOR].c_str() ) );
cJSON_AddItemToObject( controllerJson, "name", cJSON_AddItemToObject( controllerJson, "link",
cJSON_CreateString( controllerInfo[CONTROLLER_NAME].c_str() ) ); cJSON_CreateString( controllerInfo[CONTROLLER_LINK].c_str() ) );
cJSON_AddItemToObject( controllerJson, "author",
cJSON_CreateString( controllerInfo[CONTROLLER_AUTHOR].c_str() ) ); // input bindings
cJSON_AddItemToObject( controllerJson, "link", std::vector<Binding*> b = g->getMidiToAction();
cJSON_CreateString( controllerInfo[CONTROLLER_LINK].c_str() ) );
cJSON* inputBindings = cJSON_CreateArray();
// input bindings cJSON_AddItemToObject(controllerJson, "inputBindings", inputBindings );
std::vector<Binding*> b = g->getMidiToAction(); for(unsigned int i = 0; i < b.size(); i++ ) {
// create binding
cJSON* inputBindings = cJSON_CreateArray(); cJSON* binding = cJSON_CreateObject();
cJSON_AddItemToObject(controllerJson, "inputBindings", inputBindings ); cJSON_AddItemToArray( inputBindings, binding );
for(unsigned int i = 0; i < b.size(); i++ )
{ // add metadata to binding
// create binding const char* actionName = Event::getPrettyName( b.at(i)->action );
cJSON* binding = cJSON_CreateObject();
cJSON_AddItemToArray( inputBindings, binding ); if ( actionName ) {
cJSON_AddItemToObject( binding, "action", cJSON_CreateString( actionName ) );
// add metadata to binding
const char* actionName = Event::getPrettyName( b.at(i)->action ); cJSON_AddNumberToObject( binding, "status", b.at(i)->status );
cJSON_AddNumberToObject( binding, "data" , b.at(i)->data );
if ( actionName )
{ // only add JSON elements if they're not the "invalid" defaults
cJSON_AddItemToObject( binding, "action", cJSON_CreateString( actionName ) ); if ( b.at(i)->track != -2 )
cJSON_AddNumberToObject( binding, "track" , b.at(i)->track );
cJSON_AddNumberToObject( binding, "status", b.at(i)->status ); if ( b.at(i)->scene != -1 )
cJSON_AddNumberToObject( binding, "data" , b.at(i)->data ); cJSON_AddNumberToObject( binding, "scene" , b.at(i)->scene );
if ( b.at(i)->send != -1 )
// only add JSON elements if they're not the "invalid" defaults cJSON_AddNumberToObject( binding, "send" , b.at(i)->send );
if ( b.at(i)->track != -2 ) if ( b.at(i)->active!= -1 )
cJSON_AddNumberToObject( binding, "track" , b.at(i)->track ); cJSON_AddNumberToObject( binding, "active", b.at(i)->active );
if ( b.at(i)->scene != -1 )
cJSON_AddNumberToObject( binding, "scene" , b.at(i)->scene ); LUPPP_NOTE("Creating Binding: action %i == %s!", b.at(i)->action, actionName );
if ( b.at(i)->send != -1 ) } else {
cJSON_AddNumberToObject( binding, "send" , b.at(i)->send ); LUPPP_WARN("Binding action %i has no prettyName!", b.at(i)->action );
if ( b.at(i)->active!= -1 ) }
cJSON_AddNumberToObject( binding, "active", b.at(i)->active ); }
LUPPP_NOTE("Creating Binding: action %i == %s!", b.at(i)->action, actionName );
} //std::vector<Binding*> b = g->getMidiToAction();
else /*
{ cJSON* outputBindings = cJSON_CreateArray();
LUPPP_WARN("Binding action %i has no prettyName!", b.at(i)->action ); cJSON_AddItemToObject(controllerJson, "outputBindings", outputBindings );
}
} for(unsigned int i = 0; i < b.size(); i++ )
{
// create binding
//std::vector<Binding*> b = g->getMidiToAction(); cJSON* binding = cJSON_CreateObject();
/* cJSON_AddItemToArray( outputBindings, binding );
cJSON* outputBindings = cJSON_CreateArray();
cJSON_AddItemToObject(controllerJson, "outputBindings", outputBindings ); // add metadata to binding
// FIXME: get action string from Event class: need to move function from GenericMIDI to there
for(unsigned int i = 0; i < b.size(); i++ ) cJSON_AddItemToObject( binding, "action", cJSON_CreateString( "gridlogic:launchscene" ) );
{
// create binding cJSON_AddNumberToObject( binding, "status", b.at(i)->status );
cJSON* binding = cJSON_CreateObject(); cJSON_AddNumberToObject( binding, "data" , b.at(i)->data );
cJSON_AddItemToArray( outputBindings, binding );
cJSON_AddNumberToObject( binding, "track" , b.at(i)->track );
// add metadata to binding cJSON_AddNumberToObject( binding, "scene" , b.at(i)->scene );
// FIXME: get action string from Event class: need to move function from GenericMIDI to there cJSON_AddNumberToObject( binding, "send" , b.at(i)->send );
cJSON_AddItemToObject( binding, "action", cJSON_CreateString( "gridlogic:launchscene" ) ); cJSON_AddNumberToObject( binding, "active", b.at(i)->active );
}
cJSON_AddNumberToObject( binding, "status", b.at(i)->status ); */
cJSON_AddNumberToObject( binding, "data" , b.at(i)->data );
cJSON_AddNumberToObject( binding, "track" , b.at(i)->track ); // write the sample JSON node to <samplePath>/sample.cfg
cJSON_AddNumberToObject( binding, "scene" , b.at(i)->scene ); stringstream controllerCfgPath;
cJSON_AddNumberToObject( binding, "send" , b.at(i)->send ); controllerCfgPath << getenv("HOME") << "/.config/openAV/luppp/controllers/" << g->getName() << ".ctlr";
cJSON_AddNumberToObject( binding, "active", b.at(i)->active );
} ifstream infile( controllerCfgPath.str().c_str() );
*/ if ( infile.good() ) {
// file exists: ask user overwrite or rename?
//LUPPP_WARN("Controller filename exists: prompting user to overwrite y/n?");
// write the sample JSON node to <samplePath>/sample.cfg int action = fl_choice("Controller exists, action?", "Cancel", "Rename", "Overwrite");
stringstream controllerCfgPath; if ( action == 0 ) {
controllerCfgPath << getenv("HOME") << "/.config/openAV/luppp/controllers/" << g->getName() << ".ctlr"; // return OK, as user has chosen to cancel writing the file
return LUPPP_RETURN_OK;
ifstream infile( controllerCfgPath.str().c_str() ); } else if ( action == 1 ) {
if ( infile.good() ) // rename here
{ const char* name = fl_input("New name for .ctlr file:");
// file exists: ask user overwrite or rename? if ( name ) {
//LUPPP_WARN("Controller filename exists: prompting user to overwrite y/n?"); // clear the filename
int action = fl_choice("Controller exists, action?", "Cancel", "Rename", "Overwrite"); controllerCfgPath.str( "" );
if ( action == 0 ) controllerCfgPath << getenv("HOME") << "/.config/openAV/luppp/controllers/" << name << ".ctlr";
{ LUPPP_NOTE( "New .ctlr filename %s", controllerCfgPath.str().c_str() );
// return OK, as user has chosen to cancel writing the file } else {
return LUPPP_RETURN_OK; LUPPP_NOTE("No name entered for .ctlr file, canceling!");
} return LUPPP_RETURN_ERROR;
else if ( action == 1 ) }
{ } else {
// rename here // just overwrite the file, no action
const char* name = fl_input("New name for .ctlr file:"); }
if ( name )
{
// clear the filename }
controllerCfgPath.str( "" );
controllerCfgPath << getenv("HOME") << "/.config/openAV/luppp/controllers/" << name << ".ctlr"; LUPPP_NOTE("Writing %s.ctlr file to disk", g->getName().c_str() );
LUPPP_NOTE( "New .ctlr filename %s", controllerCfgPath.str().c_str() );
} ofstream controllerCfgFile;
else controllerCfgFile.open ( controllerCfgPath.str().c_str() );
{ controllerCfgFile << cJSON_Print( controllerJson );
LUPPP_NOTE("No name entered for .ctlr file, canceling!"); controllerCfgFile.close();
return LUPPP_RETURN_ERROR; } else {
} LUPPP_WARN("Invalid Controller pointer: cannot write %s as is not a GenericMIDI controller!", c->getName().c_str() );
} return LUPPP_RETURN_ERROR;
else }
{
// just overwrite the file, no action return LUPPP_RETURN_OK;
}
}
LUPPP_NOTE("Writing %s.ctlr file to disk", g->getName().c_str() );
ofstream controllerCfgFile;
controllerCfgFile.open ( controllerCfgPath.str().c_str() );
controllerCfgFile << cJSON_Print( controllerJson );
controllerCfgFile.close();
}
else
{
LUPPP_WARN("Invalid Controller pointer: cannot write %s as is not a GenericMIDI controller!", c->getName().c_str() );
return LUPPP_RETURN_ERROR;
}
return LUPPP_RETURN_OK;
} }
int DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab, int DiskWriter::writeAudioBuffer(int track, int scene, AudioBuffer* ab,
const char *gui_path) const char *gui_path)
{ {
stringstream path; stringstream path;
if ( gui_path && strlen(gui_path) ) { if ( gui_path && strlen(gui_path) ) {
printf("saving single buffer to %s\n", gui_path); printf("saving single buffer to %s\n", gui_path);
path << gui_path; path << gui_path;
} } else if ( foldersCreated ) {
else if ( foldersCreated ) stringstream filename;
{ filename << "t_" << track << "_s_" << scene << ".wav";
stringstream filename;
filename << "t_" << track << "_s_" << scene << ".wav"; // store the clip in clipData, we will write the session JSON for it in writeSession
clipData.push_back( ClipData( track, scene, filename.str() ) );
// store the clip in clipData, we will write the session JSON for it in writeSession
clipData.push_back( ClipData( track, scene, filename.str() ) ); // add the AudioBuffer metadata to the sample JSON node
cJSON* sampleClip = cJSON_CreateObject();
// add the AudioBuffer metadata to the sample JSON node cJSON_AddItemToObject(audioJson, filename.str().c_str(), sampleClip );
cJSON* sampleClip = cJSON_CreateObject(); cJSON_AddNumberToObject(sampleClip,"beats", ab->getBeats() );
cJSON_AddItemToObject(audioJson, filename.str().c_str(), sampleClip );
cJSON_AddNumberToObject(sampleClip,"beats", ab->getBeats() ); // get pretty name from GUI
std::string clipName = gui->getTrack(track)->getClipSelector()->clipName( scene );
// get pretty name from GUI cJSON_AddItemToObject ( sampleClip, "name", cJSON_CreateString( clipName.c_str() ));
std::string clipName = gui->getTrack(track)->getClipSelector()->clipName( scene );
cJSON_AddItemToObject ( sampleClip, "name", cJSON_CreateString( clipName.c_str() )); // write the AudioBuffer contents to <path>/audio/ as <name>.wav
// or alternatively t_<track>_s_<scene>.wav
// write the AudioBuffer contents to <path>/audio/ as <name>.wav
// or alternatively t_<track>_s_<scene>.wav path << audioDir << "/" << filename.str();
} else {
path << audioDir << "/" << filename.str(); LUPPP_WARN("%s", "Session folders not created yet, while trying to write audioBuffers.");
} return LUPPP_RETURN_ERROR;
else }
{
LUPPP_WARN("%s", "Session folders not created yet, while trying to write audioBuffers.");
return LUPPP_RETURN_ERROR; SndfileHandle outfile( path.str(), SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_FLOAT, 1, gui->samplerate );
}
// FIXME: the size of the buffer is bigger than the audio contained in it:
// calculate the length that needs saving using getBeats() * framesPerBeat
SndfileHandle outfile( path.str(), SFM_WRITE, SF_FORMAT_WAV | SF_FORMAT_FLOAT, 1, gui->samplerate ); if ( ab->getAudioFrames() > 0 )
outfile.write( &ab->getData()[0], ab->getAudioFrames() );
// FIXME: the size of the buffer is bigger than the audio contained in it: else {
// calculate the length that needs saving using getBeats() * framesPerBeat LUPPP_WARN("%s","Sample has zero samples");
if ( ab->getAudioFrames() > 0 ) }
outfile.write( &ab->getData()[0], ab->getAudioFrames() );
else return LUPPP_RETURN_OK;
{
LUPPP_WARN("%s","Sample has zero samples");
}
return LUPPP_RETURN_OK;
} }
void DiskWriter::writeMaster() void DiskWriter::writeMaster()
{ {
// Master track stuff // Master track stuff
cJSON* masterTrack = cJSON_CreateObject(); cJSON* masterTrack = cJSON_CreateObject();
cJSON_AddItemToObject(sessionJson, "master", masterTrack ); cJSON_AddItemToObject(sessionJson, "master", masterTrack );
GMasterTrack* master = gui->getMasterTrack(); GMasterTrack* master = gui->getMasterTrack();
cJSON_AddNumberToObject( masterTrack, "fader", master->getVolume()->value() ); cJSON_AddNumberToObject( masterTrack, "fader", master->getVolume()->value() );
cJSON_AddNumberToObject( masterTrack, "bpm", gui->getMasterTrack()->getBpm() ); cJSON_AddNumberToObject( masterTrack, "bpm", gui->getMasterTrack()->getBpm() );
// TODO add samplerate to session JSON // TODO add samplerate to session JSON
//cJSON_AddNumberToObject( masterTrack, "samplerate", gui->getMasterTrack()->getBpm() ); //cJSON_AddNumberToObject( masterTrack, "samplerate", gui->getMasterTrack()->getBpm() );
cJSON_AddNumberToObject( masterTrack, "inputVolume", gui->getMasterTrack()->getInputVolume()->value() ); cJSON_AddNumberToObject( masterTrack, "inputVolume", gui->getMasterTrack()->getInputVolume()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToSndActive", gui->getMasterTrack()->getInputToSend()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToSndActive", gui->getMasterTrack()->getInputToSend()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToKeyActive", gui->getMasterTrack()->getInputToSidechainKey()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToKeyActive", gui->getMasterTrack()->getInputToSidechainKey()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToMixActive", gui->getMasterTrack()->getInputToMix()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToMixActive", gui->getMasterTrack()->getInputToMix()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToSndVol", gui->getMasterTrack()->getInputToSendVol()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToSndVol", gui->getMasterTrack()->getInputToSendVol()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToXSide", gui->getMasterTrack()->getInputToXSide()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToXSide", gui->getMasterTrack()->getInputToXSide()->value() );
cJSON_AddNumberToObject( masterTrack, "inputToMixVol", gui->getMasterTrack()->getInputToMixVol()->value() ); cJSON_AddNumberToObject( masterTrack, "inputToMixVol", gui->getMasterTrack()->getInputToMixVol()->value() );
// scene names // scene names
Avtk::ClipSelector* clipSelector = master->getClipSelector(); Avtk::ClipSelector* clipSelector = master->getClipSelector();
cJSON* sceneNames = cJSON_CreateArray(); cJSON* sceneNames = cJSON_CreateArray();
cJSON_AddItemToObject( masterTrack, "sceneNames", sceneNames ); cJSON_AddItemToObject( masterTrack, "sceneNames", sceneNames );
for(int i = 0; i < NSCENES; i++) for(int i = 0; i < NSCENES; i++) {
{ cJSON* sceneName = cJSON_CreateString( clipSelector->clipName(i).c_str() );
cJSON* sceneName = cJSON_CreateString( clipSelector->clipName(i).c_str() ); cJSON_AddItemToArray( sceneNames, sceneName );
cJSON_AddItemToArray( sceneNames, sceneName ); }
}
} }
int DiskWriter::writeSession() int DiskWriter::writeSession()
{ {
if ( !foldersCreated ) if ( !foldersCreated ) {
{ LUPPP_WARN("%s", "Session folders not created yet, while trying to write session.");
LUPPP_WARN("%s", "Session folders not created yet, while trying to write session."); return LUPPP_RETURN_ERROR;
return LUPPP_RETURN_ERROR; }
}
// add session metadata
cJSON_AddItemToObject ( sessionJson, "session", cJSON_CreateString( sessionName.c_str() ));
cJSON_AddNumberToObject( sessionJson, "version_major", 1 );
cJSON_AddNumberToObject( sessionJson, "version_minor", 0 );
cJSON_AddNumberToObject( sessionJson, "version_patch", 0 );
writeMaster();
// add JSON "tracks" array
cJSON* trackArray = cJSON_CreateArray();
cJSON_AddItemToObject(sessionJson, "tracks", trackArray );
// write tracks into JSON tracks array
for(int t = 0; t < NTRACKS; t++)
{
cJSON* track = cJSON_CreateObject();
cJSON_AddItemToArray( trackArray, track );
// add track metadata: volumes, sends etc
cJSON_AddNumberToObject( track, "ID", t );
cJSON_AddStringToObject( track, "name", gui->getTrack(t)->bg.getLabel() );
cJSON_AddNumberToObject( track, "fader", gui->getTrack(t)->getVolume()->value() );
cJSON_AddNumberToObject( track, "sendAmount" , gui->getTrack(t)->getSend() );
cJSON_AddNumberToObject( track, "sendActive" , gui->getTrack(t)->getSendActive() );
cJSON_AddNumberToObject( track, "jacksendAmount" , gui->getTrack(t)->getJackSend() ); // add session metadata
cJSON_AddNumberToObject( track, "jacksendActive" , gui->getTrack(t)->getJackSendActivate() ); cJSON_AddItemToObject ( sessionJson, "session", cJSON_CreateString( sessionName.c_str() ));
cJSON_AddNumberToObject( track, "xsideAmount", gui->getTrack(t)->getXSide() ); cJSON_AddNumberToObject( sessionJson, "version_major", 1 );
cJSON_AddNumberToObject( track, "keyActive" , gui->getTrack(t)->getKeyActive() ); cJSON_AddNumberToObject( sessionJson, "version_minor", 0 );
cJSON_AddNumberToObject( sessionJson, "version_patch", 0 );
// write clipData vector into clip placeholder
cJSON* clips = cJSON_CreateArray();
cJSON_AddItemToObject( track, "clips", clips ); writeMaster();
// add JSON "tracks" array
for(int s = 0; s < NSCENES; s++) cJSON* trackArray = cJSON_CreateArray();
{ cJSON_AddItemToObject(sessionJson, "tracks", trackArray );
// add empty string to array
cJSON* clip = cJSON_CreateString( "" ); // write tracks into JSON tracks array
cJSON_AddItemToArray( clips, clip ); for(int t = 0; t < NTRACKS; t++) {
cJSON* track = cJSON_CreateObject();
// replace blank string if clip exists cJSON_AddItemToArray( trackArray, track );
for(unsigned int i = 0; i < clipData.size(); i++)
{ // add track metadata: volumes, sends etc
if ( clipData.at(i).track == t && cJSON_AddNumberToObject( track, "ID", t );
clipData.at(i).scene == s ) cJSON_AddStringToObject( track, "name", gui->getTrack(t)->bg.getLabel() );
{
cJSON* newClip = cJSON_CreateString( clipData.at(i).name.c_str() ); cJSON_AddNumberToObject( track, "fader", gui->getTrack(t)->getVolume()->value() );
cJSON_ReplaceItemInArray( clips, s, newClip );
}
} cJSON_AddNumberToObject( track, "sendAmount" , gui->getTrack(t)->getSend() );
cJSON_AddNumberToObject( track, "sendActive" , gui->getTrack(t)->getSendActive() );
}
cJSON_AddNumberToObject( track, "jacksendAmount" , gui->getTrack(t)->getJackSend() );
} cJSON_AddNumberToObject( track, "jacksendActive" , gui->getTrack(t)->getJackSendActivate() );
cJSON_AddNumberToObject( track, "xsideAmount", gui->getTrack(t)->getXSide() );
cJSON_AddNumberToObject( track, "keyActive" , gui->getTrack(t)->getKeyActive() );
stringstream sessionLuppp;
sessionLuppp << sessionDir << "/session.luppp"; // write clipData vector into clip placeholder
//c out << "Session dir: " << sessionDir.str() << "\n" << "Sample dir : " << audioDir.str() << endl; cJSON* clips = cJSON_CreateArray();
ofstream sessionFile; cJSON_AddItemToObject( track, "clips", clips );
sessionFile.open ( sessionLuppp.str().c_str() );
sessionFile << cJSON_Print( sessionJson );
sessionFile.close();
for(int s = 0; s < NSCENES; s++) {
// write the sample JSON node to <samplePath>/sample.cfg // add empty string to array
stringstream audioCfg; cJSON* clip = cJSON_CreateString( "" );
audioCfg << audioDir << "/audio.cfg"; cJSON_AddItemToArray( clips, clip );
ofstream audioCfgFile; // replace blank string if clip exists
audioCfgFile.open ( audioCfg.str().c_str() ); for(unsigned int i = 0; i < clipData.size(); i++) {
audioCfgFile << cJSON_Print( audioJson ); if ( clipData.at(i).track == t &&
audioCfgFile.close(); clipData.at(i).scene == s ) {
cJSON* newClip = cJSON_CreateString( clipData.at(i).name.c_str() );
// clear the clipData, clean page for next save cJSON_ReplaceItemInArray( clips, s, newClip );
clipData.clear(); }
}
// reset the cJSON objects }
cJSON_Delete( sessionJson );
cJSON_Delete( audioJson ); }
sessionJson = cJSON_CreateObject();
audioJson = cJSON_CreateObject();
stringstream sessionLuppp;
sessionLuppp << sessionDir << "/session.luppp";
return LUPPP_RETURN_OK; //c out << "Session dir: " << sessionDir.str() << "\n" << "Sample dir : " << audioDir.str() << endl;
ofstream sessionFile;
sessionFile.open ( sessionLuppp.str().c_str() );
sessionFile << cJSON_Print( sessionJson );
sessionFile.close();
// write the sample JSON node to <samplePath>/sample.cfg
stringstream audioCfg;
audioCfg << audioDir << "/audio.cfg";
ofstream audioCfgFile;
audioCfgFile.open ( audioCfg.str().c_str() );
audioCfgFile << cJSON_Print( audioJson );
audioCfgFile.close();
// clear the clipData, clean page for next save
clipData.clear();
// reset the cJSON objects
cJSON_Delete( sessionJson );
cJSON_Delete( audioJson );
sessionJson = cJSON_CreateObject();
audioJson = cJSON_CreateObject();
return LUPPP_RETURN_OK;
} }
void DiskWriter::writeDefaultConfigToUserHome() void DiskWriter::writeDefaultConfigToUserHome()
{ {
LUPPP_NOTE("Writing default preferences file."); LUPPP_NOTE("Writing default preferences file.");
cJSON* prfs = cJSON_CreateObject(); cJSON* prfs = cJSON_CreateObject();
// "__COMMENT__" : "users home + <whatever it says here>" // "__COMMENT__" : "users home + <whatever it says here>"
// "saveDirectory" : "luppp" // "saveDirectory" : "luppp"
cJSON_AddItemToObject ( prfs, "__COMMENT__", cJSON_AddItemToObject ( prfs, "__COMMENT__",
cJSON_CreateString("users home + <whatever it says here>") ); cJSON_CreateString("users home + <whatever it says here>") );
cJSON_AddItemToObject ( prfs, "saveDirectory", cJSON_CreateString( "luppp" )); cJSON_AddItemToObject ( prfs, "saveDirectory", cJSON_CreateString( "luppp" ));
// "__COMMENT__" : "0 = LINEAR, 1 = SINC_FASTEST, 2 = SINC_BEST", // "__COMMENT__" : "0 = LINEAR, 1 = SINC_FASTEST, 2 = SINC_BEST",
// "resampleQuality" : 2 // "resampleQuality" : 2
cJSON_AddItemToObject ( prfs, "__COMMENT__", cJSON_AddItemToObject ( prfs, "__COMMENT__",
cJSON_CreateString("0 = LINEAR, 1 = SINC_FASTEST, 2 = SINC_BEST") ); cJSON_CreateString("0 = LINEAR, 1 = SINC_FASTEST, 2 = SINC_BEST") );
cJSON_AddNumberToObject( prfs, "resampleQuality", 1 ); cJSON_AddNumberToObject( prfs, "resampleQuality", 1 );
// "defaultControllers" : [], // "defaultControllers" : [],
cJSON* defCtrls = cJSON_CreateArray(); cJSON* defCtrls = cJSON_CreateArray();
cJSON_AddItemToObject( prfs, "defaultControllers", defCtrls ); cJSON_AddItemToObject( prfs, "defaultControllers", defCtrls );
// per track send and return option // per track send and return option
cJSON_AddNumberToObject( prfs, "enablePerTrackSendReturns", 0 ); cJSON_AddNumberToObject( prfs, "enablePerTrackSendReturns", 0 );
// test output on console // test output on console
// cout << endl << cJSON_Print( prfs ) << endl << endl; // cout << endl << cJSON_Print( prfs ) << endl << endl;
// write JSON to .config/openAV/luppp/luppp.prfs // write JSON to .config/openAV/luppp/luppp.prfs
stringstream f; stringstream f;
f << getenv("HOME") << "/.config/openAV/luppp/luppp.prfs"; f << getenv("HOME") << "/.config/openAV/luppp/luppp.prfs";
ofstream outFile; ofstream outFile;
outFile.open ( f.str().c_str() ); outFile.open ( f.str().c_str() );
outFile << cJSON_Print( prfs ); outFile << cJSON_Print( prfs );
outFile.close(); outFile.close();
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -27,23 +27,22 @@
class AudioBuffer; class AudioBuffer;
class Controller; class Controller;
enum CONTROLLER_INFO enum CONTROLLER_INFO {
{ CONTROLLER_NAME,
CONTROLLER_NAME, CONTROLLER_AUTHOR,
CONTROLLER_AUTHOR, CONTROLLER_LINK,
CONTROLLER_LINK, CONTROLLER_INFO_SIZE,
CONTROLLER_INFO_SIZE,
}; };
/// To hold data about loaded clips until we write the JSON out /// To hold data about loaded clips until we write the JSON out
class ClipData class ClipData
{ {
public: public:
ClipData(int tr, int sc, std::string na) : ClipData(int tr, int sc, std::string na) :
track(tr), scene(sc), name(na) {} track(tr), scene(sc), name(na) {}
int track; int track;
int scene; int scene;
std::string name; std::string name;
}; };
/** DiskWriter /** DiskWriter
@ -53,51 +52,51 @@ class ClipData
**/ **/
class DiskWriter class DiskWriter
{ {
public: public:
DiskWriter(); DiskWriter();
/// sets up session write path etc /// sets up session write path etc
void initialize( std::string path, std::string sessionName ); void initialize( std::string path, std::string sessionName );
/// writes a single audio buffer to disk for saving whole state. /// writes a single audio buffer to disk for saving whole state.
// When gui_path is set, it only saves a single AB* to that path // When gui_path is set, it only saves a single AB* to that path
int writeAudioBuffer(int track, int scene, AudioBuffer* ab, int writeAudioBuffer(int track, int scene, AudioBuffer* ab,
const char* gui_path = 0); const char* gui_path = 0);
/// flush the JSON to disk, finalizing the save /// flush the JSON to disk, finalizing the save
int writeSession(); int writeSession();
std::string getLastSaveName(); std::string getLastSaveName();
std::string getLastSavePath(); std::string getLastSavePath();
/// sets a piece of info to be written to the controller /// sets a piece of info to be written to the controller
void writeControllerInfo( CONTROLLER_INFO c, std::string s ); void writeControllerInfo( CONTROLLER_INFO c, std::string s );
/// writes a controller definition .ctlr JSON file from a GenericMIDI instance /// writes a controller definition .ctlr JSON file from a GenericMIDI instance
int writeControllerFile( Controller* c ); int writeControllerFile( Controller* c );
/// writes default config file to users home if it doesn't exist /// writes default config file to users home if it doesn't exist
void writeDefaultConfigToUserHome(); void writeDefaultConfigToUserHome();
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
int runTests(); int runTests();
#endif #endif
private: private:
cJSON* sessionJson; cJSON* sessionJson;
cJSON* audioJson; cJSON* audioJson;
bool foldersCreated; bool foldersCreated;
std::string sessionName; std::string sessionName;
std::string sessionPath; std::string sessionPath;
std::string audioDir; std::string audioDir;
std::string sessionDir; std::string sessionDir;
std::vector<ClipData> clipData; std::vector<ClipData> clipData;
// convienice functions for code separation // convienice functions for code separation
void writeMaster(); void writeMaster();
std::string controllerInfo[CONTROLLER_INFO_SIZE]; std::string controllerInfo[CONTROLLER_INFO_SIZE];
}; };
#endif // LUPPP_DISK_WRITER_H #endif // LUPPP_DISK_WRITER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -26,63 +26,68 @@
class DBMeter class DBMeter
{ {
public: public:
DBMeter(int rate) DBMeter(int rate)
{ {
fSamplingFreq = rate; fSamplingFreq = rate;
fConst0 = (96.f / float(min(192000, max(1, fSamplingFreq)))); fConst0 = (96.f / float(min(192000, max(1, fSamplingFreq))));
fRec0[0] = -96.f; fRec0[0] = -96.f;
fRec0[1] = -96.f; fRec0[1] = -96.f;
fRec1[0] = -96.f; fRec1[0] = -96.f;
fRec1[1] = -96.f; fRec1[1] = -96.f;
fvbargraph0 = -96.f; fvbargraph0 = -96.f;
fvbargraph1 = -96.f; fvbargraph1 = -96.f;
} }
int getNumInputs() { return 2;} int getNumInputs()
int getNumOutputs(){ return 2;} {
return 2;
// call these to get the current dB values }
float getLeftDB() int getNumOutputs()
{ {
// range scale from range = -96 -> +10, to 0 -> 1 return 2;
float zeroOneL = (1-(fvbargraph0 / -96.f)); }
fvbargraph0 = -96;
return pow(zeroOneL, 4); // call these to get the current dB values
} float getLeftDB()
float getRightDB() {
{ // range scale from range = -96 -> +10, to 0 -> 1
float zeroOneR = (1-(fvbargraph1 / -96.f)); float zeroOneL = (1-(fvbargraph0 / -96.f));
fvbargraph1 = -96; fvbargraph0 = -96;
return pow(zeroOneR, 4); return pow(zeroOneL, 4);
} }
float getRightDB()
void process(int count, float* inputL, float* inputR ) {
{ float zeroOneR = (1-(fvbargraph1 / -96.f));
for (int i = 0; (i < count); i = (i + 1)) fvbargraph1 = -96;
{ return pow(zeroOneR, 4);
fRec0[0] = max((fRec0[1] - fConst0), min(10.f, (20.f * log10f(max(1.58489e-05f, fabsf(*inputL)))))); }
if ( fvbargraph0 < fRec0[0] )
fvbargraph0 = fRec0[0]; void process(int count, float* inputL, float* inputR )
{
fRec1[0] = max((fRec1[1] - fConst0), min(10.f, (20.f * log10f(max(1.58489e-05f, fabsf(*inputR)))))); for (int i = 0; (i < count); i = (i + 1)) {
if ( fvbargraph1 < fRec1[0] ) fRec0[0] = max((fRec0[1] - fConst0), min(10.f, (20.f * log10f(max(1.58489e-05f, fabsf(*inputL))))));
fvbargraph1 = fRec1[0]; if ( fvbargraph0 < fRec0[0] )
fvbargraph0 = fRec0[0];
fRec0[1] = fRec0[0];
fRec1[1] = fRec1[0]; fRec1[0] = max((fRec1[1] - fConst0), min(10.f, (20.f * log10f(max(1.58489e-05f, fabsf(*inputR))))));
} if ( fvbargraph1 < fRec1[0] )
} fvbargraph1 = fRec1[0];
private: fRec0[1] = fRec0[0];
float fRec0[2]; fRec1[1] = fRec1[0];
float fRec1[2]; }
int fSamplingFreq; }
float fConst0;
float fvbargraph0; private:
float fvbargraph1; float fRec0[2];
float fRec1[2];
int fSamplingFreq;
float fConst0;
float fvbargraph0;
float fvbargraph1;
}; };
#endif // OPENAV_DSP_DBMETER_H #endif // OPENAV_DSP_DBMETER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -24,450 +24,479 @@
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
template <int N> inline float faustpower(float x) { return powf(x,N); } template <int N> inline float faustpower(float x)
template <int N> inline double faustpower(double x) { return pow(x,N); } {
template <int N> inline int faustpower(int x) { return faustpower<N/2>(x) * faustpower<N-N/2>(x); } return powf(x,N);
template <> inline int faustpower<0>(int x) { return 1; } }
template <> inline int faustpower<1>(int x) { return x; } template <int N> inline double faustpower(double x)
{
return pow(x,N);
}
template <int N> inline int faustpower(int x)
{
return faustpower<N/2>(x) * faustpower<N-N/2>(x);
}
template <> inline int faustpower<0>(int x)
{
return 1;
}
template <> inline int faustpower<1>(int x)
{
return x;
}
class Reverb // : Effect class Reverb // : Effect
{ {
public: public:
Reverb(int sr) Reverb(int sr)
{ {
init( sr ); init( sr );
} }
int getNumInputs() { return 2; } int getNumInputs()
int getNumOutputs(){ return 2; } {
return 2;
void damping(float d) }
{ int getNumOutputs()
if( d > 1.0 ) d = 1.0f; {
if( d < 0.0 ) d = 0.0f; return 2;
}
_damping = (1-d) * 18500 + 1500.f;
} void damping(float d)
{
void rt60(float rt) if( d > 1.0 ) d = 1.0f;
{ if( d < 0.0 ) d = 0.0f;
if( rt > 1.0 ) rt = 1.0f;
if( rt < 0.0 ) rt = 0.0f; _damping = (1-d) * 18500 + 1500.f;
}
_rt60 = 1 + rt * 5;
} void rt60(float rt)
{
void dryWet(float dw) if( rt > 1.0 ) rt = 1.0f;
{ if( rt < 0.0 ) rt = 0.0f;
if( dw > 1.0 ) dw = 1.0f;
if( dw < 0.0 ) dw = 0.0f; _rt60 = 1 + rt * 5;
_dryWet = dw; }
}
void dryWet(float dw)
void process (int count, float** input, float** output) {
{ if( dw > 1.0 ) dw = 1.0f;
float fSlow0 = _rt60; if( dw < 0.0 ) dw = 0.0f;
float fSlow1 = expf((fConst2 / fSlow0)); _dryWet = dw;
float fSlow2 = faustpower<2>(fSlow1); }
float fSlow3 = (1.0f - fSlow2);
float fSlow4 = cosf((fConst3 * _damping)); void process (int count, float** input, float** output)
float fSlow5 = (1.0f - (fSlow4 * fSlow2)); {
float fSlow6 = sqrtf(max(0.f, ((faustpower<2>(fSlow5) / faustpower<2>(fSlow3)) - 1.0f))); float fSlow0 = _rt60;
float fSlow7 = (fSlow5 / fSlow3); float fSlow1 = expf((fConst2 / fSlow0));
float fSlow8 = (fSlow7 - fSlow6); float fSlow2 = faustpower<2>(fSlow1);
float fSlow9 = (fSlow0 - 0.5f); float fSlow3 = (1.0f - fSlow2);
float fSlow10 = ((expf((fConst2 / fSlow9)) / fSlow1) - 1); float fSlow4 = cosf((fConst3 * _damping));
float fSlow11 = (fSlow1 * ((1.0f + fSlow6) - fSlow7)); float fSlow5 = (1.0f - (fSlow4 * fSlow2));
float fSlow12 = expf((fConst12 / fSlow0)); float fSlow6 = sqrtf(max(0.f, ((faustpower<2>(fSlow5) / faustpower<2>(fSlow3)) - 1.0f)));
float fSlow13 = faustpower<2>(fSlow12); float fSlow7 = (fSlow5 / fSlow3);
float fSlow14 = (1.0f - fSlow13); float fSlow8 = (fSlow7 - fSlow6);
float fSlow15 = (1.0f - (fSlow4 * fSlow13)); float fSlow9 = (fSlow0 - 0.5f);
float fSlow16 = sqrtf(max(0.f, ((faustpower<2>(fSlow15) / faustpower<2>(fSlow14)) - 1.0f))); float fSlow10 = ((expf((fConst2 / fSlow9)) / fSlow1) - 1);
float fSlow17 = (fSlow15 / fSlow14); float fSlow11 = (fSlow1 * ((1.0f + fSlow6) - fSlow7));
float fSlow18 = (fSlow17 - fSlow16); float fSlow12 = expf((fConst12 / fSlow0));
float fSlow19 = ((expf((fConst12 / fSlow9)) / fSlow12) - 1); float fSlow13 = faustpower<2>(fSlow12);
float fSlow20 = (fSlow12 * ((1.0f + fSlow16) - fSlow17)); float fSlow14 = (1.0f - fSlow13);
float fSlow21 = expf((fConst17 / fSlow0)); float fSlow15 = (1.0f - (fSlow4 * fSlow13));
float fSlow22 = faustpower<2>(fSlow21); float fSlow16 = sqrtf(max(0.f, ((faustpower<2>(fSlow15) / faustpower<2>(fSlow14)) - 1.0f)));
float fSlow23 = (1.0f - fSlow22); float fSlow17 = (fSlow15 / fSlow14);
float fSlow24 = (1.0f - (fSlow4 * fSlow22)); float fSlow18 = (fSlow17 - fSlow16);
float fSlow25 = sqrtf(max(0.f, ((faustpower<2>(fSlow24) / faustpower<2>(fSlow23)) - 1.0f))); float fSlow19 = ((expf((fConst12 / fSlow9)) / fSlow12) - 1);
float fSlow26 = (fSlow24 / fSlow23); float fSlow20 = (fSlow12 * ((1.0f + fSlow16) - fSlow17));
float fSlow27 = (fSlow26 - fSlow25); float fSlow21 = expf((fConst17 / fSlow0));
float fSlow28 = ((expf((fConst17 / fSlow9)) / fSlow21) - 1); float fSlow22 = faustpower<2>(fSlow21);
float fSlow29 = (fSlow21 * ((1.0f + fSlow25) - fSlow26)); float fSlow23 = (1.0f - fSlow22);
float fSlow30 = expf((fConst22 / fSlow0)); float fSlow24 = (1.0f - (fSlow4 * fSlow22));
float fSlow31 = faustpower<2>(fSlow30); float fSlow25 = sqrtf(max(0.f, ((faustpower<2>(fSlow24) / faustpower<2>(fSlow23)) - 1.0f)));
float fSlow32 = (1.0f - fSlow31); float fSlow26 = (fSlow24 / fSlow23);
float fSlow33 = (1.0f - (fSlow4 * fSlow31)); float fSlow27 = (fSlow26 - fSlow25);
float fSlow34 = sqrtf(max(0.f, ((faustpower<2>(fSlow33) / faustpower<2>(fSlow32)) - 1.0f))); float fSlow28 = ((expf((fConst17 / fSlow9)) / fSlow21) - 1);
float fSlow35 = (fSlow33 / fSlow32); float fSlow29 = (fSlow21 * ((1.0f + fSlow25) - fSlow26));
float fSlow36 = (fSlow35 - fSlow34); float fSlow30 = expf((fConst22 / fSlow0));
float fSlow37 = ((expf((fConst22 / fSlow9)) / fSlow30) - 1); float fSlow31 = faustpower<2>(fSlow30);
float fSlow38 = (fSlow30 * ((1.0f + fSlow34) - fSlow35)); float fSlow32 = (1.0f - fSlow31);
float fSlow39 = expf((fConst27 / fSlow0)); float fSlow33 = (1.0f - (fSlow4 * fSlow31));
float fSlow40 = faustpower<2>(fSlow39); float fSlow34 = sqrtf(max(0.f, ((faustpower<2>(fSlow33) / faustpower<2>(fSlow32)) - 1.0f)));
float fSlow41 = (1.0f - fSlow40); float fSlow35 = (fSlow33 / fSlow32);
float fSlow42 = (1.0f - (fSlow4 * fSlow40)); float fSlow36 = (fSlow35 - fSlow34);
float fSlow43 = sqrtf(max(0.f, ((faustpower<2>(fSlow42) / faustpower<2>(fSlow41)) - 1.0f))); float fSlow37 = ((expf((fConst22 / fSlow9)) / fSlow30) - 1);
float fSlow44 = (fSlow42 / fSlow41); float fSlow38 = (fSlow30 * ((1.0f + fSlow34) - fSlow35));
float fSlow45 = (fSlow44 - fSlow43); float fSlow39 = expf((fConst27 / fSlow0));
float fSlow46 = ((expf((fConst27 / fSlow9)) / fSlow39) - 1); float fSlow40 = faustpower<2>(fSlow39);
float fSlow47 = (fSlow39 * ((1.0f + fSlow43) - fSlow44)); float fSlow41 = (1.0f - fSlow40);
float fSlow48 = expf((fConst32 / fSlow0)); float fSlow42 = (1.0f - (fSlow4 * fSlow40));
float fSlow49 = faustpower<2>(fSlow48); float fSlow43 = sqrtf(max(0.f, ((faustpower<2>(fSlow42) / faustpower<2>(fSlow41)) - 1.0f)));
float fSlow50 = (1.0f - fSlow49); float fSlow44 = (fSlow42 / fSlow41);
float fSlow51 = (1.0f - (fSlow4 * fSlow49)); float fSlow45 = (fSlow44 - fSlow43);
float fSlow52 = sqrtf(max(0.f, ((faustpower<2>(fSlow51) / faustpower<2>(fSlow50)) - 1.0f))); float fSlow46 = ((expf((fConst27 / fSlow9)) / fSlow39) - 1);
float fSlow53 = (fSlow51 / fSlow50); float fSlow47 = (fSlow39 * ((1.0f + fSlow43) - fSlow44));
float fSlow54 = (fSlow53 - fSlow52); float fSlow48 = expf((fConst32 / fSlow0));
float fSlow55 = ((expf((fConst32 / fSlow9)) / fSlow48) - 1); float fSlow49 = faustpower<2>(fSlow48);
float fSlow56 = (fSlow48 * ((1.0f + fSlow52) - fSlow53)); float fSlow50 = (1.0f - fSlow49);
float fSlow57 = expf((fConst37 / fSlow0)); float fSlow51 = (1.0f - (fSlow4 * fSlow49));
float fSlow58 = faustpower<2>(fSlow57); float fSlow52 = sqrtf(max(0.f, ((faustpower<2>(fSlow51) / faustpower<2>(fSlow50)) - 1.0f)));
float fSlow59 = (1.0f - fSlow58); float fSlow53 = (fSlow51 / fSlow50);
float fSlow60 = (1.0f - (fSlow4 * fSlow58)); float fSlow54 = (fSlow53 - fSlow52);
float fSlow61 = sqrtf(max(0.f, ((faustpower<2>(fSlow60) / faustpower<2>(fSlow59)) - 1.0f))); float fSlow55 = ((expf((fConst32 / fSlow9)) / fSlow48) - 1);
float fSlow62 = (fSlow60 / fSlow59); float fSlow56 = (fSlow48 * ((1.0f + fSlow52) - fSlow53));
float fSlow63 = (fSlow62 - fSlow61); float fSlow57 = expf((fConst37 / fSlow0));
float fSlow64 = ((expf((fConst37 / fSlow9)) / fSlow57) - 1); float fSlow58 = faustpower<2>(fSlow57);
float fSlow65 = (fSlow57 * ((1.0f + fSlow61) - fSlow62)); float fSlow59 = (1.0f - fSlow58);
float fSlow66 = expf((fConst42 / fSlow0)); float fSlow60 = (1.0f - (fSlow4 * fSlow58));
float fSlow67 = faustpower<2>(fSlow66); float fSlow61 = sqrtf(max(0.f, ((faustpower<2>(fSlow60) / faustpower<2>(fSlow59)) - 1.0f)));
float fSlow68 = (1.0f - fSlow67); float fSlow62 = (fSlow60 / fSlow59);
float fSlow69 = (1.0f - (fSlow67 * fSlow4)); float fSlow63 = (fSlow62 - fSlow61);
float fSlow70 = sqrtf(max(0.f, ((faustpower<2>(fSlow69) / faustpower<2>(fSlow68)) - 1.0f))); float fSlow64 = ((expf((fConst37 / fSlow9)) / fSlow57) - 1);
float fSlow71 = (fSlow69 / fSlow68); float fSlow65 = (fSlow57 * ((1.0f + fSlow61) - fSlow62));
float fSlow72 = (fSlow71 - fSlow70); float fSlow66 = expf((fConst42 / fSlow0));
float fSlow73 = ((expf((fConst42 / fSlow9)) / fSlow66) - 1); float fSlow67 = faustpower<2>(fSlow66);
float fSlow74 = (fSlow66 * ((1.0f + fSlow70) - fSlow71)); float fSlow68 = (1.0f - fSlow67);
float* input0 = input[0]; float fSlow69 = (1.0f - (fSlow67 * fSlow4));
float* input1 = input[1]; float fSlow70 = sqrtf(max(0.f, ((faustpower<2>(fSlow69) / faustpower<2>(fSlow68)) - 1.0f)));
float* output0 = output[0]; float fSlow71 = (fSlow69 / fSlow68);
float* output1 = output[1]; float fSlow72 = (fSlow71 - fSlow70);
for (int i=0; i<count; i++) { float fSlow73 = ((expf((fConst42 / fSlow9)) / fSlow66) - 1);
fRec11[0] = ((fConst7 * (fRec4[1] + fRec4[2])) + (fConst6 * fRec11[1])); float fSlow74 = (fSlow66 * ((1.0f + fSlow70) - fSlow71));
fRec10[0] = ((fSlow11 * (fRec4[1] + (fSlow10 * fRec11[0]))) + (fSlow8 * fRec10[1])); float* input0 = input[0];
fVec0[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec10[0])); float* input1 = input[1];
float fTemp0 = (0.3f * (float)input0[i]); float* output0 = output[0];
float fTemp1 = ((fTemp0 + fVec0[(IOTA-iConst9)&8191]) - (0.6f * fRec8[1])); float* output1 = output[1];
fVec1[IOTA&2047] = fTemp1; for (int i=0; i<count; i++) {
fRec8[0] = fVec1[(IOTA-iConst10)&2047]; fRec11[0] = ((fConst7 * (fRec4[1] + fRec4[2])) + (fConst6 * fRec11[1]));
float fRec9 = (0.6f * fVec1[IOTA&2047]); fRec10[0] = ((fSlow11 * (fRec4[1] + (fSlow10 * fRec11[0]))) + (fSlow8 * fRec10[1]));
fRec15[0] = ((fConst7 * (fRec0[1] + fRec0[2])) + (fConst6 * fRec15[1])); fVec0[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec10[0]));
fRec14[0] = ((fSlow20 * (fRec0[1] + (fSlow19 * fRec15[0]))) + (fSlow18 * fRec14[1])); float fTemp0 = (0.3f * (float)input0[i]);
fVec2[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec14[0])); float fTemp1 = ((fTemp0 + fVec0[(IOTA-iConst9)&8191]) - (0.6f * fRec8[1]));
float fTemp2 = ((fTemp0 + fVec2[(IOTA-iConst14)&8191]) - (0.6f * fRec12[1])); fVec1[IOTA&2047] = fTemp1;
fVec3[IOTA&1023] = fTemp2; fRec8[0] = fVec1[(IOTA-iConst10)&2047];
fRec12[0] = fVec3[(IOTA-iConst15)&1023]; float fRec9 = (0.6f * fVec1[IOTA&2047]);
float fRec13 = (0.6f * fVec3[IOTA&1023]); fRec15[0] = ((fConst7 * (fRec0[1] + fRec0[2])) + (fConst6 * fRec15[1]));
float fTemp3 = (fRec13 + fRec9); fRec14[0] = ((fSlow20 * (fRec0[1] + (fSlow19 * fRec15[0]))) + (fSlow18 * fRec14[1]));
fRec19[0] = ((fConst7 * (fRec2[1] + fRec2[2])) + (fConst6 * fRec19[1])); fVec2[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec14[0]));
fRec18[0] = ((fSlow29 * (fRec2[1] + (fSlow28 * fRec19[0]))) + (fSlow27 * fRec18[1])); float fTemp2 = ((fTemp0 + fVec2[(IOTA-iConst14)&8191]) - (0.6f * fRec12[1]));
fVec4[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec18[0])); fVec3[IOTA&1023] = fTemp2;
float fTemp4 = (fVec4[(IOTA-iConst19)&8191] - (fTemp0 + (0.6f * fRec16[1]))); fRec12[0] = fVec3[(IOTA-iConst15)&1023];
fVec5[IOTA&2047] = fTemp4; float fRec13 = (0.6f * fVec3[IOTA&1023]);
fRec16[0] = fVec5[(IOTA-iConst20)&2047]; float fTemp3 = (fRec13 + fRec9);
float fRec17 = (0.6f * fVec5[IOTA&2047]); fRec19[0] = ((fConst7 * (fRec2[1] + fRec2[2])) + (fConst6 * fRec19[1]));
fRec23[0] = ((fConst7 * (fRec6[1] + fRec6[2])) + (fConst6 * fRec23[1])); fRec18[0] = ((fSlow29 * (fRec2[1] + (fSlow28 * fRec19[0]))) + (fSlow27 * fRec18[1]));
fRec22[0] = ((fSlow38 * (fRec6[1] + (fSlow37 * fRec23[0]))) + (fSlow36 * fRec22[1])); fVec4[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec18[0]));
fVec6[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec22[0])); float fTemp4 = (fVec4[(IOTA-iConst19)&8191] - (fTemp0 + (0.6f * fRec16[1])));
float fTemp5 = (fVec6[(IOTA-iConst24)&8191] - (fTemp0 + (0.6f * fRec20[1]))); fVec5[IOTA&2047] = fTemp4;
fVec7[IOTA&1023] = fTemp5; fRec16[0] = fVec5[(IOTA-iConst20)&2047];
fRec20[0] = fVec7[(IOTA-iConst25)&1023]; float fRec17 = (0.6f * fVec5[IOTA&2047]);
float fRec21 = (0.6f * fVec7[IOTA&1023]); fRec23[0] = ((fConst7 * (fRec6[1] + fRec6[2])) + (fConst6 * fRec23[1]));
float fTemp6 = (fRec21 + (fRec17 + fTemp3)); fRec22[0] = ((fSlow38 * (fRec6[1] + (fSlow37 * fRec23[0]))) + (fSlow36 * fRec22[1]));
fRec27[0] = ((fConst7 * (fRec1[1] + fRec1[2])) + (fConst6 * fRec27[1])); fVec6[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec22[0]));
fRec26[0] = ((fSlow47 * (fRec1[1] + (fSlow46 * fRec27[0]))) + (fSlow45 * fRec26[1])); float fTemp5 = (fVec6[(IOTA-iConst24)&8191] - (fTemp0 + (0.6f * fRec20[1])));
fVec8[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec26[0])); fVec7[IOTA&1023] = fTemp5;
float fTemp7 = (0.3f * (float)input1[i]); fRec20[0] = fVec7[(IOTA-iConst25)&1023];
float fTemp8 = ((fTemp7 + fVec8[(IOTA-iConst29)&16383]) + (0.6f * fRec24[1])); float fRec21 = (0.6f * fVec7[IOTA&1023]);
fVec9[IOTA&2047] = fTemp8; float fTemp6 = (fRec21 + (fRec17 + fTemp3));
fRec24[0] = fVec9[(IOTA-iConst30)&2047]; fRec27[0] = ((fConst7 * (fRec1[1] + fRec1[2])) + (fConst6 * fRec27[1]));
float fRec25 = (0 - (0.6f * fVec9[IOTA&2047])); fRec26[0] = ((fSlow47 * (fRec1[1] + (fSlow46 * fRec27[0]))) + (fSlow45 * fRec26[1]));
fRec31[0] = ((fConst7 * (fRec5[1] + fRec5[2])) + (fConst6 * fRec31[1])); fVec8[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec26[0]));
fRec30[0] = ((fSlow56 * (fRec5[1] + (fSlow55 * fRec31[0]))) + (fSlow54 * fRec30[1])); float fTemp7 = (0.3f * (float)input1[i]);
fVec10[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec30[0])); float fTemp8 = ((fTemp7 + fVec8[(IOTA-iConst29)&16383]) + (0.6f * fRec24[1]));
float fTemp9 = ((fTemp7 + fVec10[(IOTA-iConst34)&8191]) + (0.6f * fRec28[1])); fVec9[IOTA&2047] = fTemp8;
fVec11[IOTA&2047] = fTemp9; fRec24[0] = fVec9[(IOTA-iConst30)&2047];
fRec28[0] = fVec11[(IOTA-iConst35)&2047]; float fRec25 = (0 - (0.6f * fVec9[IOTA&2047]));
float fRec29 = (0 - (0.6f * fVec11[IOTA&2047])); fRec31[0] = ((fConst7 * (fRec5[1] + fRec5[2])) + (fConst6 * fRec31[1]));
fRec35[0] = ((fConst7 * (fRec3[1] + fRec3[2])) + (fConst6 * fRec35[1])); fRec30[0] = ((fSlow56 * (fRec5[1] + (fSlow55 * fRec31[0]))) + (fSlow54 * fRec30[1]));
fRec34[0] = ((fSlow65 * (fRec3[1] + (fSlow64 * fRec35[0]))) + (fSlow63 * fRec34[1])); fVec10[IOTA&8191] = (1e-20f + (0.35355339059327373f * fRec30[0]));
fVec12[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec34[0])); float fTemp9 = ((fTemp7 + fVec10[(IOTA-iConst34)&8191]) + (0.6f * fRec28[1]));
float fTemp10 = ((fVec12[(IOTA-iConst39)&16383] + (0.6f * fRec32[1])) - fTemp7); fVec11[IOTA&2047] = fTemp9;
fVec13[IOTA&2047] = fTemp10; fRec28[0] = fVec11[(IOTA-iConst35)&2047];
fRec32[0] = fVec13[(IOTA-iConst40)&2047]; float fRec29 = (0 - (0.6f * fVec11[IOTA&2047]));
float fRec33 = (0 - (0.6f * fVec13[IOTA&2047])); fRec35[0] = ((fConst7 * (fRec3[1] + fRec3[2])) + (fConst6 * fRec35[1]));
fRec39[0] = ((fConst7 * (fRec7[1] + fRec7[2])) + (fConst6 * fRec39[1])); fRec34[0] = ((fSlow65 * (fRec3[1] + (fSlow64 * fRec35[0]))) + (fSlow63 * fRec34[1]));
fRec38[0] = ((fSlow74 * (fRec7[1] + (fSlow73 * fRec39[0]))) + (fSlow72 * fRec38[1])); fVec12[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec34[0]));
fVec14[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec38[0])); float fTemp10 = ((fVec12[(IOTA-iConst39)&16383] + (0.6f * fRec32[1])) - fTemp7);
float fTemp11 = ((fVec14[(IOTA-iConst44)&16383] + (0.6f * fRec36[1])) - fTemp7); fVec13[IOTA&2047] = fTemp10;
fVec15[IOTA&1023] = fTemp11; fRec32[0] = fVec13[(IOTA-iConst40)&2047];
fRec36[0] = fVec15[(IOTA-iConst45)&1023]; float fRec33 = (0 - (0.6f * fVec13[IOTA&2047]));
float fRec37 = (0 - (0.6f * fVec15[IOTA&1023])); fRec39[0] = ((fConst7 * (fRec7[1] + fRec7[2])) + (fConst6 * fRec39[1]));
fRec0[0] = (fRec12[1] + (fRec8[1] + (fRec16[1] + (fRec20[1] + (fRec24[1] + (fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + (fRec29 + (fRec25 + fTemp6)))))))))))); fRec38[0] = ((fSlow74 * (fRec7[1] + (fSlow73 * fRec39[0]))) + (fSlow72 * fRec38[1]));
fRec1[0] = (0 - ((fRec24[1] + (fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + (fRec25 + fRec29))))))) - (fRec12[1] + (fRec8[1] + (fRec16[1] + (fRec20[1] + fTemp6)))))); fVec14[IOTA&16383] = (1e-20f + (0.35355339059327373f * fRec38[0]));
float fTemp12 = (fRec17 + fRec21); float fTemp11 = ((fVec14[(IOTA-iConst44)&16383] + (0.6f * fRec36[1])) - fTemp7);
fRec2[0] = (0 - ((fRec16[1] + (fRec20[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + fTemp12)))))) - (fRec12[1] + (fRec8[1] + (fRec24[1] + (fRec28[1] + (fRec29 + (fRec25 + fTemp3)))))))); fVec15[IOTA&1023] = fTemp11;
fRec3[0] = (0 - ((fRec16[1] + (fRec20[1] + (fRec24[1] + (fRec28[1] + (fRec29 + (fRec25 + fTemp12)))))) - (fRec12[1] + (fRec8[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + fTemp3)))))))); fRec36[0] = fVec15[(IOTA-iConst45)&1023];
float fTemp13 = (fRec13 + fRec17); float fRec37 = (0 - (0.6f * fVec15[IOTA&1023]));
float fTemp14 = (fRec9 + fRec21); fRec0[0] = (fRec12[1] + (fRec8[1] + (fRec16[1] + (fRec20[1] + (fRec24[1] + (fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + (fRec29 + (fRec25 + fTemp6))))))))))));
fRec4[0] = (0 - ((fRec8[1] + (fRec20[1] + (fRec28[1] + (fRec36[1] + (fRec37 + (fRec29 + fTemp14)))))) - (fRec12[1] + (fRec16[1] + (fRec24[1] + (fRec32[1] + (fRec33 + (fRec25 + fTemp13)))))))); fRec1[0] = (0 - ((fRec24[1] + (fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + (fRec25 + fRec29))))))) - (fRec12[1] + (fRec8[1] + (fRec16[1] + (fRec20[1] + fTemp6))))));
fRec5[0] = (0 - ((fRec8[1] + (fRec20[1] + (fRec24[1] + (fRec32[1] + (fRec33 + (fRec25 + fTemp14)))))) - (fRec12[1] + (fRec16[1] + (fRec28[1] + (fRec36[1] + (fRec37 + (fRec29 + fTemp13)))))))); float fTemp12 = (fRec17 + fRec21);
float fTemp15 = (fRec13 + fRec21); fRec2[0] = (0 - ((fRec16[1] + (fRec20[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + fTemp12)))))) - (fRec12[1] + (fRec8[1] + (fRec24[1] + (fRec28[1] + (fRec29 + (fRec25 + fTemp3))))))));
float fTemp16 = (fRec9 + fRec17); fRec3[0] = (0 - ((fRec16[1] + (fRec20[1] + (fRec24[1] + (fRec28[1] + (fRec29 + (fRec25 + fTemp12)))))) - (fRec12[1] + (fRec8[1] + (fRec32[1] + (fRec36[1] + (fRec37 + (fRec33 + fTemp3))))))));
fRec6[0] = (0 - ((fRec8[1] + (fRec16[1] + (fRec28[1] + (fRec32[1] + (fRec33 + (fRec29 + fTemp16)))))) - (fRec12[1] + (fRec20[1] + (fRec24[1] + (fRec36[1] + (fRec37 + (fRec25 + fTemp15)))))))); float fTemp13 = (fRec13 + fRec17);
fRec7[0] = (0 - ((fRec8[1] + (fRec16[1] + (fRec24[1] + (fRec36[1] + (fRec37 + (fRec25 + fTemp16)))))) - (fRec12[1] + (fRec20[1] + (fRec28[1] + (fRec32[1] + (fRec33 + (fRec29 + fTemp15)))))))); float fTemp14 = (fRec9 + fRec21);
fRec4[0] = (0 - ((fRec8[1] + (fRec20[1] + (fRec28[1] + (fRec36[1] + (fRec37 + (fRec29 + fTemp14)))))) - (fRec12[1] + (fRec16[1] + (fRec24[1] + (fRec32[1] + (fRec33 + (fRec25 + fTemp13))))))));
fRec5[0] = (0 - ((fRec8[1] + (fRec20[1] + (fRec24[1] + (fRec32[1] + (fRec33 + (fRec25 + fTemp14)))))) - (fRec12[1] + (fRec16[1] + (fRec28[1] + (fRec36[1] + (fRec37 + (fRec29 + fTemp13))))))));
float reverb0 = (float)(0.37f * (fRec1[0] + fRec2[0])); float fTemp15 = (fRec13 + fRec21);
float reverb1 = (float)(0.37f * (fRec1[0] - fRec2[0])); float fTemp16 = (fRec9 + fRec17);
fRec6[0] = (0 - ((fRec8[1] + (fRec16[1] + (fRec28[1] + (fRec32[1] + (fRec33 + (fRec29 + fTemp16)))))) - (fRec12[1] + (fRec20[1] + (fRec24[1] + (fRec36[1] + (fRec37 + (fRec25 + fTemp15))))))));
output0[i] = (input0[i] * (1-_dryWet)) + (reverb0 * _dryWet ); fRec7[0] = (0 - ((fRec8[1] + (fRec16[1] + (fRec24[1] + (fRec36[1] + (fRec37 + (fRec25 + fTemp16)))))) - (fRec12[1] + (fRec20[1] + (fRec28[1] + (fRec32[1] + (fRec33 + (fRec29 + fTemp15))))))));
output1[i] = (input1[i] * (1-_dryWet)) + (reverb1 * _dryWet );
// post processing float reverb0 = (float)(0.37f * (fRec1[0] + fRec2[0]));
fRec7[2] = fRec7[1]; fRec7[1] = fRec7[0]; float reverb1 = (float)(0.37f * (fRec1[0] - fRec2[0]));
fRec6[2] = fRec6[1]; fRec6[1] = fRec6[0];
fRec5[2] = fRec5[1]; fRec5[1] = fRec5[0]; output0[i] = (input0[i] * (1-_dryWet)) + (reverb0 * _dryWet );
fRec4[2] = fRec4[1]; fRec4[1] = fRec4[0]; output1[i] = (input1[i] * (1-_dryWet)) + (reverb1 * _dryWet );
fRec3[2] = fRec3[1]; fRec3[1] = fRec3[0];
fRec2[2] = fRec2[1]; fRec2[1] = fRec2[0]; // post processing
fRec1[2] = fRec1[1]; fRec1[1] = fRec1[0]; fRec7[2] = fRec7[1];
fRec0[2] = fRec0[1]; fRec0[1] = fRec0[0]; fRec7[1] = fRec7[0];
fRec36[1] = fRec36[0]; fRec6[2] = fRec6[1];
fRec38[1] = fRec38[0]; fRec6[1] = fRec6[0];
fRec39[1] = fRec39[0]; fRec5[2] = fRec5[1];
fRec32[1] = fRec32[0]; fRec5[1] = fRec5[0];
fRec34[1] = fRec34[0]; fRec4[2] = fRec4[1];
fRec35[1] = fRec35[0]; fRec4[1] = fRec4[0];
fRec28[1] = fRec28[0]; fRec3[2] = fRec3[1];
fRec30[1] = fRec30[0]; fRec3[1] = fRec3[0];
fRec31[1] = fRec31[0]; fRec2[2] = fRec2[1];
fRec24[1] = fRec24[0]; fRec2[1] = fRec2[0];
fRec26[1] = fRec26[0]; fRec1[2] = fRec1[1];
fRec27[1] = fRec27[0]; fRec1[1] = fRec1[0];
fRec20[1] = fRec20[0]; fRec0[2] = fRec0[1];
fRec22[1] = fRec22[0]; fRec0[1] = fRec0[0];
fRec23[1] = fRec23[0]; fRec36[1] = fRec36[0];
fRec16[1] = fRec16[0]; fRec38[1] = fRec38[0];
fRec18[1] = fRec18[0]; fRec39[1] = fRec39[0];
fRec19[1] = fRec19[0]; fRec32[1] = fRec32[0];
fRec12[1] = fRec12[0]; fRec34[1] = fRec34[0];
fRec14[1] = fRec14[0]; fRec35[1] = fRec35[0];
fRec15[1] = fRec15[0]; fRec28[1] = fRec28[0];
fRec8[1] = fRec8[0]; fRec30[1] = fRec30[0];
IOTA = IOTA+1; fRec31[1] = fRec31[0];
fRec10[1] = fRec10[0]; fRec24[1] = fRec24[0];
fRec11[1] = fRec11[0]; fRec26[1] = fRec26[0];
} fRec27[1] = fRec27[0];
} fRec20[1] = fRec20[0];
fRec22[1] = fRec22[0];
private: fRec23[1] = fRec23[0];
float _dryWet; fRec16[1] = fRec16[0];
float _rt60; fRec18[1] = fRec18[0];
int iConst0; fRec19[1] = fRec19[0];
float fConst1; fRec12[1] = fRec12[0];
float fConst2; fRec14[1] = fRec14[0];
float _damping; fRec15[1] = fRec15[0];
float fConst3; fRec8[1] = fRec8[0];
float fConst4; IOTA = IOTA+1;
float fConst5; fRec10[1] = fRec10[0];
float fConst6; fRec11[1] = fRec11[0];
float fConst7; }
float fRec11[2]; }
float fRec10[2];
int IOTA; private:
float fVec0[8192]; float _dryWet;
float fConst8; float _rt60;
int iConst9; int iConst0;
float fVec1[2048]; float fConst1;
int iConst10; float fConst2;
float fRec8[2]; float _damping;
float fConst11; float fConst3;
float fConst12; float fConst4;
float fRec15[2]; float fConst5;
float fRec14[2]; float fConst6;
float fVec2[8192]; float fConst7;
float fConst13; float fRec11[2];
int iConst14; float fRec10[2];
float fVec3[1024]; int IOTA;
int iConst15; float fVec0[8192];
float fRec12[2]; float fConst8;
float fConst16; int iConst9;
float fConst17; float fVec1[2048];
float fRec19[2]; int iConst10;
float fRec18[2]; float fRec8[2];
float fVec4[8192]; float fConst11;
float fConst18; float fConst12;
int iConst19; float fRec15[2];
float fVec5[2048]; float fRec14[2];
int iConst20; float fVec2[8192];
float fRec16[2]; float fConst13;
float fConst21; int iConst14;
float fConst22; float fVec3[1024];
float fRec23[2]; int iConst15;
float fRec22[2]; float fRec12[2];
float fVec6[8192]; float fConst16;
float fConst23; float fConst17;
int iConst24; float fRec19[2];
float fVec7[1024]; float fRec18[2];
int iConst25; float fVec4[8192];
float fRec20[2]; float fConst18;
float fConst26; int iConst19;
float fConst27; float fVec5[2048];
float fRec27[2]; int iConst20;
float fRec26[2]; float fRec16[2];
float fVec8[16384]; float fConst21;
float fConst28; float fConst22;
int iConst29; float fRec23[2];
float fVec9[2048]; float fRec22[2];
int iConst30; float fVec6[8192];
float fRec24[2]; float fConst23;
float fConst31; int iConst24;
float fConst32; float fVec7[1024];
float fRec31[2]; int iConst25;
float fRec30[2]; float fRec20[2];
float fVec10[8192]; float fConst26;
float fConst33; float fConst27;
int iConst34; float fRec27[2];
float fVec11[2048]; float fRec26[2];
int iConst35; float fVec8[16384];
float fRec28[2]; float fConst28;
float fConst36; int iConst29;
float fConst37; float fVec9[2048];
float fRec35[2]; int iConst30;
float fRec34[2]; float fRec24[2];
float fVec12[16384]; float fConst31;
float fConst38; float fConst32;
int iConst39; float fRec31[2];
float fVec13[2048]; float fRec30[2];
int iConst40; float fVec10[8192];
float fRec32[2]; float fConst33;
float fConst41; int iConst34;
float fConst42; float fVec11[2048];
float fRec39[2]; int iConst35;
float fRec38[2]; float fRec28[2];
float fVec14[16384]; float fConst36;
float fConst43; float fConst37;
int iConst44; float fRec35[2];
float fVec15[1024]; float fRec34[2];
int iConst45; float fVec12[16384];
float fRec36[2]; float fConst38;
float fRec0[3]; int iConst39;
float fRec1[3]; float fVec13[2048];
float fRec2[3]; int iConst40;
float fRec3[3]; float fRec32[2];
float fRec4[3]; float fConst41;
float fRec5[3]; float fConst42;
float fRec6[3]; float fRec39[2];
float fRec7[3]; float fRec38[2];
float fVec14[16384];
/// Long nasty function setting initial values float fConst43;
void init(int samplingFreq) int iConst44;
{ float fVec15[1024];
// wet by default! int iConst45;
_dryWet = 1; float fRec36[2];
float fRec0[3];
_rt60 = 5.0f; float fRec1[3];
iConst0 = min(192000, max(1, samplingFreq)); float fRec2[3];
fConst1 = floorf((0.5f + (0.174713f * iConst0))); float fRec3[3];
fConst2 = ((0 - (6.907755278982138f * fConst1)) / iConst0); float fRec4[3];
_damping = 10000.f; float fRec5[3];
fConst3 = (6.283185307179586f / float(iConst0)); float fRec6[3];
fConst4 = (1.0f / tanf((1256.6370614359173f / iConst0))); float fRec7[3];
fConst5 = (1 + fConst4);
fConst6 = (0 - ((1 - fConst4) / fConst5)); /// Long nasty function setting initial values
fConst7 = (1.0f / fConst5); void init(int samplingFreq)
for (int i=0; i<2; i++) fRec11[i] = 0; {
for (int i=0; i<2; i++) fRec10[i] = 0; // wet by default!
IOTA = 0; _dryWet = 1;
for (int i=0; i<8192; i++) fVec0[i] = 0;
fConst8 = floorf((0.5f + (0.022904f * iConst0))); _rt60 = 5.0f;
iConst9 = int((int((fConst1 - fConst8)) & 8191)); iConst0 = min(192000, max(1, samplingFreq));
for (int i=0; i<2048; i++) fVec1[i] = 0; fConst1 = floorf((0.5f + (0.174713f * iConst0)));
iConst10 = int((int((fConst8 - 1)) & 2047)); fConst2 = ((0 - (6.907755278982138f * fConst1)) / iConst0);
for (int i=0; i<2; i++) fRec8[i] = 0; _damping = 10000.f;
fConst11 = floorf((0.5f + (0.153129f * iConst0))); fConst3 = (6.283185307179586f / float(iConst0));
fConst12 = ((0 - (6.907755278982138f * fConst11)) / iConst0); fConst4 = (1.0f / tanf((1256.6370614359173f / iConst0)));
for (int i=0; i<2; i++) fRec15[i] = 0; fConst5 = (1 + fConst4);
for (int i=0; i<2; i++) fRec14[i] = 0; fConst6 = (0 - ((1 - fConst4) / fConst5));
for (int i=0; i<8192; i++) fVec2[i] = 0; fConst7 = (1.0f / fConst5);
fConst13 = floorf((0.5f + (0.020346f * iConst0))); for (int i=0; i<2; i++) fRec11[i] = 0;
iConst14 = int((int((fConst11 - fConst13)) & 8191)); for (int i=0; i<2; i++) fRec10[i] = 0;
for (int i=0; i<1024; i++) fVec3[i] = 0; IOTA = 0;
iConst15 = int((int((fConst13 - 1)) & 1023)); for (int i=0; i<8192; i++) fVec0[i] = 0;
for (int i=0; i<2; i++) fRec12[i] = 0; fConst8 = floorf((0.5f + (0.022904f * iConst0)));
fConst16 = floorf((0.5f + (0.127837f * iConst0))); iConst9 = int((int((fConst1 - fConst8)) & 8191));
fConst17 = ((0 - (6.907755278982138f * fConst16)) / iConst0); for (int i=0; i<2048; i++) fVec1[i] = 0;
for (int i=0; i<2; i++) fRec19[i] = 0; iConst10 = int((int((fConst8 - 1)) & 2047));
for (int i=0; i<2; i++) fRec18[i] = 0; for (int i=0; i<2; i++) fRec8[i] = 0;
for (int i=0; i<8192; i++) fVec4[i] = 0; fConst11 = floorf((0.5f + (0.153129f * iConst0)));
fConst18 = floorf((0.5f + (0.031604f * iConst0))); fConst12 = ((0 - (6.907755278982138f * fConst11)) / iConst0);
iConst19 = int((int((fConst16 - fConst18)) & 8191)); for (int i=0; i<2; i++) fRec15[i] = 0;
for (int i=0; i<2048; i++) fVec5[i] = 0; for (int i=0; i<2; i++) fRec14[i] = 0;
iConst20 = int((int((fConst18 - 1)) & 2047)); for (int i=0; i<8192; i++) fVec2[i] = 0;
for (int i=0; i<2; i++) fRec16[i] = 0; fConst13 = floorf((0.5f + (0.020346f * iConst0)));
fConst21 = floorf((0.5f + (0.125f * iConst0))); iConst14 = int((int((fConst11 - fConst13)) & 8191));
fConst22 = ((0 - (6.907755278982138f * fConst21)) / iConst0); for (int i=0; i<1024; i++) fVec3[i] = 0;
for (int i=0; i<2; i++) fRec23[i] = 0; iConst15 = int((int((fConst13 - 1)) & 1023));
for (int i=0; i<2; i++) fRec22[i] = 0; for (int i=0; i<2; i++) fRec12[i] = 0;
for (int i=0; i<8192; i++) fVec6[i] = 0; fConst16 = floorf((0.5f + (0.127837f * iConst0)));
fConst23 = floorf((0.5f + (0.013458f * iConst0))); fConst17 = ((0 - (6.907755278982138f * fConst16)) / iConst0);
iConst24 = int((int((fConst21 - fConst23)) & 8191)); for (int i=0; i<2; i++) fRec19[i] = 0;
for (int i=0; i<1024; i++) fVec7[i] = 0; for (int i=0; i<2; i++) fRec18[i] = 0;
iConst25 = int((int((fConst23 - 1)) & 1023)); for (int i=0; i<8192; i++) fVec4[i] = 0;
for (int i=0; i<2; i++) fRec20[i] = 0; fConst18 = floorf((0.5f + (0.031604f * iConst0)));
fConst26 = floorf((0.5f + (0.210389f * iConst0))); iConst19 = int((int((fConst16 - fConst18)) & 8191));
fConst27 = ((0 - (6.907755278982138f * fConst26)) / iConst0); for (int i=0; i<2048; i++) fVec5[i] = 0;
for (int i=0; i<2; i++) fRec27[i] = 0; iConst20 = int((int((fConst18 - 1)) & 2047));
for (int i=0; i<2; i++) fRec26[i] = 0; for (int i=0; i<2; i++) fRec16[i] = 0;
for (int i=0; i<16384; i++) fVec8[i] = 0; fConst21 = floorf((0.5f + (0.125f * iConst0)));
fConst28 = floorf((0.5f + (0.024421f * iConst0))); fConst22 = ((0 - (6.907755278982138f * fConst21)) / iConst0);
iConst29 = int((int((fConst26 - fConst28)) & 16383)); for (int i=0; i<2; i++) fRec23[i] = 0;
for (int i=0; i<2048; i++) fVec9[i] = 0; for (int i=0; i<2; i++) fRec22[i] = 0;
iConst30 = int((int((fConst28 - 1)) & 2047)); for (int i=0; i<8192; i++) fVec6[i] = 0;
for (int i=0; i<2; i++) fRec24[i] = 0; fConst23 = floorf((0.5f + (0.013458f * iConst0)));
fConst31 = floorf((0.5f + (0.192303f * iConst0))); iConst24 = int((int((fConst21 - fConst23)) & 8191));
fConst32 = ((0 - (6.907755278982138f * fConst31)) / iConst0); for (int i=0; i<1024; i++) fVec7[i] = 0;
for (int i=0; i<2; i++) fRec31[i] = 0; iConst25 = int((int((fConst23 - 1)) & 1023));
for (int i=0; i<2; i++) fRec30[i] = 0; for (int i=0; i<2; i++) fRec20[i] = 0;
for (int i=0; i<8192; i++) fVec10[i] = 0; fConst26 = floorf((0.5f + (0.210389f * iConst0)));
fConst33 = floorf((0.5f + (0.029291f * iConst0))); fConst27 = ((0 - (6.907755278982138f * fConst26)) / iConst0);
iConst34 = int((int((fConst31 - fConst33)) & 8191)); for (int i=0; i<2; i++) fRec27[i] = 0;
for (int i=0; i<2048; i++) fVec11[i] = 0; for (int i=0; i<2; i++) fRec26[i] = 0;
iConst35 = int((int((fConst33 - 1)) & 2047)); for (int i=0; i<16384; i++) fVec8[i] = 0;
for (int i=0; i<2; i++) fRec28[i] = 0; fConst28 = floorf((0.5f + (0.024421f * iConst0)));
fConst36 = floorf((0.5f + (0.256891f * iConst0))); iConst29 = int((int((fConst26 - fConst28)) & 16383));
fConst37 = ((0 - (6.907755278982138f * fConst36)) / iConst0); for (int i=0; i<2048; i++) fVec9[i] = 0;
for (int i=0; i<2; i++) fRec35[i] = 0; iConst30 = int((int((fConst28 - 1)) & 2047));
for (int i=0; i<2; i++) fRec34[i] = 0; for (int i=0; i<2; i++) fRec24[i] = 0;
for (int i=0; i<16384; i++) fVec12[i] = 0; fConst31 = floorf((0.5f + (0.192303f * iConst0)));
fConst38 = floorf((0.5f + (0.027333f * iConst0))); fConst32 = ((0 - (6.907755278982138f * fConst31)) / iConst0);
iConst39 = int((int((fConst36 - fConst38)) & 16383)); for (int i=0; i<2; i++) fRec31[i] = 0;
for (int i=0; i<2048; i++) fVec13[i] = 0; for (int i=0; i<2; i++) fRec30[i] = 0;
iConst40 = int((int((fConst38 - 1)) & 2047)); for (int i=0; i<8192; i++) fVec10[i] = 0;
for (int i=0; i<2; i++) fRec32[i] = 0; fConst33 = floorf((0.5f + (0.029291f * iConst0)));
fConst41 = floorf((0.5f + (0.219991f * iConst0))); iConst34 = int((int((fConst31 - fConst33)) & 8191));
fConst42 = ((0 - (6.907755278982138f * fConst41)) / iConst0); for (int i=0; i<2048; i++) fVec11[i] = 0;
for (int i=0; i<2; i++) fRec39[i] = 0; iConst35 = int((int((fConst33 - 1)) & 2047));
for (int i=0; i<2; i++) fRec38[i] = 0; for (int i=0; i<2; i++) fRec28[i] = 0;
for (int i=0; i<16384; i++) fVec14[i] = 0; fConst36 = floorf((0.5f + (0.256891f * iConst0)));
fConst43 = floorf((0.5f + (0.019123f * iConst0))); fConst37 = ((0 - (6.907755278982138f * fConst36)) / iConst0);
iConst44 = int((int((fConst41 - fConst43)) & 16383)); for (int i=0; i<2; i++) fRec35[i] = 0;
for (int i=0; i<1024; i++) fVec15[i] = 0; for (int i=0; i<2; i++) fRec34[i] = 0;
iConst45 = int((int((fConst43 - 1)) & 1023)); for (int i=0; i<16384; i++) fVec12[i] = 0;
for (int i=0; i<2; i++) fRec36[i] = 0; fConst38 = floorf((0.5f + (0.027333f * iConst0)));
for (int i=0; i<3; i++) fRec0[i] = 0; iConst39 = int((int((fConst36 - fConst38)) & 16383));
for (int i=0; i<3; i++) fRec1[i] = 0; for (int i=0; i<2048; i++) fVec13[i] = 0;
for (int i=0; i<3; i++) fRec2[i] = 0; iConst40 = int((int((fConst38 - 1)) & 2047));
for (int i=0; i<3; i++) fRec3[i] = 0; for (int i=0; i<2; i++) fRec32[i] = 0;
for (int i=0; i<3; i++) fRec4[i] = 0; fConst41 = floorf((0.5f + (0.219991f * iConst0)));
for (int i=0; i<3; i++) fRec5[i] = 0; fConst42 = ((0 - (6.907755278982138f * fConst41)) / iConst0);
for (int i=0; i<3; i++) fRec6[i] = 0; for (int i=0; i<2; i++) fRec39[i] = 0;
for (int i=0; i<3; i++) fRec7[i] = 0; for (int i=0; i<2; i++) fRec38[i] = 0;
} for (int i=0; i<16384; i++) fVec14[i] = 0;
fConst43 = floorf((0.5f + (0.019123f * iConst0)));
iConst44 = int((int((fConst41 - fConst43)) & 16383));
for (int i=0; i<1024; i++) fVec15[i] = 0;
iConst45 = int((int((fConst43 - 1)) & 1023));
for (int i=0; i<2; i++) fRec36[i] = 0;
for (int i=0; i<3; i++) fRec0[i] = 0;
for (int i=0; i<3; i++) fRec1[i] = 0;
for (int i=0; i<3; i++) fRec2[i] = 0;
for (int i=0; i<3; i++) fRec3[i] = 0;
for (int i=0; i<3; i++) fRec4[i] = 0;
for (int i=0; i<3; i++) fRec5[i] = 0;
for (int i=0; i<3; i++) fRec6[i] = 0;
for (int i=0; i<3; i++) fRec7[i] = 0;
}
}; };
#endif // OPENAV_DSP_REVERB_H #endif // OPENAV_DSP_REVERB_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -22,84 +22,77 @@
#include <cmath> #include <cmath>
SidechainGain::SidechainGain(int rate) : SidechainGain::SidechainGain(int rate) :
/// initial control values /// initial control values
controlThreshold(0.2), controlThreshold(0.2),
controlReduction(1), controlReduction(1),
controlReleaseTime(0.5), controlReleaseTime(0.5),
/// filter state init /// filter state init
w(10.0f / (rate * 0.02)), w(10.0f / (rate * 0.02)),
a(0.07f), a(0.07f),
b(1.0f / (1.0f - a)), b(1.0f / (1.0f - a)),
g1(0.0f), g1(0.0f),
g2(0.0f), g2(0.0f),
peakFrameCounter(0), peakFrameCounter(0),
peakCountDuration( rate / 4 ), peakCountDuration( rate / 4 ),
currentTarget(0) currentTarget(0)
{ {
} }
void SidechainGain::process(unsigned int n_samples, float** inputs, float** outputs) void SidechainGain::process(unsigned int n_samples, float** inputs, float** outputs)
{ {
/// audio inputs /// audio inputs
float* inL = inputs[0]; float* inL = inputs[0];
float* inR = inputs[1]; float* inR = inputs[1];
float* side = inputs[2]; float* side = inputs[2];
float* outL = outputs[0]; float* outL = outputs[0];
float* outR = outputs[1]; float* outR = outputs[1];
/// control inputs /// control inputs
float threshold = controlThreshold; float threshold = controlThreshold;
float reduction = controlReduction; float reduction = controlReduction;
float releaseTime = controlReleaseTime; float releaseTime = controlReleaseTime;
/// analyse sidechain input for peak /// analyse sidechain input for peak
float sum = 0.f; float sum = 0.f;
for( unsigned int i = 0; i < n_samples; i++ ) for( unsigned int i = 0; i < n_samples; i++ ) {
{ if ( *side > 0.000001 )
if ( *side > 0.000001 ) sum += *side++;
sum += *side++; else
else sum += -*side++;
sum += -*side++; }
}
currentTarget = 0.f;
currentTarget = 0.f;
/// check for peak level (offset to avoid "always on" peak)
/// check for peak level (offset to avoid "always on" peak) if ( sum / n_samples > threshold + 0.05 ) {
if ( sum / n_samples > threshold + 0.05 ) peakFrameCounter = peakCountDuration * releaseTime;
{ currentTarget = 1.f - reduction;
peakFrameCounter = peakCountDuration * releaseTime; } else if ( peakFrameCounter < 0 ) {
currentTarget = 1.f - reduction; currentTarget = 1.f;
} } else {
else if ( peakFrameCounter < 0 ) currentTarget = 1.f - reduction;
{ }
currentTarget = 1.f;
} if ( currentTarget < 0.f )
else currentTarget = 0.f;
{
currentTarget = 1.f - reduction; peakFrameCounter -= n_samples;
}
for( unsigned int i = 0; i < n_samples; i++ ) {
if ( currentTarget < 0.f ) /// smoothing algo is a lowpass, to de-zip the fades
currentTarget = 0.f; /// x^^4 approximates linear volume increase for human ears
g1 += w * ( pow ( currentTarget, 4.f ) - g1 - a * g2 - 1e-20f);
peakFrameCounter -= n_samples; g2 += w * (b * g1 - g2 + 1e-20f);
float gain = g2;
for( unsigned int i = 0; i < n_samples; i++ )
{ *outL++ = *inL++ * gain;
/// smoothing algo is a lowpass, to de-zip the fades *outR++ = *inR++ * gain;
/// x^^4 approximates linear volume increase for human ears }
g1 += w * ( pow ( currentTarget, 4.f ) - g1 - a * g2 - 1e-20f);
g2 += w * (b * g1 - g2 + 1e-20f); /// update output value
float gain = g2; controlSidechainAmp = currentTarget;
*outL++ = *inL++ * gain;
*outR++ = *inR++ * gain;
}
/// update output value
controlSidechainAmp = currentTarget;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -25,42 +25,51 @@
class SidechainGain class SidechainGain
{ {
public: public:
SidechainGain(int rate); SidechainGain(int rate);
~SidechainGain(){} ~SidechainGain() {}
void threshold(float t){controlThreshold = t;} void threshold(float t)
void reduction(float r){controlReduction = r;} {
void time (float t){controlReleaseTime = t;} controlThreshold = t;
}
void process(unsigned int n_samples, float** inputs, float** outputs); void reduction(float r)
{
private: controlReduction = r;
/// audio buffers }
float* audioInputL; void time (float t)
float* audioInputR; {
float* audioSidechain; controlReleaseTime = t;
float* audioOutputL; }
float* audioOutputR;
void process(unsigned int n_samples, float** inputs, float** outputs);
/// control signals
float controlThreshold; private:
float controlReduction; /// audio buffers
float controlReleaseTime; float* audioInputL;
float controlSidechainAmp; float* audioInputR;
float* audioSidechain;
/// filter state float* audioOutputL;
float w, a, b, g1, g2; float* audioOutputR;
/// last peak history /// control signals
bool nowIsAPeak; float controlThreshold;
long peakFrameCounter; float controlReduction;
float controlReleaseTime;
/// nframes available for countdown float controlSidechainAmp;
long peakCountDuration;
/// filter state
/// control output float w, a, b, g1, g2;
float currentTarget;
/// last peak history
bool nowIsAPeak;
long peakFrameCounter;
/// nframes available for countdown
long peakCountDuration;
/// control output
float currentTarget;
}; };
#endif // OPENAV_DSP_SIDECHAIN_GAIN_H #endif // OPENAV_DSP_SIDECHAIN_GAIN_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -42,46 +42,78 @@ const char* EventGridLaunchScene::prettyName = "grid:launch_scene";
EVENT_TYPE Event::getTypeFromName(const char* name) EVENT_TYPE Event::getTypeFromName(const char* name)
{ {
for(int i = 0; i < EVENT_TYPE_FINAL; i++) for(int i = 0; i < EVENT_TYPE_FINAL; i++) {
{ const char* tmp = getPrettyName(i);
const char* tmp = getPrettyName(i); if ( tmp ) {
if ( tmp ) if ( strcmp( name, tmp ) == 0 ) {
{ return (EVENT_TYPE)i;
if ( strcmp( name, tmp ) == 0 ) { }
return (EVENT_TYPE)i; }
} }
}
} return EVENT_NULL;
return EVENT_NULL;
} }
const char* Event::getPrettyName( int type ) const char* Event::getPrettyName( int type )
{ {
switch ( type ) switch ( type ) {
{ case MASTER_VOL: {
case MASTER_VOL:{ return EventMasterVol::prettyName; } return EventMasterVol::prettyName;
case MASTER_RETURN:{ return EventMasterReturn::prettyName; } }
case MASTER_INPUT_VOL:{ return EventMasterInputVol::prettyName; } case MASTER_RETURN: {
case MASTER_INPUT_TO:{ return EventMasterInputTo::prettyName; } return EventMasterReturn::prettyName;
case MASTER_INPUT_TO_ACTIVE:{ return EventMasterInputToActive::prettyName; } }
case MASTER_INPUT_VOL: {
case TRACK_VOLUME:{ return EventTrackVol::prettyName; } return EventMasterInputVol::prettyName;
case TRACK_SEND:{ return EventTrackSend::prettyName; } }
case TRACK_SEND_ACTIVE:{ return EventTrackSendActive::prettyName; } case MASTER_INPUT_TO: {
case TRACK_JACKSEND:{ return EventTrackJackSend::prettyName; } return EventMasterInputTo::prettyName;
case TRACK_JACKSEND_ACTIVATE:{ return EventTrackJackSendActivate::prettyName; } }
case TRACK_RECORD_ARM:{ return EventTrackRecordArm::prettyName; } case MASTER_INPUT_TO_ACTIVE: {
return EventMasterInputToActive::prettyName;
case TIME_BPM:{ return EventTimeBPM::prettyName; } }
case TIME_TEMPO_TAP:{ return EventTimeTempoTap::prettyName; }
case TRACK_VOLUME: {
case GRID_EVENT:{ return EventGridEvent::prettyName; } return EventTrackVol::prettyName;
case GRID_LAUNCH_SCENE:{ return EventGridLaunchScene::prettyName; } }
case TRACK_SEND: {
case METRONOME_ACTIVE:{ return EventMetronomeActive::prettyName; } return EventTrackSend::prettyName;
case METRONOME_VOLUME:{ return EventMetronomeVolume::prettyName; } }
case TRACK_SEND_ACTIVE: {
default: return 0; return EventTrackSendActive::prettyName;
} }
case TRACK_JACKSEND: {
return EventTrackJackSend::prettyName;
}
case TRACK_JACKSEND_ACTIVATE: {
return EventTrackJackSendActivate::prettyName;
}
case TRACK_RECORD_ARM: {
return EventTrackRecordArm::prettyName;
}
case TIME_BPM: {
return EventTimeBPM::prettyName;
}
case TIME_TEMPO_TAP: {
return EventTimeTempoTap::prettyName;
}
case GRID_EVENT: {
return EventGridEvent::prettyName;
}
case GRID_LAUNCH_SCENE: {
return EventGridLaunchScene::prettyName;
}
case METRONOME_ACTIVE: {
return EventMetronomeActive::prettyName;
}
case METRONOME_VOLUME: {
return EventMetronomeVolume::prettyName;
}
default:
return 0;
}
} }

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -44,394 +44,447 @@ extern Jack* jack;
void handleDspEvents() void handleDspEvents()
{ {
uint availableRead = jack_ringbuffer_read_space( rbToDsp ); uint availableRead = jack_ringbuffer_read_space( rbToDsp );
while ( availableRead >= sizeof(EventBase) )
{
jack_ringbuffer_peek( rbToDsp, (char*)processDspMem, sizeof(EventBase) );
EventBase* e = (EventBase*)processDspMem;
// recheck the size against the actual event size
if ( availableRead >= e->size() )
{
// MIDI binding creation: sample the Event.
if( jack->bindingEventRecordEnable )
{
//printf("event %i\n", e->type() );
jack->bindingEventType = e->type();
const char* target = e->name();
if ( target )
{
EventControllerBindingTarget event( target );
writeToGuiRingbuffer( &event );
}
}
switch ( e->type() )
{
case Event::QUIT: {
if ( availableRead >= sizeof(EventQuit) ) {
EventQuit ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventQuit) );
jack->quit();
// we want to *quit* *fast*: remaining events don't matter!
return;
} break; }
// ======== TRANSPORT ==
case Event::TRANSPORT: {
if ( availableRead >= sizeof(EventTransportState) ) {
EventTransportState ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTransportState) );
jack->getTimeManager()->setTransportState( ev.ts );
} break; }
// ========= SAVE =====
case Event::STATE_SAVE: {
if ( availableRead >= sizeof(EventStateSave) ) {
EventStateSave ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateSave) );
jack->getState()->save();
} break; }
case Event::STATE_RESET: {
if ( availableRead >= sizeof(EventStateReset) ) {
EventStateReset ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateReset) );
jack->getState()->reset();
} break; }
case Event::STATE_SAVE_BUFFER: {
if ( availableRead >= sizeof(EventStateReset) ) {
EventStateSaveBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateSaveBuffer) );
printf("jack got save buffer in %d, %d\n", ev.track, ev.scene);
LooperClip* lc = jack->getLooper(ev.track)->getClip(ev.scene);
if(!lc) break;
EventStateSaveBuffer e;
e.track = ev.track;
e.scene = ev.scene;
e.ab = lc->getAudioBuffer();
e.no_dealloc = 1;
writeToGuiRingbuffer( &e );
} break; }
// ========= MASTER ===
case Event::MASTER_VOL: {
if ( availableRead >= sizeof(EventMasterVol) ) {
EventMasterVol ev(0);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterVol) );
jack->masterVolume( ev.vol );
} break; }
case Event::MASTER_RETURN: {
if ( availableRead >= sizeof(EventMasterReturn) ) {
EventMasterReturn ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterReturn) );
if ( ev.ret == RETURN_MAIN ) {
jack->returnVolume( ev.vol );
}
} break; }
case Event::MASTER_INPUT_VOL: {
if ( availableRead >= sizeof(EventMasterVol) ) {
EventMasterVol ev(0);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterVol) );
jack->getLogic()->masterInputVol( ev.vol );
} break; }
case Event::MASTER_INPUT_TO: {
if ( availableRead >= sizeof(EventMasterInputTo) ) {
EventMasterInputTo ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterInputTo) );
jack->bindingSend = ev.place;
jack->getLogic()->masterInputTo( ev.place, ev.value );
} break; }
case Event::MASTER_INPUT_TO_ACTIVE: {
if ( availableRead >= sizeof(EventMasterInputToActive) ) {
EventMasterInputToActive ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterInputToActive) );
jack->bindingSend = ev.place;
jack->bindingActive = ev.active;
jack->getLogic()->masterInputToActive( ev.place, ev.active );
} break; }
// ========= GRID =====
case Event::GRID_STATE: {
if ( availableRead >= sizeof(EventGridState) ) {
EventGridState ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridState) );
// clear clips in Controllers
if ( ev.state == GridLogic::STATE_EMPTY )
{
jack->getLooper( ev.track )->getClip( ev.scene )->init();
jack->getControllerUpdater()->setTrackSceneProgress(ev.track, ev.scene, 0 );
jack->getControllerUpdater()->setSceneState( ev.track, ev.scene, GridLogic::STATE_EMPTY );
}
} break; }
case Event::GRID_EVENT: {
if ( availableRead >= sizeof(EventGridEvent) ) {
EventGridEvent ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridEvent) );
jack->bindingTrack = ev.track;
jack->bindingScene = ev.scene;
if ( ev.pressed )
jack->getGridLogic()->pressed( ev.track, ev.scene );
else
jack->getGridLogic()->released( ev.track, ev.scene );
} break; }
case Event::GRID_LAUNCH_SCENE: {
EventGridLaunchScene ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridLaunchScene) );
jack->getGridLogic()->launchScene( ev.scene );
jack->bindingScene = ev.scene;
break; }
case Event::GRID_SELECT_CLIP_ENABLE: {
EventGridSelectClipEnable ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectClipEnable) );
jack->getGridLogic()->setSelectTrackScene( ev.enable );
break; }
case Event::GRID_SELECT_CLIP_EVENT: {
EventGridSelectClipEvent ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectClipEvent) );
jack->getGridLogic()->selectedTrackSceneEvent( ev.pressed );
break; }
case Event::GRID_SELECT_NEW_CHOSEN: {
EventGridSelectNewChosen ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectNewChosen) );
jack->getGridLogic()->specialScene( ev.track, ev.scene );
break; }
case Event::LOOPER_LOAD: {
if ( availableRead >= sizeof(EventLooperLoad) ) {
EventLooperLoad ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperLoad) );
jack->getGridLogic()->load( ev.track, ev.clip, (AudioBuffer*)ev.audioBuffer );
} break; }
case Event::METRONOME_ACTIVE: {
if ( availableRead >= sizeof(EventMetronomeActive) ) {
EventMetronomeActive ev(false);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMetronomeActive) );
jack->getLogic()->metronomeEnable(ev.active);
} break; }
case Event::METRONOME_VOLUME: {
if ( availableRead >= sizeof(EventMetronomeVolume) ) {
EventMetronomeVolume ev(false);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMetronomeVolume) );
LUPPP_NOTE("EventDSP: MetroVol %f", ev.vol );
jack->getMetronome()->setVolume(ev.vol);
} break; }
case Event::LOOPER_STATE: {
if ( availableRead >= sizeof(EventLooperState) ) {
EventLooperState ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperState) );
//jack->setLooperState( ev.track, ev.scene, ev.state );
} break; }
case Event::LOOPER_LOOP_LENGTH: {
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
EventLooperLoopLength ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperLoopLength) );
jack->getLogic()->looperClipLenght( ev.track, ev.scene, ev.beats );
} break; }
case Event::LOOPER_LOOP_USE_AS_TEMPO: {
if ( availableRead >= sizeof(EventLooperUseAsTempo) ) {
EventLooperUseAsTempo ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperUseAsTempo) );
jack->getLogic()->looperUseAsTempo( ev.track, ev.scene );
} break; }
case Event::TIME_BPM: {
if ( availableRead >= sizeof(EventTimeBPM) ) {
EventTimeBPM ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeBPM) );
jack->getTimeManager()->setBpm(ev.bpm);
} break; }
case Event::TIME_TEMPO_TAP: {
if ( availableRead >= sizeof(EventTimeTempoTap) ) {
EventTimeTempoTap ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeTempoTap) );
jack->getTimeManager()->tap();
} break; }
// ======== FX ===========
case Event::FX_REVERB: break;
/*{
if ( availableRead >= sizeof(EventFxReverb) ) {
EventFxReverb ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventFxReverb) );
// TODO implement reverb
break; }
}
*/
case Event::TRACK_VOLUME: {
if ( availableRead >= sizeof(EventTrackVol) ) {
EventTrackVol ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackVol) );
jack->getLogic()->trackVolume( ev.track, ev.vol );
jack->bindingTrack = ev.track;
break; }
}
case Event::TRACK_RECORD_ARM: {
if ( availableRead >= sizeof(EventTrackRecordArm) ) {
EventTrackRecordArm ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackRecordArm) );
jack->getLogic()->trackRecordArm( ev.track, ev.recordArm );
jack->bindingTrack = ev.track;
jack->bindingActive = ev.recordArm;
break; }
}
case Event::TRACK_SEND_ACTIVE: {
if ( availableRead >= sizeof(EventTrackSendActive) ) {
EventTrackSendActive ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackSendActive) );
jack->getLogic()->trackSendActive( ev.track, ev.send, ev.active );
jack->bindingTrack = ev.track;
jack->bindingSend = ev.send;
jack->bindingActive = ev.active;
} break; }
case Event::TRACK_JACKSEND_ACTIVATE: { while ( availableRead >= sizeof(EventBase) ) {
if ( availableRead >= sizeof(EventTrackJackSendActivate) ) { jack_ringbuffer_peek( rbToDsp, (char*)processDspMem, sizeof(EventBase) );
EventTrackJackSendActivate ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSendActivate) );
jack->getLogic()->trackJackSendActivate(ev.track,ev.active);
jack->bindingTrack = ev.track;
jack->bindingActive = ev.active; EventBase* e = (EventBase*)processDspMem;
} break; }
case Event::TRACK_JACKSEND: { // recheck the size against the actual event size
if ( availableRead >= sizeof(EventTrackJackSend) ) { if ( availableRead >= e->size() ) {
EventTrackJackSend ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSend) ); // MIDI binding creation: sample the Event.
jack->getLogic()->trackJackSend(ev.track,ev.value); if( jack->bindingEventRecordEnable ) {
jack->bindingTrack = ev.track; //printf("event %i\n", e->type() );
} break; } jack->bindingEventType = e->type();
case Event::TRACK_SEND: { const char* target = e->name();
if ( availableRead >= sizeof(EventTrackSend) ) { if ( target ) {
EventTrackSend ev; EventControllerBindingTarget event( target );
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackSend) ); writeToGuiRingbuffer( &event );
jack->getLogic()->trackSend( ev.track, ev.send, ev.value ); }
jack->bindingTrack = ev.track; }
jack->bindingSend = ev.send;
} break; } switch ( e->type() ) {
case Event::QUIT: {
if ( availableRead >= sizeof(EventQuit) ) {
// ========= LUPPP INTERNAL ===== EventQuit ev;
case Event::LOOPER_REQUEST_BUFFER: { jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventQuit) );
if ( availableRead >= sizeof(EventLooperClipRequestBuffer) ) { jack->quit();
EventLooperClipRequestBuffer ev; // we want to *quit* *fast*: remaining events don't matter!
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperClipRequestBuffer) ); return;
jack->getLooper( ev.track )->setRequestedBuffer( ev.scene, ev.ab );
} break; } }
break;
case Event::REQUEST_SAVE_BUFFER: { }
if ( availableRead >= sizeof(EventRequestSaveBuffer) ) {
EventRequestSaveBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRequestSaveBuffer) ); // ======== TRANSPORT ==
jack->getLooper( ev.track )->getClip(ev.scene)->recieveSaveBuffer( ev.ab ); case Event::TRANSPORT: {
} break; } if ( availableRead >= sizeof(EventTransportState) ) {
EventTransportState ev;
case Event::CONTROLLER_INSTANCE: { jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTransportState) );
if ( availableRead >= sizeof(EventControllerInstance) ) { jack->getTimeManager()->setTransportState( ev.ts );
EventControllerInstance ev; }
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstance) ); break;
jack->getControllerUpdater()->registerController( static_cast<Controller*>(ev.controller) ); }
} break; }
// ========= SAVE =====
case Event::CONTROLLER_INSTANCE_REMOVE: { case Event::STATE_SAVE: {
if ( availableRead >= sizeof(EventControllerInstanceRemove) ) { if ( availableRead >= sizeof(EventStateSave) ) {
EventControllerInstanceRemove ev; EventStateSave ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstanceRemove) ); jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateSave) );
jack->getState()->save();
jack->getControllerUpdater()->removeController( ev.ID ); }
} break; } break;
}
case Event::CONTROLLER_BINDING_ENABLE: { case Event::STATE_RESET: {
if ( availableRead >= sizeof(EventControllerBindingEnable) ) { if ( availableRead >= sizeof(EventStateReset) ) {
EventControllerBindingEnable ev; EventStateReset ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerBindingEnable) ); jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateReset) );
jack->bindingEventRecordEnable = ev.enable; jack->getState()->reset();
} break; } }
break;
}
case Event::CONTROLLER_BINDING_REMOVE: { case Event::STATE_SAVE_BUFFER: {
if ( availableRead >= sizeof(EventControllerBindingRemove) ) { if ( availableRead >= sizeof(EventStateReset) ) {
EventControllerBindingRemove ev; EventStateSaveBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerBindingRemove) ); jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventStateSaveBuffer) );
// get Controller* from controllerID printf("jack got save buffer in %d, %d\n", ev.track, ev.scene);
Controller* c =jack->getControllerUpdater()->getController(ev.controllerID); LooperClip* lc = jack->getLooper(ev.track)->getClip(ev.scene);
// dynamic cast to check for GenericMIDI controller if(!lc) break;
GenericMIDI* g = dynamic_cast<GenericMIDI*>(c); EventStateSaveBuffer e;
if ( g ) e.track = ev.track;
{ e.scene = ev.scene;
// kick out BindingID e.ab = lc->getAudioBuffer();
g->removeBinding( ev.bindingID ); e.no_dealloc = 1;
} writeToGuiRingbuffer( &e );
else }
{ break;
// GUI print notify of error removing binding }
}
} break; } // ========= MASTER ===
case Event::MASTER_VOL: {
case Event::CONTROLLER_INSTANCE_GET_TO_WRITE: { if ( availableRead >= sizeof(EventMasterVol) ) {
if ( availableRead >= sizeof(EventControllerInstanceGetToWrite) ) { EventMasterVol ev(0);
EventControllerInstanceGetToWrite ev; jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterVol) );
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstanceGetToWrite) ); jack->masterVolume( ev.vol );
}
// get the corresponding Controller with ID, and return it break;
}
Controller* c = jack->getControllerUpdater()->getController( ev.ID ); case Event::MASTER_RETURN: {
if ( availableRead >= sizeof(EventMasterReturn) ) {
cout << "controller instance get to write id " << ev.ID << endl; EventMasterReturn ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterReturn) );
EventControllerInstanceGetToWrite tmp( ev.ID, c ); if ( ev.ret == RETURN_MAIN ) {
writeToGuiRingbuffer( &tmp ); jack->returnVolume( ev.vol );
} break; } }
}
default: break;
{ }
cout << "DSP: Unkown message!! Will clog ringbuffer" << endl; case Event::MASTER_INPUT_VOL: {
// just do nothing if ( availableRead >= sizeof(EventMasterVol) ) {
break; EventMasterVol ev(0);
} jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterVol) );
} jack->getLogic()->masterInputVol( ev.vol );
} }
else break;
{ }
// next call will get the half-written event case Event::MASTER_INPUT_TO: {
return; if ( availableRead >= sizeof(EventMasterInputTo) ) {
} EventMasterInputTo ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterInputTo) );
// update available read, and loop over events jack->bindingSend = ev.place;
availableRead = jack_ringbuffer_read_space( rbToDsp ); jack->getLogic()->masterInputTo( ev.place, ev.value );
} }
break;
}
case Event::MASTER_INPUT_TO_ACTIVE: {
if ( availableRead >= sizeof(EventMasterInputToActive) ) {
EventMasterInputToActive ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMasterInputToActive) );
jack->bindingSend = ev.place;
jack->bindingActive = ev.active;
jack->getLogic()->masterInputToActive( ev.place, ev.active );
}
break;
}
// ========= GRID =====
case Event::GRID_STATE: {
if ( availableRead >= sizeof(EventGridState) ) {
EventGridState ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridState) );
// clear clips in Controllers
if ( ev.state == GridLogic::STATE_EMPTY ) {
jack->getLooper( ev.track )->getClip( ev.scene )->init();
jack->getControllerUpdater()->setTrackSceneProgress(ev.track, ev.scene, 0 );
jack->getControllerUpdater()->setSceneState( ev.track, ev.scene, GridLogic::STATE_EMPTY );
}
}
break;
}
case Event::GRID_EVENT: {
if ( availableRead >= sizeof(EventGridEvent) ) {
EventGridEvent ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridEvent) );
jack->bindingTrack = ev.track;
jack->bindingScene = ev.scene;
if ( ev.pressed )
jack->getGridLogic()->pressed( ev.track, ev.scene );
else
jack->getGridLogic()->released( ev.track, ev.scene );
}
break;
}
case Event::GRID_LAUNCH_SCENE: {
EventGridLaunchScene ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridLaunchScene) );
jack->getGridLogic()->launchScene( ev.scene );
jack->bindingScene = ev.scene;
break;
}
case Event::GRID_SELECT_CLIP_ENABLE: {
EventGridSelectClipEnable ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectClipEnable) );
jack->getGridLogic()->setSelectTrackScene( ev.enable );
break;
}
case Event::GRID_SELECT_CLIP_EVENT: {
EventGridSelectClipEvent ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectClipEvent) );
jack->getGridLogic()->selectedTrackSceneEvent( ev.pressed );
break;
}
case Event::GRID_SELECT_NEW_CHOSEN: {
EventGridSelectNewChosen ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventGridSelectNewChosen) );
jack->getGridLogic()->specialScene( ev.track, ev.scene );
break;
}
case Event::LOOPER_LOAD: {
if ( availableRead >= sizeof(EventLooperLoad) ) {
EventLooperLoad ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperLoad) );
jack->getGridLogic()->load( ev.track, ev.clip, (AudioBuffer*)ev.audioBuffer );
}
break;
}
case Event::METRONOME_ACTIVE: {
if ( availableRead >= sizeof(EventMetronomeActive) ) {
EventMetronomeActive ev(false);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMetronomeActive) );
jack->getLogic()->metronomeEnable(ev.active);
}
break;
}
case Event::METRONOME_VOLUME: {
if ( availableRead >= sizeof(EventMetronomeVolume) ) {
EventMetronomeVolume ev(false);
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMetronomeVolume) );
LUPPP_NOTE("EventDSP: MetroVol %f", ev.vol );
jack->getMetronome()->setVolume(ev.vol);
}
break;
}
case Event::LOOPER_STATE: {
if ( availableRead >= sizeof(EventLooperState) ) {
EventLooperState ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperState) );
//jack->setLooperState( ev.track, ev.scene, ev.state );
}
break;
}
case Event::LOOPER_LOOP_LENGTH: {
if ( availableRead >= sizeof(EventLooperLoopLength) ) {
EventLooperLoopLength ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperLoopLength) );
jack->getLogic()->looperClipLenght( ev.track, ev.scene, ev.beats );
}
break;
}
case Event::LOOPER_LOOP_USE_AS_TEMPO: {
if ( availableRead >= sizeof(EventLooperUseAsTempo) ) {
EventLooperUseAsTempo ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperUseAsTempo) );
jack->getLogic()->looperUseAsTempo( ev.track, ev.scene );
}
break;
}
case Event::TIME_BPM: {
if ( availableRead >= sizeof(EventTimeBPM) ) {
EventTimeBPM ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeBPM) );
jack->getTimeManager()->setBpm(ev.bpm);
}
break;
}
case Event::TIME_TEMPO_TAP: {
if ( availableRead >= sizeof(EventTimeTempoTap) ) {
EventTimeTempoTap ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeTempoTap) );
jack->getTimeManager()->tap();
}
break;
}
// ======== FX ===========
case Event::FX_REVERB:
break;
/*{
if ( availableRead >= sizeof(EventFxReverb) ) {
EventFxReverb ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventFxReverb) );
// TODO implement reverb
break; }
}
*/
case Event::TRACK_VOLUME: {
if ( availableRead >= sizeof(EventTrackVol) ) {
EventTrackVol ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackVol) );
jack->getLogic()->trackVolume( ev.track, ev.vol );
jack->bindingTrack = ev.track;
break;
}
}
case Event::TRACK_RECORD_ARM: {
if ( availableRead >= sizeof(EventTrackRecordArm) ) {
EventTrackRecordArm ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackRecordArm) );
jack->getLogic()->trackRecordArm( ev.track, ev.recordArm );
jack->bindingTrack = ev.track;
jack->bindingActive = ev.recordArm;
break;
}
}
case Event::TRACK_SEND_ACTIVE: {
if ( availableRead >= sizeof(EventTrackSendActive) ) {
EventTrackSendActive ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackSendActive) );
jack->getLogic()->trackSendActive( ev.track, ev.send, ev.active );
jack->bindingTrack = ev.track;
jack->bindingSend = ev.send;
jack->bindingActive = ev.active;
}
break;
}
case Event::TRACK_JACKSEND_ACTIVATE: {
if ( availableRead >= sizeof(EventTrackJackSendActivate) ) {
EventTrackJackSendActivate ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSendActivate) );
jack->getLogic()->trackJackSendActivate(ev.track,ev.active);
jack->bindingTrack = ev.track;
jack->bindingActive = ev.active;
}
break;
}
case Event::TRACK_JACKSEND: {
if ( availableRead >= sizeof(EventTrackJackSend) ) {
EventTrackJackSend ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackJackSend) );
jack->getLogic()->trackJackSend(ev.track,ev.value);
jack->bindingTrack = ev.track;
}
break;
}
case Event::TRACK_SEND: {
if ( availableRead >= sizeof(EventTrackSend) ) {
EventTrackSend ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTrackSend) );
jack->getLogic()->trackSend( ev.track, ev.send, ev.value );
jack->bindingTrack = ev.track;
jack->bindingSend = ev.send;
}
break;
}
// ========= LUPPP INTERNAL =====
case Event::LOOPER_REQUEST_BUFFER: {
if ( availableRead >= sizeof(EventLooperClipRequestBuffer) ) {
EventLooperClipRequestBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventLooperClipRequestBuffer) );
jack->getLooper( ev.track )->setRequestedBuffer( ev.scene, ev.ab );
}
break;
}
case Event::REQUEST_SAVE_BUFFER: {
if ( availableRead >= sizeof(EventRequestSaveBuffer) ) {
EventRequestSaveBuffer ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventRequestSaveBuffer) );
jack->getLooper( ev.track )->getClip(ev.scene)->recieveSaveBuffer( ev.ab );
}
break;
}
case Event::CONTROLLER_INSTANCE: {
if ( availableRead >= sizeof(EventControllerInstance) ) {
EventControllerInstance ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstance) );
jack->getControllerUpdater()->registerController( static_cast<Controller*>(ev.controller) );
}
break;
}
case Event::CONTROLLER_INSTANCE_REMOVE: {
if ( availableRead >= sizeof(EventControllerInstanceRemove) ) {
EventControllerInstanceRemove ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstanceRemove) );
jack->getControllerUpdater()->removeController( ev.ID );
}
break;
}
case Event::CONTROLLER_BINDING_ENABLE: {
if ( availableRead >= sizeof(EventControllerBindingEnable) ) {
EventControllerBindingEnable ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerBindingEnable) );
jack->bindingEventRecordEnable = ev.enable;
}
break;
}
case Event::CONTROLLER_BINDING_REMOVE: {
if ( availableRead >= sizeof(EventControllerBindingRemove) ) {
EventControllerBindingRemove ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerBindingRemove) );
// get Controller* from controllerID
Controller* c =jack->getControllerUpdater()->getController(ev.controllerID);
// dynamic cast to check for GenericMIDI controller
GenericMIDI* g = dynamic_cast<GenericMIDI*>(c);
if ( g ) {
// kick out BindingID
g->removeBinding( ev.bindingID );
} else {
// GUI print notify of error removing binding
}
} break;
}
case Event::CONTROLLER_INSTANCE_GET_TO_WRITE: {
if ( availableRead >= sizeof(EventControllerInstanceGetToWrite) ) {
EventControllerInstanceGetToWrite ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventControllerInstanceGetToWrite) );
// get the corresponding Controller with ID, and return it
Controller* c = jack->getControllerUpdater()->getController( ev.ID );
cout << "controller instance get to write id " << ev.ID << endl;
EventControllerInstanceGetToWrite tmp( ev.ID, c );
writeToGuiRingbuffer( &tmp );
}
break;
}
default: {
cout << "DSP: Unkown message!! Will clog ringbuffer" << endl;
// just do nothing
break;
}
}
} else {
// next call will get the half-written event
return;
}
// update available read, and loop over events
availableRead = jack_ringbuffer_read_space( rbToDsp );
}
} }
void writeToDspRingbuffer(EventBase* e) void writeToDspRingbuffer(EventBase* e)
{ {
if ( jack_ringbuffer_write_space(rbToDsp) >= e->size() ) if ( jack_ringbuffer_write_space(rbToDsp) >= e->size() ) {
{ jack_ringbuffer_write( rbToDsp, (const char*)e, e->size() );
jack_ringbuffer_write( rbToDsp, (const char*)e, e->size() ); } else {
} // non-RT context, printing is OK!
else cout << "->DSP ringbuffer full!" << endl;
{ }
// non-RT context, printing is OK!
cout << "->DSP ringbuffer full!" << endl;
}
} }
#endif // LUPPP_EVENT_HANDLER_DSP_H #endif // LUPPP_EVENT_HANDLER_DSP_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -41,395 +41,445 @@ using namespace std;
void handleGuiEvents() void handleGuiEvents()
{ {
uint availableRead = jack_ringbuffer_read_space( rbToGui ); uint availableRead = jack_ringbuffer_read_space( rbToGui );
while ( availableRead >= sizeof(EventBase) ) while ( availableRead >= sizeof(EventBase) ) {
{ jack_ringbuffer_peek( rbToGui, (char*)processGuiMem, sizeof(EventBase) );
jack_ringbuffer_peek( rbToGui, (char*)processGuiMem, sizeof(EventBase) );
EventBase* e = (EventBase*)processGuiMem;
EventBase* e = (EventBase*)processGuiMem;
// recheck the size against the actual event size
// recheck the size against the actual event size if ( availableRead >= e->size() ) {
if ( availableRead >= e->size() ) //cout << "reading event type " << e->type() << endl;
{
//cout << "reading event type " << e->type() << endl; switch ( e->type() ) {
case Event::QUIT: {
switch ( e->type() ) if ( availableRead >= sizeof(EventQuit) ) {
{ EventQuit ev;
case Event::QUIT: { jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventQuit) );
if ( availableRead >= sizeof(EventQuit) ) { LUPPP_NOTE("%s","GUI QUIT");
EventQuit ev; gui->quit();
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventQuit) ); }
LUPPP_NOTE("%s","GUI QUIT"); break;
gui->quit(); }
} break; }
case Event::SAMPLERATE: {
case Event::SAMPLERATE: { if ( availableRead >= sizeof(EventSamplerate) ) {
if ( availableRead >= sizeof(EventSamplerate) ) { EventSamplerate ev;
EventSamplerate ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSamplerate) );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventSamplerate) ); gui->samplerate = ev.samplerate;
gui->samplerate = ev.samplerate; //LUPPP_NOTE("Gui Samplerate: %i", gui->samplerate);
//LUPPP_NOTE("Gui Samplerate: %i", gui->samplerate); }
} break; } break;
}
/// master
case Event::MASTER_INPUT_TO: { /// master
if ( availableRead >= sizeof(EventMasterInputTo) ) { case Event::MASTER_INPUT_TO: {
EventMasterInputTo ev; if ( availableRead >= sizeof(EventMasterInputTo) ) {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputTo) ); EventMasterInputTo ev;
gui->getMasterTrack()->setInputTo( (int)ev.place, ev.value ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputTo) );
} break; } gui->getMasterTrack()->setInputTo( (int)ev.place, ev.value );
case Event::MASTER_INPUT_TO_ACTIVE: { }
if ( availableRead >= sizeof(EventMasterInputToActive) ) { break;
EventMasterInputToActive ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputToActive) ); case Event::MASTER_INPUT_TO_ACTIVE: {
gui->getMasterTrack()->setInputToActive( (int)ev.place, ev.active ); if ( availableRead >= sizeof(EventMasterInputToActive) ) {
} break; } EventMasterInputToActive ev;
case Event::MASTER_INPUT_VOL: { jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputToActive) );
if ( availableRead >= sizeof(EventMasterInputVol) ) { gui->getMasterTrack()->setInputToActive( (int)ev.place, ev.active );
EventMasterInputVol ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputVol) ); break;
gui->getMasterTrack()->setInputVol( ev.vol ); }
} break; } case Event::MASTER_INPUT_VOL: {
case Event::MASTER_RETURN: { if ( availableRead >= sizeof(EventMasterInputVol) ) {
if ( availableRead >= sizeof(EventMasterReturn) ) { EventMasterInputVol ev;
EventMasterReturn ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterInputVol) );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterReturn) ); gui->getMasterTrack()->setInputVol( ev.vol );
gui->getMasterTrack()->setReturnVol( ev.vol ); }
} break; } break;
case Event::MASTER_VOL: { }
if ( availableRead >= sizeof(EventMasterVol) ) { case Event::MASTER_RETURN: {
EventMasterVol ev(0); if ( availableRead >= sizeof(EventMasterReturn) ) {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterVol) ); EventMasterReturn ev;
gui->getMasterTrack()->getVolume()->fader( ev.vol ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterReturn) );
} break; } gui->getMasterTrack()->setReturnVol( ev.vol );
}
break;
case Event::METRONOME_ACTIVE: { }
if ( availableRead >= sizeof(EventMetronomeActive) ) { case Event::MASTER_VOL: {
EventMetronomeActive ev(false); if ( availableRead >= sizeof(EventMasterVol) ) {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMetronomeActive) ); EventMasterVol ev(0);
gui->getMasterTrack()->metronomeEnable(ev.active); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMasterVol) );
} break; } gui->getMasterTrack()->getVolume()->fader( ev.vol );
case Event::LOOPER_STATE: { }
if ( availableRead >= sizeof(EventLooperState) ) { break;
EventLooperState ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
//gui->getTrack(ev.track)->getClipSelector()->setState(ev.scene, ev.state);
//jack->setLooperState( ev.track, ev.state ); case Event::METRONOME_ACTIVE: {
} break; } if ( availableRead >= sizeof(EventMetronomeActive) ) {
case Event::LOOPER_LOOP_LENGTH: { EventMetronomeActive ev(false);
if ( availableRead >= sizeof(EventLooperLoopLength) ) { jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventMetronomeActive) );
//EventLooperLoopLength ev; gui->getMasterTrack()->metronomeEnable(ev.active);
//jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) ); }
//jack->setLooperLoopLength( ev.track, ev.scale ); break;
} break; } }
case Event::LOOPER_PROGRESS: { case Event::LOOPER_STATE: {
if ( availableRead >= sizeof(EventLooperProgress) ) { if ( availableRead >= sizeof(EventLooperState) ) {
EventLooperProgress ev; EventLooperState ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperState) );
//gui->getTrack(ev.track)->getClipSelector()->setState(ev.scene, ev.state);
// only update if significant change //jack->setLooperState( ev.track, ev.state );
//if ( ev.progress - gui->getTrack(ev.track)->radial.value() >= 0.05 || }
// ev.progress > 0.9 ) break;
gui->getTrack(ev.track)->radial.value(ev.progress); }
case Event::LOOPER_LOOP_LENGTH: {
} break; } if ( availableRead >= sizeof(EventLooperLoopLength) ) {
//EventLooperLoopLength ev;
//jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperLoopLength) );
// FIXME: reset signal level to 0 //jack->setLooperLoopLength( ev.track, ev.scale );
case Event::TRACK_SIGNAL_LEVEL: { } break;
if ( availableRead >= sizeof(EventTrackSignalLevel) ) { }
EventTrackSignalLevel ev; case Event::LOOPER_PROGRESS: {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) ); if ( availableRead >= sizeof(EventLooperProgress) ) {
if ( ev.track == -2 ) { EventLooperProgress ev;
gui->getMasterTrack()->getInputVolume()->amplitude( ev.left, ev.right ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperProgress) );
} else if ( ev.track == -1 ) {
gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right ); // only update if significant change
} else { //if ( ev.progress - gui->getTrack(ev.track)->radial.value() >= 0.05 ||
gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right ); } // ev.progress > 0.9 )
} break; } gui->getTrack(ev.track)->radial.value(ev.progress);
case Event::TRACK_VOLUME: {
if ( availableRead >= sizeof(EventTrackVol) ) { }
EventTrackVol ev; break;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackVol) ); }
gui->getTrack(ev.track)->getVolume()->fader( ev.vol );
} break; }
// FIXME: reset signal level to 0
case Event::TRACK_SIGNAL_LEVEL: {
case Event::TRACK_RECORD_ARM: { if ( availableRead >= sizeof(EventTrackSignalLevel) ) {
if ( availableRead >= sizeof(EventTrackRecordArm) ) { EventTrackSignalLevel ev;
EventTrackRecordArm ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSignalLevel) );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackRecordArm) ); if ( ev.track == -2 ) {
gui->getTrack(ev.track)->setRecordActive( ev.recordArm ); gui->getMasterTrack()->getInputVolume()->amplitude( ev.left, ev.right );
break; } } else if ( ev.track == -1 ) {
} gui->getMasterTrack()->getVolume()->amplitude( ev.left, ev.right );
} else {
case Event::TIME_BPM: { gui->getTrack(ev.track)->getVolume()->amplitude( ev.left, ev.right );
if ( availableRead >= sizeof(EventTimeBPM) ) { }
EventTimeBPM ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBPM) ); break;
gui->getMasterTrack()->setBpm( ev.bpm ); }
} break; } case Event::TRACK_VOLUME: {
if ( availableRead >= sizeof(EventTrackVol) ) {
EventTrackVol ev;
case Event::STATE_SAVE_BUFFER: { jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackVol) );
if ( availableRead >= sizeof(EventStateSaveBuffer) ) { gui->getTrack(ev.track)->getVolume()->fader( ev.vol );
EventStateSaveBuffer ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveBuffer) ); break;
}
case Event::TRACK_RECORD_ARM: {
if ( availableRead >= sizeof(EventTrackRecordArm) ) {
EventTrackRecordArm ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackRecordArm) );
gui->getTrack(ev.track)->setRecordActive( ev.recordArm );
break;
}
}
case Event::TIME_BPM: {
if ( availableRead >= sizeof(EventTimeBPM) ) {
EventTimeBPM ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBPM) );
gui->getMasterTrack()->setBpm( ev.bpm );
}
break;
}
case Event::STATE_SAVE_BUFFER: {
if ( availableRead >= sizeof(EventStateSaveBuffer) ) {
EventStateSaveBuffer ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveBuffer) );
#ifdef DEBUG_SAVE #ifdef DEBUG_SAVE
cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl; cout << "EventSaveBuffer: " << ev.track << " " << ev.scene << " " << ev.ab->getID() << endl;
#endif #endif
gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab ); gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
// de allocate the AudioBuffer only if reqested // de allocate the AudioBuffer only if reqested
if(!ev.no_dealloc) { if(!ev.no_dealloc) {
gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab ); gui->getDiskWriter()->writeAudioBuffer( ev.track, ev.scene, ev.ab );
delete ev.ab; delete ev.ab;
} else } else {
{ gui->getDiskWriter()->writeAudioBuffer(ev.track, ev.scene, ev.ab,
gui->getDiskWriter()->writeAudioBuffer(ev.track, ev.scene, ev.ab, gui->saveBufferPath.c_str());
gui->saveBufferPath.c_str()); gui->saveBufferPath = "";
gui->saveBufferPath = ""; }
}
} break; } }
break;
case Event::STATE_SAVE_FINISH: { }
if ( availableRead >= sizeof(EventStateSaveFinish) ) {
EventStateSaveFinish ev; case Event::STATE_SAVE_FINISH: {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveFinish) ); if ( availableRead >= sizeof(EventStateSaveFinish) ) {
EventStateSaveFinish ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventStateSaveFinish) );
#ifdef DEBUG_SAVE #ifdef DEBUG_SAVE
cout << "EventSaveFinish!" << endl; cout << "EventSaveFinish!" << endl;
#endif #endif
gui->getDiskWriter()->writeSession(); gui->getDiskWriter()->writeSession();
} break; } }
break;
}
case Event::GRID_STATE: {
if ( availableRead >= sizeof(EventGridState) ) {
EventGridState ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridState) );
gui->getTrack(ev.track)->getClipSelector()->setState( ev.scene, ev.state );
if ( ev.state == GridLogic::STATE_RECORDING )
gui->getTrack(ev.track)->getRadialStatus()->recording( true );
else
gui->getTrack(ev.track)->getRadialStatus()->recording( false );
} break; }
case Event::GRID_LAUNCH_SCENE: {
if ( availableRead >= sizeof(EventGridLaunchScene) ) {
EventGridLaunchScene ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridLaunchScene) );
for(int i = 0; i < NSCENES; i++)
gui->getMasterTrack()->getClipSelector()->setState( i, GridLogic::STATE_EMPTY );
gui->getMasterTrack()->getClipSelector()->setState( ev.scene, GridLogic::STATE_PLAYING );
} break; }
case Event::GRID_SELECT_NEW_CHOSEN: {
if ( availableRead >= sizeof(EventGridSelectNewChosen) ) {
EventGridSelectNewChosen ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridSelectNewChosen) );
//LUPPP_NOTE("New special, %i, %i", ev.track, ev.scene);
for(int i = 0; i < NTRACKS; i++)
{
gui->getTrack(i)->getClipSelector()->setSpecial( i == ev.track ? ev.scene : -1 );
}
gui->specialTrack = ev.track;
gui->specialScene = ev.scene;
} break; }
case Event::TRACK_SEND: {
if ( availableRead >= sizeof(EventTrackSend) ) {
EventTrackSend ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSend) );
if ( ev.send == SEND_POSTFADER )
if ( ev.track < NTRACKS )
{
gui->getTrack(ev.track)->setSend(ev.value );
}
if ( ev.send == SEND_XSIDE )
if ( ev.track < NTRACKS )
{
gui->getTrack(ev.track)->setXSide( ev.value );
}
} break; }
case Event::TRACK_JACKSEND: {
if ( availableRead >= sizeof(EventTrackJackSend) ) {
EventTrackJackSend ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSend) );
gui->getTrack(ev.track)->setJackSend(ev.value);
} break; }
case Event::TRACK_JACKSEND_ACTIVATE: { case Event::GRID_STATE: {
if ( availableRead >= sizeof(EventTrackJackSendActivate) ) { if ( availableRead >= sizeof(EventGridState) ) {
EventTrackJackSendActivate ev; EventGridState ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSendActivate) ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridState) );
gui->getTrack(ev.track)->setJackSendActivate(ev.active); gui->getTrack(ev.track)->getClipSelector()->setState( ev.scene, ev.state );
} break; } if ( ev.state == GridLogic::STATE_RECORDING )
gui->getTrack(ev.track)->getRadialStatus()->recording( true );
case Event::TRACK_SEND_ACTIVE: { else
if ( availableRead >= sizeof(EventTrackSendActive) ) { gui->getTrack(ev.track)->getRadialStatus()->recording( false );
EventTrackSendActive ev; }
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSendActive) ); break;
if ( ev.send == SEND_POSTFADER ) }
if ( ev.track < NTRACKS ) case Event::GRID_LAUNCH_SCENE: {
{ if ( availableRead >= sizeof(EventGridLaunchScene) ) {
gui->getTrack(ev.track)->setSendActive(ev.active ); EventGridLaunchScene ev;
} jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridLaunchScene) );
if ( ev.send == SEND_KEY ) for(int i = 0; i < NSCENES; i++)
{ gui->getMasterTrack()->getClipSelector()->setState( i, GridLogic::STATE_EMPTY );
if ( ev.track < NTRACKS ) gui->getMasterTrack()->getClipSelector()->setState( ev.scene, GridLogic::STATE_PLAYING );
{ }
gui->getTrack(ev.track)->setKeyActive( ev.active ); break;
} }
}
} break; } case Event::GRID_SELECT_NEW_CHOSEN: {
if ( availableRead >= sizeof(EventGridSelectNewChosen) ) {
case Event::GUI_PRINT: { EventGridSelectNewChosen ev;
if ( availableRead >= sizeof(EventGuiPrint) ) { jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGridSelectNewChosen) );
EventGuiPrint ev; //LUPPP_NOTE("New special, %i, %i", ev.track, ev.scene);
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGuiPrint) ); for(int i = 0; i < NTRACKS; i++) {
//cout << "DSP: " << ev.getMessage() << endl; gui->getTrack(i)->getClipSelector()->setSpecial( i == ev.track ? ev.scene : -1 );
LUPPP_DSP("%s", ev.getMessage() ); }
} break; } gui->specialTrack = ev.track;
case Event::TIME_BAR_BEAT: { gui->specialScene = ev.scene;
if ( availableRead >= sizeof(EventTimeBarBeat) ) { }
EventTimeBarBeat ev; break;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBarBeat) ); }
gui->getMasterTrack()->setBarBeat( ev.bar, ev.beat);
} break; }
case Event::TIME_TEMPO_TAP: { case Event::TRACK_SEND: {
if ( availableRead >= sizeof(EventTimeTempoTap) ) { if ( availableRead >= sizeof(EventTrackSend) ) {
EventTimeTempoTap ev; EventTrackSend ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeTempoTap) ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSend) );
gui->getMasterTrack()->setTapTempo( ev.pressed ); if ( ev.send == SEND_POSTFADER )
} break; } if ( ev.track < NTRACKS ) {
gui->getTrack(ev.track)->setSend(ev.value );
}
case Event::LOOPER_REQUEST_BUFFER: { if ( ev.send == SEND_XSIDE )
if ( availableRead >= sizeof(EventLooperClipRequestBuffer) ) { if ( ev.track < NTRACKS ) {
EventLooperClipRequestBuffer ev; gui->getTrack(ev.track)->setXSide( ev.value );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperClipRequestBuffer) ); }
}
/// allocate a new AudioBuffer with ev.numElements, pass back to DSP break;
AudioBuffer* ab = new AudioBuffer(ev.numElements); }
EventLooperClipRequestBuffer returnEvent(ev.track, ev.scene, ab);
writeToDspRingbuffer( &returnEvent ); case Event::TRACK_JACKSEND: {
if ( availableRead >= sizeof(EventTrackJackSend) ) {
EventTrackJackSend ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSend) );
gui->getTrack(ev.track)->setJackSend(ev.value);
}
break;
}
case Event::TRACK_JACKSEND_ACTIVATE: {
if ( availableRead >= sizeof(EventTrackJackSendActivate) ) {
EventTrackJackSendActivate ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackJackSendActivate) );
gui->getTrack(ev.track)->setJackSendActivate(ev.active);
}
break;
}
case Event::TRACK_SEND_ACTIVE: {
if ( availableRead >= sizeof(EventTrackSendActive) ) {
EventTrackSendActive ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTrackSendActive) );
if ( ev.send == SEND_POSTFADER )
if ( ev.track < NTRACKS ) {
gui->getTrack(ev.track)->setSendActive(ev.active );
}
if ( ev.send == SEND_KEY ) {
if ( ev.track < NTRACKS ) {
gui->getTrack(ev.track)->setKeyActive( ev.active );
}
}
}
break;
}
case Event::GUI_PRINT: {
if ( availableRead >= sizeof(EventGuiPrint) ) {
EventGuiPrint ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventGuiPrint) );
//cout << "DSP: " << ev.getMessage() << endl;
LUPPP_DSP("%s", ev.getMessage() );
}
break;
}
case Event::TIME_BAR_BEAT: {
if ( availableRead >= sizeof(EventTimeBarBeat) ) {
EventTimeBarBeat ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeBarBeat) );
gui->getMasterTrack()->setBarBeat( ev.bar, ev.beat);
}
break;
}
case Event::TIME_TEMPO_TAP: {
if ( availableRead >= sizeof(EventTimeTempoTap) ) {
EventTimeTempoTap ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventTimeTempoTap) );
gui->getMasterTrack()->setTapTempo( ev.pressed );
}
break;
}
case Event::LOOPER_REQUEST_BUFFER: {
if ( availableRead >= sizeof(EventLooperClipRequestBuffer) ) {
EventLooperClipRequestBuffer ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventLooperClipRequestBuffer) );
/// allocate a new AudioBuffer with ev.numElements, pass back to DSP
AudioBuffer* ab = new AudioBuffer(ev.numElements);
EventLooperClipRequestBuffer returnEvent(ev.track, ev.scene, ab);
writeToDspRingbuffer( &returnEvent );
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
printf("new buffer going to track %i, scene %i\n",ev.track, ev.scene); printf("new buffer going to track %i, scene %i\n",ev.track, ev.scene);
#endif #endif
} break; } }
break;
case Event::REQUEST_SAVE_BUFFER: { }
if ( availableRead >= sizeof(EventRequestSaveBuffer) ) {
EventRequestSaveBuffer ev; case Event::REQUEST_SAVE_BUFFER: {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventRequestSaveBuffer) ); if ( availableRead >= sizeof(EventRequestSaveBuffer) ) {
EventRequestSaveBuffer ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventRequestSaveBuffer) );
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
printf("Save buffer to track %i, scene %i\n",ev.track, ev.scene); printf("Save buffer to track %i, scene %i\n",ev.track, ev.scene);
#endif #endif
/// allocate a new AudioBuffer with ev.numElements, pass back to DSP /// allocate a new AudioBuffer with ev.numElements, pass back to DSP
AudioBuffer* ab = new AudioBuffer(ev.bufferSize); AudioBuffer* ab = new AudioBuffer(ev.bufferSize);
if ( ab ) if ( ab ) {
{ //LUPPP_NOTE("Save buffer sent with t %i, s %i, ab* %i", ev.track, ev.scene, ab );
//LUPPP_NOTE("Save buffer sent with t %i, s %i, ab* %i", ev.track, ev.scene, ab ); EventRequestSaveBuffer returnEvent( ev.track, ev.scene, ab);
EventRequestSaveBuffer returnEvent( ev.track, ev.scene, ab); writeToDspRingbuffer( &returnEvent );
writeToDspRingbuffer( &returnEvent ); } else {
} cout << "error allocating save buffer!" << endl;
else }
{ }
cout << "error allocating save buffer!" << endl; break;
} }
} break; }
case Event::DEALLOCATE_BUFFER: {
case Event::DEALLOCATE_BUFFER: { if ( availableRead >= sizeof(EventDeallocateBuffer) ) {
if ( availableRead >= sizeof(EventDeallocateBuffer) ) { EventDeallocateBuffer ev;
EventDeallocateBuffer ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventDeallocateBuffer) );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventDeallocateBuffer) ); delete ev.ab;
delete ev.ab; }
} break; } break;
}
case Event::CONTROLLER_BINDING_ENABLE: {
if ( availableRead >= sizeof(EventControllerBindingEnable) ) { case Event::CONTROLLER_BINDING_ENABLE: {
EventControllerBindingEnable ev; if ( availableRead >= sizeof(EventControllerBindingEnable) ) {
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingEnable) ); EventControllerBindingEnable ev;
ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingEnable) );
if ( c ) ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID );
c->setBindEnable( ev.enable ); if ( c )
else c->setBindEnable( ev.enable );
LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID ); else
} break; } LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID );
}
case Event::CONTROLLER_BINDING_TARGET: { break;
if ( availableRead >= sizeof(EventControllerBindingTarget) ) { }
EventControllerBindingTarget ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingTarget) ); case Event::CONTROLLER_BINDING_TARGET: {
gui->getOptionsWindow()->setTarget( ev.target ); if ( availableRead >= sizeof(EventControllerBindingTarget) ) {
} break; } EventControllerBindingTarget ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingTarget) );
case Event::CONTROLLER_BINDING_MADE: { gui->getOptionsWindow()->setTarget( ev.target );
if ( availableRead >= sizeof(EventControllerBindingMade) ) { }
EventControllerBindingMade ev; break;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingMade) ); }
ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID );
if ( c ) case Event::CONTROLLER_BINDING_MADE: {
c->addBinding( (Binding*)ev.binding ); if ( availableRead >= sizeof(EventControllerBindingMade) ) {
else EventControllerBindingMade ev;
LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID ); jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerBindingMade) );
} break; } ControllerUI* c = gui->getOptionsWindow()->getControllerUI( ev.controllerID );
if ( c )
case Event::CONTROLLER_INSTANCE_GET_TO_WRITE: { c->addBinding( (Binding*)ev.binding );
if ( availableRead >= sizeof(EventControllerInstanceGetToWrite) ) { else
EventControllerInstanceGetToWrite ev; LUPPP_WARN("ControllerUI %i doesn't exist in the UI", ev.controllerID );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstanceGetToWrite) ); }
// write the contents of the GenericMIDI controller to .ctlr file break;
gui->getDiskWriter()->writeControllerFile( (Controller*)ev.controller ); }
} break; }
case Event::CONTROLLER_INSTANCE_GET_TO_WRITE: {
case Event::CONTROLLER_INSTANCE: { if ( availableRead >= sizeof(EventControllerInstanceGetToWrite) ) {
if ( availableRead >= sizeof(EventControllerInstance) ) { EventControllerInstanceGetToWrite ev;
EventControllerInstance ev; jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstanceGetToWrite) );
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstance) ); // write the contents of the GenericMIDI controller to .ctlr file
// remove this controller from use: gui->getDiskWriter()->writeControllerFile( (Controller*)ev.controller );
Controller* c = (Controller*)ev.controller; }
LUPPP_NOTE("Deleting controller %s", c->getName().c_str() ); break;
// delete will call the destructor for the Controller: this should }
// clean up ports etc, all from the GUI thread as appropriate
delete c; case Event::CONTROLLER_INSTANCE: {
} break; } if ( availableRead >= sizeof(EventControllerInstance) ) {
EventControllerInstance ev;
jack_ringbuffer_read( rbToGui, (char*)&ev, sizeof(EventControllerInstance) );
// remove this controller from use:
default: Controller* c = (Controller*)ev.controller;
{ LUPPP_NOTE("Deleting controller %s", c->getName().c_str() );
cout << "GUI: Unkown message!! Will clog ringbuffer" << endl; // delete will call the destructor for the Controller: this should
// just do nothing // clean up ports etc, all from the GUI thread as appropriate
break; delete c;
} }
} break;
} }
else
{
// next call will get the half-written event
return; default: {
} cout << "GUI: Unkown message!! Will clog ringbuffer" << endl;
// just do nothing
// update available read, and loop over events break;
availableRead = jack_ringbuffer_read_space( rbToGui ); }
} }
} else {
// next call will get the half-written event
return;
}
// update available read, and loop over events
availableRead = jack_ringbuffer_read_space( rbToGui );
}
} }
void writeToGuiRingbuffer(EventBase* e) void writeToGuiRingbuffer(EventBase* e)
{ {
if ( jack_ringbuffer_write_space(rbToGui) >= e->size() ) if ( jack_ringbuffer_write_space(rbToGui) >= e->size() ) {
{ jack_ringbuffer_write( rbToGui, (const char*)e, e->size() );
jack_ringbuffer_write( rbToGui, (const char*)e, e->size() ); } else {
} cout << "->GUI ringbuffer full!" << endl;
else }
{
cout << "->GUI ringbuffer full!" << endl;
}
} }
#endif // LUPPP_EVENT_HANDLER_DSP_H #endif // LUPPP_EVENT_HANDLER_DSP_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -31,154 +31,157 @@ extern Gui* gui;
#include "avtk/avtk_button.h" #include "avtk/avtk_button.h"
void oneCB (Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 1 ); } void oneCB (Fl_Widget*,void* data)
void twoCB (Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 2 ); } {
void fourCB (Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 4 ); } ((AudioEditor*)data)->setBeatsAndQuit( 1 );
void eightCB (Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 8 ); } }
void sixteenCB (Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 16); } void twoCB (Fl_Widget*,void* data)
void thirtyTwoCB(Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 32); } {
void sixtyfourCB(Fl_Widget*,void* data) { ((AudioEditor*)data)->setBeatsAndQuit( 64); } ((AudioEditor*)data)->setBeatsAndQuit( 2 );
}
void fourCB (Fl_Widget*,void* data)
{
((AudioEditor*)data)->setBeatsAndQuit( 4 );
}
void eightCB (Fl_Widget*,void* data)
{
((AudioEditor*)data)->setBeatsAndQuit( 8 );
}
void sixteenCB (Fl_Widget*,void* data)
{
((AudioEditor*)data)->setBeatsAndQuit( 16);
}
void thirtyTwoCB(Fl_Widget*,void* data)
{
((AudioEditor*)data)->setBeatsAndQuit( 32);
}
void sixtyfourCB(Fl_Widget*,void* data)
{
((AudioEditor*)data)->setBeatsAndQuit( 64);
}
void cancelCB(Fl_Widget*,void* data) void cancelCB(Fl_Widget*,void* data)
{ {
printf("button, beats = 4\n"); printf("button, beats = 4\n");
AudioEditor* ae = (AudioEditor*) data; AudioEditor* ae = (AudioEditor*) data;
ae->setBeatsAndQuit( -1 ); ae->setBeatsAndQuit( -1 );
} }
AudioEditor::AudioEditor() AudioEditor::AudioEditor()
{ {
window = new Fl_Double_Window(460,200,"Audio Editor : Beats?"); window = new Fl_Double_Window(460,200,"Audio Editor : Beats?");
waveform = new Avtk::Waveform(5, 5, 450, 150, "Waveform"); waveform = new Avtk::Waveform(5, 5, 450, 150, "Waveform");
cancel = new Avtk::Button(360, 160, 80,30, "Cancel"); cancel = new Avtk::Button(360, 160, 80,30, "Cancel");
const char* names[] = { const char* names[] = {
"1","2","4","8","16","32","64" "1","2","4","8","16","32","64"
}; };
for(int i = 0; i < 7; i++) for(int i = 0; i < 7; i++) {
{ stringstream s;
stringstream s; s << i;
s << i; beatButtons[i] = new Avtk::Button(5 + i * 50, 160, 40,30, strdup(names[i]) );
beatButtons[i] = new Avtk::Button(5 + i * 50, 160, 40,30, strdup(names[i]) ); }
} window->end();
window->end();
beatButtons[0]->callback( oneCB , this);
beatButtons[0]->callback( oneCB , this); beatButtons[1]->callback( twoCB , this);
beatButtons[1]->callback( twoCB , this); beatButtons[2]->callback( fourCB , this);
beatButtons[2]->callback( fourCB , this); beatButtons[3]->callback( eightCB , this);
beatButtons[3]->callback( eightCB , this); beatButtons[4]->callback( sixteenCB , this);
beatButtons[4]->callback( sixteenCB , this); beatButtons[5]->callback( thirtyTwoCB, this);
beatButtons[5]->callback( thirtyTwoCB, this); beatButtons[6]->callback( sixtyfourCB, this);
beatButtons[6]->callback( sixtyfourCB, this);
cancel->callback( cancelCB, this );
cancel->callback( cancelCB, this );
} }
void AudioEditor::show( AudioBuffer* buf, bool modal ) void AudioEditor::show( AudioBuffer* buf, bool modal )
{ {
ab = buf; ab = buf;
if ( !ab ) if ( !ab ) {
{ LUPPP_WARN("called with ab == 0");
LUPPP_WARN("called with ab == 0"); } else {
} std::vector<float>& tmp = ab->getData();
else int size = tmp.size();
{ waveform->setData( &tmp[0], size );
std::vector<float>& tmp = ab->getData();
int size = tmp.size(); const int beats[]= {1,2,4,8,16,32,64};
waveform->setData( &tmp[0], size );
int iBeatOne = -1;
const int beats[]={1,2,4,8,16,32,64}; int iBeatTwo = -1;
int iBeatOne = -1; // figure out BPM values from size
int iBeatTwo = -1; for( int i = 0; i < 7; i++ ) {
int beat = beats[i];
// figure out BPM values from size
for( int i = 0; i < 7; i++ ) int fpb = size / beat;
{
int beat = beats[i]; int bpm = (gui->samplerate / fpb) * 60;
int fpb = size / beat;
if ( bpm < 60 || bpm > 220 ) {
int bpm = (gui->samplerate / fpb) * 60; // disable option: not valid
beatButtons[i]->setGreyOut( true );
beatButtons[i]->setColor( 0.4, 0.4, 0.4 );
if ( bpm < 60 || bpm > 220 ) } else {
{ //printf("%i, fpb = %i, bpm= = %i\n", beat, fpb, bpm );
// disable option: not valid // enable option ( may be disabled previously! )
beatButtons[i]->setGreyOut( true ); beatButtons[i]->setGreyOut( false );
beatButtons[i]->setColor( 0.4, 0.4, 0.4 );
} // remember this beat was a valid one, to check for best match
else if ( iBeatOne == -1 )
{ iBeatOne = i;
//printf("%i, fpb = %i, bpm= = %i\n", beat, fpb, bpm ); else
// enable option ( may be disabled previously! ) iBeatTwo = i;
beatButtons[i]->setGreyOut( false ); }
}
// remember this beat was a valid one, to check for best match
if ( iBeatOne == -1 ) // both valid: compare, and adjust color
iBeatOne = i; if ( iBeatOne != -1 && iBeatTwo != -1 ) {
else int masterFpb = (gui->samplerate * 60) / gui->getMasterTrack()->getBpm();
iBeatTwo = i; int oneFpb = size / beats[iBeatOne];
} int twoFpb = size / beats[iBeatTwo];
}
int oneDelta = masterFpb - oneFpb;
// both valid: compare, and adjust color int twoDelta = masterFpb - twoFpb;
if ( iBeatOne != -1 && iBeatTwo != -1 )
{ if ( oneDelta < 0 ) oneDelta = -oneDelta;
int masterFpb = (gui->samplerate * 60) / gui->getMasterTrack()->getBpm(); if ( twoDelta < 0 ) twoDelta = -twoDelta;
int oneFpb = size / beats[iBeatOne];
int twoFpb = size / beats[iBeatTwo]; if ( oneDelta == twoDelta ) {
beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 );
int oneDelta = masterFpb - oneFpb; beatButtons[iBeatTwo]->setColor( 0.0, 1.0, 0.0 );
int twoDelta = masterFpb - twoFpb; } else if ( oneDelta <= twoDelta ) {
// one is the better match
if ( oneDelta < 0 ) oneDelta = -oneDelta; beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 );
if ( twoDelta < 0 ) twoDelta = -twoDelta; beatButtons[iBeatTwo]->setColor( 1.0, 0.0, 0.0 );
} else {
if ( oneDelta == twoDelta ) beatButtons[iBeatTwo]->setColor( 0.0, 1.0, 0.0 );
{ beatButtons[iBeatOne]->setColor( 1.0, 0.0, 0.0 );
beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 ); }
beatButtons[iBeatTwo]->setColor( 0.0, 1.0, 0.0 ); } else if( iBeatOne != -1 && iBeatTwo == -1) { // only one valid
} beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 );
else if ( oneDelta <= twoDelta ) } else {
{ // no valid BPM range..?
// one is the better match }
beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 );
beatButtons[iBeatTwo]->setColor( 1.0, 0.0, 0.0 ); }
}
else window->set_modal();
{ window->show();
beatButtons[iBeatTwo]->setColor( 0.0, 1.0, 0.0 );
beatButtons[iBeatOne]->setColor( 1.0, 0.0, 0.0 );
}
}
else if( iBeatOne != -1 && iBeatTwo == -1) // only one valid
{
beatButtons[iBeatOne]->setColor( 0.0, 1.0, 0.0 );
}
else
{
// no valid BPM range..?
}
}
window->set_modal();
window->show();
} }
void AudioEditor::hide() void AudioEditor::hide()
{ {
window->hide(); window->hide();
} }
void AudioEditor::setBeatsAndQuit(int beats) void AudioEditor::setBeatsAndQuit(int beats)
{ {
ab->setBeats(beats); ab->setBeats(beats);
window->hide(); window->hide();
} }
/* /*
@ -190,10 +193,10 @@ AudioBuffer* AudioEditor::getAudioBuffer()
bool AudioEditor::shown() bool AudioEditor::shown()
{ {
return window->shown(); return window->shown();
} }
AudioEditor::~AudioEditor() AudioEditor::~AudioEditor()
{ {
delete window; delete window;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -24,38 +24,39 @@
#include <FL/Fl_Double_Window.H> #include <FL/Fl_Double_Window.H>
class AudioBuffer; class AudioBuffer;
namespace Avtk { namespace Avtk
{
class Waveform; class Waveform;
class Button; class Button;
} }
class AudioEditor class AudioEditor
{ {
public: public:
AudioEditor(); AudioEditor();
~AudioEditor(); ~AudioEditor();
/// shows the window, and loads the audio buffer into the display /// shows the window, and loads the audio buffer into the display
void show( AudioBuffer* ab, bool modal = false ); void show( AudioBuffer* ab, bool modal = false );
void hide(); void hide();
/// returns true if the editor window is shown /// returns true if the editor window is shown
bool shown(); bool shown();
void setBeatsAndQuit( int beats ); void setBeatsAndQuit( int beats );
//AudioBuffer* getAudioBuffer(); //AudioBuffer* getAudioBuffer();
private: private:
// GUI elements // GUI elements
Fl_Double_Window* window; Fl_Double_Window* window;
Avtk::Waveform* waveform; Avtk::Waveform* waveform;
Avtk::Button* cancel; Avtk::Button* cancel;
Avtk::Button* beatButtons[7]; Avtk::Button* beatButtons[7];
// Contents // Contents
AudioBuffer* ab; AudioBuffer* ab;
}; };
#endif // LUPPP_AUDIO_EDITOR_H #endif // LUPPP_AUDIO_EDITOR_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -22,378 +22,358 @@
static void gmastertrack_tempoDial_callback(Fl_Widget *w, void *data) static void gmastertrack_tempoDial_callback(Fl_Widget *w, void *data)
{ {
Avtk::Dial* b = (Avtk::Dial*)w; Avtk::Dial* b = (Avtk::Dial*)w;
float bpm = (int)(b->value() * 160.f + 60); float bpm = (int)(b->value() * 160.f + 60);
if(std::fabs(bpm-round(bpm))) if(std::fabs(bpm-round(bpm))) {
{ LUPPP_WARN("%f",bpm);
LUPPP_WARN("%f",bpm); }
} EventTimeBPM e = EventTimeBPM( bpm );
EventTimeBPM e = EventTimeBPM( bpm ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e );
} }
static void gmastertrack_volume_callback(Fl_Widget *w, void *data) static void gmastertrack_volume_callback(Fl_Widget *w, void *data)
{ {
Avtk::Volume* b = (Avtk::Volume*)w; Avtk::Volume* b = (Avtk::Volume*)w;
float v = b->value(); float v = b->value();
EventMasterVol e( v ); EventMasterVol e( v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} }
static void gmastertrack_inputVolume_callback(Fl_Widget *w, void *data) static void gmastertrack_inputVolume_callback(Fl_Widget *w, void *data)
{ {
Avtk::Volume* b = (Avtk::Volume*)w; Avtk::Volume* b = (Avtk::Volume*)w;
float v = b->value(); float v = b->value();
EventMasterInputVol e( v ); EventMasterInputVol e( v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} }
static void gmastertrack_sidchainKeyButton_callback(Fl_Widget *w, void *data) static void gmastertrack_sidchainKeyButton_callback(Fl_Widget *w, void *data)
{ {
Avtk::LightButton* b = (Avtk::LightButton*)w; Avtk::LightButton* b = (Avtk::LightButton*)w;
b->value( !b->value() ); b->value( !b->value() );
EventMasterInputToActive e( INPUT_TO_SIDE_KEY, b->value() ); EventMasterInputToActive e( INPUT_TO_SIDE_KEY, b->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("Key button\n"); //printf("Key button\n");
} }
static void gmastertrack_mixButton_callback(Fl_Widget *w, void *data) static void gmastertrack_mixButton_callback(Fl_Widget *w, void *data)
{ {
Avtk::LightButton* b = (Avtk::LightButton*)w; Avtk::LightButton* b = (Avtk::LightButton*)w;
b->value( !b->value() ); b->value( !b->value() );
EventMasterInputToActive e( INPUT_TO_MIX, b->value() ); EventMasterInputToActive e( INPUT_TO_MIX, b->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("Mix button\n"); //printf("Mix button\n");
} }
static void gmastertrack_sendButton_callback(Fl_Widget *w, void *data) static void gmastertrack_sendButton_callback(Fl_Widget *w, void *data)
{ {
Avtk::LightButton* b = (Avtk::LightButton*)w; Avtk::LightButton* b = (Avtk::LightButton*)w;
b->value( !b->value() ); b->value( !b->value() );
EventMasterInputToActive e( INPUT_TO_SEND, b->value() ); EventMasterInputToActive e( INPUT_TO_SEND, b->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("Send button\n"); //printf("Send button\n");
} }
static void gmastertrack_sendVol_callback(Fl_Widget *w, void *data) static void gmastertrack_sendVol_callback(Fl_Widget *w, void *data)
{ {
Avtk::Dial* b = (Avtk::Dial*)w; Avtk::Dial* b = (Avtk::Dial*)w;
float v = b->value(); float v = b->value();
EventMasterInputTo e = EventMasterInputTo( INPUT_TO_SEND, v ); EventMasterInputTo e = EventMasterInputTo( INPUT_TO_SEND, v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
///printf("Send dial\n"); ///printf("Send dial\n");
} }
static void gmastertrack_xSideVol_callback(Fl_Widget *w, void *data) static void gmastertrack_xSideVol_callback(Fl_Widget *w, void *data)
{ {
Avtk::Dial* b = (Avtk::Dial*)w; Avtk::Dial* b = (Avtk::Dial*)w;
float v = b->value(); float v = b->value();
EventMasterInputTo e = EventMasterInputTo( INPUT_TO_XSIDE, v ); EventMasterInputTo e = EventMasterInputTo( INPUT_TO_XSIDE, v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("XSide dial\n"); //printf("XSide dial\n");
} }
/// return volume /// return volume
static void gmastertrack_returnVol_callback(Fl_Widget *w, void *data) static void gmastertrack_returnVol_callback(Fl_Widget *w, void *data)
{ {
Avtk::Dial* b = (Avtk::Dial*)w; Avtk::Dial* b = (Avtk::Dial*)w;
float v = b->value(); float v = b->value();
EventMasterReturn e( RETURN_MAIN, v ); EventMasterReturn e( RETURN_MAIN, v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("Return dial\n"); //printf("Return dial\n");
} }
static void gmastertrack_mixVol_callback(Fl_Widget *w, void *data) static void gmastertrack_mixVol_callback(Fl_Widget *w, void *data)
{ {
Avtk::Dial* b = (Avtk::Dial*)w; Avtk::Dial* b = (Avtk::Dial*)w;
float v = b->value(); float v = b->value();
EventMasterInputTo e = EventMasterInputTo( INPUT_TO_MIX, v ); EventMasterInputTo e = EventMasterInputTo( INPUT_TO_MIX, v );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} }
static void gmastertrack_transport_callback(Fl_Widget *w, void *data) static void gmastertrack_transport_callback(Fl_Widget *w, void *data)
{ {
Avtk::LightButton* b = (Avtk::LightButton*)w; Avtk::LightButton* b = (Avtk::LightButton*)w;
if( b->value() ) if( b->value() ) {
{ EventTransportState e = EventTransportState( TRANSPORT_ROLLING );
EventTransportState e = EventTransportState( TRANSPORT_ROLLING ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); w->label( "Stop" );
w->label( "Stop" ); b->value( 0 );
b->value( 0 ); } else {
} EventTransportState e = EventTransportState( TRANSPORT_STOPPED );
else writeToDspRingbuffer( &e );
{ w->label( "Play" );
EventTransportState e = EventTransportState( TRANSPORT_STOPPED ); b->value( 1 );
writeToDspRingbuffer( &e ); }
w->label( "Play" );
b->value( 1 );
}
} }
static void gmastertrack_button_callback(Fl_Widget *w, void *data) static void gmastertrack_button_callback(Fl_Widget *w, void *data)
{ {
if ( strcmp( w->label(), "Metro" ) == 0 ) if ( strcmp( w->label(), "Metro" ) == 0 ) {
{ if ( Fl::event_button() == FL_RIGHT_MOUSE ) {
if ( Fl::event_button() == FL_RIGHT_MOUSE ) // popup volume menu: 10 "steps of volume"
{ Fl_Menu_Item rclick_menu[] = {
// popup volume menu: 10 "steps of volume" { "Vol 100%" },
Fl_Menu_Item rclick_menu[] = { "Vol 75%" },
{ { "Vol 50%" },
{ "Vol 100%" }, { "Vol 25%"},
{ "Vol 75%" }, { 0 }
{ "Vol 50%" }, };
{ "Vol 25%"},
{ 0 } Fl_Menu_Item *m = (Fl_Menu_Item*) rclick_menu->popup( Fl::event_x(), Fl::event_y(), 0, 0, 0);
};
float v = 0.f;
Fl_Menu_Item *m = (Fl_Menu_Item*) rclick_menu->popup( Fl::event_x(), Fl::event_y(), 0, 0, 0); if ( !m ) {
return;
float v = 0.f; } else if ( strcmp(m->label(), "Vol 100%") == 0 ) {
if ( !m ) v = 1;
{ } else if ( strcmp(m->label(), "Vol 75%") == 0 ) {
return; v = 0.75;
} } else if ( strcmp(m->label(), "Vol 50%") == 0 ) {
else if ( strcmp(m->label(), "Vol 100%") == 0 ) { v = 0.5;
v = 1; } else
} v = 0.25;
else if ( strcmp(m->label(), "Vol 75%") == 0 ) {
v = 0.75; LUPPP_NOTE("metro vol = %f", v );
}
else if ( strcmp(m->label(), "Vol 50%") == 0 ) { EventMetronomeVolume e( v );
v = 0.5; writeToDspRingbuffer( &e );
} } else {
else Avtk::LightButton* b = (Avtk::LightButton*)w;
v = 0.25; b->value( !b->value() );
EventMetronomeActive e = EventMetronomeActive( b->value() );
LUPPP_NOTE("metro vol = %f", v ); writeToDspRingbuffer( &e );
}
EventMetronomeVolume e( v );
writeToDspRingbuffer( &e );
}
else } else if ( strcmp( w->label(), "Tap" ) == 0 ) {
{ EventTimeTempoTap e;
Avtk::LightButton* b = (Avtk::LightButton*)w; writeToDspRingbuffer( &e );
b->value( !b->value() ); } else {
EventMetronomeActive e = EventMetronomeActive( b->value() ); LUPPP_WARN("Error: unknown command string");
writeToDspRingbuffer( &e ); }
}
}
else if ( strcmp( w->label(), "Tap" ) == 0 )
{
EventTimeTempoTap e;
writeToDspRingbuffer( &e );
}
else
{
LUPPP_WARN("Error: unknown command string");
}
} }
#define OFST 33 #define OFST 33
GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) : GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
Fl_Group(x, y, w, h), Fl_Group(x, y, w, h),
title( strdup(l) ), title( strdup(l) ),
bg( x, y , w, h, title ), bg( x, y , w, h, title ),
// with "true" master flag: launches scenes instead of clips on tracks // with "true" master flag: launches scenes instead of clips on tracks
clipSel(x + 5, y + 26 + 102, 140, 294,"", true), clipSel(x + 5, y + 26 + 102, 140, 294,"", true),
source(x+5, y+26, 140, 100, ""), source(x+5, y+26, 140, 100, ""),
volBox(x+5, y+422, 140, 232, ""), volBox(x+5, y+422, 140, 232, ""),
transport ( x + w * 2/4.f - 18, y + 436 + OFST * 0, 44,28, "Stop" ), transport ( x + w * 2/4.f - 18, y + 436 + OFST * 0, 44,28, "Stop" ),
tapTempo ( x + w * 2/4.f - 18, y + 436 + OFST * 1, 44,28, "Tap" ), tapTempo ( x + w * 2/4.f - 18, y + 436 + OFST * 1, 44,28, "Tap" ),
metronomeButton( x + w * 2/4.f - 18, y + 436 + OFST * 2, 44,28,"Metro"), metronomeButton( x + w * 2/4.f - 18, y + 436 + OFST * 2, 44,28,"Metro"),
tempoDial ( x + w * 2/4.f - 18, y + 436 + OFST * 3.5, 45, 38,"BPM"), tempoDial ( x + w * 2/4.f - 18, y + 436 + OFST * 3.5, 45, 38,"BPM"),
returnVol ( x + w * 2/4.f - 18, y + 436 + OFST * 5, 45, 38,"Return"), returnVol ( x + w * 2/4.f - 18, y + 436 + OFST * 5, 45, 38,"Return"),
inputVolume(x + 9,y + 26 + 4, w - 18, 30,""), inputVolume(x + 9,y + 26 + 4, w - 18, 30,""),
inputToSend (x + 10,y + 28 + 68, 40, 26,"Snd"), inputToSend (x + 10,y + 28 + 68, 40, 26,"Snd"),
inputToSendVol(x + w*0.2-15,y + 28 + 36, 30, 30,""), inputToSendVol(x + w*0.2-15,y + 28 + 36, 30, 30,""),
inputToSidechainKey (x + w*0.5-20,y + 28 + 68, 40, 26,"Key"), inputToSidechainKey (x + w*0.5-20,y + 28 + 68, 40, 26,"Key"),
inputToSidechainSignalVol(x + w*0.5-15,y + 28 + 36, 30, 30,""), inputToSidechainSignalVol(x + w*0.5-15,y + 28 + 36, 30, 30,""),
inputToMix (x + w*0.8-20,y + 28 + 68, 40, 26,"Mix"), inputToMix (x + w*0.8-20,y + 28 + 68, 40, 26,"Mix"),
inputToMixVol(x + w*0.8-15,y + 28 + 36, 30, 30,""), inputToMixVol(x + w*0.8-15,y + 28 + 36, 30, 30,""),
volume(x+106, y +425, 36, 216, "") volume(x+106, y +425, 36, 216, "")
{ {
ID = privateID++; ID = privateID++;
bar = 0; bar = 0;
inputVolume.value(0.5); inputVolume.value(0.5);
inputVolume.setOrientationHorizontal(); inputVolume.setOrientationHorizontal();
inputVolume.callback( gmastertrack_inputVolume_callback, 0 ); inputVolume.callback( gmastertrack_inputVolume_callback, 0 );
transport.callback( gmastertrack_transport_callback, &ID ); transport.callback( gmastertrack_transport_callback, &ID );
tapTempo.callback( gmastertrack_button_callback, &ID ); tapTempo.callback( gmastertrack_button_callback, &ID );
metronomeButton.callback( gmastertrack_button_callback, 0 ); metronomeButton.callback( gmastertrack_button_callback, 0 );
tempoDial.callback( gmastertrack_tempoDial_callback, 0 ); tempoDial.callback( gmastertrack_tempoDial_callback, 0 );
inputToSend.setColor( 0, 1.0, 0 ); inputToSend.setColor( 0, 1.0, 0 );
inputToSend.callback( gmastertrack_sendButton_callback, 0 ); inputToSend.callback( gmastertrack_sendButton_callback, 0 );
inputToSendVol.callback( gmastertrack_sendVol_callback, 0 ); inputToSendVol.callback( gmastertrack_sendVol_callback, 0 );
inputToSidechainKey.setColor( 0, 0.6, 1 ); inputToSidechainKey.setColor( 0, 0.6, 1 );
inputToSidechainKey.callback( gmastertrack_sidchainKeyButton_callback, 0 ); inputToSidechainKey.callback( gmastertrack_sidchainKeyButton_callback, 0 );
inputToSidechainSignalVol.value( 0 ); inputToSidechainSignalVol.value( 0 );
inputToSidechainSignalVol.callback( gmastertrack_xSideVol_callback, 0 ); inputToSidechainSignalVol.callback( gmastertrack_xSideVol_callback, 0 );
inputToMix.callback ( gmastertrack_mixButton_callback, 0 ); inputToMix.callback ( gmastertrack_mixButton_callback, 0 );
inputToMixVol.callback ( gmastertrack_mixVol_callback, 0 ); inputToMixVol.callback ( gmastertrack_mixVol_callback, 0 );
tempoDial.align( FL_ALIGN_CENTER ); tempoDial.align( FL_ALIGN_CENTER );
returnVol.value( 1.f ); returnVol.value( 1.f );
returnVol.align( FL_ALIGN_CENTER ); returnVol.align( FL_ALIGN_CENTER );
returnVol.callback( gmastertrack_returnVol_callback, 0 ); returnVol.callback( gmastertrack_returnVol_callback, 0 );
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++) {
{ beatLights[i] = new Avtk::LightButton( x + 10, y + 437 + 54 * i, 40, 42, "" );
beatLights[i] = new Avtk::LightButton( x + 10, y + 437 + 54 * i, 40, 42, "" ); }
} beatLights[0]->setColor( 1.0, 0.0 , 0.0 );
beatLights[0]->setColor( 1.0, 0.0 , 0.0 ); beatLights[1]->setColor( 1.0, 0.48, 0.0 );
beatLights[1]->setColor( 1.0, 0.48, 0.0 ); beatLights[2]->setColor( 1.0, 1.0 , 0.0 );
beatLights[2]->setColor( 1.0, 1.0 , 0.0 ); beatLights[3]->setColor( 0.0, 1.0 , 0.0 );
beatLights[3]->setColor( 0.0, 1.0 , 0.0 );
volume.amplitude( 0.0, 0.0 );
volume.amplitude( 0.0, 0.0 ); volume.callback( gmastertrack_volume_callback, 0 );
volume.callback( gmastertrack_volume_callback, 0 );
end(); // close the group
end(); // close the group
} }
void GMasterTrack::setBpm( int b ) void GMasterTrack::setBpm( int b )
{ {
bpm = b; bpm = b;
tempoDial.value( ( bpm - 60 ) / 160.f ); tempoDial.value( ( bpm - 60 ) / 160.f );
std::stringstream s; std::stringstream s;
s << bpm; s << bpm;
tempoDial.setLabel( s.str().c_str() ); tempoDial.setLabel( s.str().c_str() );
} }
void GMasterTrack::setInputVol(float f) void GMasterTrack::setInputVol(float f)
{ {
//LUPPP_NOTE(" gmtrck, inputVol %f", f ); //LUPPP_NOTE(" gmtrck, inputVol %f", f );
inputVolume.value( f ); inputVolume.value( f );
} }
void GMasterTrack::setReturnVol(float f) void GMasterTrack::setReturnVol(float f)
{ {
LUPPP_NOTE(" gmtrck, returnVol %f", f ); LUPPP_NOTE(" gmtrck, returnVol %f", f );
returnVol.value( f ); returnVol.value( f );
} }
void GMasterTrack::setInputTo(int to, float f) void GMasterTrack::setInputTo(int to, float f)
{ {
//LUPPP_NOTE(" gmtrck, inputTO %i, %f", to, f ); //LUPPP_NOTE(" gmtrck, inputTO %i, %f", to, f );
if ( to == Event::INPUT_TO_MIX ) if ( to == Event::INPUT_TO_MIX )
inputToMixVol.value( f ); inputToMixVol.value( f );
else if ( to == Event::INPUT_TO_SEND ) else if ( to == Event::INPUT_TO_SEND )
inputToSendVol.value( f ); inputToSendVol.value( f );
else if ( to == Event::INPUT_TO_XSIDE ) else if ( to == Event::INPUT_TO_XSIDE )
inputToSidechainSignalVol.value( f ); inputToSidechainSignalVol.value( f );
} }
void GMasterTrack::setInputToActive(int to, bool f) void GMasterTrack::setInputToActive(int to, bool f)
{ {
//LUPPP_NOTE(" gmtrck, inputToActive %i, %i", to, int(f) ); //LUPPP_NOTE(" gmtrck, inputToActive %i, %i", to, int(f) );
if ( to == Event::INPUT_TO_MIX ) if ( to == Event::INPUT_TO_MIX )
inputToMix.value( f ); inputToMix.value( f );
else if ( to == Event::INPUT_TO_SEND ) else if ( to == Event::INPUT_TO_SEND )
inputToSend.value( f ); inputToSend.value( f );
else if ( to == Event::INPUT_TO_SIDE_KEY ) else if ( to == Event::INPUT_TO_SIDE_KEY )
inputToSidechainKey.value( f ); inputToSidechainKey.value( f );
} }
void GMasterTrack::metronomeEnable( bool b ) void GMasterTrack::metronomeEnable( bool b )
{ {
metronomeButton.value( b ); metronomeButton.value( b );
} }
int GMasterTrack::getBpm() int GMasterTrack::getBpm()
{ {
return bpm; return bpm;
} }
void GMasterTrack::setTapTempo( bool b ) void GMasterTrack::setTapTempo( bool b )
{ {
tapTempo.setHighlight( b ); tapTempo.setHighlight( b );
} }
void GMasterTrack::setBarBeat(int b, int beat) void GMasterTrack::setBarBeat(int b, int beat)
{ {
// FIXME: hard coded 4/4 time here // FIXME: hard coded 4/4 time here
if ( beat % 4 == 0 ) if ( beat % 4 == 0 ) {
{ bar = bar % 4 + 1;
bar = bar % 4 + 1; }
}
// turn all off
// turn all off for( int i = 0; i < 4; i++)
for( int i = 0; i < 4; i++) beatLights[i]->value( 0 );
beatLights[i]->value( 0 );
// beat starts at 4
// beat starts at 4 // FIXME: hard coded 4/4 time
// FIXME: hard coded 4/4 time beatLights[ 3 - beat%4 ]->value( 1 );
beatLights[ 3 - beat%4 ]->value( 1 );
} }
Avtk::Volume* GMasterTrack::getInputVolume() Avtk::Volume* GMasterTrack::getInputVolume()
{ {
return &inputVolume; return &inputVolume;
} }
Avtk::Volume* GMasterTrack::getVolume() Avtk::Volume* GMasterTrack::getVolume()
{ {
return &volume; return &volume;
} }
Avtk::LightButton* GMasterTrack::getInputToSend() Avtk::LightButton* GMasterTrack::getInputToSend()
{ {
return &inputToSend; return &inputToSend;
} }
Avtk::LightButton* GMasterTrack::getInputToSidechainKey() Avtk::LightButton* GMasterTrack::getInputToSidechainKey()
{ {
return &inputToSidechainKey; return &inputToSidechainKey;
} }
Avtk::LightButton* GMasterTrack::getInputToMix() Avtk::LightButton* GMasterTrack::getInputToMix()
{ {
return &inputToMix; return &inputToMix;
} }
Avtk::Dial* GMasterTrack::getInputToSendVol() Avtk::Dial* GMasterTrack::getInputToSendVol()
{ {
return &inputToSendVol; return &inputToSendVol;
} }
Avtk::Dial* GMasterTrack::getInputToXSide() Avtk::Dial* GMasterTrack::getInputToXSide()
{ {
return &inputToSidechainSignalVol; return &inputToSidechainSignalVol;
} }
Avtk::Dial* GMasterTrack::getInputToMixVol() Avtk::Dial* GMasterTrack::getInputToMixVol()
{ {
return &inputToMixVol; return &inputToMixVol;
} }
Avtk::ClipSelector* GMasterTrack::getClipSelector() Avtk::ClipSelector* GMasterTrack::getClipSelector()
{ {
return &clipSel; return &clipSel;
} }
GMasterTrack::~GMasterTrack() GMasterTrack::~GMasterTrack()
{ {
free(title); free(title);
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -45,72 +45,72 @@ using namespace std;
class GMasterTrack : public Fl_Group class GMasterTrack : public Fl_Group
{ {
public: public:
GMasterTrack(int x, int y, int w, int h, const char* l = 0 ); GMasterTrack(int x, int y, int w, int h, const char* l = 0 );
int getBpm(); int getBpm();
void setBpm( int bpm ); void setBpm( int bpm );
void setTapTempo( bool b ); void setTapTempo( bool b );
void setBarBeat(int b, int beat); void setBarBeat(int b, int beat);
void setReturnVol(float f); void setReturnVol(float f);
void setInputVol(float f); void setInputVol(float f);
void setInputTo(int to, float f); void setInputTo(int to, float f);
void setInputToActive(int to, bool f); void setInputToActive(int to, bool f);
void metronomeEnable( bool b ); void metronomeEnable( bool b );
Avtk::Volume* getInputVolume(); Avtk::Volume* getInputVolume();
Avtk::Volume* getVolume(); Avtk::Volume* getVolume();
Avtk::ClipSelector* getClipSelector(); Avtk::ClipSelector* getClipSelector();
Avtk::LightButton* getInputToSend(); Avtk::LightButton* getInputToSend();
Avtk::LightButton* getInputToSidechainKey(); Avtk::LightButton* getInputToSidechainKey();
Avtk::LightButton* getInputToMix(); Avtk::LightButton* getInputToMix();
Avtk::Dial* getInputToSendVol(); Avtk::Dial* getInputToSendVol();
Avtk::Dial* getInputToXSide(); Avtk::Dial* getInputToXSide();
Avtk::Dial* getInputToMixVol(); Avtk::Dial* getInputToMixVol();
~GMasterTrack(); ~GMasterTrack();
private: private:
int ID; int ID;
char* title; char* title;
int bar; int bar;
int bpm; int bpm;
Avtk::Background bg; Avtk::Background bg;
Avtk::ClipSelector clipSel; Avtk::ClipSelector clipSel;
Avtk::Box source; Avtk::Box source;
Avtk::Box volBox; Avtk::Box volBox;
Avtk::Button transport; Avtk::Button transport;
Avtk::Button tapTempo; Avtk::Button tapTempo;
Avtk::LightButton metronomeButton; Avtk::LightButton metronomeButton;
Avtk::Dial tempoDial; Avtk::Dial tempoDial;
Avtk::Dial returnVol; Avtk::Dial returnVol;
Avtk::LightButton* beatLights[4]; Avtk::LightButton* beatLights[4];
Avtk::Volume inputVolume; Avtk::Volume inputVolume;
Avtk::LightButton inputToSend; Avtk::LightButton inputToSend;
Avtk::Dial inputToSendVol; Avtk::Dial inputToSendVol;
Avtk::LightButton inputToSidechainKey; Avtk::LightButton inputToSidechainKey;
Avtk::Dial inputToSidechainSignalVol; Avtk::Dial inputToSidechainSignalVol;
Avtk::LightButton inputToMix; Avtk::LightButton inputToMix;
Avtk::Dial inputToMixVol; Avtk::Dial inputToMixVol;
Avtk::Volume volume; Avtk::Volume volume;
static int privateID; static int privateID;
}; };
#endif // LUPPP_G_MASTER_TRACK_H #endif // LUPPP_G_MASTER_TRACK_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,449 +33,432 @@ extern Gui* gui;
static void addControllerUiDsp(OptionsWindow* self, GenericMIDI* c) static void addControllerUiDsp(OptionsWindow* self, GenericMIDI* c)
{ {
// add the controller to the UI // add the controller to the UI
int x, y, w, h; int x, y, w, h;
self->tabs->client_area( x, y, w, h, 25 ); self->tabs->client_area( x, y, w, h, 25 );
self->controllers.push_back( new ControllerUI( x, y, w, h, c->getName().c_str(), c->getID() ) ); self->controllers.push_back( new ControllerUI( x, y, w, h, c->getName().c_str(), c->getID() ) );
// store the pointer to the options window: needed to make remove button work
self->controllers.back()->optionsWindow = self;
LUPPP_NOTE("Added controller %s, ID %i", c->getName().c_str(), c->getID() );
// add widget before "add" button // store the pointer to the options window: needed to make remove button work
self->tabs->insert( *self->controllers.back()->widget, self->addGroup ); self->controllers.back()->optionsWindow = self;
// tell the ControllerUI to add the bindings from this Controller* LUPPP_NOTE("Added controller %s, ID %i", c->getName().c_str(), c->getID() );
self->controllers.back()->setAuthor( c->getAuthor() );
self->controllers.back()->setLink( c->getEmail() ); // add widget before "add" button
self->controllers.back()->addBindings( c ); self->tabs->insert( *self->controllers.back()->widget, self->addGroup );
self->tabs->redraw(); // tell the ControllerUI to add the bindings from this Controller*
self->controllers.back()->setAuthor( c->getAuthor() );
// send to DSP side self->controllers.back()->setLink( c->getEmail() );
EventControllerInstance e(c); self->controllers.back()->addBindings( c );
writeToDspRingbuffer( &e );
self->tabs->redraw();
// send to DSP side
EventControllerInstance e(c);
writeToDspRingbuffer( &e );
} }
static void updateAuthorCB(Fl_Widget* w, void* data) static void updateAuthorCB(Fl_Widget* w, void* data)
{ {
ControllerUI* c = (ControllerUI*)data; ControllerUI* c = (ControllerUI*)data;
const char* s = fl_input( "Author: ", "" ); const char* s = fl_input( "Author: ", "" );
if ( s ) if ( s ) {
{ c->setAuthor( s );
c->setAuthor( s ); }
}
} }
static void updateLinkCB(Fl_Widget* w, void* data) static void updateLinkCB(Fl_Widget* w, void* data)
{ {
ControllerUI* c = (ControllerUI*)data; ControllerUI* c = (ControllerUI*)data;
stringstream str; stringstream str;
str << "xdg-open "; str << "xdg-open ";
// add http:// if its not in the string // add http:// if its not in the string
std::string l = c->getLink(); std::string l = c->getLink();
if ( ( l.find("http") ) == std::string::npos ) if ( ( l.find("http") ) == std::string::npos )
str << " http://"; str << " http://";
str << l; str << l;
system( str.str().c_str() ); system( str.str().c_str() );
} }
static void writeBindEnable(Fl_Widget* w, void* data) static void writeBindEnable(Fl_Widget* w, void* data)
{ {
OptionsWindow* o = (OptionsWindow*) data; OptionsWindow* o = (OptionsWindow*) data;
//LUPPP_NOTE("MIDI bind mode"); //LUPPP_NOTE("MIDI bind mode");
Avtk::LightButton* l = (Avtk::LightButton*)w; Avtk::LightButton* l = (Avtk::LightButton*)w;
l->value( !l->value() ); l->value( !l->value() );
int controllerID = -1; // waste? int controllerID = -1; // waste?
EventControllerBindingEnable e( controllerID, l->value() ); EventControllerBindingEnable e( controllerID, l->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} }
static void removeControllerCB(Fl_Widget* w, void* data) static void removeControllerCB(Fl_Widget* w, void* data)
{ {
ControllerUI* self = (ControllerUI*)data; ControllerUI* self = (ControllerUI*)data;
// Remove UI tab for that controller // Remove UI tab for that controller
// should return "tabs" from OptionsWindow // should return "tabs" from OptionsWindow
self->optionsWindow->tabs->remove( self->widget ); self->optionsWindow->tabs->remove( self->widget );
self->optionsWindow->tabs->redraw(); self->optionsWindow->tabs->redraw();
// FIXME: confirm action here? // FIXME: confirm action here?
//LUPPP_NOTE("Removing controllerID %i", self->controllerID ); //LUPPP_NOTE("Removing controllerID %i", self->controllerID );
EventControllerInstanceRemove e( self->controllerID ); EventControllerInstanceRemove e( self->controllerID );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
delete self; delete self;
} }
static void addNewController(Fl_Widget* w, void* ud) static void addNewController(Fl_Widget* w, void* ud)
{ {
OptionsWindow* self = (OptionsWindow*)ud; OptionsWindow* self = (OptionsWindow*)ud;
LUPPP_NOTE("%s","ADD Controller cb"); LUPPP_NOTE("%s","ADD Controller cb");
GenericMIDI* c = 0; GenericMIDI* c = 0;
const char* name = fl_input( "Controller name: ", "" ); const char* name = fl_input( "Controller name: ", "" );
if ( name ) if ( name ) {
{ c = new GenericMIDI( 0, name);
c = new GenericMIDI( 0, name); } else {
} return;
else }
{
return;
} if ( c->status() == Controller::CONTROLLER_OK ) {
addControllerUiDsp( self, c );
} else {
if ( c->status() == Controller::CONTROLLER_OK ) LUPPP_ERROR("Controller initialization failed!");
{ }
addControllerUiDsp( self, c );
}
else
{
LUPPP_ERROR("Controller initialization failed!");
}
} }
static void selectLoadController(Fl_Widget* w, void* data) static void selectLoadController(Fl_Widget* w, void* data)
{ {
OptionsWindow* self = (OptionsWindow*)data; OptionsWindow* self = (OptionsWindow*)data;
// FIXME: refactor // FIXME: refactor
string path; string path;
Fl_Native_File_Chooser fnfc; Fl_Native_File_Chooser fnfc;
fnfc.title("Pick a controller definition"); fnfc.title("Pick a controller definition");
fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE); fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
fnfc.filter("Controllers\t*.ctlr"); fnfc.filter("Controllers\t*.ctlr");
stringstream s; stringstream s;
s << getenv("HOME") << "/.config/openAV/luppp/controllers/"; s << getenv("HOME") << "/.config/openAV/luppp/controllers/";
fnfc.directory( s.str().c_str() ); // default directory to use fnfc.directory( s.str().c_str() ); // default directory to use
// Show native chooser // Show native chooser
switch ( fnfc.show() ) { switch ( fnfc.show() ) {
case -1: /*printf("ERROR: %s\n", fnfc.errmsg());*/ break; // ERROR case -1: /*printf("ERROR: %s\n", fnfc.errmsg());*/
case 1: /*printf("CANCEL\n"); */ break; // CANCEL break; // ERROR
default: case 1: /*printf("CANCEL\n"); */
//printf("Loading controller at %s\n", fnfc.filename()); break; // CANCEL
path = fnfc.filename(); default:
break; //printf("Loading controller at %s\n", fnfc.filename());
} path = fnfc.filename();
break;
if ( strcmp( path.c_str(), "" ) == 0 ) }
return;
if ( strcmp( path.c_str(), "" ) == 0 )
//LUPPP_NOTE("%s","ADD Controller cb"); return;
GenericMIDI* c = new GenericMIDI( path );
//LUPPP_NOTE("%s","ADD Controller cb");
if ( c->status() == Controller::CONTROLLER_OK ) GenericMIDI* c = new GenericMIDI( path );
{
addControllerUiDsp( self, c ); if ( c->status() == Controller::CONTROLLER_OK ) {
} addControllerUiDsp( self, c );
else } else {
{ LUPPP_ERROR("Controller initialization failed!");
LUPPP_ERROR("Controller initialization failed!"); }
}
} }
static void writeControllerFile(Fl_Widget* w, void* data) static void writeControllerFile(Fl_Widget* w, void* data)
{ {
ControllerUI* c = (ControllerUI*)data; ControllerUI* c = (ControllerUI*)data;
LUPPP_NOTE("Writing controller %li, %s ID %i .ctlr to disk", c, c->name.c_str(), c->controllerID ); LUPPP_NOTE("Writing controller %li, %s ID %i .ctlr to disk", c, c->name.c_str(), c->controllerID );
// Set the Controller details in diskWriter, so it write it pretty // Set the Controller details in diskWriter, so it write it pretty
gui->getDiskWriter()->writeControllerInfo( CONTROLLER_NAME , c->name ); gui->getDiskWriter()->writeControllerInfo( CONTROLLER_NAME , c->name );
gui->getDiskWriter()->writeControllerInfo( CONTROLLER_AUTHOR, c->getAuthor()); gui->getDiskWriter()->writeControllerInfo( CONTROLLER_AUTHOR, c->getAuthor());
gui->getDiskWriter()->writeControllerInfo( CONTROLLER_LINK , c->getLink() ); gui->getDiskWriter()->writeControllerInfo( CONTROLLER_LINK , c->getLink() );
EventControllerInstanceGetToWrite e( c->controllerID ); EventControllerInstanceGetToWrite e( c->controllerID );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
} }
static void deleteBindingFromController(Fl_Widget* w, void* ud) static void deleteBindingFromController(Fl_Widget* w, void* ud)
{ {
ControllerUI* self = (ControllerUI*)ud; ControllerUI* self = (ControllerUI*)ud;
stringstream s; stringstream s;
s << w->label(); s << w->label();
int tmp; int tmp;
s >> tmp; s >> tmp;
LUPPP_NOTE("CtlrID %i: Deleting binding with ID %i", self->controllerID, tmp ); LUPPP_NOTE("CtlrID %i: Deleting binding with ID %i", self->controllerID, tmp );
EventControllerBindingRemove e( self->controllerID, tmp ); EventControllerBindingRemove e( self->controllerID, tmp );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
// remove "this" widget (and its parent Pack) from the list of MIDI bindings: // remove "this" widget (and its parent Pack) from the list of MIDI bindings:
self->bindingsPack->remove( w->parent() ); self->bindingsPack->remove( w->parent() );
self->bindingsPack->redraw(); self->bindingsPack->redraw();
self->scroll->redraw(); self->scroll->redraw();
} }
ControllerUI::ControllerUI(int x, int y, int w, int h, std::string n, int ID) ControllerUI::ControllerUI(int x, int y, int w, int h, std::string n, int ID)
{ {
name = n; name = n;
widget = new Fl_Group( x, y, w, h, name.c_str()); widget = new Fl_Group( x, y, w, h, name.c_str());
{ {
// author / link // author / link
authorLabel = new Avtk::Button( x + 5, y + 5, 190, 25, "Author?" ); authorLabel = new Avtk::Button( x + 5, y + 5, 190, 25, "Author?" );
linkLabel = new Avtk::Button( x + 7+ w/2, y + 5, 190, 25, "Link?" ); linkLabel = new Avtk::Button( x + 7+ w/2, y + 5, 190, 25, "Link?" );
authorLabel->label("Author?"); authorLabel->label("Author?");
authorLabel->label("Link?"); authorLabel->label("Link?");
authorLabel->callback( updateAuthorCB, this ); authorLabel->callback( updateAuthorCB, this );
linkLabel->callback( updateLinkCB, this ); linkLabel->callback( updateLinkCB, this );
// binding / target // binding / target
targetLabelStat = new Fl_Box(x + 100,y + 32, 75, 25,"Target: "); targetLabelStat = new Fl_Box(x + 100,y + 32, 75, 25,"Target: ");
targetLabel = new Fl_Box(x + 140,y + 32, 200, 25,""); targetLabel = new Fl_Box(x + 140,y + 32, 200, 25,"");
bindEnable = new Avtk::LightButton(x + 5, y + 32, 100, 25, "Bind Enable"); bindEnable = new Avtk::LightButton(x + 5, y + 32, 100, 25, "Bind Enable");
writeControllerBtn = new Avtk::Button( x + 5, y + h - 27, 100, 25, "Save" ); writeControllerBtn = new Avtk::Button( x + 5, y + h - 27, 100, 25, "Save" );
removeController = new Avtk::Button( x + 110, y + h - 27, 100, 25, "Remove"); removeController = new Avtk::Button( x + 110, y + h - 27, 100, 25, "Remove");
scroll = new Fl_Scroll( x + 5, y + 82, 395, 265 ); scroll = new Fl_Scroll( x + 5, y + 82, 395, 265 );
{ {
bindingsPack = new Fl_Pack( x + 5, y + 82, w - 15, 270-10); bindingsPack = new Fl_Pack( x + 5, y + 82, w - 15, 270-10);
bindingsPack->end(); bindingsPack->end();
bindingsPack->spacing( 2 ); bindingsPack->spacing( 2 );
bindingsPack->box(FL_DOWN_FRAME); bindingsPack->box(FL_DOWN_FRAME);
} }
scroll->resizable( bindingsPack ); scroll->resizable( bindingsPack );
scroll->box( FL_DOWN_FRAME ); scroll->box( FL_DOWN_FRAME );
scroll->type( Fl_Scroll::VERTICAL_ALWAYS ); scroll->type( Fl_Scroll::VERTICAL_ALWAYS );
scroll->end(); scroll->end();
widget->resizable( scroll ); widget->resizable( scroll );
} }
widget->end(); widget->end();
widget->redraw(); widget->redraw();
// save the controller ID this ControllerUI represents // save the controller ID this ControllerUI represents
controllerID = ID; controllerID = ID;
LUPPP_NOTE("Controller %li ID on create %i", this, controllerID ); LUPPP_NOTE("Controller %li ID on create %i", this, controllerID );
//ctlrButton->callback( selectLoadController ); //ctlrButton->callback( selectLoadController );
bindEnable->callback( writeBindEnable, this ); bindEnable->callback( writeBindEnable, this );
removeController->callback( removeControllerCB, this ); removeController->callback( removeControllerCB, this );
writeControllerBtn->callback( writeControllerFile, this ); writeControllerBtn->callback( writeControllerFile, this );
} }
void OptionsWindow::setTarget(const char* n) void OptionsWindow::setTarget(const char* n)
{ {
for(unsigned int i = 0; i < controllers.size(); i++ ) for(unsigned int i = 0; i < controllers.size(); i++ ) {
{ controllers.at(i)->setTarget( n );
controllers.at(i)->setTarget( n ); }
}
} }
void ControllerUI::setTarget( const char* n ) void ControllerUI::setTarget( const char* n )
{ {
target = n; target = n;
targetLabel->label( target.c_str() ); targetLabel->label( target.c_str() );
targetLabel->redraw(); targetLabel->redraw();
} }
void ControllerUI::setAuthor(std::string a) void ControllerUI::setAuthor(std::string a)
{ {
author = a; author = a;
authorLabel->label( author.c_str() ); authorLabel->label( author.c_str() );
authorLabel->redraw(); authorLabel->redraw();
} }
void ControllerUI::setLink(std::string e) void ControllerUI::setLink(std::string e)
{ {
link = e; link = e;
linkLabel->label( link.c_str() ); linkLabel->label( link.c_str() );
linkLabel->redraw(); linkLabel->redraw();
} }
void ControllerUI::setBindEnable( bool b ) void ControllerUI::setBindEnable( bool b )
{ {
bindEnable->value( b ); bindEnable->value( b );
} }
void ControllerUI::addBinding( Binding* b ) void ControllerUI::addBinding( Binding* b )
{ {
if ( b->action != EVENT_NULL ) if ( b->action != EVENT_NULL ) {
{ // add individual bindings as they're made
// add individual bindings as they're made const char* tmp = Event::getPrettyName( b->action );
const char* tmp = Event::getPrettyName( b->action ); if ( !tmp ) {
if ( !tmp )
{
#ifdef DEBUG_MIDI #ifdef DEBUG_MIDI
LUPPP_NOTE("new binding, action string returned NULL, action number %i ", b->action ); LUPPP_NOTE("new binding, action string returned NULL, action number %i ", b->action );
#endif #endif
return; return;
} }
} } else {
else LUPPP_WARN("new binding, action: == EVENT_NULL" );
{ return;
LUPPP_WARN("new binding, action: == EVENT_NULL" ); }
return;
} // push the bindingID onto the vector
bindingID.push_back( b->ID );
// push the bindingID onto the vector
bindingID.push_back( b->ID ); // create a horizontal pack, add that to the bindingsPack
Fl_Pack* tmp = new Fl_Pack( 35, 35, 25, 25);
// create a horizontal pack, add that to the bindingsPack {
Fl_Pack* tmp = new Fl_Pack( 35, 35, 25, 25); tmp->type( Fl_Pack::HORIZONTAL );
{ tmp->spacing( 2 );
tmp->type( Fl_Pack::HORIZONTAL );
tmp->spacing( 2 ); stringstream s;
stringstream s; if ( b->action == MASTER_VOL )
s << "Master Volume";
if ( b->action == MASTER_VOL ) else if ( false )
s << "Master Volume"; s << "stuff";
else if ( false ) else
s << "stuff"; s << Event::getPrettyName( b->action );
else
s << Event::getPrettyName( b->action );
if (b->track != -2)
s << " Track:" << b->track + 1;
if (b->track != -2)
s << " Track:" << b->track + 1; if (b->scene != -1)
s << " Scene:" << b->scene + 1;
if (b->scene != -1)
s << " Scene:" << b->scene + 1; if ( b->send == Event::SEND_POSTFADER )
s << " Post-fader Send";
if ( b->send == Event::SEND_POSTFADER ) if ( b->send == Event::SEND_XSIDE )
s << " Post-fader Send"; s << " Sidechain Crossfade";
if ( b->send == Event::SEND_XSIDE ) if ( b->send == Event::SEND_KEY )
s << " Sidechain Crossfade"; s << " Sidechain Key";
if ( b->send == Event::SEND_KEY )
s << " Sidechain Key"; if ( b->active != -1) {
if ( b->active == true )
if ( b->active != -1) s << " On";
{ if ( b->active == false )
if ( b->active == true ) s << " Off";
s << " On"; }
if ( b->active == false )
s << " Off"; // button to remove a binding, uses bindingsID vector to get unique number
} stringstream id;
id << b->ID;
// button to remove a binding, uses bindingsID vector to get unique number Fl_Button* but = new Fl_Button(35, 35, 25, 25, strdup(id.str().c_str() ) );
stringstream id; but->callback( deleteBindingFromController, this );
id << b->ID; but->redraw();
Fl_Button* but = new Fl_Button(35, 35, 25, 25, strdup(id.str().c_str() ) );
but->callback( deleteBindingFromController, this ); Fl_Box* b = new Fl_Box(35, 35, 400, 25, strdup(s.str().c_str()) );
but->redraw(); b->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE );
b->redraw();
Fl_Box* b = new Fl_Box(35, 35, 400, 25, strdup(s.str().c_str()) ); }
b->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); tmp->end();
b->redraw();
} // push the binding to the UI pack, *and* store its binding ID in the same
tmp->end(); // array element in the bindingID vector. Used to remove bindings
bindingsPack->add( tmp );
// push the binding to the UI pack, *and* store its binding ID in the same
// array element in the bindingID vector. Used to remove bindings bindingsPack->resize( bindingsPack->x(),bindingsPack->y(),bindingsPack->w(),bindingsPack->children() * 36 );
bindingsPack->add( tmp ); bindingsPack->redraw();
scroll->redraw();
bindingsPack->resize( bindingsPack->x(),bindingsPack->y(),bindingsPack->w(),bindingsPack->children() * 36 );
bindingsPack->redraw(); //LUPPP_NOTE("binding size %i %i", bindingsPack->w(), bindingsPack->h() );
scroll->redraw();
//LUPPP_NOTE("binding size %i %i", bindingsPack->w(), bindingsPack->h() );
} }
void ControllerUI::addBindings( GenericMIDI* c ) void ControllerUI::addBindings( GenericMIDI* c )
{ {
std::vector<Binding*> bindingVector= c->getMidiToAction(); std::vector<Binding*> bindingVector= c->getMidiToAction();
for(unsigned int i = 0; i < bindingVector.size(); i++ ) for(unsigned int i = 0; i < bindingVector.size(); i++ ) {
{ addBinding( bindingVector.at(i) );
addBinding( bindingVector.at(i) ); }
}
} }
ControllerUI::~ControllerUI() ControllerUI::~ControllerUI()
{ {
// free all binding resources here: // free all binding resources here:
delete authorLabel; delete authorLabel;
delete linkLabel; delete linkLabel;
delete targetLabel; delete targetLabel;
delete targetLabelStat; delete targetLabelStat;
delete bindEnable; delete bindEnable;
delete removeController; delete removeController;
delete writeControllerBtn; delete writeControllerBtn;
} }
OptionsWindow::OptionsWindow() OptionsWindow::OptionsWindow()
{ {
window = new Fl_Double_Window(400,400,"Options"); window = new Fl_Double_Window(400,400,"Options");
window->set_non_modal(); window->set_non_modal();
tabs = new Fl_Tabs(0, 0, 400, 400); tabs = new Fl_Tabs(0, 0, 400, 400);
window->resizable( tabs ); window->resizable( tabs );
int x, y, w, h; int x, y, w, h;
tabs->client_area( x, y, w, h, 25 ); tabs->client_area( x, y, w, h, 25 );
addGroup = new Fl_Group(x,y,w,h,"Add"); addGroup = new Fl_Group(x,y,w,h,"Add");
{ {
newButton = new Avtk::Button( x+2, y+2, w-4, 30, "New Generic MIDI"); newButton = new Avtk::Button( x+2, y+2, w-4, 30, "New Generic MIDI");
loadButton = new Avtk::Button( x+2, y+2+32, w-4, 30, "Load Generic MIDI"); loadButton = new Avtk::Button( x+2, y+2+32, w-4, 30, "Load Generic MIDI");
} }
addGroup->end(); addGroup->end();
tabs->end(); tabs->end();
newButton ->callback( addNewController, this ); newButton ->callback( addNewController, this );
loadButton->callback( selectLoadController, this ); loadButton->callback( selectLoadController, this );
window->end(); window->end();
} }
OptionsWindow::~OptionsWindow() OptionsWindow::~OptionsWindow()
{ {
delete newButton; delete newButton;
delete loadButton; delete loadButton;
delete addGroup; delete addGroup;
delete tabs; delete tabs;
delete window; delete window;
} }
void OptionsWindow::show() void OptionsWindow::show()
{ {
window->show(); window->show();
} }
void OptionsWindow::hide() void OptionsWindow::hide()
{ {
window->hide(); window->hide();
} }
ControllerUI* OptionsWindow::getControllerUI(int id) ControllerUI* OptionsWindow::getControllerUI(int id)
{ {
for(unsigned int i = 0; i < controllers.size(); i++ ) for(unsigned int i = 0; i < controllers.size(); i++ ) {
{ if ( controllers.at(i)->controllerID == id ) {
if ( controllers.at(i)->controllerID == id ) return controllers.at(i);
{ }
return controllers.at(i); }
}
} // error: controller not found!
return 0;
// error: controller not found!
return 0;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -43,78 +43,84 @@ class OptionsWindow;
/// contains UI elements to represent one controller /// contains UI elements to represent one controller
class ControllerUI class ControllerUI
{ {
public: public:
ControllerUI( int x, int y, int w, int h, std::string name,int id); ControllerUI( int x, int y, int w, int h, std::string name,int id);
~ControllerUI(); ~ControllerUI();
void setAuthor(std::string author); void setAuthor(std::string author);
void setLink (std::string link ); void setLink (std::string link );
std::string getAuthor(){return author;} std::string getAuthor()
std::string getLink(){return link;} {
return author;
void setTarget(const char* n); }
void setBindEnable( bool b ); std::string getLink()
{
void addBinding( Binding* b ); return link;
void addBindings( GenericMIDI* c ); }
// the ControllerID this UI class represents void setTarget(const char* n);
int controllerID; void setBindEnable( bool b );
// for adding to GOptions tabs void addBinding( Binding* b );
Fl_Group* widget; void addBindings( GenericMIDI* c );
std::string name; // the ControllerID this UI class represents
int controllerID;
OptionsWindow* optionsWindow;
// for adding to GOptions tabs
// public to redraw when removing from static Fl_Group* widget;
Fl_Scroll* scroll;
Fl_Pack* bindingsPack; std::string name;
private: OptionsWindow* optionsWindow;
// bindings
std::string target; // public to redraw when removing from static
std::string author; Fl_Scroll* scroll;
std::string link; Fl_Pack* bindingsPack;
Avtk::Button* authorLabel; private:
Avtk::Button* linkLabel; // bindings
std::string target;
std::vector<int> bindingID; std::string author;
std::string link;
Fl_Box* targetLabel;
Fl_Box* targetLabelStat; Avtk::Button* authorLabel;
//Avtk::Bindings* bindings; Avtk::Button* linkLabel;
Avtk::LightButton* bindEnable;
Avtk::Button* removeController; std::vector<int> bindingID;
Avtk::Button* writeControllerBtn;
Fl_Box* targetLabel;
Fl_Box* targetLabelStat;
//Avtk::Bindings* bindings;
Avtk::LightButton* bindEnable;
Avtk::Button* removeController;
Avtk::Button* writeControllerBtn;
}; };
class OptionsWindow class OptionsWindow
{ {
public: public:
OptionsWindow(); OptionsWindow();
~OptionsWindow(); ~OptionsWindow();
void show(); void show();
void hide(); void hide();
void setTarget(const char* n); void setTarget(const char* n);
ControllerUI* getControllerUI(int id); ControllerUI* getControllerUI(int id);
// public for static methods only // public for static methods only
Fl_Tabs* tabs; Fl_Tabs* tabs;
std::vector<ControllerUI*> controllers; std::vector<ControllerUI*> controllers;
Fl_Group* addGroup; Fl_Group* addGroup;
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
int runTests(); int runTests();
#endif #endif
private: private:
Fl_Double_Window* window; Fl_Double_Window* window;
Avtk::Button* newButton; Avtk::Button* newButton;
Avtk::Button* loadButton; Avtk::Button* loadButton;
}; };
#endif // LUPPP_OPTIONS_H #endif // LUPPP_OPTIONS_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -26,269 +26,245 @@
extern Jack* jack; extern Jack* jack;
const char* GridLogic::StateString[8] = { const char* GridLogic::StateString[8] = {
"Empty", "Empty",
"Playing", "Playing",
"Play queued", "Play queued",
"Stopped", "Stopped",
"Stop queued", "Stop queued",
"Recording", "Recording",
"Record queued" "Record queued"
}; };
GridLogic::GridLogic() GridLogic::GridLogic()
{ {
sceneLaunch = 0; sceneLaunch = 0;
sampleTrackScene = false; sampleTrackScene = false;
selectedTrack = 0; selectedTrack = 0;
selectedScene = 0; selectedScene = 0;
} }
void GridLogic::selectedTrackSceneEvent(bool p) void GridLogic::selectedTrackSceneEvent(bool p)
{ {
if ( p ) if ( p ) {
{ pressed( selectedTrack, selectedScene );
pressed( selectedTrack, selectedScene ); } else {
} released( selectedTrack, selectedScene );
else }
{
released( selectedTrack, selectedScene );
}
} }
void GridLogic::setSelectTrackScene(bool b) void GridLogic::setSelectTrackScene(bool b)
{ {
char tmp[40]; char tmp[40];
sprintf( tmp, "Select track enable %i", int(b) ); sprintf( tmp, "Select track enable %i", int(b) );
EventGuiPrint e( tmp ); EventGuiPrint e( tmp );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
sampleTrackScene = b; sampleTrackScene = b;
} }
int GridLogic::getLaunchedScene() int GridLogic::getLaunchedScene()
{ {
return sceneLaunch; return sceneLaunch;
} }
int GridLogic::getSelectedTrack() int GridLogic::getSelectedTrack()
{ {
return selectedTrack; return selectedTrack;
} }
int GridLogic::getSelectedScene() int GridLogic::getSelectedScene()
{ {
return selectedScene; return selectedScene;
} }
void GridLogic::setSelectedTrack(int t) void GridLogic::setSelectedTrack(int t)
{ {
selectedTrack = t; selectedTrack = t;
} }
void GridLogic::setSelectedScene(int s) void GridLogic::setSelectedScene(int s)
{ {
selectedScene = s; selectedScene = s;
} }
void GridLogic::launchScene( int scene ) void GridLogic::launchScene( int scene )
{ {
for(unsigned int t = 0; t < NTRACKS; t++ ) for(unsigned int t = 0; t < NTRACKS; t++ ) {
{ for(int s = 0; s < NSCENES; s++ ) {
for(int s = 0; s < NSCENES; s++ ) LooperClip* lc = jack->getLooper( t )->getClip( s );
{ if ( s == scene ) {
LooperClip* lc = jack->getLooper( t )->getClip( s ); lc->queuePlay();
if ( s == scene ) jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
{ } else {
lc->queuePlay(); if ( lc->playing() ) {
jack->getControllerUpdater()->setSceneState( t, s, lc->getState() ); lc->queueStop();
} jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
else } else if ( lc->somethingQueued() ) {
{ lc->neutralize();
if ( lc->playing() ) jack->getControllerUpdater()->setSceneState( t, s, lc->getState() );
{ }
lc->queueStop(); }
jack->getControllerUpdater()->setSceneState( t, s, lc->getState() ); }
} }
else if ( lc->somethingQueued() )
{ sceneLaunch = scene;
lc->neutralize();
jack->getControllerUpdater()->setSceneState( t, s, lc->getState() ); jack->getControllerUpdater()->launchScene( scene );
}
}
}
}
sceneLaunch = scene;
jack->getControllerUpdater()->launchScene( scene );
} }
void GridLogic::specialScene(int t, int s) void GridLogic::specialScene(int t, int s)
{ {
if ( t < 0 ) t = 0; if ( t < 0 ) t = 0;
if ( t >= NTRACKS ) t = NTRACKS-1; if ( t >= NTRACKS ) t = NTRACKS-1;
if ( s < 0 ) s = 0; if ( s < 0 ) s = 0;
if ( s >= NSCENES ) s = NSCENES-1; if ( s >= NSCENES ) s = NSCENES-1;
selectedTrack = t; selectedTrack = t;
selectedScene = s; selectedScene = s;
// update UI's // update UI's
jack->getControllerUpdater()->specialScene( t, s ); jack->getControllerUpdater()->specialScene( t, s );
} }
void GridLogic::pressed( int track, int scene ) void GridLogic::pressed( int track, int scene )
{ {
if ( sampleTrackScene ) if ( sampleTrackScene ) {
{ specialScene( track, scene );
specialScene( track, scene );
// don't act on grid press!
// don't act on grid press! return;
return; }
}
// get the clip, do the "press" action based on current state.
// get the clip, do the "press" action based on current state. LooperClip* lc = jack->getLooper( track )->getClip( scene );
LooperClip* lc = jack->getLooper( track )->getClip( scene ); TrackOutput* to = jack->getTrackOutput( track );
TrackOutput* to = jack->getTrackOutput( track ); GridLogic::State s = lc->getState();
GridLogic::State s = lc->getState();
#ifdef DEBUG_CLIP #ifdef DEBUG_CLIP
printf("GridLogic::pressed() before press state = %s\n", StateString[ int(scene) ] ); printf("GridLogic::pressed() before press state = %s\n", StateString[ int(scene) ] );
#endif
if ( to->recordArm() && !lc->recording() )
{
lc->queueRecord();
to->recordArm(false);
jack->getControllerUpdater()->recordArm( track, false );
}
else
{
if ( s == STATE_EMPTY )
lc->queueRecord();
if ( s == STATE_STOPPED )
{
// hack, stop all scenes, then launch proper one
for( int i = 0; i < NTRACKS; i++ )
{
LooperClip* ilc = jack->getLooper( track )->getClip( i );
if ( ilc->playing() )
{
ilc->queueStop();
}
}
lc->queuePlay();
}
if ( s == STATE_PLAYING )
lc->queueStop();
if ( s == STATE_RECORDING )
lc->queuePlay();
if ( s == STATE_PLAY_QUEUED )
lc->queueStop();
if ( s == STATE_STOP_QUEUED )
lc->queuePlay();
// don't re-trigger if already playing!
if ( s == STATE_STOP_QUEUED && lc->playing() )
lc->neutralize();
if ( s == STATE_RECORD_QUEUED )
lc->neutralize();
}
// check state of new clip, if getQueuePlay() == true, queueStop() all other scenes
//if ( lc->getQueuePlay() )
{
for(int i = 0; i < NSCENES; i++)
{
// exclude current scene
if ( i != scene )
{
//LUPPP_NOTE("netralizing & qStop on scene %i due to press on %i", i, scene );
LooperClip* ilc = jack->getLooper( track )->getClip( i );
ilc->neutralize();
ilc->queueStop();
jack->getControllerUpdater()->setSceneState(track, i, ilc->getState() );
}
}
}
s = lc->getState();
#ifdef DEBUG_CLIP
printf("GridLogic::pressed() after press state = %s\n", StateString[ int(s) ] );
#endif #endif
jack->getControllerUpdater()->setSceneState(track, scene, s );
if ( to->recordArm() && !lc->recording() ) {
lc->queueRecord();
to->recordArm(false);
jack->getControllerUpdater()->recordArm( track, false );
} else {
if ( s == STATE_EMPTY )
lc->queueRecord();
if ( s == STATE_STOPPED ) {
// hack, stop all scenes, then launch proper one
for( int i = 0; i < NTRACKS; i++ ) {
LooperClip* ilc = jack->getLooper( track )->getClip( i );
if ( ilc->playing() ) {
ilc->queueStop();
}
}
lc->queuePlay();
}
if ( s == STATE_PLAYING )
lc->queueStop();
if ( s == STATE_RECORDING )
lc->queuePlay();
if ( s == STATE_PLAY_QUEUED )
lc->queueStop();
if ( s == STATE_STOP_QUEUED )
lc->queuePlay();
// don't re-trigger if already playing!
if ( s == STATE_STOP_QUEUED && lc->playing() )
lc->neutralize();
if ( s == STATE_RECORD_QUEUED )
lc->neutralize();
}
// check state of new clip, if getQueuePlay() == true, queueStop() all other scenes
//if ( lc->getQueuePlay() )
{
for(int i = 0; i < NSCENES; i++) {
// exclude current scene
if ( i != scene ) {
//LUPPP_NOTE("netralizing & qStop on scene %i due to press on %i", i, scene );
LooperClip* ilc = jack->getLooper( track )->getClip( i );
ilc->neutralize();
ilc->queueStop();
jack->getControllerUpdater()->setSceneState(track, i, ilc->getState() );
}
}
}
s = lc->getState();
#ifdef DEBUG_CLIP
printf("GridLogic::pressed() after press state = %s\n", StateString[ int(s) ] );
#endif
jack->getControllerUpdater()->setSceneState(track, scene, s );
} }
void GridLogic::released( int track, int scene ) void GridLogic::released( int track, int scene )
{ {
GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState(); GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
jack->getControllerUpdater()->setSceneState(track, scene, s ); jack->getControllerUpdater()->setSceneState(track, scene, s );
} }
void GridLogic::load(int track, int scene, AudioBuffer* ab) void GridLogic::load(int track, int scene, AudioBuffer* ab)
{ {
jack->getLooper( track )->getClip( scene )->load( ab ); jack->getLooper( track )->getClip( scene )->load( ab );
GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState(); GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
jack->getControllerUpdater()->setSceneState(track, scene, s ); jack->getControllerUpdater()->setSceneState(track, scene, s );
} }
void GridLogic::updateState() void GridLogic::updateState()
{ {
//printf("GridLogic::updateState() stub" ); //printf("GridLogic::updateState() stub" );
for(int t = 0; t < NTRACKS; t++) for(int t = 0; t < NTRACKS; t++) {
{ for(int s = 0; s < NSCENES; s++) {
for(int s = 0; s < NSCENES; s++) GridLogic::State st = jack->getLooper( t )->getClip( s )->getState();
{ EventGuiPrint e( GridLogic::StateString[st] );
GridLogic::State st = jack->getLooper( t )->getClip( s )->getState(); writeToGuiRingbuffer( &e );
EventGuiPrint e( GridLogic::StateString[st] ); jack->getControllerUpdater()->setSceneState(t, s, st );
writeToGuiRingbuffer( &e ); }
jack->getControllerUpdater()->setSceneState(t, s, st ); }
}
}
} }
void GridLogic::bar() void GridLogic::bar()
{ {
#ifdef DEBUG_CLIP #ifdef DEBUG_CLIP
EventGuiPrint e( "GridLogic::bar()" ); EventGuiPrint e( "GridLogic::bar()" );
//writeToGuiRingbuffer( &e ); //writeToGuiRingbuffer( &e );
#endif #endif
/// iterate over all clips, if they're set to QUEUED, set to the next state /// iterate over all clips, if they're set to QUEUED, set to the next state
for( int i = 0; i < NTRACKS*NSCENES; i++ ) for( int i = 0; i < NTRACKS*NSCENES; i++ ) {
{ int track = i / NSCENES;
int track = i / NSCENES; int scene = i - track * NSCENES;
int scene = i - track * NSCENES; jack->getLooper( track )->getClip(scene)->bar();
jack->getLooper( track )->getClip(scene)->bar();
#ifdef DEBUG_CLIP #ifdef DEBUG_CLIP
GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState(); GridLogic::State s = jack->getLooper( track )->getClip( scene )->getState();
if ( s != STATE_EMPTY ) if ( s != STATE_EMPTY ) {
{ //printf("%i, %i:after bar() state = %s\n", track, scene, StateString[ int(s) ] );
//printf("%i, %i:after bar() state = %s\n", track, scene, StateString[ int(s) ] ); }
}
#endif #endif
} }
} }
void GridLogic::beat() void GridLogic::beat()
{ {
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,82 +29,85 @@ class AudioBuffer;
* separtated from the Looper class so it can be repurposed by different * separtated from the Looper class so it can be repurposed by different
* controllers and input devices. The UI and eg. APC / Launchpad all have a * controllers and input devices. The UI and eg. APC / Launchpad all have a
* similar grid style interface: the logic is implemented here once. * similar grid style interface: the logic is implemented here once.
* *
* The class sends Looper messages to change its state, thus abstracting away * The class sends Looper messages to change its state, thus abstracting away
* the details of the Looper control, and exposing its functionality using a * the details of the Looper control, and exposing its functionality using a
* convinient API. * convinient API.
* *
* When the state of a block changes, it will update the state of the grid on * When the state of a block changes, it will update the state of the grid on
* the controller. * the controller.
* *
* It inherits from TimeObserver so it can change the state of the clip on the * It inherits from TimeObserver so it can change the state of the clip on the
* bar / beat. * bar / beat.
**/ **/
class GridLogic : public TimeObserver class GridLogic : public TimeObserver
{ {
public: public:
/// possible states of each square. Public so Controller subclasses can /// possible states of each square. Public so Controller subclasses can
/// determine the state of the square /// determine the state of the square
enum State { enum State {
STATE_EMPTY = 0, STATE_EMPTY = 0,
STATE_PLAYING, STATE_PLAYING,
STATE_PLAY_QUEUED, STATE_PLAY_QUEUED,
STATE_STOPPED, STATE_STOPPED,
STATE_STOP_QUEUED, STATE_STOP_QUEUED,
STATE_RECORDING, STATE_RECORDING,
STATE_RECORD_QUEUED, STATE_RECORD_QUEUED,
}; };
GridLogic(); GridLogic();
~GridLogic(){}; ~GridLogic() {};
/// button press / click event /// button press / click event
void pressed( int track, int scene ); void pressed( int track, int scene );
/// button release / click-release event /// button release / click-release event
void released( int track, int scene ); void released( int track, int scene );
/// master controls, launches a horizontal scene with one event /// master controls, launches a horizontal scene with one event
void launchScene( int scene ); void launchScene( int scene );
int getCurrentScene(){return sceneLaunch;} int getCurrentScene()
int getLaunchedScene(); {
return sceneLaunch;
/// selected track functions }
void setSelectTrackScene(bool b); int getLaunchedScene();
void setSelectedTrack(int t);
void setSelectedScene(int s); /// selected track functions
int getSelectedTrack(); void setSelectTrackScene(bool b);
int getSelectedScene(); void setSelectedTrack(int t);
void setSelectedScene(int s);
void selectedTrackSceneEvent(bool pressed); int getSelectedTrack();
int getSelectedScene();
void specialScene(int t, int s);
void selectedTrackSceneEvent(bool pressed);
/// GUI load event
void load(int track, int scene, AudioBuffer* ab); void specialScene(int t, int s);
/// resend entire grid state to controllers /// GUI load event
void updateState(); void load(int track, int scene, AudioBuffer* ab);
/// time functions, not for use by Controller subclasses /// resend entire grid state to controllers
void bar(); void updateState();
void beat();
/// time functions, not for use by Controller subclasses
/// for debug purposes: use static_cast<int>(GridLogic::State) to access void bar();
static const char* StateString[8]; void beat();
/// for debug purposes: use static_cast<int>(GridLogic::State) to access
static const char* StateString[8];
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
int runTests(); int runTests();
#endif #endif
private: private:
/// holds last scene launch /// holds last scene launch
int sceneLaunch; int sceneLaunch;
/// holds selected track / scene for special clip /// holds selected track / scene for special clip
bool sampleTrackScene; // turn on to have selected clip, press event acted on bool sampleTrackScene; // turn on to have selected clip, press event acted on
int selectedTrack; int selectedTrack;
int selectedScene; int selectedScene;
}; };

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,199 +33,217 @@ static void gtrack_jacksendactivate_cb(Fl_Widget* w,void *data);
GTrack::GTrack(int x, int y, int w, int h, const char* l ) : GTrack::GTrack(int x, int y, int w, int h, const char* l ) :
Fl_Group(x, y, w, h), Fl_Group(x, y, w, h),
bg( x, y , w, h, l ), bg( x, y , w, h, l ),
radial( x+5, y+ 26, 100, 100, ""), radial( x+5, y+ 26, 100, 100, ""),
clipSel(x + 5, y + 26 + 102, 100, 294,""), clipSel(x + 5, y + 26 + 102, 100, 294,""),
jackSendBox(x+5, y+422, 100, 45, ""), jackSendBox(x+5, y+422, 100, 45, ""),
jackSendDial(x+21, y+422+8, 30,30, ""), jackSendDial(x+21, y+422+8, 30,30, ""),
jackSendActivate(x+66, y+422+11, 36,25, "FX"), jackSendActivate(x+66, y+422+11, 36,25, "FX"),
volBox(x+5, y+422+50, 100, 172, ""), volBox(x+5, y+422+50, 100, 172, ""),
volume(x+66, y +425+50, 36, 166, ""), volume(x+66, y +425+50, 36, 166, ""),
sendDial (x+21, y +430 + 50, 30, 30, ""), sendDial (x+21, y +430 + 50, 30, 30, ""),
sendActive (x+11, y +430 + 82, 50, 25, "Snd"), sendActive (x+11, y +430 + 82, 50, 25, "Snd"),
xsideDial (x+21, y +430 + 69+50, 30, 30, ""), xsideDial (x+21, y +430 + 69+50, 30, 30, ""),
keyActive (x+11, y +430 + 151, 50, 25, "Key"), keyActive (x+11, y +430 + 151, 50, 25, "Key"),
recordActive (x+11, y +430 + 182, 50, 25, "XRec") recordActive (x+11, y +430 + 182, 50, 25, "XRec")
{ {
ID = privateID++; ID = privateID++;
clipSel.setID( ID );
sendDial.callback( gtrack_sendDial_cb, this );
sendActive.setColor( 0, 1.0, 0.0 );
sendActive.callback( gtrack_send_cb, this );
xsideDial.callback( gtrack_xsideDial_cb, this );
xsideDial.align( FL_ALIGN_BOTTOM );
keyActive.callback( gtrack_key_cb, this );
keyActive.setColor( 0, 0.6, 1 );
recordActive.setColor( 1, 0.0, 0.0 );
recordActive.callback( gtrack_record_cb, this );
volume.callback( gtrack_vol_cb, this );
jackSendActivate.setColor( 1, 1, 0 ); clipSel.setID( ID );
jackSendActivate.callback(gtrack_jacksendactivate_cb,this);
jackSendDial.align(FL_ALIGN_INSIDE); sendDial.callback( gtrack_sendDial_cb, this );
jackSendDial.callback(gtrack_jacksend_cb,this); sendActive.setColor( 0, 1.0, 0.0 );
jackSendDial.value(1.0); sendActive.callback( gtrack_send_cb, this );
//volBox.color( fl_rgb_color( 0,0,0 ) );
xsideDial.callback( gtrack_xsideDial_cb, this );
end(); // close the group xsideDial.align( FL_ALIGN_BOTTOM );
keyActive.callback( gtrack_key_cb, this );
keyActive.setColor( 0, 0.6, 1 );
recordActive.setColor( 1, 0.0, 0.0 );
recordActive.callback( gtrack_record_cb, this );
volume.callback( gtrack_vol_cb, this );
jackSendActivate.setColor( 1, 1, 0 );
jackSendActivate.callback(gtrack_jacksendactivate_cb,this);
jackSendDial.align(FL_ALIGN_INSIDE);
jackSendDial.callback(gtrack_jacksend_cb,this);
jackSendDial.value(1.0);
//volBox.color( fl_rgb_color( 0,0,0 ) );
end(); // close the group
} }
float GTrack::getSend(){return sendDial.value(); } float GTrack::getSend()
float GTrack::getXSide(){return xsideDial.value(); } {
return sendDial.value();
}
float GTrack::getXSide()
{
return xsideDial.value();
}
bool GTrack::getSendActive (){return sendActive.value(); } bool GTrack::getSendActive ()
bool GTrack::getKeyActive (){return keyActive.value(); } {
bool GTrack::getRecordActive(){return recordActive.value(); } return sendActive.value();
}
bool GTrack::getKeyActive ()
{
return keyActive.value();
}
bool GTrack::getRecordActive()
{
return recordActive.value();
}
void GTrack::setSend(float s){ sendDial.value( s ); } void GTrack::setSend(float s)
void GTrack::setXSide(float s){ xsideDial.value( s ); } {
sendDial.value( s );
}
void GTrack::setXSide(float s)
{
xsideDial.value( s );
}
void GTrack::setSendActive(bool a){ sendActive.value( a ); } void GTrack::setSendActive(bool a)
void GTrack::setKeyActive(bool a){ keyActive.value( a ); } {
void GTrack::setRecordActive(bool a){ recordActive.value( a ); } sendActive.value( a );
}
void GTrack::setKeyActive(bool a)
{
keyActive.value( a );
}
void GTrack::setRecordActive(bool a)
{
recordActive.value( a );
}
void GTrack::setJackSend(float s) void GTrack::setJackSend(float s)
{ {
jackSendDial.value(s); jackSendDial.value(s);
} }
void GTrack::setJackSendActivate(bool a) void GTrack::setJackSendActivate(bool a)
{ {
jackSendActivate.value(a); jackSendActivate.value(a);
} }
float GTrack::getJackSend() float GTrack::getJackSend()
{ {
return jackSendDial.value(); return jackSendDial.value();
} }
bool GTrack::getJackSendActivate() bool GTrack::getJackSendActivate()
{ {
return jackSendActivate.value(); return jackSendActivate.value();
} }
void gtrack_sendDial_cb(Fl_Widget *w, void *data) void gtrack_sendDial_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
EventTrackSend e( track->ID, SEND_POSTFADER, ((Avtk::Dial*)w)->value() ); EventTrackSend e( track->ID, SEND_POSTFADER, ((Avtk::Dial*)w)->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("track %i reverb send %f\n", track->ID, ((Avtk::Dial*)w)->value() ); //printf("track %i reverb send %f\n", track->ID, ((Avtk::Dial*)w)->value() );
} }
void gtrack_key_cb(Fl_Widget *w, void *data) void gtrack_key_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
Avtk::LightButton* d = (Avtk::LightButton*)w; Avtk::LightButton* d = (Avtk::LightButton*)w;
bool b = d->value(); bool b = d->value();
if ( b < 0.5 ) if ( b < 0.5 ) {
{ EventTrackSendActive e( track->ID, SEND_KEY, true );
EventTrackSendActive e( track->ID, SEND_KEY, true ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); } else {
} EventTrackSendActive e( track->ID, SEND_KEY, false );
else writeToDspRingbuffer( &e );
{ }
EventTrackSendActive e( track->ID, SEND_KEY, false ); //printf("track %i post send %s\n", track->ID, b ? "off" : "on" );
writeToDspRingbuffer( &e );
}
//printf("track %i post send %s\n", track->ID, b ? "off" : "on" );
} }
void gtrack_xsideDial_cb(Fl_Widget *w, void *data) void gtrack_xsideDial_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
EventTrackSend e( track->ID, SEND_XSIDE, ((Avtk::Dial*)w)->value() ); EventTrackSend e( track->ID, SEND_XSIDE, ((Avtk::Dial*)w)->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("track %i side send %f\n", track->ID, ((Avtk::Dial*)w)->value() ); //printf("track %i side send %f\n", track->ID, ((Avtk::Dial*)w)->value() );
} }
void gtrack_vol_cb(Fl_Widget *w, void *data) void gtrack_vol_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
EventTrackVol e( track->ID, ((Avtk::Volume*)w)->value() ); EventTrackVol e( track->ID, ((Avtk::Volume*)w)->value() );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
//printf("track %i vol %f\n", track->ID, ((Avtk::Dial*)w)->value() ); //printf("track %i vol %f\n", track->ID, ((Avtk::Dial*)w)->value() );
} }
void gtrack_send_cb(Fl_Widget *w, void *data) void gtrack_send_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
Avtk::LightButton* d = (Avtk::LightButton*)w; Avtk::LightButton* d = (Avtk::LightButton*)w;
bool b = d->value(); bool b = d->value();
d->value( !b ); d->value( !b );
if ( b < 0.5 ) if ( b < 0.5 ) {
{ EventTrackSendActive e( track->ID, SEND_POSTFADER, 1.0f );
EventTrackSendActive e( track->ID, SEND_POSTFADER, 1.0f ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); } else {
} EventTrackSendActive e( track->ID, SEND_POSTFADER, 0.0f );
else writeToDspRingbuffer( &e );
{ }
EventTrackSendActive e( track->ID, SEND_POSTFADER, 0.0f ); //printf("track %i reverb send %s\n", track->ID, b ? "true" : "false" );
writeToDspRingbuffer( &e );
}
//printf("track %i reverb send %s\n", track->ID, b ? "true" : "false" );
} }
void gtrack_jacksend_cb(Fl_Widget *w, void *data) void gtrack_jacksend_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
Avtk::Dial* d = (Avtk::Dial*)w; Avtk::Dial* d = (Avtk::Dial*)w;
float v = d->value(); float v = d->value();
EventTrackJackSend ev(track->ID,v); EventTrackJackSend ev(track->ID,v);
writeToDspRingbuffer(&ev); writeToDspRingbuffer(&ev);
//printf("track %i reverb send %s\n", track->ID, b ? "true" : "false" ); //printf("track %i reverb send %s\n", track->ID, b ? "true" : "false" );
} }
void gtrack_record_cb(Fl_Widget *w, void *data) void gtrack_record_cb(Fl_Widget *w, void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
Avtk::LightButton* d = (Avtk::LightButton*)w; Avtk::LightButton* d = (Avtk::LightButton*)w;
bool b = d->value(); bool b = d->value();
if ( b < 0.5 ) if ( b < 0.5 ) {
{ EventTrackRecordArm e( track->ID, 1.0f );
EventTrackRecordArm e( track->ID, 1.0f ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); } else {
} EventTrackRecordArm e( track->ID, 0.0f );
else writeToDspRingbuffer( &e );
{ }
EventTrackRecordArm e( track->ID, 0.0f ); //printf("track %i record Arm %s\n", track->ID, b ? "off" : "on" );
writeToDspRingbuffer( &e );
}
//printf("track %i record Arm %s\n", track->ID, b ? "off" : "on" );
} }
void gtrack_jacksendactivate_cb(Fl_Widget* w,void *data) void gtrack_jacksendactivate_cb(Fl_Widget* w,void *data)
{ {
GTrack* track = (GTrack*) data; GTrack* track = (GTrack*) data;
Avtk::LightButton* d = (Avtk::LightButton*)w; Avtk::LightButton* d = (Avtk::LightButton*)w;
bool b=d->value(); bool b=d->value();
// d->value(!b); // d->value(!b);
if ( b < 0.5 ) if ( b < 0.5 ) {
{ EventTrackJackSendActivate e( track->ID, 1.0f );
EventTrackJackSendActivate e( track->ID, 1.0f ); writeToDspRingbuffer( &e );
writeToDspRingbuffer( &e ); } else {
} EventTrackJackSendActivate e( track->ID, 0.0f );
else writeToDspRingbuffer( &e );
{ }
EventTrackJackSendActivate e( track->ID, 0.0f );
writeToDspRingbuffer( &e );
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -45,63 +45,72 @@ using namespace std;
class GTrack : public Fl_Group class GTrack : public Fl_Group
{ {
public: public:
Avtk::Volume* getVolume(){return &volume;}
Avtk::RadialStatus* getRadialStatus(){return &radial;}
Avtk::ClipSelector* getClipSelector(){return &clipSel;}
GTrack(int x, int y, int w, int h, const char* l = 0 );
// getters
float getSend();
float getXSide();
bool getSendActive();
bool getKeyActive();
bool getRecordActive();
// setters
void setSend(float s);
void setXSide(float s);
void setSendActive(bool a);
void setKeyActive(bool a);
void setRecordActive(bool a);
void setJackSend(float s);
void setJackSendActivate(bool a);
int ID;
Avtk::Background bg;
Avtk::RadialStatus radial;
Avtk::ClipSelector clipSel;
Avtk::Box volBox; Avtk::Volume* getVolume()
{
Avtk::Volume volume; return &volume;
}
float getJackSend(); Avtk::RadialStatus* getRadialStatus()
bool getJackSendActivate(); {
return &radial;
}
Avtk::ClipSelector* getClipSelector()
{
return &clipSel;
}
GTrack(int x, int y, int w, int h, const char* l = 0 );
// getters
float getSend();
float getXSide();
bool getSendActive();
bool getKeyActive();
bool getRecordActive();
// setters
void setSend(float s);
void setXSide(float s);
void setSendActive(bool a);
void setKeyActive(bool a);
void setRecordActive(bool a);
void setJackSend(float s);
void setJackSendActivate(bool a);
int ID;
Avtk::Background bg;
Avtk::RadialStatus radial;
Avtk::ClipSelector clipSel;
Avtk::Box volBox;
Avtk::Volume volume;
float getJackSend();
bool getJackSendActivate();
private: private:
Avtk::Box jackSendBox; Avtk::Box jackSendBox;
Avtk::Dial jackSendDial; Avtk::Dial jackSendDial;
Avtk::LightButton jackSendActivate; Avtk::LightButton jackSendActivate;
Avtk::Dial sendDial; Avtk::Dial sendDial;
Avtk::LightButton sendActive; Avtk::LightButton sendActive;
Avtk::Dial xsideDial; Avtk::Dial xsideDial;
Avtk::LightButton keyActive; Avtk::LightButton keyActive;
Avtk::LightButton recordActive; Avtk::LightButton recordActive;
static int privateID; static int privateID;
}; };
#endif // LUPPP_G_TRACK_H #endif // LUPPP_G_TRACK_H

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -46,92 +46,107 @@ class AudioBuffer;
class Gui class Gui
{ {
public: public:
Gui(const char* argZero); Gui(const char* argZero);
~Gui(); ~Gui();
int show();
int quit();
void askQuit();
/// returns the options window
OptionsWindow* getOptionsWindow();
/// open audio editor window with an AudioBuffer
AudioEditor* getAudioEditor();
/// resets the state to "new"
void reset();
/// sets up MIDI controllers: must be done *after* backend is started
void addMidiControllerToSetup(std::string);
void setupMidiControllers();
GTrack* getTrack(int id);
GMasterTrack* getMasterTrack(){return master;}
DiskWriter* getDiskWriter(){return diskWriter;}
DiskReader* getDiskReader(){return diskReader;}
/// used to load samples into the grid
void selectLoadSample( int track, int clip );
void selectSaveSample( int track, int clip );
char* selectSavePath();
/// allows the user to select a Controller definition
static void selectLoadController(Fl_Widget* w, void*);
int samplerate;
////Enable per track send and resturn jack ports
bool enablePerTrackOutput;
int getWindowWidth(){return window.w();} int show();
nsm_client_t* getNsm(){return nsm;} int quit();
void askQuit();
/// current special clip: /// returns the options window
int specialTrack; OptionsWindow* getOptionsWindow();
int specialScene;
/// open audio editor window with an AudioBuffer
/// The project directory is the default directoy which is shown upon load/save AudioEditor* getAudioEditor();
void setProjectsDir(string dir);
string getProjectsDir(); /// resets the state to "new"
void reset();
// save a particular sample to path
std::string saveBufferPath; /// sets up MIDI controllers: must be done *after* backend is started
void addMidiControllerToSetup(std::string);
private: void setupMidiControllers();
vector<std::string> controllerVector;
GTrack* getTrack(int id);
Fl_Double_Window window; GMasterTrack* getMasterTrack()
{
Fl_Group* lupppGroup; return master;
}
OptionsWindow* optionWindow;
DiskWriter* getDiskWriter()
std::string lupppProjectsDir; {
return diskWriter;
AudioEditor* audioEditor; }
DiskReader* getDiskReader()
DiskReader* diskReader; {
DiskWriter* diskWriter; return diskReader;
}
GMasterTrack* master;
/// used to load samples into the grid
vector<GTrack*> tracks; void selectLoadSample( int track, int clip );
void selectSaveSample( int track, int clip );
// FIXME: refactor tooltip code out..? char* selectSavePath();
std::string tooltip;
Fl_Box* tooltipLabel; /// allows the user to select a Controller definition
static void selectLoadController(Fl_Widget* w, void*);
// non-session-manager
nsm_client_t* nsm;
int samplerate;
static int keyboardHandler(int event);
////Enable per track send and resturn jack ports
bool enablePerTrackOutput;
int getWindowWidth()
{
return window.w();
}
nsm_client_t* getNsm()
{
return nsm;
}
/// current special clip:
int specialTrack;
int specialScene;
/// The project directory is the default directoy which is shown upon load/save
void setProjectsDir(string dir);
string getProjectsDir();
// save a particular sample to path
std::string saveBufferPath;
private:
vector<std::string> controllerVector;
Fl_Double_Window window;
Fl_Group* lupppGroup;
OptionsWindow* optionWindow;
std::string lupppProjectsDir;
AudioEditor* audioEditor;
DiskReader* diskReader;
DiskWriter* diskWriter;
GMasterTrack* master;
vector<GTrack*> tracks;
// FIXME: refactor tooltip code out..?
std::string tooltip;
Fl_Box* tooltipLabel;
// non-session-manager
nsm_client_t* nsm;
static int keyboardHandler(int event);
}; };
#endif // LUPPP_GUI #endif // LUPPP_GUI

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -37,35 +37,35 @@ using namespace std;
class GUnitTrack : public Fl_Group class GUnitTrack : public Fl_Group
{ {
public: public:
GUnitTrack(int x, int y, int w, int h, const char* l = 0 ) : GUnitTrack(int x, int y, int w, int h, const char* l = 0 ) :
Fl_Group(x, y, w, h), Fl_Group(x, y, w, h),
title( strdup(l) ), title( strdup(l) ),
bg( x, y , w, h, title ) bg( x, y , w, h, title )
{ {
int uh = h / 5; int uh = h / 5;
unit[0] = new Avtk::Unit(x + 2, y + uh * 4 - 2, w - 6, h / 5 - 2,"1"); unit[0] = new Avtk::Unit(x + 2, y + uh * 4 - 2, w - 6, h / 5 - 2,"1");
unit[1] = new Avtk::Unit(x + 2, y + uh * 3 - 2, w - 6, h / 5 - 2,"2"); unit[1] = new Avtk::Unit(x + 2, y + uh * 3 - 2, w - 6, h / 5 - 2,"2");
unit[2] = new Avtk::Unit(x + 2, y + uh * 2 - 2, w - 6, h / 5 - 2,"3"); unit[2] = new Avtk::Unit(x + 2, y + uh * 2 - 2, w - 6, h / 5 - 2,"3");
unit[3] = new Avtk::Unit(x + 2, y + uh * 1 - 2, w - 6, h / 5 - 2,"4"); unit[3] = new Avtk::Unit(x + 2, y + uh * 1 - 2, w - 6, h / 5 - 2,"4");
unit[4] = new Avtk::Unit(x + 2, y - 2 , w - 6, h / 5 - 2,"5"); unit[4] = new Avtk::Unit(x + 2, y - 2 , w - 6, h / 5 - 2,"5");
end(); // close the group end(); // close the group
} }
~GUnitTrack() ~GUnitTrack()
{ {
free(title); free(title);
} }
private: private:
char* title; char* title;
Avtk::Background bg; Avtk::Background bg;
Avtk::Unit* unit[5]; Avtk::Unit* unit[5];
}; };
#endif // LUPPP_G_UNIT_TRACK_H #endif // LUPPP_G_UNIT_TRACK_H

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -54,144 +54,162 @@ using namespace std;
**/ **/
class Jack class Jack
{ {
public: public:
Jack(std::string name); Jack(std::string name);
~Jack(); ~Jack();
static void setup(std::string name);
void activate();
/// quits the JACK client, destroying ports etc. Call only on exit of Luppp.
void quit();
int getBuffersize();
int getSamplerate();
// Luppp process callback: bar() events can occur between these
void processFrames(int nframes);
//Sets the first nframes of all the internal output buffers to zero. NO LIMIT CHECKS static void setup(std::string name);
void clearInternalBuffers(int nframes);
/// get functions for components owned by Jack
Looper* getLooper(int t);
TrackOutput* getTrackOutput(int t);
State* getState(){return state;}
Logic* getLogic(){return logic;}
Metronome* getMetronome(){return metronome;}
GridLogic* getGridLogic(){return gridLogic;}
TimeManager* getTimeManager(){return timeManager;}
ControllerUpdater* getControllerUpdater(){return controllerUpdater;}
void transportRolling(bool rolling); void activate();
/// quits the JACK client, destroying ports etc. Call only on exit of Luppp.
/// register a MIDI observer void quit();
void registerMidiIO( MidiIO* mo );
void unregisterMidiIO( MidiIO* mo );
/// set the master i/o volume / sends
void inputVolume( float vol );
void masterVolume( float vol );
void returnVolume( float vol );
void inputTo(INPUT_TO to, float v);
void inputToActive(INPUT_TO to, bool a);
jack_client_t* getJackClientPointer()
{
return client;
};
void resetMidiBindingState();
// MIDI binding creation
bool bindingEventRecordEnable;
int bindingEventType;
int bindingTrack;
int bindingScene;
int bindingSend;
int bindingActive;
JackSendReturn *getJackSendReturn(int t); int getBuffersize();
int getSamplerate();
// Luppp process callback: bar() events can occur between these
void processFrames(int nframes);
//Sets the first nframes of all the internal output buffers to zero. NO LIMIT CHECKS
void clearInternalBuffers(int nframes);
/// get functions for components owned by Jack
Looper* getLooper(int t);
TrackOutput* getTrackOutput(int t);
State* getState()
{
return state;
}
Logic* getLogic()
{
return logic;
}
Metronome* getMetronome()
{
return metronome;
}
GridLogic* getGridLogic()
{
return gridLogic;
}
TimeManager* getTimeManager()
{
return timeManager;
}
ControllerUpdater* getControllerUpdater()
{
return controllerUpdater;
}
void transportRolling(bool rolling);
/// register a MIDI observer
void registerMidiIO( MidiIO* mo );
void unregisterMidiIO( MidiIO* mo );
/// set the master i/o volume / sends
void inputVolume( float vol );
void masterVolume( float vol );
void returnVolume( float vol );
void inputTo(INPUT_TO to, float v);
void inputToActive(INPUT_TO to, bool a);
jack_client_t* getJackClientPointer()
{
return client;
};
void resetMidiBindingState();
// MIDI binding creation
bool bindingEventRecordEnable;
int bindingEventType;
int bindingTrack;
int bindingScene;
int bindingSend;
int bindingActive;
JackSendReturn *getJackSendReturn(int t);
private: private:
int lastnframes; int lastnframes;
jack_client_t* client; jack_client_t* client;
Buffers buffers;
TimeManager* timeManager;
Metronome* metronome;
State* state;
Logic* logic;
GridLogic* gridLogic;
ControllerUpdater* controllerUpdater;
vector<Looper*> loopers;
vector<JackSendReturn*> tracksendreturns;
vector<TrackOutput*> trackOutputs;
vector<MidiIO*> midiIO;
// FX
DBMeter* inputMeter;
DBMeter* masterMeter;
float inputVol;
/// _toMasterLag is a volume that lags behind _toMaster when setMaster() is called
/// This prohibits audible jumps when rapidly changing the volume
float masterVol;
float masterVolLag;
float masterVolDiff;
float returnVol;
float inputToMixVol;
float inputToSendVol;
float inputToXSideVol;
bool inputToKeyEnable;
bool inputToMixEnable;
bool inputToSendEnable;
// JACK member variables
bool clientActive;
int samplerate;
jack_port_t* masterInput;
jack_port_t* masterOutputL;
jack_port_t* masterOutputR;
jack_port_t* masterReturnL; Buffers buffers;
jack_port_t* masterReturnR; TimeManager* timeManager;
jack_port_t* headphonesPort; Metronome* metronome;
State* state;
jack_port_t* sidechainKeyOutput; Logic* logic;
jack_port_t* sidechainSignalOutput; GridLogic* gridLogic;
jack_port_t* sendOutput; ControllerUpdater* controllerUpdater;
jack_port_t* masterMidiInput; vector<Looper*> loopers;
vector<JackSendReturn*> tracksendreturns;
vector<TrackOutput*> trackOutputs;
vector<MidiIO*> midiIO;
// FX
DBMeter* inputMeter;
DBMeter* masterMeter;
float inputVol;
/// _toMasterLag is a volume that lags behind _toMaster when setMaster() is called
/// This prohibits audible jumps when rapidly changing the volume
float masterVol;
float masterVolLag;
float masterVolDiff;
float returnVol;
float inputToMixVol;
float inputToSendVol;
float inputToXSideVol;
bool inputToKeyEnable;
bool inputToMixEnable;
bool inputToSendEnable;
// JACK member variables
bool clientActive;
int samplerate;
jack_port_t* masterInput;
jack_port_t* masterOutputL;
jack_port_t* masterOutputR;
jack_port_t* masterReturnL;
jack_port_t* masterReturnR;
jack_port_t* headphonesPort;
jack_port_t* sidechainKeyOutput;
jack_port_t* sidechainSignalOutput;
jack_port_t* sendOutput;
jack_port_t* masterMidiInput;
jack_port_t* trackJackOutputPorts[NTRACKS];
// JACK callback
int process (jack_nframes_t);
int timebase(jack_transport_state_t,
jack_nframes_t,
jack_position_t*,
int );
// static JACK callbacks
static int static_process (jack_nframes_t, void *);
static int static_timebase (jack_transport_state_t,
jack_nframes_t,
jack_position_t*,
int,
void* );
// UI update variables
int uiUpdateCounter;
int uiUpdateConstant;
jack_port_t* trackJackOutputPorts[NTRACKS];
// JACK callback
int process (jack_nframes_t);
int timebase(jack_transport_state_t,
jack_nframes_t,
jack_position_t*,
int );
// static JACK callbacks
static int static_process (jack_nframes_t, void *);
static int static_timebase (jack_transport_state_t,
jack_nframes_t,
jack_position_t*,
int,
void* );
// UI update variables
int uiUpdateCounter;
int uiUpdateConstant;
}; };
#endif // LUPPP_JACK_H #endif // LUPPP_JACK_H

View file

@ -4,63 +4,62 @@
#include <assert.h> #include <assert.h>
extern Jack* jack; extern Jack* jack;
JackSendReturn::JackSendReturn(int trackid, AudioProcessor *prev, jack_client_t *client) JackSendReturn::JackSendReturn(int trackid, AudioProcessor *prev, jack_client_t *client)
:m_trackid(trackid), m_previousProcessor(prev), m_sendvol(1.0f) :m_trackid(trackid), m_previousProcessor(prev), m_sendvol(1.0f)
{ {
char name[50]; char name[50];
sprintf(name, "Send_track_%d\n",trackid); sprintf(name, "Send_track_%d\n",trackid);
m_sendport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0); m_sendport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0);
sprintf(name, "Return_track_%d\n",trackid); sprintf(name, "Return_track_%d\n",trackid);
m_returnport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0); m_returnport=jack_port_register(client,name,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0);
m_active=false; m_active=false;
m_counter=0; m_counter=0;
} }
void JackSendReturn::process(unsigned int nframes, Buffers *buffers) void JackSendReturn::process(unsigned int nframes, Buffers *buffers)
{ {
//Reset send buffer //Reset send buffer
int offset=m_counter%(buffers->nframes); int offset=m_counter%(buffers->nframes);
float* sendtrack=&(buffers->audio[Buffers::SEND_TRACK_0+m_trackid][0]); float* sendtrack=&(buffers->audio[Buffers::SEND_TRACK_0+m_trackid][0]);
float* rettrack=&(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid][0]); float* rettrack=&(buffers->audio[Buffers::RETURN_TRACK_0+m_trackid][0]);
memset(sendtrack,0,nframes*sizeof(float)); memset(sendtrack,0,nframes*sizeof(float));
//Process previous AudioProcessor //Process previous AudioProcessor
m_previousProcessor->process(nframes,buffers); m_previousProcessor->process(nframes,buffers);
float* send=(float*)jack_port_get_buffer(m_sendport,(jack_nframes_t)(buffers->nframes)); float* send=(float*)jack_port_get_buffer(m_sendport,(jack_nframes_t)(buffers->nframes));
float* ret=(float*)jack_port_get_buffer(m_returnport,(jack_nframes_t)(buffers->nframes)); float* ret=(float*)jack_port_get_buffer(m_returnport,(jack_nframes_t)(buffers->nframes));
if(offset) if(offset) {
{ send+=offset;
send+=offset; ret+=offset;
ret+=offset; }
}
for(int i=0;i<nframes;i++) for(int i=0; i<nframes; i++)
send[i]=m_sendvol*sendtrack[i]; send[i]=m_sendvol*sendtrack[i];
// if(nframes!=buffers->nframes) // if(nframes!=buffers->nframes)
// { // {
// cout<<send<<endl; // cout<<send<<endl;
// } // }
if(offset) if(offset)
assert(offset+nframes==buffers->nframes); assert(offset+nframes==buffers->nframes);
if(m_active) if(m_active)
memcpy(rettrack,ret,nframes*sizeof(float)); memcpy(rettrack,ret,nframes*sizeof(float));
else else
memcpy(rettrack, memcpy(rettrack,
sendtrack,nframes*sizeof(float)); sendtrack,nframes*sizeof(float));
m_counter+=nframes; m_counter+=nframes;
} }
void JackSendReturn::activate(bool act) void JackSendReturn::activate(bool act)
{ {
m_active=act; m_active=act;
} }
void JackSendReturn::sendVolume(float vol) void JackSendReturn::sendVolume(float vol)
{ {
m_sendvol=vol; m_sendvol=vol;
} }

View file

@ -30,25 +30,25 @@
class JackSendReturn: public AudioProcessor class JackSendReturn: public AudioProcessor
{ {
public: public:
//Constructor: the registration of the jack send/return is done here //Constructor: the registration of the jack send/return is done here
JackSendReturn(int trackid,AudioProcessor* prev,jack_client_t* client); JackSendReturn(int trackid,AudioProcessor* prev,jack_client_t* client);
//The process callback //The process callback
virtual void process(unsigned int nframes, Buffers* buffers); virtual void process(unsigned int nframes, Buffers* buffers);
//Activate the return chain. When m_active=true then Buffers::RETURN_TRACK_0+m_trackid gets the data //Activate the return chain. When m_active=true then Buffers::RETURN_TRACK_0+m_trackid gets the data
//from the return port. The send port always send the incoming data //from the return port. The send port always send the incoming data
void activate(bool act); void activate(bool act);
void sendVolume(float vol); void sendVolume(float vol);
private: private:
bool m_active; bool m_active;
float m_sendvol; float m_sendvol;
jack_port_t* m_sendport; jack_port_t* m_sendport;
jack_port_t* m_returnport; jack_port_t* m_returnport;
int m_trackid; int m_trackid;
AudioProcessor* m_previousProcessor; AudioProcessor* m_previousProcessor;
int m_counter; int m_counter;
}; };

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -28,154 +28,130 @@ extern Jack* jack;
#include "jacksendreturn.hxx" #include "jacksendreturn.hxx"
Logic::Logic() Logic::Logic()
{ {
} }
void Logic::tapTempo() void Logic::tapTempo()
{ {
jack->getTimeManager()->tap(); jack->getTimeManager()->tap();
} }
void Logic::setBpm(float bpm) void Logic::setBpm(float bpm)
{ {
jack->getTimeManager()->setBpm( bpm ); jack->getTimeManager()->setBpm( bpm );
} }
void Logic::metronomeEnable(bool b) void Logic::metronomeEnable(bool b)
{ {
jack->getMetronome()->setActive(b); jack->getMetronome()->setActive(b);
jack->getControllerUpdater()->metronomeEnable( b ); jack->getControllerUpdater()->metronomeEnable( b );
} }
void Logic::masterInputVol( float v ) void Logic::masterInputVol( float v )
{ {
jack->inputVolume( v ); jack->inputVolume( v );
jack->getControllerUpdater()->masterInputVol( v ); jack->getControllerUpdater()->masterInputVol( v );
} }
void Logic::masterInputTo( int to, float v ) void Logic::masterInputTo( int to, float v )
{ {
jack->inputTo( (Event::INPUT_TO)to, v ); jack->inputTo( (Event::INPUT_TO)to, v );
jack->getControllerUpdater()->masterInputTo( to, v ); jack->getControllerUpdater()->masterInputTo( to, v );
} }
void Logic::masterInputToActive( int inputTo, bool active) void Logic::masterInputToActive( int inputTo, bool active)
{ {
jack->inputToActive( (Event::INPUT_TO)inputTo, active); jack->inputToActive( (Event::INPUT_TO)inputTo, active);
jack->getControllerUpdater()->masterInputToActive( (int)inputTo, active ); jack->getControllerUpdater()->masterInputToActive( (int)inputTo, active );
} }
void Logic::masterReturn( int returnNum, float value ) void Logic::masterReturn( int returnNum, float value )
{ {
jack->returnVolume( value ); jack->returnVolume( value );
jack->getControllerUpdater()->masterReturnVolume( value ); jack->getControllerUpdater()->masterReturnVolume( value );
} }
void Logic::trackVolume(int t, float v) void Logic::trackVolume(int t, float v)
{ {
if ( t == -1 ) // master track if ( t == -1 ) { // master track
{ jack->masterVolume(v);
jack->masterVolume(v); jack->getControllerUpdater()->masterVolume( v );
jack->getControllerUpdater()->masterVolume( v ); } else if ( t >= 0 && t < NTRACKS ) {
} jack->getTrackOutput( t )->setMaster( v );
else if ( t >= 0 && t < NTRACKS ) jack->getControllerUpdater()->volume( t, v );
{ } else {
jack->getTrackOutput( t )->setMaster( v ); LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
jack->getControllerUpdater()->volume( t, v ); }
}
else
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::trackRecordArm(int t, bool v) void Logic::trackRecordArm(int t, bool v)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getTrackOutput( t )->recordArm( v );
jack->getTrackOutput( t )->recordArm( v ); jack->getControllerUpdater()->recordArm( t, v );
jack->getControllerUpdater()->recordArm( t, v ); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::trackSendActive(int t, int s, bool v) void Logic::trackSendActive(int t, int s, bool v)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getTrackOutput( t )->setSendActive( s, v );
jack->getTrackOutput( t )->setSendActive( s, v ); jack->getControllerUpdater()->setTrackSendActive( t, s, v );
jack->getControllerUpdater()->setTrackSendActive( t, s, v ); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::trackSend(int t, int send, float v) void Logic::trackSend(int t, int send, float v)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getTrackOutput( t )->setSend( send, v );
jack->getTrackOutput( t )->setSend( send, v ); jack->getControllerUpdater()->setTrackSend( t, send, v );
jack->getControllerUpdater()->setTrackSend( t, send, v ); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::trackJackSendActivate(int t, bool active) void Logic::trackJackSendActivate(int t, bool active)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getJackSendReturn(t)->activate(active);
jack->getJackSendReturn(t)->activate(active); jack->getControllerUpdater()->setTrackJackSendActive( t, active );
jack->getControllerUpdater()->setTrackJackSendActive( t, active ); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::trackJackSend(int t, float vol) void Logic::trackJackSend(int t, float vol)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getJackSendReturn(t)->sendVolume(vol);
jack->getJackSendReturn(t)->sendVolume(vol); jack->getControllerUpdater()->setTrackJackSend( t, vol );
jack->getControllerUpdater()->setTrackJackSend( t, vol ); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::looperClipLenght(int t, int s, int l) void Logic::looperClipLenght(int t, int s, int l)
{ {
if ( t >= 0 && t < NTRACKS ) if ( t >= 0 && t < NTRACKS ) {
{ jack->getLooper( t )->getClip( s )->setBeats(l);
jack->getLooper( t )->getClip( s )->setBeats(l); } else {
} LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
else }
{
LUPPP_WARN("invalid track number %i: check controller map has \"track\" field.", t );
}
} }
void Logic::looperUseAsTempo(int t, int s) void Logic::looperUseAsTempo(int t, int s)
{ {
size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats(); size_t clipBeats = jack->getLooper( t )->getClip( s )->getBeats();
size_t clipFrames = jack->getLooper( t )->getClip( s )->getBufferLenght(); size_t clipFrames = jack->getLooper( t )->getClip( s )->getBufferLenght();
if ( clipBeats > 0 ) if ( clipBeats > 0 ) {
{ size_t framesPerBeat = clipFrames / clipBeats;
size_t framesPerBeat = clipFrames / clipBeats; jack->getTimeManager()->setFpb( framesPerBeat );
jack->getTimeManager()->setFpb( framesPerBeat ); }
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -25,42 +25,42 @@
* This class contains an interface exposing most functionality in Luppp. The * This class contains an interface exposing most functionality in Luppp. The
* interface is used to have one central place from where each controller can * interface is used to have one central place from where each controller can
* interact with Luppp using the same function calls. * interact with Luppp using the same function calls.
* *
* This class should be used for input from any device. The interface is * This class should be used for input from any device. The interface is
* deliberatly specific with regards to scheduling events: controllers should * deliberatly specific with regards to scheduling events: controllers should
* NOT attempt to schedule changes: use the provided functions directly when * NOT attempt to schedule changes: use the provided functions directly when
* events occur on a controller. * events occur on a controller.
* *
* The ControllerUpdater class is the opposite of this class, it provides * The ControllerUpdater class is the opposite of this class, it provides
* feedback of each event that occurs. * feedback of each event that occurs.
* *
* Note: The GridLogic class provides the interface to scene selection / state. * Note: The GridLogic class provides the interface to scene selection / state.
**/ **/
class Logic class Logic
{ {
public: public:
Logic(); Logic();
void tapTempo();
void setBpm(float bpm); /// 0-1 input
void metronomeEnable(bool b);
void masterInputVol( float v );
void masterInputTo( int inputTo, float v);
void masterInputToActive( int inputTo, bool active);
void masterReturn( int returnNum, float v);
void trackVolume(int track, float volume);
void trackRecordArm(int track, bool armed);
void trackSendActive(int track, int send, bool active);
void trackSend(int track, int send, float value);
void trackJackSendActivate(int t, bool active); void tapTempo();
void trackJackSend(int t, float vol); void setBpm(float bpm); /// 0-1 input
void looperUseAsTempo(int track, int scene);
void looperClipLenght(int track, int scene, int lenght); void metronomeEnable(bool b);
void masterInputVol( float v );
void masterInputTo( int inputTo, float v);
void masterInputToActive( int inputTo, bool active);
void masterReturn( int returnNum, float v);
void trackVolume(int track, float volume);
void trackRecordArm(int track, bool armed);
void trackSendActive(int track, int send, bool active);
void trackSend(int track, int send, float value);
void trackJackSendActivate(int t, bool active);
void trackJackSend(int t, float vol);
void looperUseAsTempo(int track, int scene);
void looperClipLenght(int track, int scene, int lenght);
}; };
#endif // LUPPP_LOGIC_H #endif // LUPPP_LOGIC_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -31,50 +31,50 @@
extern Jack* jack; extern Jack* jack;
Looper::Looper(int t) : Looper::Looper(int t) :
AudioProcessor(), AudioProcessor(),
TimeObserver(), TimeObserver(),
track(t) track(t)
{ {
uiUpdateConstant= jack->getSamplerate() / 30.f; uiUpdateConstant= jack->getSamplerate() / 30.f;
uiUpdateCounter = jack->getSamplerate() / 30.f; uiUpdateCounter = jack->getSamplerate() / 30.f;
// pre-zero the internal sample // pre-zero the internal sample
//tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE ); //tmpRecordBuffer = (float*)malloc( sizeof(float) * MAX_BUFFER_SIZE );
//memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE ); //memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE );
for(int i = 0; i < 10; i++ ) for(int i = 0; i < 10; i++ ) {
{ clips[i] = new LooperClip(track, i);
clips[i] = new LooperClip(track, i); }
}
tmpBuffer.resize( MAX_BUFFER_SIZE );
tmpBuffer.resize( MAX_BUFFER_SIZE );
fpb = 22050;
fpb = 22050;
// init faust pitch shift variables
// init faust pitch shift variables fSamplingFreq = jack->getSamplerate();
fSamplingFreq = jack->getSamplerate(); IOTA = 0;
IOTA = 0;
//tmpRecordBuffer.resize(MAX_BUFFER_SIZE);
//tmpRecordBuffer.resize(MAX_BUFFER_SIZE);
for (int i=0; i<65536; i++)
for (int i=0; i<65536; i++) fVec0[i] = 0;
fVec0[i] = 0; for (int i=0; i<2; i++)
for (int i=0; i<2; i++) fRec0[i] = 0;
fRec0[i] = 0; semitoneShift = 0.0f;
semitoneShift = 0.0f; windowSize = 1000;
windowSize = 1000; crossfadeSize = 1000;
crossfadeSize = 1000;
} }
LooperClip* Looper::getClip(int scene) LooperClip* Looper::getClip(int scene)
{ {
return clips[scene]; return clips[scene];
} }
void Looper::beat() void Looper::beat()
{//TODO needed? {
//FIXME: Need to keep looperClips in sync when there exists no int N //TODO needed?
// such that playSpeed*N==1 //FIXME: Need to keep looperClips in sync when there exists no int N
// such that playSpeed*N==1
// for(int i=0;i<NSCENES;i++) // for(int i=0;i<NSCENES;i++)
// { // {
// int iph=clips[i]->getPlayhead()+1.0; // int iph=clips[i]->getPlayhead()+1.0;
@ -94,117 +94,108 @@ void Looper::beat()
void Looper::setRequestedBuffer(int s, AudioBuffer* ab) void Looper::setRequestedBuffer(int s, AudioBuffer* ab)
{ {
clips[s]->setRequestedBuffer( ab ); clips[s]->setRequestedBuffer( ab );
} }
void Looper::setFpb(int f) void Looper::setFpb(int f)
{ {
fpb = f; fpb = f;
} }
void Looper::process(unsigned int nframes, Buffers* buffers) void Looper::process(unsigned int nframes, Buffers* buffers)
{ {
// process each clip individually: this allows for playback of one clip, // process each clip individually: this allows for playback of one clip,
// while another clip records. // while another clip records.
for ( int clip = 0; clip < NSCENES; clip++ ) for ( int clip = 0; clip < NSCENES; clip++ ) {
{ // handle state of clip, and do what needs doing:
// handle state of clip, and do what needs doing: // record into buffer, play from buffer, etc
// record into buffer, play from buffer, etc if ( clips[clip]->recording() ) {
if ( clips[clip]->recording() ) if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST &&
{ !clips[clip]->newBufferInTransit() ) {
if ( clips[clip]->recordSpaceAvailable() < LOOPER_SAMPLES_BEFORE_REQUEST && EventLooperClipRequestBuffer e( track, clip, clips[clip]->audioBufferSize() + LOOPER_SAMPLES_UPDATE_SIZE);
!clips[clip]->newBufferInTransit() ) writeToGuiRingbuffer( &e );
{ clips[clip]->newBufferInTransit(true);
EventLooperClipRequestBuffer e( track, clip, clips[clip]->audioBufferSize() + LOOPER_SAMPLES_UPDATE_SIZE); }
writeToGuiRingbuffer( &e );
clips[clip]->newBufferInTransit(true); // copy data from input buffer to recording buffer
} float* input = buffers->audio[Buffers::MASTER_INPUT];
clips[clip]->record( nframes, input, 0 );
// copy data from input buffer to recording buffer } else if ( clips[clip]->playing() ) {
float* input = buffers->audio[Buffers::MASTER_INPUT]; // copy data into tmpBuffer, then pitch-stretch into track buffer
clips[clip]->record( nframes, input, 0 ); long targetFrames = clips[clip]->getBeats() * fpb;
} long actualFrames = clips[clip]->getActualAudioLength();//getBufferLenght();
else if ( clips[clip]->playing() ) float playSpeed = 1.0;
{
// copy data into tmpBuffer, then pitch-stretch into track buffer if ( targetFrames != 0 && actualFrames != 0 ) {
long targetFrames = clips[clip]->getBeats() * fpb; playSpeed = float(actualFrames) / targetFrames;
long actualFrames = clips[clip]->getActualAudioLength();//getBufferLenght(); }
float playSpeed = 1.0;
float* out = buffers->audio[Buffers::SEND_TRACK_0 + track];
if ( targetFrames != 0 && actualFrames != 0 )
{ for(unsigned int i = 0; i < nframes; i++ ) {
playSpeed = float(actualFrames) / targetFrames; // REFACTOR into system that is better than per sample function calls
} float tmp = clips[clip]->getSample(playSpeed);
float* out = buffers->audio[Buffers::SEND_TRACK_0 + track]; float deltaPitch = 12 * log ( playSpeed ) / log (2);
semitoneShift = -deltaPitch;
for(unsigned int i = 0; i < nframes; i++ )
{ // write the pitch-shifted signal to the track buffer
// REFACTOR into system that is better than per sample function calls //FIXME: pitchShift adds delay even for playSpeed = 1.0!!
float tmp = clips[clip]->getSample(playSpeed); //we should use something better (e.g librubberband)
if(playSpeed!=1.0f)
float deltaPitch = 12 * log ( playSpeed ) / log (2); pitchShift( 1, &tmp, &out[i] );
semitoneShift = -deltaPitch; else
out[i]+=tmp;
// write the pitch-shifted signal to the track buffer }
//FIXME: pitchShift adds delay even for playSpeed = 1.0!!
//we should use something better (e.g librubberband) //printf("Looper %i playing(), speed = %f\n", track, playSpeed );
if(playSpeed!=1.0f)
pitchShift( 1, &tmp, &out[i] ); if ( uiUpdateCounter > uiUpdateConstant ) {
else jack->getControllerUpdater()->setTrackSceneProgress(track, clip, clips[clip]->getProgress() );
out[i]+=tmp; uiUpdateCounter = 0;
} }
uiUpdateCounter += nframes;
//printf("Looper %i playing(), speed = %f\n", track, playSpeed ); }
if ( uiUpdateCounter > uiUpdateConstant ) }
{
jack->getControllerUpdater()->setTrackSceneProgress(track, clip, clips[clip]->getProgress() );
uiUpdateCounter = 0;
}
uiUpdateCounter += nframes;
}
}
} }
void Looper::resetTimeState() void Looper::resetTimeState()
{ {
for(int i=0;i<NSCENES;i++) for(int i=0; i<NSCENES; i++)
clips[i]->setPlayHead(0.0); clips[i]->setPlayHead(0.0);
} }
void Looper::pitchShift(int count, float* input, float* output) void Looper::pitchShift(int count, float* input, float* output)
{ {
float fSlow0 = windowSize; float fSlow0 = windowSize;
float fSlow1 = ((1 + fSlow0) - powf(2,(0.08333333333333333f * semitoneShift))); float fSlow1 = ((1 + fSlow0) - powf(2,(0.08333333333333333f * semitoneShift)));
float fSlow2 = (1.0f / crossfadeSize); float fSlow2 = (1.0f / crossfadeSize);
float fSlow3 = (fSlow0 - 1); float fSlow3 = (fSlow0 - 1);
float* input0 = &input[0]; float* input0 = &input[0];
//float* output0 = &output[0]; //float* output0 = &output[0];
for (int i=0; i<count; i++) for (int i=0; i<count; i++) {
{ float fTemp0 = (float)input0[i];
float fTemp0 = (float)input0[i]; fVec0[IOTA&65535] = fTemp0;
fVec0[IOTA&65535] = fTemp0; fRec0[0] = fmodf((fRec0[1] + fSlow1),fSlow0);
fRec0[0] = fmodf((fRec0[1] + fSlow1),fSlow0); int iTemp1 = int(fRec0[0]);
int iTemp1 = int(fRec0[0]); int iTemp2 = (1 + iTemp1);
int iTemp2 = (1 + iTemp1); float fTemp3 = min((fSlow2 * fRec0[0]), 1.f );
float fTemp3 = min((fSlow2 * fRec0[0]), 1.f ); float fTemp4 = (fSlow0 + fRec0[0]);
float fTemp4 = (fSlow0 + fRec0[0]); int iTemp5 = int(fTemp4);
int iTemp5 = int(fTemp4); float out=output[0];
float out=output[0]; out += (float)(((1 - fTemp3) * (((fTemp4 - iTemp5) *
out += (float)(((1 - fTemp3) * (((fTemp4 - iTemp5) * fVec0[(IOTA-int((int((1 + iTemp5)) & 65535)))&65535]) + ((0 - ((
fVec0[(IOTA-int((int((1 + iTemp5)) & 65535)))&65535]) + ((0 - (( fRec0[0] + fSlow3) - iTemp5)) * fVec0[(IOTA-int((iTemp5 & 65535)))
fRec0[0] + fSlow3) - iTemp5)) * fVec0[(IOTA-int((iTemp5 & 65535))) &65535]))) + (fTemp3 * (((fRec0[0] - iTemp1) * fVec0[(IOTA-int((int(
&65535]))) + (fTemp3 * (((fRec0[0] - iTemp1) * fVec0[(IOTA-int((int( iTemp2) & 65535)))&65535]) + ((iTemp2 - fRec0[0]) * fVec0[(IOTA-int((
iTemp2) & 65535)))&65535]) + ((iTemp2 - fRec0[0]) * fVec0[(IOTA-int(( iTemp1 & 65535)))&65535]))));
iTemp1 & 65535)))&65535]))));
output[0]=out;
output[0]=out; fRec0[1] = fRec0[0];
fRec0[1] = fRec0[0]; IOTA = IOTA+1;
IOTA = IOTA+1; }
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -37,55 +37,55 @@ using namespace std;
**/ **/
class Looper : public AudioProcessor, public TimeObserver class Looper : public AudioProcessor, public TimeObserver
{ {
public: public:
Looper(int t); Looper(int t);
/// *sets* the new audiobuffer, but the content gets copied to the new buffer.
/// Used for infinite lenght recording
void setRequestedBuffer(int s, AudioBuffer* ab);
/// stores the framesPerBeat from TimeManager. Used to stretch audio
void setFpb(int f);
/// Retrieve a clip from the Looper
LooperClip* getClip(int scene);
/// Override beat(). Resyncs loperclips to beat in case playSpeed is funny fraction
/// that doesnt add up to 1 (e.g if playSpeed=3/4 then 3/4+3/4+3/4+3/4=3!=1 bringing
/// looperClip out of sync)
virtual void beat();
/// Process nframes of audio
void process(unsigned int nframes, Buffers* buffers);
/// reset timestate implementation: rest all looperClips /// *sets* the new audiobuffer, but the content gets copied to the new buffer.
virtual void resetTimeState(); /// Used for infinite lenght recording
void setRequestedBuffer(int s, AudioBuffer* ab);
private:
const int track; /// stores the framesPerBeat from TimeManager. Used to stretch audio
void setFpb(int f);
/// variables used to determing the current actions of the looper
int playingScene; /// Retrieve a clip from the Looper
int queuedScene; LooperClip* getClip(int scene);
int fpb; /// Override beat(). Resyncs loperclips to beat in case playSpeed is funny fraction
/// that doesnt add up to 1 (e.g if playSpeed=3/4 then 3/4+3/4+3/4+3/4=3!=1 bringing
//vector<float> tmpRecordBuffer; /// looperClip out of sync)
LooperClip* clips[10]; virtual void beat();
/// Process nframes of audio
// Pitch Shifting void process(unsigned int nframes, Buffers* buffers);
void pitchShift(int count, float* input, float* output);
vector<float> tmpBuffer; /// reset timestate implementation: rest all looperClips
virtual void resetTimeState();
int IOTA;
float fVec0[65536]; private:
float semitoneShift; const int track;
float windowSize;
float fRec0[2]; /// variables used to determing the current actions of the looper
float crossfadeSize; int playingScene;
float fSamplingFreq; int queuedScene;
int uiUpdateConstant; int fpb;
int uiUpdateCounter;
//vector<float> tmpRecordBuffer;
LooperClip* clips[10];
// Pitch Shifting
void pitchShift(int count, float* input, float* output);
vector<float> tmpBuffer;
int IOTA;
float fVec0[65536];
float semitoneShift;
float windowSize;
float fRec0[2];
float crossfadeSize;
float fSamplingFreq;
int uiUpdateConstant;
int uiUpdateCounter;
}; };
#endif // LUPPP_LOOPER_H #endif // LUPPP_LOOPER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,465 +33,429 @@
extern Jack* jack; extern Jack* jack;
LooperClip::LooperClip(int t, int s) : LooperClip::LooperClip(int t, int s) :
Stately(), Stately(),
track(t), track(t),
scene(s) scene(s)
{ {
_buffer = new AudioBuffer(); _buffer = new AudioBuffer();
_buffer->nonRtResize( 4410 ); _buffer->nonRtResize( 4410 );
init(); init();
} }
void LooperClip::init() void LooperClip::init()
{ {
_loaded = false; _loaded = false;
_playing = false; _playing = false;
_recording = false; _recording = false;
_queuePlay = false; _queuePlay = false;
_queueStop = false; _queueStop = false;
_queueRecord= false; _queueRecord= false;
if ( _buffer ) if ( _buffer ) {
{ _buffer->init();
_buffer->init(); }
} _newBufferInTransit = false;
_newBufferInTransit = false;
_playhead = 0;
_playhead = 0; _recordhead = 0;
_recordhead = 0;
} }
void LooperClip::save() void LooperClip::save()
{ {
// ensure the buffer exists, and is saveable (not recording) // ensure the buffer exists, and is saveable (not recording)
if ( _loaded && !_recording && !_queueRecord ) if ( _loaded && !_recording && !_queueRecord ) {
{ char buffer [50];
char buffer [50]; sprintf (buffer, "LC::save() track %i, scene %i", track,scene);
sprintf (buffer, "LC::save() track %i, scene %i", track,scene); EventGuiPrint e( buffer );
EventGuiPrint e( buffer ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e );
int frames = _buffer->getAudioFrames();
int frames = _buffer->getAudioFrames(); EventRequestSaveBuffer e2( track, scene, frames );
EventRequestSaveBuffer e2( track, scene, frames ); writeToGuiRingbuffer( &e2 );
writeToGuiRingbuffer( &e2 ); } else {
} // notify of "success" of save if there *is* no state to save
else Stately::success();
{ }
// notify of "success" of save if there *is* no state to save
Stately::success();
}
} }
void LooperClip::reset() void LooperClip::reset()
{ {
// TODO make the LooperClip reset to initial state // TODO make the LooperClip reset to initial state
if ( _loaded ) if ( _loaded ) {
{ char buffer [50];
char buffer [50]; sprintf (buffer, "LC::reset() track %i, scene %i", track,scene);
sprintf (buffer, "LC::reset() track %i, scene %i", track,scene); EventGuiPrint e( buffer );
EventGuiPrint e( buffer ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e );
// set "progress" to zero as there's no clip anymore
// set "progress" to zero as there's no clip anymore jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 );
jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 ); } else {
} //SaveAble::done();
else }
{
//SaveAble::done(); init();
}
init();
} }
/// loads a sample: eg from disk, unloading current sample if necessary /// loads a sample: eg from disk, unloading current sample if necessary
void LooperClip::load( AudioBuffer* ab ) void LooperClip::load( AudioBuffer* ab )
{ {
_loaded = true; _loaded = true;
_recording = false; _recording = false;
_playing = false; _playing = false;
_queuePlay = false; _queuePlay = false;
_queueStop = false; _queueStop = false;
_queueRecord= false; _queueRecord= false;
if ( _buffer ) if ( _buffer ) {
{ EventDeallocateBuffer e( _buffer );
EventDeallocateBuffer e( _buffer ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e ); }
}
_buffer = ab;
_buffer = ab;
_playhead = 0;
_playhead = 0; jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 );
jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 );
// set the endpoint to the buffer's size
// set the endpoint to the buffer's size _recordhead = _buffer->getData().size();
_recordhead = _buffer->getData().size();
#ifdef DEBUG_BUFFER #ifdef DEBUG_BUFFER
char buffer [50]; char buffer [50];
sprintf (buffer, "LC::load() t %i, s %i, aF %i",track, scene, int(_buffer->getAudioFrames()) ); sprintf (buffer, "LC::load() t %i, s %i, aF %i",track, scene, int(_buffer->getAudioFrames()) );
EventGuiPrint e( buffer ); EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
#endif #endif
} }
void LooperClip::setRequestedBuffer( AudioBuffer* ab ) void LooperClip::setRequestedBuffer( AudioBuffer* ab )
{ {
if ( _buffer ) if ( _buffer ) {
{ size_t size = _buffer->getData().size();
size_t size = _buffer->getData().size(); memcpy( &ab->getData().at(0), &_buffer->getData().at(0), sizeof(float)*size);
memcpy( &ab->getData().at(0), &_buffer->getData().at(0), sizeof(float)*size);
ab->setID ( _buffer->getID() );
ab->setID ( _buffer->getID() ); ab->setBeats( _buffer->getBeats() );
ab->setBeats( _buffer->getBeats() );
EventDeallocateBuffer e( _buffer );
EventDeallocateBuffer e( _buffer ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e ); }
}
_buffer = ab;
_buffer = ab;
_newBufferInTransit = false;
_newBufferInTransit = false;
} }
void LooperClip::recieveSaveBuffer( AudioBuffer* saveBuffer ) void LooperClip::recieveSaveBuffer( AudioBuffer* saveBuffer )
{ {
if ( saveBuffer->getData().size() >= _buffer->getData().at(0) ) if ( saveBuffer->getData().size() >= _buffer->getData().at(0) ) {
{ // copy current contents into save buffer,
// copy current contents into save buffer, size_t framesBySize = _buffer->getAudioFrames();
size_t framesBySize = _buffer->getAudioFrames(); memcpy( &saveBuffer->getData().at(0), &_buffer->getData().at(0), sizeof(float)*framesBySize);
memcpy( &saveBuffer->getData().at(0), &_buffer->getData().at(0), sizeof(float)*framesBySize);
saveBuffer->setID ( _buffer->getID() );
saveBuffer->setID ( _buffer->getID() ); saveBuffer->setBeats( _buffer->getBeats() );
saveBuffer->setBeats( _buffer->getBeats() ); saveBuffer->setAudioFrames( _buffer->getAudioFrames() );
saveBuffer->setAudioFrames( _buffer->getAudioFrames() );
EventStateSaveBuffer e ( track, scene, saveBuffer );
EventStateSaveBuffer e ( track, scene, saveBuffer ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e );
Stately::success();
Stately::success(); } else {
} char buffer [50];
else sprintf (buffer, "LC:: %i, %i: can't save, buf too small",track, scene );
{ EventGuiPrint e( buffer );
char buffer [50]; writeToGuiRingbuffer( &e );
sprintf (buffer, "LC:: %i, %i: can't save, buf too small",track, scene ); Stately::error("");
EventGuiPrint e( buffer ); }
writeToGuiRingbuffer( &e );
Stately::error("");
}
} }
void LooperClip::setPlayHead(float ph) void LooperClip::setPlayHead(float ph)
{ {
if(!_recording&&_playing) if(!_recording&&_playing) {
{ _playhead = ph;
_playhead = ph; jack->getControllerUpdater()->setTrackSceneProgress(track, scene, getProgress() );
jack->getControllerUpdater()->setTrackSceneProgress(track, scene, getProgress() ); }
}
} }
void LooperClip::record(int count, float* L, float* R) void LooperClip::record(int count, float* L, float* R)
{ {
// write "count" samples into current buffer. // write "count" samples into current buffer.
if ( _buffer ) if ( _buffer ) {
{ size_t size = _buffer->getData().size();
size_t size = _buffer->getData().size();
for(int i = 0; i < count; i++) {
for(int i = 0; i < count; i++) if ( _recordhead < size ) {
{ _buffer->getData().at( _recordhead ) = *L++;
if ( _recordhead < size ) _recordhead++;
{ } else {
_buffer->getData().at( _recordhead ) = *L++; // break: this is *BAD*, audio data is lost but the buffer isn't here
_recordhead++; // yet to hold new audio data so there's no option. This has not been
} // encountered in actual usage, only during the development process.
else char buffer [50];
{ sprintf (buffer, "LooperClip t %i, s %i, Error: out of mem!",track, scene );
// break: this is *BAD*, audio data is lost but the buffer isn't here EventGuiPrint e( buffer );
// yet to hold new audio data so there's no option. This has not been writeToGuiRingbuffer( &e );
// encountered in actual usage, only during the development process.
char buffer [50];
sprintf (buffer, "LooperClip t %i, s %i, Error: out of mem!",track, scene );
EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e );
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
LUPPP_WARN("%s","buffer has no space"); LUPPP_WARN("%s","buffer has no space");
#endif #endif
break; break;
} }
} }
} }
_loaded = true; _loaded = true;
} }
unsigned long LooperClip::recordSpaceAvailable() unsigned long LooperClip::recordSpaceAvailable()
{ {
if ( _buffer ) if ( _buffer )
return _buffer->getData().size() - _recordhead; return _buffer->getData().size() - _recordhead;
return 0; return 0;
} }
size_t LooperClip::audioBufferSize() size_t LooperClip::audioBufferSize()
{ {
if ( _buffer ) if ( _buffer ) {
{ return _buffer->getData().size();
return _buffer->getData().size(); }
} return 0;
return 0;
} }
void LooperClip::setBeats(int beats) void LooperClip::setBeats(int beats)
{ {
if ( _buffer ) if ( _buffer ) {
{ _buffer->setBeats( beats );
_buffer->setBeats( beats ); }
}
} }
int LooperClip::getBeats() int LooperClip::getBeats()
{ {
if ( _buffer ) if ( _buffer )
return _buffer->getBeats(); return _buffer->getBeats();
return 0; return 0;
} }
long LooperClip::getBufferLenght() long LooperClip::getBufferLenght()
{ {
return _recordhead; return _recordhead;
} }
long LooperClip::getActualAudioLength() long LooperClip::getActualAudioLength()
{ {
char cbuffer [50]; char cbuffer [50];
// sprintf (cbuffer, "LooperClip recordhead %f,audioFrames %d \n",_recordhead,(int)_buffer->getAudioFrames()); // sprintf (cbuffer, "LooperClip recordhead %f,audioFrames %d \n",_recordhead,(int)_buffer->getAudioFrames());
// EventGuiPrint e( cbuffer ); // EventGuiPrint e( cbuffer );
// writeToGuiRingbuffer( &e ); // writeToGuiRingbuffer( &e );
// printf(cbuffer); // printf(cbuffer);
return _buffer->getAudioFrames(); return _buffer->getAudioFrames();
} }
void LooperClip::bar() void LooperClip::bar()
{ {
bool change = false; bool change = false;
GridLogic::State s = GridLogic::STATE_EMPTY; GridLogic::State s = GridLogic::STATE_EMPTY;
// first update the buffer, as time has passed // first update the buffer, as time has passed
if ( _recording ) if ( _recording ) {
{ // FIXME: assumes 4 beats in a bar
// FIXME: assumes 4 beats in a bar _buffer->setBeats( _buffer->getBeats() + 4 );
_buffer->setBeats( _buffer->getBeats() + 4 ); _buffer->setAudioFrames( jack->getTimeManager()->getFpb() * _buffer->getBeats() );
_buffer->setAudioFrames( jack->getTimeManager()->getFpb() * _buffer->getBeats() ); }
}
if ( _playhead >= _recordhead ) {
if ( _playhead >= _recordhead ) _playhead = 0.f;
{ }
_playhead = 0.f;
} if ( _queuePlay && _loaded ) {
//LUPPP_NOTE("QPLay + loaded" );
if ( _queuePlay && _loaded ) _playing = true;
{ s = GridLogic::STATE_PLAYING;
//LUPPP_NOTE("QPLay + loaded" ); _recording = false;
_playing = true; _queuePlay = false;
s = GridLogic::STATE_PLAYING; change = true;
_recording = false;
_queuePlay = false; _playhead = 0;
change = true; } else if ( _queueStop && _loaded ) {
_playing = false;
_playhead = 0; s = GridLogic::STATE_STOPPED;
} _recording = false;
else if ( _queueStop && _loaded ) _queueStop = false;
{ change = true;
_playing = false; // set "progress" to zero, as we're stopped!
s = GridLogic::STATE_STOPPED; jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 );
_recording = false; } else if ( _queueRecord ) {
_queueStop = false; _recording = true;
change = true; s = GridLogic::STATE_RECORDING;
// set "progress" to zero, as we're stopped! _playing = false;
jack->getControllerUpdater()->setTrackSceneProgress(track, scene, 0 ); _queueRecord = false;
} change = true;
else if ( _queueRecord )
{ if ( _buffer ) {
_recording = true; _buffer->setBeats( 0 );
s = GridLogic::STATE_RECORDING; }
_playing = false;
_queueRecord = false; _recordhead = 0;
change = true; } else if ( _queuePlay ) {
// clip was queued, but there's nothing loaded
if ( _buffer ) _queuePlay = false;
{ change = true;
_buffer->setBeats( 0 ); }
}
if ( change ) {
_recordhead = 0; jack->getControllerUpdater()->setSceneState(track, scene, s );
} }
else if ( _queuePlay )
{
// clip was queued, but there's nothing loaded
_queuePlay = false;
change = true;
}
if ( change )
{
jack->getControllerUpdater()->setSceneState(track, scene, s );
}
} }
void LooperClip::neutralize() void LooperClip::neutralize()
{ {
_queuePlay = false; _queuePlay = false;
_queueRecord = false; _queueRecord = false;
_queueStop = false; _queueStop = false;
} }
bool LooperClip::somethingQueued() bool LooperClip::somethingQueued()
{ {
if ( _queuePlay || _queueStop || _queueRecord ) if ( _queuePlay || _queueStop || _queueRecord ) {
{ return true;
return true; }
} return false;
return false;
} }
void LooperClip::queuePlay(bool qP) void LooperClip::queuePlay(bool qP)
{ {
_queuePlay = true; _queuePlay = true;
_queueStop = false; _queueStop = false;
_queueRecord = false; _queueRecord = false;
} }
void LooperClip::queueStop() void LooperClip::queueStop()
{ {
// comment // comment
if ( _loaded ) if ( _loaded ) {
{ _queueStop = true;
_queueStop = true; _queuePlay = false;
_queuePlay = false; }
}
} }
void LooperClip::queueRecord() void LooperClip::queueRecord()
{ {
_queueRecord = true; _queueRecord = true;
_queuePlay = false; _queuePlay = false;
_queueStop = false; _queueStop = false;
} }
GridLogic::State LooperClip::getState() GridLogic::State LooperClip::getState()
{ {
GridLogic::State s = GridLogic::STATE_EMPTY; GridLogic::State s = GridLogic::STATE_EMPTY;
if ( _loaded ) if ( _loaded )
s = GridLogic::STATE_STOPPED; s = GridLogic::STATE_STOPPED;
if ( _playing ) if ( _playing )
s = GridLogic::STATE_PLAYING; s = GridLogic::STATE_PLAYING;
if ( _recording ) if ( _recording )
s = GridLogic::STATE_RECORDING; s = GridLogic::STATE_RECORDING;
if ( _queuePlay ) if ( _queuePlay )
s = GridLogic::STATE_PLAY_QUEUED; s = GridLogic::STATE_PLAY_QUEUED;
if ( _queueStop ) if ( _queueStop )
s = GridLogic::STATE_STOP_QUEUED; s = GridLogic::STATE_STOP_QUEUED;
if ( _queueRecord ) if ( _queueRecord )
s = GridLogic::STATE_RECORD_QUEUED; s = GridLogic::STATE_RECORD_QUEUED;
return s; return s;
} }
bool LooperClip::playing() bool LooperClip::playing()
{ {
return _playing; return _playing;
} }
bool LooperClip::getQueueStop() bool LooperClip::getQueueStop()
{ {
return _queueStop; return _queueStop;
} }
bool LooperClip::getQueuePlay() bool LooperClip::getQueuePlay()
{ {
return _queuePlay; return _queuePlay;
} }
bool LooperClip::getLoaded() bool LooperClip::getLoaded()
{ {
return _loaded; return _loaded;
} }
bool LooperClip::recording() bool LooperClip::recording()
{ {
return _recording; return _recording;
} }
void LooperClip::newBufferInTransit(bool n) void LooperClip::newBufferInTransit(bool n)
{ {
_newBufferInTransit = n; _newBufferInTransit = n;
} }
bool LooperClip::newBufferInTransit() bool LooperClip::newBufferInTransit()
{ {
return _newBufferInTransit; return _newBufferInTransit;
} }
float LooperClip::getSample(float playSpeed) float LooperClip::getSample(float playSpeed)
{ {
if ( _buffer && _buffer->getData().size() > 0 ) if ( _buffer && _buffer->getData().size() > 0 ) {
{ if ( _playhead >= _recordhead ||
if ( _playhead >= _recordhead || _playhead >= _buffer->getData().size() ||
_playhead >= _buffer->getData().size() || _playhead < 0 ) {
_playhead < 0 ) _playhead = 0;
{
_playhead = 0;
EventGuiPrint e( "LooperClip resetting _playhead" );
//writeToGuiRingbuffer( &e );
}
std::vector<float>& v = _buffer->getData();
float tmp = v.at(_playhead);
_playhead +=playSpeed;
return tmp; EventGuiPrint e( "LooperClip resetting _playhead" );
} //writeToGuiRingbuffer( &e );
}
return 0.f;
std::vector<float>& v = _buffer->getData();
float tmp = v.at(_playhead);
_playhead +=playSpeed;
return tmp;
}
return 0.f;
} }
float LooperClip::getProgress() float LooperClip::getProgress()
{ {
if ( _buffer && _playing ) if ( _buffer && _playing ) {
{ float p = float(_playhead) / _recordhead;
float p = float(_playhead) / _recordhead; //printf("LooperClip progress %f\n", p );
//printf("LooperClip progress %f\n", p ); return p;
return p; }
} return 0.f;
return 0.f;
} }
float LooperClip::getPlayhead() float LooperClip::getPlayhead()
{ {
return _playhead; return _playhead;
} }
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
void LooperClip::setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec ) void LooperClip::setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec )
{ {
_loaded = load; _loaded = load;
_playing = play; _playing = play;
_recording = rec; _recording = rec;
_queuePlay = qPlay; _queuePlay = qPlay;
_queueStop = qStop; _queueStop = qStop;
_queueRecord = qRec; _queueRecord = qRec;
} }
#endif #endif

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -34,110 +34,113 @@ class AudioBuffer;
* The transition between AudioBuffer instances is seamless: when the clip is * The transition between AudioBuffer instances is seamless: when the clip is
* running out, the new one is requested. Upon its arrival the current data is * running out, the new one is requested. Upon its arrival the current data is
* copied, and the old buffer is returned for deallocation. * copied, and the old buffer is returned for deallocation.
* *
* This system allows for arbitrary length recordings, without huge * This system allows for arbitrary length recordings, without huge
* pre-allocated buffers while it is still quite simple. * pre-allocated buffers while it is still quite simple.
* *
* Each clip has its properties like length and bars/beats, so the Looper knows * Each clip has its properties like length and bars/beats, so the Looper knows
* to dynamically stretch / process the audio appropriately. Controllers and the * to dynamically stretch / process the audio appropriately. Controllers and the
* UI are updated from this data. * UI are updated from this data.
* *
* This class inherits from SaveAble to save its state. * This class inherits from SaveAble to save its state.
**/ **/
class LooperClip : public Stately class LooperClip : public Stately
{ {
public: public:
LooperClip(int track, int scene); LooperClip(int track, int scene);
void init();
/// loads a sample: eg from disk, unloading current sample if necessary
void load( AudioBuffer* ab );
/// audio functionality
float getSample(float playSpeed);
void record(int count, float* L, float* R);
/// TimeObserver override
void bar();
/// SaveAble overrides
void save();
void reset();
/// analyses current _playing _recording vars, returns the current State
GridLogic::State getState();
bool playing();
bool getLoaded();
bool getQueueStop();
bool getQueuePlay();
bool recording();
/// get buffer details
int getBeats();
float getProgress();
float getPlayhead();
//Return the length of the complete buffer
long getBufferLenght();
//Return the nr of samples holding actual audio. This is less then getBufferLength();
long getActualAudioLength();
size_t audioBufferSize();
AudioBuffer* getAudioBuffer() {return _buffer;} void init();
/// set clip state /// loads a sample: eg from disk, unloading current sample if necessary
void queuePlay(bool=true); void load( AudioBuffer* ab );
void queueStop();
void queueRecord(); /// audio functionality
float getSample(float playSpeed);
void neutralize(); // removes all play || record states if on void record(int count, float* L, float* R);
bool somethingQueued(); // returns true if any state is queued
/// TimeObserver override
/// set buffer state void bar();
void setBeats(int beats);
/// SaveAble overrides
/// Luppp internal buffer resizing void save();
void newBufferInTransit(bool n); void reset();
bool newBufferInTransit();
unsigned long recordSpaceAvailable(); /// analyses current _playing _recording vars, returns the current State
GridLogic::State getState();
/** used to update the size of the buffer for this looperclip. The current bool playing();
* data is copied into the new buffer, then the smaller buffer is sent bool getLoaded();
* for de-allocation. bool getQueueStop();
**/ bool getQueuePlay();
void setRequestedBuffer( AudioBuffer* ab ); bool recording();
/// used for saving the contents of this buffer to disk /// get buffer details
void recieveSaveBuffer( AudioBuffer* ab ); int getBeats();
float getProgress();
float getPlayhead();
//Return the length of the complete buffer
long getBufferLenght();
//Return the nr of samples holding actual audio. This is less then getBufferLength();
long getActualAudioLength();
size_t audioBufferSize();
AudioBuffer* getAudioBuffer()
{
return _buffer;
}
/// set clip state
void queuePlay(bool=true);
void queueStop();
void queueRecord();
void neutralize(); // removes all play || record states if on
bool somethingQueued(); // returns true if any state is queued
/// set buffer state
void setBeats(int beats);
/// Luppp internal buffer resizing
void newBufferInTransit(bool n);
bool newBufferInTransit();
unsigned long recordSpaceAvailable();
/** used to update the size of the buffer for this looperclip. The current
* data is copied into the new buffer, then the smaller buffer is sent
* for de-allocation.
**/
void setRequestedBuffer( AudioBuffer* ab );
/// used for saving the contents of this buffer to disk
void recieveSaveBuffer( AudioBuffer* ab );
///reset the play head to zero. Does nothing when recording
void setPlayHead(float ph);
///reset the play head to zero. Does nothing when recording
void setPlayHead(float ph);
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
// used only in test cases // used only in test cases
void setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec ); void setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec );
#endif #endif
private: private:
int track, scene; int track, scene;
/** Luppp needs more than the current state of the clip to accuratly handle /** Luppp needs more than the current state of the clip to accuratly handle
* it. The current state of the grid is kept up-to-date by GridLogic * it. The current state of the grid is kept up-to-date by GridLogic
* abstracting detail away, sending GridLogic::State to Controllers. * abstracting detail away, sending GridLogic::State to Controllers.
**/ **/
bool _loaded; bool _loaded;
bool _playing; bool _playing;
bool _recording; bool _recording;
bool _queuePlay; bool _queuePlay;
bool _queueStop; bool _queueStop;
bool _queueRecord; bool _queueRecord;
bool _newBufferInTransit; bool _newBufferInTransit;
float _playhead; float _playhead;
float _recordhead; float _recordhead;
AudioBuffer* _buffer; AudioBuffer* _buffer;
}; };
#endif // LUPPP_LOOPER_CLIP_H #endif // LUPPP_LOOPER_CLIP_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -45,99 +45,92 @@ Jack* jack = 0;
void signalHanlder(int signum) void signalHanlder(int signum)
{ {
signalHanlderInt = signum; signalHanlderInt = signum;
} }
static void gui_static_loadSession_cb(void* inst) static void gui_static_loadSession_cb(void* inst)
{ {
char* tmp = (char*) inst; char* tmp = (char*) inst;
int sess = gui->getDiskReader()->readSession( tmp ); int sess = gui->getDiskReader()->readSession( tmp );
if ( sess != LUPPP_RETURN_OK ) if ( sess != LUPPP_RETURN_OK )
LUPPP_ERROR( "Error loading session" ); LUPPP_ERROR( "Error loading session" );
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
LUPPP_NOTE("Git: %s", GIT_VERSION ); LUPPP_NOTE("Git: %s", GIT_VERSION );
bool runTests = false; bool runTests = false;
if ( runTests ){} // remove unused warning if not built with BUILD_TESTS if ( runTests ) {} // remove unused warning if not built with BUILD_TESTS
for(int i = 0; i < argc; i++) for(int i = 0; i < argc; i++) {
{ if ( strcmp(argv[i], "-test" ) == 0 ) {
if ( strcmp(argv[i], "-test" ) == 0 ) { runTests = true;
runTests = true; } else if ( i != 0 ) { // don't try load with the program name!
} // assume filename, try load it
else if ( i != 0 ) // don't try load with the program name! Fl::repeat_timeout( 1 / 30.f, &gui_static_loadSession_cb, argv[i] );
{ }
// assume filename, try load it }
Fl::repeat_timeout( 1 / 30.f, &gui_static_loadSession_cb, argv[i] );
} // setup the environment
} AVOIDDENORMALS();
signal(SIGINT , signalHanlder);
// setup the environment signal(SIGTERM, signalHanlder);
AVOIDDENORMALS();
signal(SIGINT , signalHanlder); // allocate data to read from
signal(SIGTERM, signalHanlder); processDspMem = (EventBase*)malloc( sizeof(EventBase) );
processGuiMem = (EventBase*)malloc( sizeof(EventBase) );
// allocate data to read from
processDspMem = (EventBase*)malloc( sizeof(EventBase) ); rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase));
processGuiMem = (EventBase*)malloc( sizeof(EventBase) ); rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase));
rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase));
rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase));
#ifdef BUILD_TESTS #ifdef BUILD_TESTS
LUPPP_NOTE("Built with BUILD_TESTS enabled"); LUPPP_NOTE("Built with BUILD_TESTS enabled");
if ( runTests ) if ( runTests ) {
{ // counts failures
// counts failures int testResult = 0;
int testResult = 0;
// setup the testing Gui / JACK: Jack first, then GUI
// setup the testing Gui / JACK: Jack first, then GUI gui = new Gui( argv[0] );
gui = new Gui( argv[0] ); Jack::setup("LupppTEST");
Jack::setup("LupppTEST");
// test offline functionality
// test offline functionality testResult += gui->getDiskReader()->runTests();
testResult += gui->getDiskReader()->runTests(); testResult += gui->getDiskWriter()->runTests();
testResult += gui->getDiskWriter()->runTests();
// test realtime functionality
// test realtime functionality testResult += jack->getGridLogic()->runTests();
testResult += jack->getGridLogic()->runTests();
jack->quit();
jack->quit();
delete gui;
delete gui; delete jack;
delete jack; jack = 0;
jack = 0;
// running tests == quitting after testing finishes
// running tests == quitting after testing finishes return testResult;
return testResult; }
}
#endif #endif
// Create a GUI, check for NSM integration // Create a GUI, check for NSM integration
gui = new Gui( argv[0] ); gui = new Gui( argv[0] );
if ( gui->getNsm() ) if ( gui->getNsm() ) {
{ // the NSM OSC Open message will trigger Jack initialization: necessary
// the NSM OSC Open message will trigger Jack initialization: necessary // to use the right name to create the JACK client.
// to use the right name to create the JACK client. } else {
} Jack::setup("Luppp");
else jack->activate();
{ }
Jack::setup("Luppp");
jack->activate(); gui->show();
}
gui->show(); return 0;
return 0;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -30,91 +30,88 @@ extern Jack* jack;
using namespace std; using namespace std;
Metronome::Metronome() : Metronome::Metronome() :
TimeObserver(), TimeObserver(),
playBar (false), playBar (false),
active (false), active (false),
vol (1), vol (1),
playPoint (0) playPoint (0)
{ {
//Create Beat/Bar samples //Create Beat/Bar samples
beatSample=new float[jack->getSamplerate()]; beatSample=new float[jack->getSamplerate()];
barSample=new float[jack->getSamplerate()]; barSample=new float[jack->getSamplerate()];
// create beat and bar samples // create beat and bar samples
endPoint = ( jack->getSamplerate()/10 ); endPoint = ( jack->getSamplerate()/10 );
// samples per cycle of // samples per cycle of
float scale = 2 * 3.1415 *880/jack->getSamplerate(); float scale = 2 * 3.1415 *880/jack->getSamplerate();
// And fill it up // And fill it up
for(int i=0;i < jack->getSamplerate();i++){ for(int i=0; i < jack->getSamplerate(); i++) {
beatSample[i]= sin(i*scale); beatSample[i]= sin(i*scale);
barSample [i]= sin(i*scale*2); barSample [i]= sin(i*scale*2);
} }
// don't play after creation // don't play after creation
playPoint = endPoint + 1; playPoint = endPoint + 1;
} }
Metronome::~Metronome() Metronome::~Metronome()
{ {
if(beatSample) if(beatSample)
delete [] beatSample; delete [] beatSample;
if(barSample) if(barSample)
delete [] barSample; delete [] barSample;
} }
void Metronome::setActive(bool a) void Metronome::setActive(bool a)
{ {
active = a; active = a;
// don't play immidiatly // don't play immidiatly
playPoint = endPoint + 1; playPoint = endPoint + 1;
} }
void Metronome::setVolume( float v ) void Metronome::setVolume( float v )
{ {
vol = v; vol = v;
printf(" vol = %f \n", vol ); printf(" vol = %f \n", vol );
} }
void Metronome::bar() void Metronome::bar()
{ {
playPoint = 0; playPoint = 0;
playBar = true; playBar = true;
} }
void Metronome::beat() void Metronome::beat()
{ {
playPoint = 0; playPoint = 0;
playBar = false; playBar = false;
} }
void Metronome::setFpb(int f) void Metronome::setFpb(int f)
{ {
fpb = f; fpb = f;
// disable play until next beat // disable play until next beat
playPoint = endPoint + 1; playPoint = endPoint + 1;
} }
void Metronome::process(int nframes, Buffers* buffers) void Metronome::process(int nframes, Buffers* buffers)
{ {
if ( not active ) if ( not active )
return; return;
float* out = buffers->audio[Buffers::HEADPHONES_OUT]; float* out = buffers->audio[Buffers::HEADPHONES_OUT];
float* sample = &beatSample[0]; float* sample = &beatSample[0];
if( playBar ) if( playBar ) {
{ sample = &barSample[0];
sample = &barSample[0]; }
}
for(int i = 0; i < nframes; i++) {
for(int i = 0; i < nframes; i++) if ( playPoint < endPoint ) {
{ out[i] += sample[playPoint] * vol;
if ( playPoint < endPoint ) playPoint++;
{ }
out[i] += sample[playPoint] * vol; }
playPoint++;
}
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -30,30 +30,30 @@ using namespace std;
class Metronome : public TimeObserver class Metronome : public TimeObserver
{ {
public: public:
Metronome(); Metronome();
~Metronome(); ~Metronome();
void setActive(bool a); void setActive(bool a);
void bar(); void bar();
void beat(); void beat();
void setFpb(int f); void setFpb(int f);
void setVolume( float v ); void setVolume( float v );
void process(int nframes, Buffers* buffers); void process(int nframes, Buffers* buffers);
private: private:
int fpb; int fpb;
bool playBar; bool playBar;
bool active; bool active;
float vol; float vol;
int playPoint, endPoint; int playPoint, endPoint;
float* barSample; float* barSample;
float* beatSample; float* beatSample;
}; };
#endif // LUPPP_METRONOME_H #endif // LUPPP_METRONOME_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -25,109 +25,101 @@
extern Jack* jack; extern Jack* jack;
MidiIO::MidiIO() : MidiIO::MidiIO() :
portsRegistered(false), portsRegistered(false),
jackInputPort(0), jackInputPort(0),
jackOutputPort(0) jackOutputPort(0)
{ {
//LUPPP_NOTE("MidiIO %i",this); //LUPPP_NOTE("MidiIO %i",this);
} }
MidiIO::~MidiIO() MidiIO::~MidiIO()
{ {
jack->unregisterMidiIO( this ); jack->unregisterMidiIO( this );
//LUPPP_NOTE("~MidiIO unregistring ports"); //LUPPP_NOTE("~MidiIO unregistring ports");
jack_port_unregister( jack->getJackClientPointer(), jackInputPort ); jack_port_unregister( jack->getJackClientPointer(), jackInputPort );
jack_port_unregister( jack->getJackClientPointer(), jackOutputPort ); jack_port_unregister( jack->getJackClientPointer(), jackOutputPort );
} }
void MidiIO::writeMidi( unsigned char* data ) void MidiIO::writeMidi( unsigned char* data )
{ {
void* portBuffer = jack_port_get_buffer( jackOutputPort, jack->getBuffersize() ); void* portBuffer = jack_port_get_buffer( jackOutputPort, jack->getBuffersize() );
unsigned char* buffer = jack_midi_event_reserve( portBuffer, 0, 3); unsigned char* buffer = jack_midi_event_reserve( portBuffer, 0, 3);
if( buffer == 0 ) if( buffer == 0 ) {
{ return;
return; } else {
} //memcpy( buffer, data, sizeof(unsigned char)*3 );
else buffer[0] = data[0];
{ buffer[1] = data[1];
//memcpy( buffer, data, sizeof(unsigned char)*3 ); buffer[2] = data[2];
buffer[0] = data[0]; }
buffer[1] = data[1];
buffer[2] = data[2];
}
} }
int MidiIO::registerMidiPorts(std::string name) int MidiIO::registerMidiPorts(std::string name)
{ {
if( !jack ) if( !jack ) {
{ LUPPP_ERROR("Attempted register of controller, JACK not instantiated yet!");
LUPPP_ERROR("Attempted register of controller, JACK not instantiated yet!"); return LUPPP_RETURN_ERROR;
return LUPPP_RETURN_ERROR; }
}
jack_client_t* c = jack->getJackClientPointer();
jack_client_t* c = jack->getJackClientPointer();
// register the JACK MIDI ports
// register the JACK MIDI ports stringstream i;
stringstream i; i << name << " in";
i << name << " in"; jackInputPort = jack_port_register( c,
jackInputPort = jack_port_register( c, i.str().c_str(),
i.str().c_str(), JACK_DEFAULT_MIDI_TYPE,
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput,
JackPortIsInput, 0 );
0 ); stringstream o;
stringstream o; o << name << " out";
o << name << " out"; jackOutputPort = jack_port_register( c,
jackOutputPort = jack_port_register( c, o.str().c_str(),
o.str().c_str(), JACK_DEFAULT_MIDI_TYPE,
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput,
JackPortIsOutput, 0 );
0 );
if ( jackInputPort && jackOutputPort ) {
if ( jackInputPort && jackOutputPort ) //LUPPP_NOTE("%i, %i", jackInputPort, jackOutputPort );
{ portsRegistered = true;
//LUPPP_NOTE("%i, %i", jackInputPort, jackOutputPort ); return LUPPP_RETURN_OK;
portsRegistered = true; } else {
return LUPPP_RETURN_OK; LUPPP_ERROR("Error registering JACK ports" );
} return LUPPP_RETURN_ERROR;
else }
{
LUPPP_ERROR("Error registering JACK ports" );
return LUPPP_RETURN_ERROR;
}
} }
void MidiIO::initBuffers(int nframes) void MidiIO::initBuffers(int nframes)
{ {
if ( !portsRegistered ) if ( !portsRegistered )
return; return;
// clear the output buffer // clear the output buffer
void* outputBuffer= (void*) jack_port_get_buffer( jackOutputPort, nframes ); void* outputBuffer= (void*) jack_port_get_buffer( jackOutputPort, nframes );
jack_midi_clear_buffer( outputBuffer ); jack_midi_clear_buffer( outputBuffer );
} }
void MidiIO::process(int nframes) void MidiIO::process(int nframes)
{ {
if ( !portsRegistered ) if ( !portsRegistered )
return; return;
// get port buffers and setup // get port buffers and setup
void* inputBuffer = (void*) jack_port_get_buffer( jackInputPort, nframes ); void* inputBuffer = (void*) jack_port_get_buffer( jackInputPort, nframes );
jack_midi_event_t event; jack_midi_event_t event;
int index = 0; int index = 0;
int event_count = (int) jack_midi_get_event_count( inputBuffer ); int event_count = (int) jack_midi_get_event_count( inputBuffer );
while ( index < event_count ) while ( index < event_count ) {
{ jack_midi_event_get(&event, inputBuffer, index);
jack_midi_event_get(&event, inputBuffer, index); midi( (unsigned char*) &event.buffer[0] );
midi( (unsigned char*) &event.buffer[0] ); //printf( "MIDI %i %i %i\n", int(event.buffer[0]), int(event.buffer[1]), int(event.buffer[2]) );
//printf( "MIDI %i %i %i\n", int(event.buffer[0]), int(event.buffer[1]), int(event.buffer[2]) ); index++;
index++; }
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,32 +32,32 @@ extern Jack* jack;
**/ **/
class MidiIO class MidiIO
{ {
public: public:
MidiIO(); MidiIO();
virtual ~MidiIO(); virtual ~MidiIO();
/// name string to show in UI /// name string to show in UI
virtual std::string getName() = 0; virtual std::string getName() = 0;
/// gets / clears MIDI buffers /// gets / clears MIDI buffers
void initBuffers(int nframes); void initBuffers(int nframes);
/// gets called each process() in JACK /// gets called each process() in JACK
void process(int nframes); void process(int nframes);
/// called by the subclass to create MIDI ports /// called by the subclass to create MIDI ports
int registerMidiPorts(std::string name); int registerMidiPorts(std::string name);
virtual void midi(unsigned char* /*data*/){}; virtual void midi(unsigned char* /*data*/) {};
void writeMidi( unsigned char* /*data*/ ); void writeMidi( unsigned char* /*data*/ );
private: private:
bool portsRegistered; bool portsRegistered;
// there are jack_port_t* registered ports // there are jack_port_t* registered ports
jack_port_t* jackInputPort; jack_port_t* jackInputPort;
jack_port_t* jackOutputPort; jack_port_t* jackOutputPort;
}; };
#endif // LUPPP_MIDI_IO_H #endif // LUPPP_MIDI_IO_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -25,6 +25,6 @@ extern Jack* jack;
TimeObserver::TimeObserver() TimeObserver::TimeObserver()
{ {
jack->getTimeManager()->registerObserver( this ); jack->getTimeManager()->registerObserver( this );
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -23,23 +23,23 @@
class TimeObserver class TimeObserver
{ {
public: public:
/// registers with TimeManager /// registers with TimeManager
TimeObserver(); TimeObserver();
virtual ~TimeObserver(){}; virtual ~TimeObserver() {};
virtual void setFpb(int fpb){}; virtual void setFpb(int fpb) {};
//Reset any internal set of this object regarding time. Don't reset/delete any buffers!! //Reset any internal set of this object regarding time. Don't reset/delete any buffers!!
//This is not to be confused with Stately::reset() //This is not to be confused with Stately::reset()
virtual void resetTimeState(){}; virtual void resetTimeState() {};
virtual void bar(){}; virtual void bar() {};
virtual void beat(){}; virtual void beat() {};
virtual void tapTempo(bool b){}; virtual void tapTempo(bool b) {};
}; };
#endif // LUPPP_TIME_OBSERVER_H #endif // LUPPP_TIME_OBSERVER_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -34,38 +34,36 @@ State::State()
void State::registerStately(Stately* s) void State::registerStately(Stately* s)
{ {
statelys.push_back( s ); statelys.push_back( s );
} }
void State::save() void State::save()
{ {
for( unsigned int i = 0; i < statelys.size(); i++) for( unsigned int i = 0; i < statelys.size(); i++) {
{ statelys.at(i)->save();
statelys.at(i)->save(); }
}
} }
void State::reset() void State::reset()
{ {
for( unsigned int i = 0; i < statelys.size(); i++) for( unsigned int i = 0; i < statelys.size(); i++) {
{ statelys.at(i)->reset();
statelys.at(i)->reset(); }
}
jack->getGridLogic()->updateState();
jack->getGridLogic()->updateState();
} }
void State::finish() void State::finish()
{ {
// trigger the GUI to write the metadata to disk, as each component of the // trigger the GUI to write the metadata to disk, as each component of the
// engine is done saving // engine is done saving
EventStateSaveFinish e; EventStateSaveFinish e;
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
} }
int State::getNumStatelys() int State::getNumStatelys()
{ {
return statelys.size(); return statelys.size();
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,24 +29,24 @@
**/ **/
class State class State
{ {
public: public:
State(); State();
/// called to initiate a save on all Statelys /// called to initiate a save on all Statelys
void save(); void save();
/// called to initiate a reset on all Statelys /// called to initiate a reset on all Statelys
void reset(); void reset();
/// called when each part is finished, and we can flush the metadata to disk /// called when each part is finished, and we can flush the metadata to disk
void finish(); void finish();
void registerStately(Stately* s); void registerStately(Stately* s);
int getNumStatelys(); int getNumStatelys();
private: private:
std::vector<Stately*> statelys; std::vector<Stately*> statelys;
}; };
#endif // LUPPP_STATE_H #endif // LUPPP_STATE_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -29,7 +29,7 @@ int Stately::saveErrors = 0;
Stately::Stately() Stately::Stately()
{ {
jack->getState()->registerStately( this ); jack->getState()->registerStately( this );
} }
@ -43,34 +43,32 @@ void Stately::save()
void Stately::checkCompletedSave() void Stately::checkCompletedSave()
{ {
if ( (saveSuccess + saveErrors) >= jack->getState()->getNumStatelys() ) if ( (saveSuccess + saveErrors) >= jack->getState()->getNumStatelys() ) {
{ jack->getState()->finish();
jack->getState()->finish();
if ( saveErrors ) {
if ( saveErrors ) // send message to UI to be printed, noting # of clips unsaved due to errors
{ char buf[50];
// send message to UI to be printed, noting # of clips unsaved due to errors sprintf( buf, "Saved with %i clips !saved due to errors", saveErrors);
char buf[50]; EventGuiPrint e( buf );
sprintf( buf, "Saved with %i clips !saved due to errors", saveErrors); writeToGuiRingbuffer( &e );
EventGuiPrint e( buf ); }
writeToGuiRingbuffer( &e );
} // reset in case of another save before quit
saveErrors = 0;
// reset in case of another save before quit saveSuccess = 0;
saveErrors = 0; }
saveSuccess = 0;
}
} }
void Stately::success() void Stately::success()
{ {
saveSuccess++; saveSuccess++;
checkCompletedSave(); checkCompletedSave();
} }
void Stately::error(const char* errorString) void Stately::error(const char* errorString)
{ {
// CRITICAL FIXME: add error handling code, noting an error occured, perhaps prompt user? // CRITICAL FIXME: add error handling code, noting an error occured, perhaps prompt user?
saveErrors++; saveErrors++;
checkCompletedSave(); checkCompletedSave();
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -21,40 +21,40 @@
/** Stately /** Stately
* This class is inherited from by all classes that have state. * This class is inherited from by all classes that have state.
* *
* save() should be overriden if the object needs to save its state * save() should be overriden if the object needs to save its state
* reset() should be overriden if the object can clear its state * reset() should be overriden if the object can clear its state
* *
* The flexibility allows eg LooperClips to request buffers to tranfser audio * The flexibility allows eg LooperClips to request buffers to tranfser audio
* data into the GUI thread for disk serialization, and scales for future * data into the GUI thread for disk serialization, and scales for future
* classes which also need to request memory in order to save in a RT safe way. * classes which also need to request memory in order to save in a RT safe way.
**/ **/
class Stately class Stately
{ {
public: public:
Stately(); Stately();
/// this function being called resets the state of the instance to blank /// this function being called resets the state of the instance to blank
virtual void reset(); virtual void reset();
/// this function is called when the user initiates a save action /// this function is called when the user initiates a save action
virtual void save(); virtual void save();
/// this function *must* be called by each sub-class when it is *finished* /// this function *must* be called by each sub-class when it is *finished*
/// a successful save action. Once each Stately is done, the final save is OK-ed. /// a successful save action. Once each Stately is done, the final save is OK-ed.
static void success(); static void success();
/// this function notes that a stately could *not* successfully save: buffer /// this function notes that a stately could *not* successfully save: buffer
/// size mismatch in LooperClip for example. /// size mismatch in LooperClip for example.
static void error(const char* errorString); static void error(const char* errorString);
private: private:
/// holds the amount of successful / error-full saves. Used by success() /// holds the amount of successful / error-full saves. Used by success()
/// and error() /// and error()
static int saveSuccess; static int saveSuccess;
static int saveErrors; static int saveErrors;
static void checkCompletedSave(); static void checkCompletedSave();
}; };
#endif // LUPPP_STATELY_H #endif // LUPPP_STATELY_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,21 +32,21 @@ extern bool testsPassed;
int DiskReader::runTests() int DiskReader::runTests()
{ {
QUnit::UnitTest qunit( QUnit::normal ); QUnit::UnitTest qunit( QUnit::normal );
// set the session path to /tmp for test writing // set the session path to /tmp for test writing
string path = "/tmp"; string path = "/tmp";
string session = "testSession"; string session = "testSession";
//AudioBuffer ab(440); //AudioBuffer ab(440);
//gui->getDiskWriter()->initialize(path, session); //gui->getDiskWriter()->initialize(path, session);
QUNIT_IS_TRUE( gui->getDiskReader()->loadSample( 0, 0,"/tmp/lupppTestMaterial/beat.wav" ) == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( gui->getDiskReader()->loadSample( 0, 0,"/tmp/lupppTestMaterial/beat.wav" ) == LUPPP_RETURN_OK );
QUNIT_IS_TRUE( gui->getDiskReader()->readSession("/tmp/lupppTestMaterial/lupppTest" ) == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( gui->getDiskReader()->readSession("/tmp/lupppTestMaterial/lupppTest" ) == LUPPP_RETURN_OK );
return qunit.errors(); return qunit.errors();
} }
#endif #endif

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -35,51 +35,51 @@ extern bool testsPassed;
int DiskWriter::runTests() int DiskWriter::runTests()
{ {
QUnit::UnitTest qunit( QUnit::normal ); QUnit::UnitTest qunit( QUnit::normal );
// set the session path to /tmp for test writing // set the session path to /tmp for test writing
string path = "/tmp"; string path = "/tmp";
string session = "testSession"; string session = "testSession";
AudioBuffer ab(440); AudioBuffer ab(440);
gui->getDiskWriter()->initialize(path, session); gui->getDiskWriter()->initialize(path, session);
QUNIT_IS_TRUE( gui->getDiskWriter()->writeAudioBuffer(0, 0, &ab) == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( gui->getDiskWriter()->writeAudioBuffer(0, 0, &ab) == LUPPP_RETURN_OK );
QUNIT_IS_TRUE( gui->getDiskWriter()->writeSession() == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( gui->getDiskWriter()->writeSession() == LUPPP_RETURN_OK );
QUNIT_IS_TRUE( strcmp( gui->getDiskWriter()->getLastSavePath().c_str(), path.c_str() ) == 0 ); QUNIT_IS_TRUE( strcmp( gui->getDiskWriter()->getLastSavePath().c_str(), path.c_str() ) == 0 );
QUNIT_IS_TRUE( strcmp( gui->getDiskWriter()->getLastSaveName().c_str(), session.c_str() ) == 0 ); QUNIT_IS_TRUE( strcmp( gui->getDiskWriter()->getLastSaveName().c_str(), session.c_str() ) == 0 );
/** write controller test: /** write controller test:
* This test ensures that when writing a GenericMIDI* controller to disk the * This test ensures that when writing a GenericMIDI* controller to disk the
* data is correct. A dummy controller instance is setup, and then written to * data is correct. A dummy controller instance is setup, and then written to
* disk. * disk.
**/ **/
int waste = 0; int waste = 0;
GenericMIDI* dummy = new GenericMIDI( waste, "dummy" ); GenericMIDI* dummy = new GenericMIDI( waste, "dummy" );
std::string name = "dummy name"; std::string name = "dummy name";
std::string author = "dummy author"; std::string author = "dummy author";
std::string link = "www.dummylink.com"; std::string link = "www.dummylink.com";
int d = gui->getDiskWriter()->writeControllerFile( dummy ); int d = gui->getDiskWriter()->writeControllerFile( dummy );
QUNIT_IS_TRUE( d == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( d == LUPPP_RETURN_OK );
dummy->setupBinding( Event::TRACK_VOLUME, 176, 7, 0, 0, 0, 0 ); dummy->setupBinding( Event::TRACK_VOLUME, 176, 7, 0, 0, 0, 0 );
dummy->setupBinding( Event::GRID_LAUNCH_SCENE, 144, 60, 0, 2, 0, 0 ); dummy->setupBinding( Event::GRID_LAUNCH_SCENE, 144, 60, 0, 2, 0, 0 );
int d1 = gui->getDiskWriter()->writeControllerFile( dummy ); int d1 = gui->getDiskWriter()->writeControllerFile( dummy );
QUNIT_IS_TRUE( d1 == LUPPP_RETURN_OK ); QUNIT_IS_TRUE( d1 == LUPPP_RETURN_OK );
/// test dynamic cast, null, and invalid Controller* type /// test dynamic cast, null, and invalid Controller* type
int r1 = gui->getDiskWriter()->writeControllerFile( 0 ); int r1 = gui->getDiskWriter()->writeControllerFile( 0 );
QUNIT_IS_TRUE( r1 == LUPPP_RETURN_ERROR ); QUNIT_IS_TRUE( r1 == LUPPP_RETURN_ERROR );
Controller* non = new NonSeq(); Controller* non = new NonSeq();
int r2 = gui->getDiskWriter()->writeControllerFile( non); int r2 = gui->getDiskWriter()->writeControllerFile( non);
QUNIT_IS_TRUE( r2 == LUPPP_RETURN_ERROR ); QUNIT_IS_TRUE( r2 == LUPPP_RETURN_ERROR );
return qunit.errors(); return qunit.errors();
} }
#endif #endif

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -26,14 +26,14 @@
int OptionsWindow::runTests() int OptionsWindow::runTests()
{ {
QUnit::UnitTest qunit( QUnit::normal, true ); QUnit::UnitTest qunit( QUnit::normal, true );
OptionsWindow opts; OptionsWindow opts;
//opts.show(); //opts.show();
//Fl::run(); //Fl::run();
//QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == s ); //QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == s );
return 0; return 0;
} }
#endif // BUILD_TESTS #endif // BUILD_TESTS

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,124 +32,124 @@ extern Jack* jack;
int GridLogic::runTests() int GridLogic::runTests()
{ {
QUnit::UnitTest qunit( QUnit::normal, true ); QUnit::UnitTest qunit( QUnit::normal, true );
int t = 0; int t = 0;
int s = 0; int s = 0;
LooperClip* lc = jack->getLooper( t )->getClip( s ); LooperClip* lc = jack->getLooper( t )->getClip( s );
// "pretty" prints the state of the clip // "pretty" prints the state of the clip
//LUPPP_NOTE("%s", GridLogic::StateString[ lc->getState() ] ); //LUPPP_NOTE("%s", GridLogic::StateString[ lc->getState() ] );
/// SCENE LAUNCH /// SCENE LAUNCH
lc->init(); lc->init();
jack->getGridLogic()->launchScene( s ); jack->getGridLogic()->launchScene( s );
QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == s ); QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == s );
/// QUEUE s1, then launch s2, s1 /// QUEUE s1, then launch s2, s1
int launchScene = s + 1; int launchScene = s + 1;
lc->init(); lc->init();
lc->setState( true, false, false, true, false, false ); // loaded + qplay lc->setState( true, false, false, true, false, false ); // loaded + qplay
LUPPP_NOTE("state before = %s", GridLogic::StateString[ lc->getState() ] ); LUPPP_NOTE("state before = %s", GridLogic::StateString[ lc->getState() ] );
jack->getGridLogic()->launchScene( launchScene ); // launch different clip jack->getGridLogic()->launchScene( launchScene ); // launch different clip
QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == launchScene ); QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == launchScene );
LUPPP_NOTE("state after launch before bar = %s", GridLogic::StateString[ lc->getState() ] ); LUPPP_NOTE("state after launch before bar = %s", GridLogic::StateString[ lc->getState() ] );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
LUPPP_NOTE("state after bar = %s", GridLogic::StateString[ lc->getState() ] ); LUPPP_NOTE("state after bar = %s", GridLogic::StateString[ lc->getState() ] );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED );
/// s1 playing, then launch s2, s1 /// s1 playing, then launch s2, s1
lc->init(); lc->init();
lc->setState( true, true, false, false, false, false ); // playing lc->setState( true, true, false, false, false, false ); // playing
//LUPPP_NOTE("state before = %s", GridLogic::StateString[ lc->getState() ] ); //LUPPP_NOTE("state before = %s", GridLogic::StateString[ lc->getState() ] );
jack->getGridLogic()->launchScene( launchScene ); // launch different clip jack->getGridLogic()->launchScene( launchScene ); // launch different clip
QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == launchScene ); QUNIT_IS_TRUE( jack->getGridLogic()->getLaunchedScene() == launchScene );
//LUPPP_NOTE("state after before bar = %s", GridLogic::StateString[ lc->getState() ] ); //LUPPP_NOTE("state after before bar = %s", GridLogic::StateString[ lc->getState() ] );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
//LUPPP_NOTE("state after bar = %s", GridLogic::StateString[ lc->getState() ] ); //LUPPP_NOTE("state after bar = %s", GridLogic::StateString[ lc->getState() ] );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED );
/// PRESS PAD /// PRESS PAD
// empty -> recording // empty -> recording
lc->init(); lc->init();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORD_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORD_QUEUED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORDING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORDING );
float buffer[64]; float buffer[64];
lc->record(64, &buffer[0], &buffer[0]); lc->record(64, &buffer[0], &buffer[0]);
// recording -> playing // recording -> playing
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING );
// playing -> stopped // playing -> stopped
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED );
// stopped -> playing // stopped -> playing
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED );
jack->getGridLogic()->bar(); jack->getGridLogic()->bar();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING );
/// DOUBLE PRESS PAD /// DOUBLE PRESS PAD
// empty -> recordQ -> empty // empty -> recordQ -> empty
lc->init(); lc->init();
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORD_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORD_QUEUED );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_EMPTY );
lc->bar(); lc->bar();
// recording -> playing -> stopped // recording -> playing -> stopped
lc->setState( true, false, true, false, false, false ); lc->setState( true, false, true, false, false, false );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORDING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_RECORDING );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED );
lc->bar(); lc->bar();
// stopped -> playing -> stopped // stopped -> playing -> stopped
lc->setState( true, false, false, false, false, false ); lc->setState( true, false, false, false, false, false );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOPPED );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAY_QUEUED );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED );
// stopped -> playing // stopped -> playing
lc->setState( true, true, false, false, false, false ); lc->setState( true, true, false, false, false, false );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_STOP_QUEUED );
jack->getGridLogic()->pressed( t, s ); jack->getGridLogic()->pressed( t, s );
jack->getGridLogic()->released( t, s ); jack->getGridLogic()->released( t, s );
QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING ); QUNIT_IS_TRUE( lc->getState() == GridLogic::STATE_PLAYING );
return qunit.errors(); return qunit.errors();
} }
#endif // BUILD_TESTS #endif // BUILD_TESTS

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -33,259 +33,241 @@ extern Jack* jack;
using namespace std; using namespace std;
TimeManager::TimeManager(): TimeManager::TimeManager():
transportState( TRANSPORT_ROLLING ), transportState( TRANSPORT_ROLLING ),
observers() observers()
{ {
samplerate = jack->getSamplerate(); samplerate = jack->getSamplerate();
// 120 BPM default // 120 BPM default
fpb = samplerate / 2; fpb = samplerate / 2;
//Counter for current bar/beat //Counter for current bar/beat
barCounter = 0; barCounter = 0;
beatCounter = 0; beatCounter = 0;
previousBeat = 0; previousBeat = 0;
//In process() we want to immediately process bar(), beat() of all observers //In process() we want to immediately process bar(), beat() of all observers
// thats why beatFrameCountdown<nframes, but we don't know yet what value nframes has // thats why beatFrameCountdown<nframes, but we don't know yet what value nframes has
// so set beatFrameCountdown to a value that garantees beatFrameCountdown<nframes // so set beatFrameCountdown to a value that garantees beatFrameCountdown<nframes
beatFrameCountdown = -1;//fpb; beatFrameCountdown = -1;//fpb;
totalFrameCounter = 0; totalFrameCounter = 0;
tapTempoPos = 0; tapTempoPos = 0;
tapTempo[0] = 0; tapTempo[0] = 0;
tapTempo[1] = 0; tapTempo[1] = 0;
tapTempo[2] = 0; tapTempo[2] = 0;
} }
int TimeManager::getFpb() int TimeManager::getFpb()
{ {
return fpb; return fpb;
} }
void TimeManager::setBpm(float bpm) void TimeManager::setBpm(float bpm)
{ {
#ifdef DEBUG_TIME #ifdef DEBUG_TIME
LUPPP_NOTE("%s %f","setBpm()",bpm); LUPPP_NOTE("%s %f","setBpm()",bpm);
#endif #endif
setFpb( samplerate / bpm * 60 ); setFpb( samplerate / bpm * 60 );
barCounter = 0; barCounter = 0;
beatCounter = 0; beatCounter = 0;
beatFrameCountdown = -1; beatFrameCountdown = -1;
/* /*
for(int i=0;i<observers.size();i++) for(int i=0;i<observers.size();i++)
observers[i]->resetTimeState(); observers[i]->resetTimeState();
*/ */
} }
void TimeManager::setBpmZeroOne(float b) void TimeManager::setBpmZeroOne(float b)
{ {
setBpm( b * 160 + 60 ); // 60 - 220 setBpm( b * 160 + 60 ); // 60 - 220
} }
void TimeManager::setFpb(float f) void TimeManager::setFpb(float f)
{ {
fpb = f; fpb = f;
int bpm = ( samplerate * 60) / f; int bpm = ( samplerate * 60) / f;
char buffer [50]; char buffer [50];
sprintf (buffer, "TM, setFpb() %i, bpm = %i", int(f), int(bpm) ); sprintf (buffer, "TM, setFpb() %i, bpm = %i", int(f), int(bpm) );
EventGuiPrint e( buffer ); EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
EventTimeBPM e2( bpm ); EventTimeBPM e2( bpm );
writeToGuiRingbuffer( &e2 ); writeToGuiRingbuffer( &e2 );
for(uint i = 0; i < observers.size(); i++) for(uint i = 0; i < observers.size(); i++) {
{ observers.at(i)->setFpb(fpb);
observers.at(i)->setFpb(fpb); }
}
} }
void TimeManager::registerObserver(TimeObserver* o) void TimeManager::registerObserver(TimeObserver* o)
{ {
//LUPPP_NOTE("%s","registerObserver()"); //LUPPP_NOTE("%s","registerObserver()");
observers.push_back(o); observers.push_back(o);
o->setFpb( fpb ); o->setFpb( fpb );
int bpm = ( samplerate * 60) / fpb; int bpm = ( samplerate * 60) / fpb;
EventTimeBPM e2( bpm ); EventTimeBPM e2( bpm );
writeToGuiRingbuffer( &e2 ); writeToGuiRingbuffer( &e2 );
} }
void TimeManager::tap() void TimeManager::tap()
{ {
// reset tap tempo to "first tap" if more than 5 secs elapsed since last tap // reset tap tempo to "first tap" if more than 5 secs elapsed since last tap
if ( tapTempo[0] < totalFrameCounter - samplerate * 5 ) if ( tapTempo[0] < totalFrameCounter - samplerate * 5 ) {
{ tapTempoPos = 0;
tapTempoPos = 0; }
}
if ( tapTempoPos < 3 )
{
tapTempo[tapTempoPos] = totalFrameCounter;
tapTempoPos++;
}
else
{
// calculate frames per tap
int tapFpb1 = tapTempo[1] - tapTempo[0];
int tapFpb2 = tapTempo[2] - tapTempo[1];
int tapFpb3 = totalFrameCounter - tapTempo[2]; // last tap, until now
int average = (tapFpb1 + tapFpb2 + tapFpb3) / 3;
if( average < 13000 ) if ( tapTempoPos < 3 ) {
{ tapTempo[tapTempoPos] = totalFrameCounter;
char buffer [50]; tapTempoPos++;
sprintf (buffer, "TM, tap() average too slow! quitting"); } else {
EventGuiPrint e( buffer ); // calculate frames per tap
writeToGuiRingbuffer( &e ); int tapFpb1 = tapTempo[1] - tapTempo[0];
return; int tapFpb2 = tapTempo[2] - tapTempo[1];
} int tapFpb3 = totalFrameCounter - tapTempo[2]; // last tap, until now
char buffer [50];
sprintf (buffer, "TM, tap() average = %i", average );
EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e );
setFpb(average); int average = (tapFpb1 + tapFpb2 + tapFpb3) / 3;
// reset, so next 3 taps restart process if( average < 13000 ) {
tapTempoPos = 0; char buffer [50];
} sprintf (buffer, "TM, tap() average too slow! quitting");
EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e );
return;
}
char buffer [50];
sprintf (buffer, "TM, tap() average = %i", average );
EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e );
setFpb(average);
// reset, so next 3 taps restart process
tapTempoPos = 0;
}
} }
int TimeManager::getNframesToBeat() int TimeManager::getNframesToBeat()
{ {
// FIXME // FIXME
return -1; //beatFrameCountdown; return -1; //beatFrameCountdown;
} }
void TimeManager::setTransportState( TRANSPORT_STATE s ) void TimeManager::setTransportState( TRANSPORT_STATE s )
{ {
transportState = s; transportState = s;
if(transportState == TRANSPORT_STOPPED) if(transportState == TRANSPORT_STOPPED)
jack->transportRolling(false); jack->transportRolling(false);
else else {
{ jack->transportRolling(true);
jack->transportRolling(true); barCounter = 0;
barCounter = 0; beatCounter = 0;
beatCounter = 0; beatFrameCountdown = -1;
beatFrameCountdown = -1; for(int i=0; i<observers.size(); i++)
for(int i=0;i<observers.size();i++) observers[i]->resetTimeState();
observers[i]->resetTimeState(); }
}
} }
void TimeManager::process(Buffers* buffers) void TimeManager::process(Buffers* buffers)
{ {
// time signature? // time signature?
//buffers->transportPosition->beats_per_bar = 4; //buffers->transportPosition->beats_per_bar = 4;
//buffers->transportPosition->beat_type = 4; //buffers->transportPosition->beat_type = 4;
if ( transportState == TRANSPORT_STOPPED ) if ( transportState == TRANSPORT_STOPPED ) {
{ return;
return; }
}
int nframes = buffers->nframes;
int nframes = buffers->nframes;
if ( beatFrameCountdown < nframes )
{ if ( beatFrameCountdown < nframes ) {
//length of beat is not multiple of nframes, so need to process last frames of last beat *before* setting next beat //length of beat is not multiple of nframes, so need to process last frames of last beat *before* setting next beat
//then set new beat (get the queued actions: play, rec etc) //then set new beat (get the queued actions: play, rec etc)
// then process first frames *after* new beat // then process first frames *after* new beat
int before=(beatCounter*fpb)%nframes; int before=(beatCounter*fpb)%nframes;
int after=nframes-before; int after=nframes-before;
if ( before < nframes && after <= nframes && before + after == nframes ) if ( before < nframes && after <= nframes && before + after == nframes ) {
{ char buffer [50];
char buffer [50];
// sprintf (buffer, "Timing OK: before %i, after %i, b+a %i", before, after, before+after ); // sprintf (buffer, "Timing OK: before %i, after %i, b+a %i", before, after, before+after );
// EventGuiPrint e2( buffer ); // EventGuiPrint e2( buffer );
// writeToGuiRingbuffer( &e2 ); // writeToGuiRingbuffer( &e2 );
}
else
{
char buffer [50];
sprintf (buffer, "Timing Error: before: %i, after %i", before, after );
EventGuiPrint e2( buffer );
writeToGuiRingbuffer( &e2 );
}
// process before beat:
if(before)
jack->processFrames( before );
// handle beat:
// inform observers of new beat FIRST
for(uint i = 0; i < observers.size(); i++)
{
observers.at(i)->beat();
}
if ( beatCounter % 4 == 0 )
{
// inform observers of new bar SECOND
for(uint i = 0; i < observers.size(); i++)
{
observers.at(i)->bar();
}
barCounter++;
//beatCounter=0;
}
// process after
// we need to clear internal buffers in order to write *after* frames to them
jack->clearInternalBuffers(nframes);
if(after)
jack->processFrames( after );
// write new beat to UI (bar info currently not used) } else {
EventTimeBarBeat e( barCounter, beatCounter ); char buffer [50];
writeToGuiRingbuffer( &e ); sprintf (buffer, "Timing Error: before: %i, after %i", before, after );
EventGuiPrint e2( buffer );
writeToGuiRingbuffer( &e2 );
}
beatFrameCountdown = fpb-after;
beatCounter++;
}
else
{
jack->processFrames( nframes );
beatFrameCountdown -= nframes;
} // process before beat:
if(before)
jack->processFrames( before );
totalFrameCounter += nframes; // handle beat:
// inform observers of new beat FIRST
// write BPM / transport info to JACK for(uint i = 0; i < observers.size(); i++) {
int bpm = ( samplerate * 60) / fpb; observers.at(i)->beat();
if ( buffers->transportPosition ) }
{
buffers->transportPosition->valid = (jack_position_bits_t)(JackPositionBBT | JackTransportPosition); if ( beatCounter % 4 == 0 ) {
// inform observers of new bar SECOND
buffers->transportPosition->bar = beatCounter / 4 + 1;// bars 1-based for(uint i = 0; i < observers.size(); i++) {
buffers->transportPosition->beat = (beatCounter % 4) + 1; // beats 1-4 observers.at(i)->bar();
}
float part = float( fpb-beatFrameCountdown) / fpb; barCounter++;
buffers->transportPosition->tick = part > 1.0f? 0.9999*1920 : part*1920; //beatCounter=0;
}
buffers->transportPosition->frame = totalFrameCounter;
// process after
buffers->transportPosition->ticks_per_beat = 1920; // we need to clear internal buffers in order to write *after* frames to them
buffers->transportPosition->beats_per_bar = 4; jack->clearInternalBuffers(nframes);
if(after)
buffers->transportPosition->beats_per_minute = bpm; jack->processFrames( after );
}
// write new beat to UI (bar info currently not used)
EventTimeBarBeat e( barCounter, beatCounter );
writeToGuiRingbuffer( &e );
beatFrameCountdown = fpb-after;
beatCounter++;
} else {
jack->processFrames( nframes );
beatFrameCountdown -= nframes;
}
totalFrameCounter += nframes;
// write BPM / transport info to JACK
int bpm = ( samplerate * 60) / fpb;
if ( buffers->transportPosition ) {
buffers->transportPosition->valid = (jack_position_bits_t)(JackPositionBBT | JackTransportPosition);
buffers->transportPosition->bar = beatCounter / 4 + 1;// bars 1-based
buffers->transportPosition->beat = (beatCounter % 4) + 1; // beats 1-4
float part = float( fpb-beatFrameCountdown) / fpb;
buffers->transportPosition->tick = part > 1.0f? 0.9999*1920 : part*1920;
buffers->transportPosition->frame = totalFrameCounter;
buffers->transportPosition->ticks_per_beat = 1920;
buffers->transportPosition->beats_per_bar = 4;
buffers->transportPosition->beats_per_minute = bpm;
}
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -32,57 +32,57 @@ using namespace std;
class TimeManager class TimeManager
{ {
public: public:
TimeManager(); TimeManager();
int getFpb(); int getFpb();
void setBpm(float bpm); void setBpm(float bpm);
void setBpmZeroOne(float bpm); void setBpmZeroOne(float bpm);
void setFpb(float f); void setFpb(float f);
/// add a component to be updated for time events /// add a component to be updated for time events
void registerObserver(TimeObserver* o); void registerObserver(TimeObserver* o);
/// call this when a tempo-tap occurs /// call this when a tempo-tap occurs
void tap(); void tap();
/// called to process buffers->nframes samples. If a beat is present, this /// called to process buffers->nframes samples. If a beat is present, this
/// is handled gracefully, first calling process up to the beat, then doing /// is handled gracefully, first calling process up to the beat, then doing
/// a beat() event on all TimeObservers, and processing the remaining samples /// a beat() event on all TimeObservers, and processing the remaining samples
void process(Buffers* buffers); void process(Buffers* buffers);
/// returns the number of samples till beat if a beat exists in this process /// returns the number of samples till beat if a beat exists in this process
/// Otherwise returns nframes /// Otherwise returns nframes
int getNframesToBeat(); int getNframesToBeat();
/// TRANSPORT_STATE is defined in transport.hxx /// TRANSPORT_STATE is defined in transport.hxx
void setTransportState( TRANSPORT_STATE s ); void setTransportState( TRANSPORT_STATE s );
private: private:
int samplerate; int samplerate;
/// the "state" of the transport: rolling or stopped /// the "state" of the transport: rolling or stopped
TRANSPORT_STATE transportState; TRANSPORT_STATE transportState;
/// number of frames per beat /// number of frames per beat
int fpb; int fpb;
/// holds the number of frames processed /// holds the number of frames processed
long long totalFrameCounter; long long totalFrameCounter;
/// frame number of the last beat /// frame number of the last beat
long previousBeat; long previousBeat;
long beatFrameCountdown; long beatFrameCountdown;
/// counts bars / beats processed /// counts bars / beats processed
int barCounter; int barCounter;
int beatCounter; int beatCounter;
int tapTempoPos; int tapTempoPos;
long long tapTempo[3]; long long tapTempo[3];
std::vector<TimeObserver*> observers; std::vector<TimeObserver*> observers;
}; };
#endif // LUPPP_TIME_H #endif // LUPPP_TIME_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -22,149 +22,145 @@
extern Jack* jack; extern Jack* jack;
TrackOutput::TrackOutput(int t, AudioProcessor* ap) : TrackOutput::TrackOutput(int t, AudioProcessor* ap) :
AudioProcessor(), AudioProcessor(),
track(t), track(t),
_recordArm(false), _recordArm(false),
previousInChain(ap) previousInChain(ap)
{ {
// UI update // UI update
uiUpdateConstant = jack->getSamplerate() / 30; uiUpdateConstant = jack->getSamplerate() / 30;
uiUpdateCounter = jack->getSamplerate() / 30; uiUpdateCounter = jack->getSamplerate() / 30;
dbMeter = new DBMeter( jack->getSamplerate() ); dbMeter = new DBMeter( jack->getSamplerate() );
_toMaster = 0.8; _toMaster = 0.8;
_toMasterLag = 0.8; _toMasterLag = 0.8;
_toMasterDiff = 0; _toMasterDiff = 0;
_toReverb = 0.0; _toReverb = 0.0;
_toSidechain = 0.0; _toSidechain = 0.0;
_toPostSidechain = 0.0; _toPostSidechain = 0.0;
_toPostfaderActive = 0; _toPostfaderActive = 0;
_toKeyActive = 0; _toKeyActive = 0;
_toXSideActive = true; _toXSideActive = true;
} }
void TrackOutput::setMaster(float value) void TrackOutput::setMaster(float value)
{ {
if(value < 0.01) if(value < 0.01)
value = 0.f; value = 0.f;
_toMaster = value; _toMaster = value;
_toMasterDiff=_toMaster-_toMasterLag; _toMasterDiff=_toMaster-_toMasterLag;
} }
float TrackOutput::getMaster() float TrackOutput::getMaster()
{ {
return _toMaster; return _toMaster;
} }
bool TrackOutput::recordArm() bool TrackOutput::recordArm()
{ {
return _recordArm; return _recordArm;
} }
void TrackOutput::recordArm(bool r) void TrackOutput::recordArm(bool r)
{ {
_recordArm = r; _recordArm = r;
} }
void TrackOutput::setSendActive( int send, bool a ) void TrackOutput::setSendActive( int send, bool a )
{ {
switch( send ) switch( send ) {
{ case SEND_POSTFADER:
case SEND_POSTFADER: _toPostfaderActive = a;
_toPostfaderActive = a; break;
break; case SEND_KEY:
case SEND_KEY: _toKeyActive = a;
_toKeyActive = a; break;
break; //case SEND_XSIDE:
//case SEND_XSIDE: // _toXSideActive = a;
// _toXSideActive = a; default:
default: break;
break; }
}
} }
void TrackOutput::setSend( int send, float value ) void TrackOutput::setSend( int send, float value )
{ {
switch( send ) switch( send ) {
{ case SEND_POSTFADER:
case SEND_POSTFADER: _toReverb = value;
_toReverb = value; break;
break; case SEND_KEY:
case SEND_KEY: // setSendActive() handles on/off for this send
// setSendActive() handles on/off for this send //_toSidechain = value;
//_toSidechain = value; break;
break; case SEND_XSIDE:
case SEND_XSIDE: _toPostSidechain = value;
_toPostSidechain = value; break;
break; }
}
} }
void TrackOutput::process(unsigned int nframes, Buffers* buffers) void TrackOutput::process(unsigned int nframes, Buffers* buffers)
{ {
//compute master volume lag; //compute master volume lag;
if(fabs(_toMaster-_toMasterLag)>=fabs(_toMasterDiff/100.0)) if(fabs(_toMaster-_toMasterLag)>=fabs(_toMasterDiff/100.0))
_toMasterLag+=_toMasterDiff/10.0; _toMasterLag+=_toMasterDiff/10.0;
// get & zero track buffer // get & zero track buffer
float* trackBuffer = buffers->audio[Buffers::RETURN_TRACK_0 + track]; float* trackBuffer = buffers->audio[Buffers::RETURN_TRACK_0 + track];
memset( trackBuffer, 0, sizeof(float)*nframes ); memset( trackBuffer, 0, sizeof(float)*nframes );
// call process() up the chain // call process() up the chain
previousInChain->process( nframes, buffers ); previousInChain->process( nframes, buffers );
// run the meter // run the meter
dbMeter->process( nframes, trackBuffer, trackBuffer ); dbMeter->process( nframes, trackBuffer, trackBuffer );
if (uiUpdateCounter > uiUpdateConstant ) if (uiUpdateCounter > uiUpdateConstant ) {
{ float l = dbMeter->getLeftDB() * _toMasterLag;
float l = dbMeter->getLeftDB() * _toMasterLag; float r = dbMeter->getRightDB() * _toMasterLag;
float r = dbMeter->getRightDB() * _toMasterLag; EventTrackSignalLevel e( track, l, r );
EventTrackSignalLevel e( track, l, r ); writeToGuiRingbuffer( &e );
writeToGuiRingbuffer( &e ); uiUpdateCounter = 0;
uiUpdateCounter = 0; }
}
uiUpdateCounter += nframes;
uiUpdateCounter += nframes;
// copy audio data into reverb / sidechain / master buffers
// copy audio data into reverb / sidechain / master buffers float* reverb = buffers->audio[Buffers::SEND];
float* reverb = buffers->audio[Buffers::SEND]; float* sidechain = buffers->audio[Buffers::SIDECHAIN_KEY];
float* sidechain = buffers->audio[Buffers::SIDECHAIN_KEY]; float* postSidechain = buffers->audio[Buffers::SIDECHAIN_SIGNAL];
float* postSidechain = buffers->audio[Buffers::SIDECHAIN_SIGNAL];
float* masterL = buffers->audio[Buffers::MASTER_OUT_L];
float* masterL = buffers->audio[Buffers::MASTER_OUT_L]; float* masterR = buffers->audio[Buffers::MASTER_OUT_R];
float* masterR = buffers->audio[Buffers::MASTER_OUT_R];
float* jackoutput = buffers->audio[Buffers::JACK_TRACK_0+track]; float* jackoutput = buffers->audio[Buffers::JACK_TRACK_0+track];
for(unsigned int i = 0; i < nframes; i++) for(unsigned int i = 0; i < nframes; i++) {
{ // * master for "post-fader" sends
// * master for "post-fader" sends float tmp = trackBuffer[i];
float tmp = trackBuffer[i];
// post-sidechain *moves* signal between "before/after" ducking, not add!
// post-sidechain *moves* signal between "before/after" ducking, not add! masterL[i] += tmp * _toMasterLag * (1-_toPostSidechain);
masterL[i] += tmp * _toMasterLag * (1-_toPostSidechain); masterR[i] += tmp * _toMasterLag * (1-_toPostSidechain);
masterR[i] += tmp * _toMasterLag * (1-_toPostSidechain); if(jackoutput)
if(jackoutput) jackoutput[i] = tmp * _toMasterLag * (1-_toPostSidechain);
jackoutput[i] = tmp * _toMasterLag * (1-_toPostSidechain); if ( _toPostfaderActive )
if ( _toPostfaderActive ) reverb[i] += tmp * _toReverb * _toMasterLag;
reverb[i] += tmp * _toReverb * _toMasterLag;
if ( _toXSideActive )
if ( _toXSideActive ) postSidechain[i] += tmp * _toPostSidechain * _toMasterLag;
postSidechain[i] += tmp * _toPostSidechain * _toMasterLag;
// turning down an element in the mix should *NOT* influence sidechaining
// turning down an element in the mix should *NOT* influence sidechaining if ( _toKeyActive )
if ( _toKeyActive ) sidechain[i] += tmp;
sidechain[i] += tmp;
}
}
} }
TrackOutput::~TrackOutput() TrackOutput::~TrackOutput()
{ {
delete dbMeter; delete dbMeter;
} }

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -35,52 +35,52 @@
**/ **/
class TrackOutput : public AudioProcessor class TrackOutput : public AudioProcessor
{ {
public: public:
TrackOutput(int t, AudioProcessor* ap); TrackOutput(int t, AudioProcessor* ap);
/// set main mix, 0-1 /// set main mix, 0-1
void setMaster(float value); void setMaster(float value);
float getMaster(); float getMaster();
bool recordArm(); bool recordArm();
void recordArm(bool r); void recordArm(bool r);
/// set send /// set send
void setSend( int send, float value ); void setSend( int send, float value );
void setSendActive( int send, bool active ); void setSendActive( int send, bool active );
/// copies the track output to master buffer, sidechain & post-side buffer /// copies the track output to master buffer, sidechain & post-side buffer
void process(unsigned int nframes, Buffers* buffers); void process(unsigned int nframes, Buffers* buffers);
~TrackOutput(); ~TrackOutput();
private: private:
int track; int track;
bool _recordArm; bool _recordArm;
/// _toMasterLag is a volume that lags behind _toMaster when setMaster() is called /// _toMasterLag is a volume that lags behind _toMaster when setMaster() is called
/// This prohibits audible jumps when rapidly changing the volume /// This prohibits audible jumps when rapidly changing the volume
float _toMaster; float _toMaster;
float _toMasterLag; float _toMasterLag;
float _toMasterDiff; float _toMasterDiff;
float _toReverb;
float _toSidechain;
float _toPostSidechain;
bool _toPostfaderActive;
bool _toKeyActive;
bool _toXSideActive;
/// Pointer to "previous" processor: the graph is backwards
AudioProcessor* previousInChain;
// Metering variables
long uiUpdateCounter;
long uiUpdateConstant;
DBMeter* dbMeter;
float _toReverb;
float _toSidechain;
float _toPostSidechain;
bool _toPostfaderActive;
bool _toKeyActive;
bool _toXSideActive;
/// Pointer to "previous" processor: the graph is backwards
AudioProcessor* previousInChain;
// Metering variables
long uiUpdateCounter;
long uiUpdateConstant;
DBMeter* dbMeter;
}; };
#endif // LUPPP_TRACK_OUTPUT_H #endif // LUPPP_TRACK_OUTPUT_H

View file

@ -1,17 +1,17 @@
/* /*
* Author: Harry van Haaren 2013 * Author: Harry van Haaren 2013
* harryhaaren@gmail.com * harryhaaren@gmail.com
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -19,10 +19,9 @@
#ifndef LUPPP_TRANSPORT_H #ifndef LUPPP_TRANSPORT_H
#define LUPPP_TRANSPORT_H #define LUPPP_TRANSPORT_H
enum TRANSPORT_STATE enum TRANSPORT_STATE {
{ TRANSPORT_STOPPED = 0,
TRANSPORT_STOPPED = 0, TRANSPORT_ROLLING,
TRANSPORT_ROLLING,
}; };
#endif #endif