-Implemented Transport Play/Stop, and UI button

This commit is contained in:
Harry van Haaren 2014-08-08 13:54:18 +01:00
parent 4a1c27907b
commit 3070b2904a
9 changed files with 84 additions and 19 deletions

View file

@ -538,7 +538,7 @@ int DiskReader::readScenes(int t, cJSON* track)
// get metadata for Clip
cJSON* clip = cJSON_GetArrayItem( clips, s );
if ( !strcmp(clip->valuestring, "") == 0 )
if ( strcmp(clip->valuestring, "") != 0 )
{
stringstream sampleFilePath;
sampleFilePath << sessionPath << "/audio/" << clip->valuestring;

View file

@ -30,6 +30,7 @@
#include "looper.hxx"
#include "gridlogic.hxx"
#include "transport.hxx"
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -97,7 +98,9 @@ namespace Event
LOOPER_LOOP_LENGTH,
LOOPER_LOOP_USE_AS_TEMPO,
/// Transport etc
METRONOME_ACTIVE,
TRANSPORT, /// rolling or stopped
TIME_BPM,
TIME_BAR_BEAT,
@ -149,6 +152,16 @@ class EventBase
virtual const char* name(){return 0;}
};
class EventTransportState : public EventBase
{
public:
int type() { return int(TRANSPORT); }
uint32_t size() { return sizeof(EventTransportState); }
TRANSPORT_STATE ts;
EventTransportState(): ts( TRANSPORT_STOPPED ){}
EventTransportState( TRANSPORT_STATE t): ts(t){}
};
class EventControllerBindingMade : public EventBase
{
public:

View file

@ -81,6 +81,15 @@ void handleDspEvents()
} 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) ) {

View file

@ -107,6 +107,26 @@ static void gmastertrack_mixVol_callback(Fl_Widget *w, void *data)
//printf("MIX dial\n");
}
static void gmastertrack_transport_callback(Fl_Widget *w, void *data)
{
Avtk::LightButton* b = (Avtk::LightButton*)w;
if( b->value() )
{
EventTransportState e = EventTransportState( TRANSPORT_ROLLING );
writeToDspRingbuffer( &e );
w->label( "Stop" );
b->value( 0 );
}
else
{
EventTransportState e = EventTransportState( TRANSPORT_STOPPED );
writeToDspRingbuffer( &e );
w->label( "Play" );
b->value( 1 );
}
}
static void gmastertrack_button_callback(Fl_Widget *w, void *data)
{
if ( strcmp( w->label(), "Metro" ) == 0 )
@ -138,8 +158,9 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
source(x+5, y+26, 140, 100, ""),
volBox(x+5, y+422, 140, 172, ""),
tapTempo ( x + w * 2/4.f - 18, y + 426 + 41 * 0, 44,38, "Tap"),
metronomeButton( x + w * 2/4.f - 18, y + 426 + 41 * 1, 44, 38,"Metro"),
transport ( x + w * 2/4.f - 18, y + 426 + 26 * 0, 44,24, "Stop" ),
tapTempo ( x + w * 2/4.f - 18, y + 426 + 26 * 1, 44,24, "Tap" ),
metronomeButton( x + w * 2/4.f - 18, y + 426 + 26 * 2, 44,24,"Metro"),
tempoDial ( x + w * 2/4.f - 18, y + 426 + 41 * 2, 45, 36,"BPM"),
returnVol ( x + w * 2/4.f - 18, y + 426 + 41 * 3, 45, 36,"Return"),
@ -166,7 +187,10 @@ GMasterTrack::GMasterTrack(int x, int y, int w, int h, const char* l ) :
inputVolume.callback( gmastertrack_inputVolume_callback, 0 );
transport.callback( gmastertrack_transport_callback, &ID );
tapTempo.callback( gmastertrack_button_callback, &ID );
metronomeButton.callback( gmastertrack_button_callback, 0 );
tempoDial.callback( gmastertrack_tempoDial_callback, 0 );

View file

@ -88,6 +88,7 @@ class GMasterTrack : public Fl_Group
Avtk::Box source;
Avtk::Box volBox;
Avtk::Button transport;
Avtk::Button tapTempo;
Avtk::LightButton metronomeButton;
Avtk::Dial tempoDial;

View file

@ -345,6 +345,17 @@ int Jack::process (jack_nframes_t nframes)
buffers.audio[Buffers::JACK_SIDECHAIN_KEY] = (float*)jack_port_get_buffer(sidechainKeyOutput,nframes);
buffers.audio[Buffers::JACK_SIDECHAIN_SIGNAL]=(float*)jack_port_get_buffer(sidechainSignalOutput,nframes);
// clear the buffers
memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::HEADPHONES_OUT] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes );
//buffers.midi [Buffers::MASTER_MIDI_INPUT] = (void*) jack_port_get_buffer( masterMidiInput, nframes );
/// init buffers for each MidiIO
@ -394,18 +405,6 @@ void Jack::processFrames(int nframes)
return;
}
// clear the buffers
memset( buffers.audio[Buffers::JACK_MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::JACK_MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_L] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::MASTER_OUT_R] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::HEADPHONES_OUT] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SEND] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_KEY] , 0, sizeof(float) * nframes );
memset( buffers.audio[Buffers::SIDECHAIN_SIGNAL] , 0, sizeof(float) * nframes );
/// process each MidiIO registered MIDI port
for(unsigned int i = 0; i < midiIO.size(); i++ )
{

View file

@ -87,7 +87,7 @@ int main(int argc, char** argv)
rbToDsp = jack_ringbuffer_create( 5000 * sizeof(EventBase));
rbToGui = jack_ringbuffer_create( 5000 * sizeof(EventBase));
#ifdef BUILD_TESTS
LUPPP_NOTE("Built with BUILD_TESTS enabled");
if ( runTests )
@ -115,8 +115,8 @@ int main(int argc, char** argv)
// running tests == quitting after testing finishes
return testResult;
}
#endif
#endif
// Create a GUI, check for NSM integration
gui = new Gui( argv[0] );
@ -134,6 +134,7 @@ int main(int argc, char** argv)
gui->show();
return 0;
}

