mirror of
https://github.com/vale981/openAV-Luppp
synced 2025-03-04 16:51:37 -05:00
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:
parent
0020d9a672
commit
01f71ec5e4
93 changed files with 11792 additions and 11466 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@ src/*.o
|
||||||
luppp
|
luppp
|
||||||
|
|
||||||
*.zip
|
*.zip
|
||||||
|
*.orig
|
||||||
|
|
||||||
build/*
|
build/*
|
||||||
buildTest/*
|
buildTest/*
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
172
src/buffers.hxx
172
src/buffers.hxx
|
@ -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
|
||||||
|
|
|
@ -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/>.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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" );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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__
|
||||||
|
|
||||||
|
|
1149
src/diskreader.cxx
1149
src/diskreader.cxx
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
114
src/event.cxx
114
src/event.cxx
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1435
src/event.hxx
1435
src/event.hxx
File diff suppressed because it is too large
Load diff
|
@ -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/>.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
685
src/goptions.cxx
685
src/goptions.cxx
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
144
src/goptions.hxx
144
src/goptions.hxx
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
294
src/gtrack.cxx
294
src/gtrack.cxx
|
@ -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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
123
src/gtrack.hxx
123
src/gtrack.hxx
|
@ -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
|
||||||
|
|
1311
src/gui.cxx
1311
src/gui.cxx
File diff suppressed because it is too large
Load diff
191
src/gui.hxx
191
src/gui.hxx
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
1020
src/jack.cxx
1020
src/jack.cxx
File diff suppressed because it is too large
Load diff
288
src/jack.hxx
288
src/jack.hxx
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
160
src/logic.cxx
160
src/logic.cxx
|
@ -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 );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
263
src/looper.cxx
263
src/looper.cxx
|
@ -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;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
102
src/looper.hxx
102
src/looper.hxx
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
163
src/main.cxx
163
src/main.cxx
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue