-BPM button working, Tap tempo button implemented. Working on Tap Tempo algorithm

This commit is contained in:
Harry van Haaren 2013-05-16 17:45:46 +01:00
parent d39fe8b948
commit 19d522b7f7
6 changed files with 85 additions and 25 deletions

View file

@ -28,6 +28,7 @@ namespace Event
METRONOME_ACTIVE, METRONOME_ACTIVE,
TIME_BPM, TIME_BPM,
TIME_TEMPO_TAP,
GUI_PRINT, GUI_PRINT,
}; };
@ -148,6 +149,17 @@ class EventTimeBPM : public EventBase
EventTimeBPM(float b) : bpm(b) {} EventTimeBPM(float b) : bpm(b) {}
}; };
class EventTimeTempoTap : public EventBase
{
public:
int type() { return int(TIME_TEMPO_TAP); }
uint32_t size() { return sizeof(EventTimeTempoTap); }
// no data needed, the event itself is an "event",
// jack measures time intervals in frames & does math
EventTimeTempoTap(){}
};
// prints the string S in the GUI console // prints the string S in the GUI console
class EventGuiPrint : public EventBase class EventGuiPrint : public EventBase

View file

@ -74,6 +74,12 @@ void handleDspEvents()
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeBPM) ); jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeBPM) );
jack->getTimeManager()->setBpm(ev.bpm); jack->getTimeManager()->setBpm(ev.bpm);
} break; } } break; }
case Event::TIME_TEMPO_TAP: {
if ( availableRead >= sizeof(EventTimeTempoTap) ) {
EventTimeTempoTap ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventTimeTempoTap) );
jack->getTimeManager()->tap();
} break; }
default: default:
{ {
// just do nothing // just do nothing

View file

@ -39,7 +39,12 @@ static void gmastertrack_button_callback(Fl_Widget *w, void *data) {
float bpm = b->value() * 160 + 60; // 60 - 220 float bpm = b->value() * 160 + 60; // 60 - 220
EventTimeBPM e = EventTimeBPM( bpm ); EventTimeBPM e = EventTimeBPM( bpm );
writeToDspRingbuffer( &e ); writeToDspRingbuffer( &e );
cout << "GUI writing bpm = " << bpm << endl; }
else if ( strcmp( w->label(), "Tap" ) == 0 )
{
Avtk::Button* b = (Avtk::Button*)w;
EventTimeTempoTap e;
writeToDspRingbuffer( &e );
} }
else else
{ {
@ -54,8 +59,9 @@ class GMasterTrack : public Fl_Group
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 ),
tapTempo(x + 25 + 22, y + 75, 44, 44,"Tap"),
/* /*
button1(x + 5, y + 24, 100, 18,"Rec"),
button2(x + 5, y + 44, 100, 18,"Play"), button2(x + 5, y + 44, 100, 18,"Play"),
button3(x + 5, y + 64, 100, 18,"Stop"), button3(x + 5, y + 64, 100, 18,"Stop"),
button4(x + 5, y + 84, 48, 18,"-"), button4(x + 5, y + 84, 48, 18,"-"),
@ -71,8 +77,10 @@ class GMasterTrack : public Fl_Group
*/ */
{ {
ID = privateID++; ID = privateID++;
tapTempo.callback( gmastertrack_button_callback, &ID );
/* /*
button1.callback( gmastertrack_button_callback, &ID );
button2.callback( gmastertrack_button_callback, &ID ); button2.callback( gmastertrack_button_callback, &ID );
button3.callback( gmastertrack_button_callback, &ID ); button3.callback( gmastertrack_button_callback, &ID );
button4.callback( gmastertrack_button_callback, &ID ); button4.callback( gmastertrack_button_callback, &ID );
@ -97,8 +105,9 @@ class GMasterTrack : public Fl_Group
char* title; char* title;
Avtk::Background bg; Avtk::Background bg;
Avtk::Button tapTempo;
/* /*
Avtk::Button button1;
Avtk::Button button2; Avtk::Button button2;
Avtk::Button button3; Avtk::Button button3;
Avtk::Button button4; Avtk::Button button4;

View file

@ -19,7 +19,9 @@
using namespace std; using namespace std;
static void gtrack_button_callback(Fl_Widget *w, void *data) { static void gtrack_button_callback(Fl_Widget *w, void *data) {
int track = *(int*)data; int track = 0;
if ( data )
track = *(int*)data;
//cout << "Button " << *(int*)data << " " << w->label() << " clicked" << endl; //cout << "Button " << *(int*)data << " " << w->label() << " clicked" << endl;
if ( strcmp( w->label() , "Rec" ) == 0 ) if ( strcmp( w->label() , "Rec" ) == 0 )
@ -49,8 +51,7 @@ static void gtrack_button_callback(Fl_Widget *w, void *data) {
} }
else if ( strcmp( w->label() , "Vol" ) == 0 ) else if ( strcmp( w->label() , "Vol" ) == 0 )
{ {
EventLooperLoopLength e = EventLooperLoopLength(track, 0.5);
writeToDspRingbuffer( &e );
} }
else else
{ {

View file

@ -54,7 +54,9 @@ class Metronome : public Observer
void setFpb(int f) void setFpb(int f)
{ {
fpb = f; fpb = f;
//cout << "Looper " << track << " got fpb of " << fpb << endl;
// disable play until next beat
playPoint = endPoint + 1;
} }
void process(int nframes, Buffers* buffers) void process(int nframes, Buffers* buffers)

View file

@ -18,49 +18,71 @@ class TimeManager
{ {
public: public:
TimeManager(): TimeManager():
bpm(120), fpb(120),
oldBeat(0) oldBeat(0)
{ {
tapTempoPos = 0;
tapTempo[0] = 0;
tapTempo[1] = 0;
tapTempo[2] = 0;
} }
void setBpm(float b) void setBpm(float bpm)
{ {
char buffer [50]; setFpb( 44100 / bpm * 60 );
sprintf (buffer, "%d", b); }
//printf ("[%s] is a string %d chars long\n",buffer,n); void setFpb(float f)
{
fpb = f;
char buffer [50];
sprintf (buffer, "TM, setFpb() %i", int(f) );
EventGuiPrint e( buffer ); EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e ); writeToGuiRingbuffer( &e );
bpm = b;
for(uint i = 0; i < observers.size(); i++) for(uint i = 0; i < observers.size(); i++)
{ {
observers.at(i)->setFpb(bpm); observers.at(i)->setFpb(fpb);
} }
} }
void registerObserver(Observer* o) void registerObserver(Observer* o)
{ {
observers.push_back(o); observers.push_back(o);
int fpb = 44100 / bpm * 60;
char buffer [50];
sprintf (buffer, "TM, bpm = %i, fpb = %i", int(bpm), fpb );
EventGuiPrint e( buffer );
writeToGuiRingbuffer( &e );
// triggers newly registered object to have bpm set
o->setFpb( fpb ); o->setFpb( fpb );
} }
void tap()
{
if ( tapTempoPos < 3 )
{
tapTempo[tapTempoPos] = frame;
}
else
{
// calculate frames per tap
int tapFpb1 = tapTempo[1] - tapTempo[0];
int tapFpb2 = tapTempo[2] - tapTempo[1];
int average = (tapFpb1 + tapFpb2) / 2;
setFpb(average);
}
}
void process(Buffers* buffers) void process(Buffers* buffers)
{ {
int framesPerBeat = (int) buffers->samplerate / (bpm / 60.0); // tap tempo measurements
frame = buffers->transportFrame;
//int framesPerBeat = (int) buffers->samplerate / (bpm / 60.0);
// 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;
int beat = buffers->transportFrame / framesPerBeat; int beat = buffers->transportFrame / fpb;
//int beat = int(beat); //int beat = int(beat);
//int tick = int( (beatFloat - beat) * 1920 ); //int tick = int( (beatFloat - beat) * 1920 );
@ -90,13 +112,21 @@ class TimeManager
buffers->transportPosition->tick = 0; buffers->transportPosition->tick = 0;
buffers->transportPosition->ticks_per_beat = 1920; buffers->transportPosition->ticks_per_beat = 1920;
int bpm = int(buffers->samplerate * fpb / 60.0);
buffers->transportPosition->beats_per_minute = bpm; buffers->transportPosition->beats_per_minute = bpm;
} }
private: private:
float bpm; float fpb;
int oldBeat; int oldBeat;
// tap tempo measurements
int frame;
int tapTempoPos;
int tapTempo[3];
std::vector<Observer*> observers; std::vector<Observer*> observers;
}; };