View file

@ -33,7 +33,8 @@ extern Jack* jack;
using namespace std;
TimeManager::TimeManager():
observers()
observers(),
transportState( TRANSPORT_ROLLING )
{
samplerate = jack->getSamplerate();
// 120 BPM default
@ -144,12 +145,22 @@ int TimeManager::getNframesToBeat()
return -1; //beatFrameCountdown;
}
void TimeManager::setTransportState( TRANSPORT_STATE s )
{
transportState = s;
}
void TimeManager::process(Buffers* buffers)
{
// time signature?
//buffers->transportPosition->beats_per_bar = 4;
//buffers->transportPosition->beat_type = 4;
if ( transportState == TRANSPORT_STOPPED )
{
return;
}
int nframes = buffers->nframes;
totalFrameCounter += nframes;
@ -221,7 +232,7 @@ void TimeManager::process(Buffers* buffers)
buffers->transportPosition->beat = (beatCounter % 4) + 1; // beats 1-4
float part = float( fpb-beatFrameCountdown) / fpb;
buffers->transportPosition->tick = part > 1.0f? 0.9999 : part*1920;
buffers->transportPosition->tick = part > 1.0f? 0.9999*1920 : part*1920;
buffers->transportPosition->frame = totalFrameCounter;

View file

@ -23,6 +23,7 @@
#include <cstdio>
#include "buffers.hxx"
#include "transport.hxx"
#include "eventhandler.hxx"
#include "observer/time.hxx"
@ -53,10 +54,16 @@ class TimeManager
/// returns the number of samples till beat if a beat exists in this process
/// Otherwise returns nframes
int getNframesToBeat();
/// TRANSPORT_STATE is defined in transport.hxx
void setTransportState( TRANSPORT_STATE s );
private:
int samplerate;
/// the "state" of the transport: rolling or stopped
TRANSPORT_STATE transportState;
/// number of frames per beat
float fpb;