-Updated Controller ControllerUpdater, added GUI Controller subclass, added progress test for feedback

This commit is contained in:
Harry van Haaren 2013-08-04 18:04:26 +01:00
parent d636d709af
commit eb94b51162
16 changed files with 210 additions and 45 deletions

View file

@ -27,11 +27,12 @@
#include <string>
#include "../gridlogic.hxx"
#include "../gclipselectoraction.hxx"
#include "../worker.hxx"
#include "../looper.hxx"
#include "../audiobuffer.hxx"
#include "../audiobuffer.hxx"./
#include "../eventhandler.hxx"
@ -125,44 +126,51 @@ class ClipSelector : public Fl_Button
/** 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.
**/
void setState( int clipNum, int )
void setState( int clipNum, GridLogic::State s )
{
/*
switch(s)
{
case Looper::STATE_PLAYING:
case GridLogic::STATE_EMPTY:
break;
case GridLogic::STATE_LOADED:
clips[clipNum].load();
break;
case GridLogic::STATE_PLAYING:
printf("clipSelector setState() clip %i = CLIP_PLAYING\n", clipNum);
for(int i = 0; i < numClips; i++ )
clips[clipNum].stop();
clips[clipNum].play();
break;
case Looper::STATE_PLAY_QUEUED:
case GridLogic::STATE_PLAY_QUEUED:
for(int i = 0; i < numClips; i++ )
clips[clipNum].unqueue();
clips[clipNum].queue();
printf("clipSelector setState() clip %i = CLIP_QUEUED\n", clipNum);
break;
case Looper::STATE_RECORDING:
case GridLogic::STATE_RECORDING:
for(int i = 0; i < numClips; i++ )
clips[clipNum].stopRecord();
clips[clipNum].record();
printf("clipSelector setState() clip %i = CLIP_RECORDING\n", clipNum);
break;
case Looper::STATE_RECORD_QUEUED:
case GridLogic::STATE_RECORD_QUEUED:
for(int i = 0; i < numClips; i++ )
clips[clipNum].unqueue();
clips[clipNum].queue();
printf("clipSelector setState() clip %i = CLIP_QUEUED\n", clipNum);
break;
case Looper::STATE_STOPPED:
/*
case GridLogic::STATE_STOPPED:
clips[clipNum].stop();
printf("clipSelector setState() clip %i = STATE_STOPPED\n", clipNum);
break;
case Looper::STATE_STOP_QUEUED:
*/
case GridLogic::STATE_STOP_QUEUED:
printf("clipSelector setState() clip %i = CLIP_QUEUED\n", clipNum);
break;
}
*/
redraw();
}

View file

