-Added metronome class, plays back synthesized sins on beat & bar

This commit is contained in:
Harry van Haaren 2013-05-15 22:48:43 +01:00
parent 2021054fd2
commit a30d540b49
5 changed files with 100 additions and 14 deletions

View file

@ -52,6 +52,9 @@ Jack::Jack()
loopers.push_back( new Looper(i) );
timeManager.registerObserver( loopers.back() );
}
timeManager.registerObserver( &metronome );
jack_transport_start(client);
}
@ -77,6 +80,9 @@ int Jack::process (jack_nframes_t nframes)
for(uint i = 0; i < loopers.size(); i++)
loopers.at(i)->process( nframes, &buffers );
if (true)
metronome.process( nframes, &buffers );
/*
float* input = buffers.audio[Buffers::MASTER_INPUT];
float* output = buffers.audio[Buffers::MASTER_OUTPUT];

View file

@ -18,6 +18,7 @@
#include <jack/transport.h>
#include "looper.hxx"
#include "metronome.hxx"
#include "timemanager.hxx"
using namespace std;
@ -40,6 +41,7 @@ class Jack
private:
Buffers buffers;
Metronome metronome;
TimeManager timeManager;
vector<Looper*> loopers;

View file

@ -34,19 +34,19 @@ class Looper : public Observer // for notifications
void bar()
{
cout << "Looper " << track << " got bar()" << flush;
//cout << "Looper " << track << " got bar()" << flush;
playPoint = 0;
if ( state == STATE_PLAY_QUEUED )
{
cout << " Q->Playing endpoint = " << endPoint;
cout << " Q->Playing endpoint = " << endPoint << endl;
state = STATE_PLAYING;
playPoint = 0;
endPoint = lastWrittenSampleIndex;
}
if ( state == STATE_RECORD_QUEUED )
{
cout << " Q->Recording ";
cout << " Q->Recording " << endl;
state = STATE_RECORDING;
playPoint = 0;
endPoint = 0;
@ -54,11 +54,10 @@ class Looper : public Observer // for notifications
}
if ( state == STATE_PLAY_QUEUED )
{
cout << " Q->Stopped ";
cout << " Q->Stopped " << endl;
state = STATE_STOPPED;
endPoint = lastWrittenSampleIndex;
}
cout << endl;
}
void beat()

79
src/metronome.hxx Normal file
View file

@ -0,0 +1,79 @@
#ifndef LUPPP_METRONOME_H
#define LUPPP_METRONOME_H
#include <cmath>
#include <iostream>
#include "buffers.hxx"
#include "observer/observer.hxx"
using namespace std;
// simple metronome class
class Metronome : public Observer
{
public:
Metronome() :
playPoint (0),
playBar (false)
{
// create beat and bar samples
endPoint = (44100.f/441);
// samples per cycle of
float scale = 2 * 3.1415 / endPoint;
/*And fill it up*/
for(int i=0;i < endPoint*40;i++){
beatSample[i]= sin(i*scale);
barSample [i]= sin(i*scale*1.5);
}
}
void bar()
{
playPoint = 0;
playBar = true;
}
void beat()
{
playPoint = 0;
//cout << "Looper " << track << " got beat()" << flush;
}
void setFpb(int f)
{
fpb = f;
//cout << "Looper " << track << " got fpb of " << fpb << endl;
}
void process(int nframes, Buffers* buffers)
{
float* out = buffers->audio[Buffers::MASTER_OUTPUT];
float* sample = &beatSample[0];
if( playBar ) { sample = &barSample[0]; playBar = false; }
for(int i = 0; i < nframes; i++)
{
if ( playPoint < endPoint )
{
out[i] += sample[playPoint++];
}
}
}
private:
int fpb;
bool playBar;
int playPoint, endPoint;
float barSample[44100];
float beatSample[44100];
};
#endif // LUPPP_METRONOME_H

View file

@ -49,19 +49,19 @@ class TimeManager
if ( beat != oldBeat )
{
if ( beat % (int)buffers->transportPosition->beats_per_bar == 0 )
{
// inform observers of new bar
for(uint i = 0; i < observers.size(); i++) { observers.at(i)->bar(); }
buffers->transportPosition->bar++;
}
// inform observers of new beat
// inform observers of new beat FIRST
for(uint i = 0; i < observers.size(); i++)
{
observers.at(i)->beat();
}
if ( beat % (int)buffers->transportPosition->beats_per_bar == 0 )
{
// inform observers of new bar SECOND
for(uint i = 0; i < observers.size(); i++) { observers.at(i)->bar(); }
buffers->transportPosition->bar++;
}
oldBeat = beat;
}