diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..4fe900c --- /dev/null +++ b/meson.build @@ -0,0 +1,42 @@ +project( 'openav_luppp', ['c','cpp'], + default_options : [ + 'cpp_std=c++11', + ]) + +conf_data = configuration_data() +conf_data.set('version', '1.1.1') + + +if(get_option('tests') == true) + add_project_arguments('-DBUILD_TESTS', language : 'cpp') +endif + +add_project_arguments('-Wno-unused-variable', language : 'cpp') +add_project_arguments('-Wno-reorder', language : 'cpp') +add_project_arguments('-Wno-sign-compare', language : 'cpp') + +cc = meson.get_compiler('c') +cpp = meson.get_compiler('cpp') + +luppp_src = [] +subdir('src') + + +dep_names = [ + 'ntk', + 'cairo', + 'liblo', + 'jack', + 'sndfile', + 'samplerate', + 'x11' + ] +deps = [] + +foreach dep : dep_names + deps += dependency(dep) +endforeach + +# compile the main project +executable('luppp', luppp_src + [version_hxx], + dependencies: deps) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..701b984 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1 @@ +option('tests', type : 'boolean', value : true, description : 'Build tests') diff --git a/src/avtk/avtk_unit.h b/src/avtk/avtk_unit.h index c2626c8..935c0fd 100644 --- a/src/avtk/avtk_unit.h +++ b/src/avtk/avtk_unit.h @@ -76,7 +76,7 @@ public: clips[5].state = UnitState::UNIT_STOPPING; } - static const int numClips = 10; + static const int numClips = NSCENES; UnitState clips[numClips]; bool mouseOver; diff --git a/src/avtk/clipselector.cxx b/src/avtk/clipselector.cxx index c2f8fd9..07a3e5d 100644 --- a/src/avtk/clipselector.cxx +++ b/src/avtk/clipselector.cxx @@ -47,7 +47,7 @@ ClipSelector::ClipSelector( int _x, int _y, int _w, int _h, _master = master; if ( _master ) { - for(int i = 0; i < numClips; i++ ) { + for(int i = 0; i < NSCENES; i++ ) { stringstream s; s << "Scene " << i + 1; clips[i].setName( s.str() ); diff --git a/src/avtk/clipselector.hxx b/src/avtk/clipselector.hxx index 2902905..c4228e0 100644 --- a/src/avtk/clipselector.hxx +++ b/src/avtk/clipselector.hxx @@ -97,8 +97,7 @@ public: int ID; - // FIXME: NSCENES? - static const int numClips = 11; + static const int numClips = NSCENES; ClipState clips[numClips]; /// indicates if a clip is the "special" clip diff --git a/src/avtk/meson.build b/src/avtk/meson.build new file mode 100644 index 0000000..66860a8 --- /dev/null +++ b/src/avtk/meson.build @@ -0,0 +1 @@ +luppp_src += files( 'bindings.cxx', 'volume.cxx', 'clipselector.cxx') diff --git a/src/cjson/meson.build b/src/cjson/meson.build new file mode 100644 index 0000000..3d44a70 --- /dev/null +++ b/src/cjson/meson.build @@ -0,0 +1 @@ +luppp_src += files('cJSON.c') diff --git a/src/config.hxx b/src/config.hxx index bc035ab..b238204 100644 --- a/src/config.hxx +++ b/src/config.hxx @@ -51,6 +51,10 @@ #define NSCENES 10 #define MAX_BUFFER_SIZE 1024 +/// TEMPO +#define MIN_TEMPO 60 +#define MAX_TEMPO 220 + #define CONTROLLERS_PREALLOC 20 // nsamples remaining during recording before Looper requests larger buffer diff --git a/src/controller/genericmidi.cxx b/src/controller/genericmidi.cxx index b729678..78ca8b3 100644 --- a/src/controller/genericmidi.cxx +++ b/src/controller/genericmidi.cxx @@ -547,7 +547,7 @@ void GenericMIDI::midi(unsigned char* midi) break; case Event::TIME_BPM: // FIXME: quick-fix for "ZeroOne" type value -> BPM range - jack->getLogic()->setBpm( value * 160 + 60 ); + jack->getLogic()->setBpm( value * (MAX_TEMPO - MIN_TEMPO) + MIN_TEMPO ); break; case Event::METRONOME_ACTIVE: jack->getLogic()->metronomeEnable( b->active ); diff --git a/src/controller/meson.build b/src/controller/meson.build new file mode 100644 index 0000000..f240e87 --- /dev/null +++ b/src/controller/meson.build @@ -0,0 +1,6 @@ +luppp_src += files( + 'controller.cxx', + 'genericmidi.cxx', + 'guicontroller.cxx', + 'nonseq.cxx' +) diff --git a/src/dsp/meson.build b/src/dsp/meson.build new file mode 100644 index 0000000..c84e1a3 --- /dev/null +++ b/src/dsp/meson.build @@ -0,0 +1 @@ +luppp_src += files('dsp_sidechain_gain.cxx') diff --git a/src/gmastertrack.cxx b/src/gmastertrack.cxx index e61f3dd..a25106a 100644 --- a/src/gmastertrack.cxx +++ b/src/gmastertrack.cxx @@ -23,7 +23,7 @@ static void gmastertrack_tempoDial_callback(Fl_Widget *w, void *data) { Avtk::Dial* b = (Avtk::Dial*)w; - float bpm = (int)(b->value() * 160.f + 60); + float bpm = (int)(b->value() * (float)(MAX_TEMPO - MIN_TEMPO) + MIN_TEMPO); if(std::fabs(bpm-round(bpm))) { LUPPP_WARN("%f",bpm); } @@ -169,8 +169,20 @@ static void gmastertrack_button_callback(Fl_Widget *w, void *data) } else if ( strcmp( w->label(), "Tap" ) == 0 ) { - EventTimeTempoTap e; - writeToDspRingbuffer( &e ); + if ( Fl::event_button() == FL_RIGHT_MOUSE ) { + const char* answer = fl_input("Enter BPM value (range %d and %d):", 0, MIN_TEMPO, MAX_TEMPO); + if(answer) { + int bpm = atoi(answer); + + if ( bpm >= MIN_TEMPO && bpm <= MAX_TEMPO) { + EventTimeBPM e = EventTimeBPM( bpm ); + writeToDspRingbuffer( &e ); + } + } + } else { + EventTimeTempoTap e; + writeToDspRingbuffer( &e ); + } } else { LUPPP_WARN("Error: unknown command string"); } @@ -260,7 +272,7 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) : void GMasterTrack::setBpm( int b ) { bpm = b; - tempoDial.value( ( bpm - 60 ) / 160.f ); + tempoDial.value( ( bpm - MIN_TEMPO ) / (float)(MAX_TEMPO - MIN_TEMPO) ); std::stringstream s; s << bpm; tempoDial.copy_label( s.str().c_str() ); diff --git a/src/gui.cxx b/src/gui.cxx index 3aaf3cd..f1e692e 100644 --- a/src/gui.cxx +++ b/src/gui.cxx @@ -880,7 +880,17 @@ int Gui::keyboardHandler(int event) } } - // keyboard arrows to special key mapping + // keyboard arrows / space to special key mapping + if ( Fl::event_key( 32 ) && Fl::event_state( FL_SHIFT ) ) { //spacebar + shift + EventGridState e( gui->specialTrack, gui->specialScene, GridLogic::STATE_EMPTY ); + writeToDspRingbuffer( &e ); + return 1; + } + if ( Fl::event_key( 32 ) ) { //spacebar + EventGridEvent e( gui->specialTrack, gui->specialScene, true ); + writeToDspRingbuffer( &e ); + return 1; + } if ( Fl::event_key( FL_Left ) ) { EventGridSelectNewChosen e( gui->specialTrack-1, gui->specialScene ); writeToDspRingbuffer( &e ); diff --git a/src/jacksendreturn.cxx b/src/jacksendreturn.cxx index 6b87e99..d803f4c 100644 --- a/src/jacksendreturn.cxx +++ b/src/jacksendreturn.cxx @@ -36,10 +36,12 @@ void JackSendReturn::process(unsigned int nframes, Buffers *buffers) //Process previous AudioProcessor m_previousProcessor->process(nframes,buffers); - float* sendL=(float*)jack_port_get_buffer(m_sendport_l,(jack_nframes_t)(buffers->nframes)); - float* sendR=(float*)jack_port_get_buffer(m_sendport_r,(jack_nframes_t)(buffers->nframes)); - float* retL=(float*)jack_port_get_buffer(m_returnport_l,(jack_nframes_t)(buffers->nframes)); - float* retR=(float*)jack_port_get_buffer(m_returnport_r,(jack_nframes_t)(buffers->nframes)); + + float* sendL=(float*)jack_port_get_buffer(m_sendport_l, (jack_nframes_t)(buffers->nframes)); + float* sendR=(float*)jack_port_get_buffer(m_sendport_r, (jack_nframes_t)(buffers->nframes)); + float* retL =(float*)jack_port_get_buffer(m_returnport_l,(jack_nframes_t)(buffers->nframes)); + float* retR =(float*)jack_port_get_buffer(m_returnport_r,(jack_nframes_t)(buffers->nframes)); + if(offset) { sendL+=offset; sendR+=offset; @@ -50,11 +52,7 @@ void JackSendReturn::process(unsigned int nframes, Buffers *buffers) for(int i=0; inframes) -// { -// cout<nframes); @@ -62,13 +60,11 @@ void JackSendReturn::process(unsigned int nframes, Buffers *buffers) if(m_active) { memcpy(rettrackL,retL,nframes*sizeof(float)); memcpy(rettrackR,retR,nframes*sizeof(float)); - } + } else { - memcpy(rettrackL, - sendtrackL,nframes*sizeof(float)); - memcpy(rettrackR, - sendtrackR,nframes*sizeof(float)); - } + memcpy(rettrackL, sendtrackL,nframes*sizeof(float)); + memcpy(rettrackR, sendtrackR,nframes*sizeof(float)); + } m_counter+=nframes; } diff --git a/src/looper.cxx b/src/looper.cxx index 13cda8b..92fb8aa 100644 --- a/src/looper.cxx +++ b/src/looper.cxx @@ -42,7 +42,7 @@ Looper::Looper(int t) : //tmpRecordBuffer = (float*)malloc( 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 < NSCENES; i++ ) { clips[i] = new LooperClip(track, i); } @@ -150,7 +150,7 @@ void Looper::process(unsigned int nframes, Buffers* buffers) // 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) - if(playSpeed!=1.0f) { + if(0) { //playSpeed!=1.0f) { pitchShift( 1, &tmpL, &outL[i] ); pitchShift( 1, &tmpR, &outR[i] ); } else { diff --git a/src/looper.hxx b/src/looper.hxx index 5bc3720..2f37814 100644 --- a/src/looper.hxx +++ b/src/looper.hxx @@ -70,7 +70,7 @@ private: int fpb; //vector tmpRecordBuffer; - LooperClip* clips[10]; + LooperClip* clips[NSCENES]; // Pitch Shifting void pitchShift(int count, float* input, float* output); diff --git a/src/looperclip.cxx b/src/looperclip.cxx index c6c8236..a852cf3 100644 --- a/src/looperclip.cxx +++ b/src/looperclip.cxx @@ -450,9 +450,9 @@ void LooperClip::getSample(float playSpeed, float* L, float* R) std::vector& vL = _buffer->getDataL(); std::vector& vR = _buffer->getDataR(); - *L = vL.at(_playhead); - *R = vR.at(_playhead); - _playhead +=playSpeed; + *L = vL[_playhead]; + *R = vR[_playhead]; + _playhead += playSpeed; } else { *L = 0.f; *R = 0.f; diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..d350343 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,40 @@ +version_hxx = vcs_tag( + input : 'version.hxx.in', + output : 'version.hxx') + +luppp_src = files( + 'audiobuffer.cxx', + 'controllerupdater.cxx', + 'debug.cxx', + 'diskreader.cxx', + 'diskwriter.cxx', + 'event.cxx', + 'eventhandlerdsp.cxx', + 'eventhandlergui.cxx', + 'gaudioeditor.cxx', + 'gmastertrack.cxx', + 'goptions.cxx', + 'gridlogic.cxx', + 'gtrack.cxx', + 'gui.cxx', + 'jack.cxx', + 'jacksendreturn.cxx', + 'logic.cxx', + 'looperclip.cxx', + 'looper.cxx', + 'main.cxx', + 'metronome.cxx', + 'timemanager.cxx', + 'trackoutput.cxx' + ) + +subdir('cjson') +subdir('dsp') +subdir('controller') +subdir('observer') +subdir('state') +subdir('avtk') + +if(get_option('tests') == true) + subdir('tests') +endif diff --git a/src/observer/meson.build b/src/observer/meson.build new file mode 100644 index 0000000..8016da9 --- /dev/null +++ b/src/observer/meson.build @@ -0,0 +1 @@ +luppp_src += files('midi.cxx', 'time.cxx') diff --git a/src/state/meson.build b/src/state/meson.build new file mode 100644 index 0000000..236ada8 --- /dev/null +++ b/src/state/meson.build @@ -0,0 +1 @@ +luppp_src += files('state.cxx', 'stately.cxx') diff --git a/src/tests/meson.build b/src/tests/meson.build new file mode 100644 index 0000000..2a5604d --- /dev/null +++ b/src/tests/meson.build @@ -0,0 +1,5 @@ +luppp_src += files( + 'diskreadertest.cxx', + 'diskwritertest.cxx', + 'goptionstest.cxx', + 'gridlogictests.cxx') diff --git a/src/timemanager.cxx b/src/timemanager.cxx index 1a262d3..60bc9b2 100644 --- a/src/timemanager.cxx +++ b/src/timemanager.cxx @@ -82,7 +82,7 @@ void TimeManager::setBpm(float bpm) void TimeManager::setBpmZeroOne(float b) { - setBpm( b * 160 + 60 ); // 60 - 220 + setBpm( b * (MAX_TEMPO - MIN_TEMPO) + MIN_TEMPO ); // 60 - 220 } diff --git a/src/version.hxx.in b/src/version.hxx.in new file mode 100644 index 0000000..9f82d90 --- /dev/null +++ b/src/version.hxx.in @@ -0,0 +1 @@ +#define GIT_VERSION "@VCS_TAG@"