@ -25,6 +25,15 @@ void AkaiAPC::recordArm(int t, bool enabled)
jack->writeApcOutput( &data[0] );
}
void AkaiAPC::progress(int t, int s, float f)
{
unsigned char data[3];
data[0] = 176;
data[1] = 48; // record enable LED
data[2] = 127 * f;
jack->writeApcOutput( &data[0] );
}
void AkaiAPC::setSceneState(int t, int clip, GridLogic::State s)
{
unsigned char data[3];

View file

@ -16,6 +16,7 @@ class AkaiAPC : public Controller, public MidiObserver
void mute(int t, bool b);
void volume(int t, float f);
void progress(int t, int s, float f);
void recordArm(int t, bool b);
void setSceneState(int track, int clip, GridLogic::State s);

View file

@ -10,27 +10,16 @@
class Controller
{
public:
enum ClipMode {
CLIP_MODE_EMPTY,
CLIP_MODE_PLAYING,
CLIP_MODE_PLAY_QUEUED,
CLIP_MODE_LOADED,
CLIP_MODE_STOP_QUEUED,
CLIP_MODE_RECORDING,
CLIP_MODE_RECORD_QUEUED,
};
Controller(){};
virtual ~Controller(){};
/// name string to show in UI
virtual std::string getName() = 0;
//virtual void setTrack(TrackState& t);
/// functionality
/// 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){};
};

43
src/controller/gui.cxx Normal file
View file

@ -0,0 +1,43 @@
#include "gui.hxx"
#include <iostream>
#include "../jack.hxx"
#include "../gridlogic.hxx"
extern Jack* jack;
LupppGUI::LupppGUI() :
Controller()
{
}
void LupppGUI::recordArm(int t, bool enabled)
{
}
void LupppGUI::setSceneState(int t, int clip, GridLogic::State s)
{
}
void LupppGUI::mute(int t, bool b)
{
}
void LupppGUI::volume(int t, float f)
{
}
void LupppGUI::progress(int t, int s, float f)
{
EventLooperProgress e( t, f );
writeToGuiRingbuffer( &e );
}

26
src/controller/gui.hxx Normal file
View file

@ -0,0 +1,26 @@
#ifndef LUPPP_CONTROLLER_GUI_H
#define LUPPP_CONTROLLER_GUI_H
#include "controller.hxx"
#include "../observer/midi.hxx"
class LupppGUI : public Controller
{
public:
LupppGUI();
std::string getName(){return "Luppp GUI";}
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 setSceneState(int track, int clip, GridLogic::State s);
};
#endif // LUPPP_CONTROLLER_GUI_H

View file

@ -33,6 +33,12 @@ class ControllerUpdater
c.at(i)->mute(t,b);
}
void setTrackSceneProgress(int t, int s, float p)
{
for(unsigned int i = 0; i < c.size(); i++)
c.at(i)->progress(t,s,p);
}
void setSceneState(int t, int clip, GridLogic::State s)
{
for(unsigned int i = 0; i < c.size(); i++)

View file

@ -14,7 +14,7 @@ GridLogic::GridLogic()
void GridLogic::pressed( int track, int scene )
{
state[track*NTRACKS + scene] = STATE_PLAYING;
jack->getControllerUpdater()->setSceneState(track, scene, STATE_PLAYING);
jack->getControllerUpdater()->setSceneState(track, scene, STATE_PLAY_QUEUED);
}
@ -28,3 +28,52 @@ void GridLogic::updateState()
{
}
void GridLogic::updateState( int track, int scene )
{
jack->getControllerUpdater()->setSceneState(track, scene, state[track*NTRACKS + scene] );
}
void GridLogic::bar()
{
printf("GridLogic::bar()\n" );
for( int i = 0; i < NTRACKS*NSCENES; i++ )
{
bool change = false;
if ( state[i] == STATE_PLAY_QUEUED )
{
state[i] = STATE_PLAYING;
change = true;
}
else if ( state[i] == STATE_STOP_QUEUED )
{
state[i] = STATE_LOADED;
change = true;
}
else if ( state[i] == STATE_RECORD_QUEUED )
{
state[i] = STATE_RECORDING;
change = true;
}
if ( change )
{
int scene = i % NTRACKS;
int track = i - scene;
updateState( track, scene );
printf("GridLogic::bar(), updated %i, %i\n", track, scene );
}
}
}
void GridLogic::beat()
{
}

View file

@ -44,8 +44,16 @@ class GridLogic : public TimeObserver
/// button release / click-release event
void released( int track, int scene );
/// resend entire grid state to controller
/// resend entire grid state to controllers
void updateState();
/// resend track / scene combo to controllers
void updateState( int track, int scene );
/// time functions, not for use by Controller subclasses
void bar();
void beat();
private:
/// contains the current state of each grid square

View file

@ -7,6 +7,8 @@
#include "eventhandler.hxx"
#include "controller/gui.hxx"
using namespace std;
extern int jackSamplerate;
@ -14,7 +16,10 @@ extern int jackSamplerate;
Jack::Jack() :
clientActive(false),
client( 0 ),
controllerUpdater( new ControllerUpdater() )
controllerUpdater( new ControllerUpdater() ),
timeManager(),
metronome( new Metronome() ),
gridLogic( new GridLogic() )
{
// open the client
client = jack_client_open ( "Luppp", JackNullOption , 0 , 0 );
@ -76,7 +81,7 @@ Jack::Jack() :
timeManager.registerObserver( loopers.back() );
}
timeManager.registerObserver( &metronome );
//timeManager.registerObserver( &metronome );
/// setup FX
reverb = new Reverb( buffers.samplerate );
@ -106,6 +111,12 @@ void Jack::activate()
// move to "settings" class or so
Controller* c = new AkaiAPC();
controllerUpdater->registerController( c );
Controller* g = new LupppGUI();
controllerUpdater->registerController( g );
// move to time class, get instantiate order right
jack->getTimeManager()->registerObserver( metronome );
jack->getTimeManager()->registerObserver( gridLogic );
jack_activate( client );
jack_transport_start(client);
@ -184,7 +195,7 @@ int Jack::process (jack_nframes_t nframes)
}
metronome.process( nframes, &buffers );
metronome->process( nframes, &buffers );
// process fx

View file

@ -43,8 +43,8 @@ class Jack
/// get functions for components owned by Jack
Looper* getLooper(int t) {return loopers.at(t); }
Metronome* getMetronome(){return &metronome;}
GridLogic* getGridLogic(){return &gridLogic;}
Metronome* getMetronome(){return metronome;}
GridLogic* getGridLogic(){return gridLogic;}
TrackOutput* getTrackOutput(int t){return trackOutputs.at(t);}
TimeManager* getTimeManager(){return &timeManager;}
ControllerUpdater* getControllerUpdater(){return controllerUpdater;}
@ -64,18 +64,15 @@ class Jack
void writeApcOutput( unsigned char* data );
private:
Buffers buffers;
Metronome metronome;
GridLogic gridLogic;
TimeManager timeManager;
Buffers buffers;
TimeManager timeManager;
Metronome* metronome;
GridLogic* gridLogic;
ControllerUpdater* controllerUpdater;
ControllerUpdater* controllerUpdater;
vector<Looper*> loopers;
vector<TrackOutput*> trackOutputs;
vector<MidiObserver*> midiObservers;
vector<Looper*> loopers;
vector<TrackOutput*> trackOutputs;
vector<MidiObserver*> midiObservers;
int nframes;
int samplerate;

View file

@ -215,9 +215,7 @@ void Looper::process(int nframes, Buffers* buffers)
// update UI of progress
if ( uiUpdateCounter > uiUpdateConstant )
{
EventLooperProgress e(track, clips[clip].getProgress() );
writeToGuiRingbuffer( &e );
//printf("writing event\n");
jack->getControllerUpdater()->setTrackSceneProgress(track, clip, clips[clip].getProgress() );
uiUpdateCounter = 0;
}
uiUpdateCounter += nframes;

11
src/observer/time.cxx Normal file
View file

@ -0,0 +1,11 @@
#include "time.hxx"
#include "../jack.hxx"
extern Jack* jack;
TimeObserver::TimeObserver()
{
//jack->getTimeManager()->registerObserver( this );
}

View file

@ -5,6 +5,9 @@
class TimeObserver
{
public:
/// registers with TimeManager
TimeObserver();
virtual void setFpb(int fpb){};
virtual void bar(){};

View file

@ -17,12 +17,15 @@ class TimeManager
public:
TimeManager():
fpb(22050),
oldBeat(0)
oldBeat(0),
observers()
{
tapTempoPos = 0;
tapTempo[0] = 0;
tapTempo[1] = 0;
tapTempo[2] = 0;
cout << "TimeManager() done" << endl;
}
void setBpm(float bpm)

View file

@ -27,9 +27,12 @@ def build(bld):
'src/looper.cxx',
'src/gridlogic.cxx',
'src/observer/time.cxx',
'src/observer/midi.cxx',
'src/controller/apc.cxx',
'src/controller/gui.cxx',
'src/eventhandlergui.cxx',
'src/eventhandlerdsp.cxx']