Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add midi beat event #313

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/controller/binding.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ class Binding
{
public:
Binding() : status(0), data(0), action(0), active(1),
track(-2),scene(-1),send(-1)
track(-2),scene(-1),send(-1),dataList(0),dataListSize(0)
{
ID = privateID++;
}

~Binding()
{
if (dataList) delete dataList;
}

int ID;

unsigned char status;
Expand All @@ -48,10 +53,15 @@ public:
int track;
int scene;
int send;
int beat;
wvengen marked this conversation as resolved.
Show resolved Hide resolved

/// maps from Gridlogic::State to MIDI output value from binding
std::map<int,int> clipStateMap;

/// arbitrary-length data (TODO use this instead of data)
unsigned char *dataList;
unsigned int dataListSize;

private:
/// static int counter to allow deleting this specific instance
static int privateID;
Expand Down
6 changes: 6 additions & 0 deletions src/controller/controller.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define LUPPP_CONTROLLER_H

#include <string>
#include <jack/jack.h>

#include "../gridlogic.hxx"

Expand Down Expand Up @@ -79,6 +80,7 @@ public:
/// Time
virtual void bpm(int bpm) {}
virtual void tapTempo(bool b) {}
virtual void setBarBeat(int ba, int be) {}

/// Special
virtual void specialScene(int t, int scene) {}
Expand All @@ -95,6 +97,10 @@ public:
/// reset controller
virtual void reset();

/// Jack MIDI (dis)connect
virtual void midiConnect( jack_port_t* a, jack_port_t *b ) {}
virtual void midiDisconnect( jack_port_t* a, jack_port_t *b ) {}

private:
static int privateID;
int ID;
Expand Down
90 changes: 84 additions & 6 deletions src/controller/genericmidi.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void GenericMIDI::recordArm(int t, bool enabled)
data[0] = b->status;
data[1] = b->data;
data[2] = enabled ? 127 : 0;
writeMidi( data );
writeMidi( data, 3 );
return;
}
}
Expand All @@ -154,7 +154,7 @@ void GenericMIDI::metronomeEnable(bool enabled)
data[0] = b->status;
data[1] = b->data;
data[2] = enabled ? 127 : 0;
writeMidi( data );
writeMidi( data, 3 );
return;
}
}
Expand All @@ -171,7 +171,7 @@ void GenericMIDI::trackSend(int t, int send, float v)
data[0] = b->status;
data[1] = b->data;
data[2] = v * 127;
writeMidi( data );
writeMidi( data, 3 );
return;
}
}
Expand All @@ -187,7 +187,7 @@ void GenericMIDI::trackSendActive(int t, int send, bool a)
data[0] = b->status;
data[1] = b->data;
data[2] = a ? 127 : 0;
writeMidi( data );
writeMidi( data, 3 );
return;
}
}
Expand All @@ -203,6 +203,18 @@ void GenericMIDI::trackJackSendActivate(int t, bool a)

}

void GenericMIDI::setBarBeat(int ba, int be)
{
for(unsigned int i = 0; i < actionToMidi.size(); i++) {
Binding* b = actionToMidi.at(i);

// 4 beats per bar hardcoded
if ( b->action == TIME_BAR_BEAT && b->beat == be % 4 ) {
writeMidi( b->dataList, b->dataListSize );
}
}
}

void GenericMIDI::midi(unsigned char* midi)
{
int status = midi[0];
Expand Down Expand Up @@ -352,7 +364,7 @@ void GenericMIDI::setSceneState(int t, int scene, GridLogic::State s)
data[2] = it->second;

//LUPPP_NOTE("GenericMIDI::sceneState() writing event %i, %i, %i", data[0],data[1],data[2] );
writeMidi( data );
writeMidi( data, 3 );
}
}
}
Expand Down Expand Up @@ -388,12 +400,28 @@ void GenericMIDI::launchScene( int scene )
data[2] = (i == scene) * 127;

//LUPPP_NOTE("this = %i GenericMIDI::launchScene()", this );
writeMidi( data );
writeMidi( data, 3 );
}
}

}

void GenericMIDI::midiConnect(jack_port_t* a, jack_port_t *b)
{
// skip unless this controller's output port is connected
if (!isMyOutput(a) && !isMyOutput(b)) {
return;
}

for(unsigned int i = 0; i < actionToMidi.size(); i++) {
Binding* b = actionToMidi.at(i);

if ( b->action == MIDI_CONNECT && b->dataListSize > 0 ) {
writeMidi( b->dataList, b->dataListSize );
}
}

}

int GenericMIDI::loadController( std::string file )
{
Expand Down Expand Up @@ -560,6 +588,56 @@ Binding* GenericMIDI::setupBinding( cJSON* binding )
return 0;
}

if ( strcmp( actionJson->valuestring, "midi:connect" ) == 0 ) {
tmp->action = Event::MIDI_CONNECT;

cJSON* dataList = cJSON_GetObjectItem( binding, "dataList" );
if ( !dataList ) {
LUPPP_WARN("Binding midi connect: doesn't have dataList field");
delete tmp;
return 0;
}

tmp->dataListSize = cJSON_GetArraySize( dataList );
tmp->dataList = new unsigned char[tmp->dataListSize];

for(int i = 0; i < tmp->dataListSize; i++ ) {
cJSON* dataListItem = cJSON_GetArrayItem( dataList, i );
tmp->dataList[i] = dataListItem->valueint;
}

return tmp;
}

if ( strcmp( actionJson->valuestring, "metronome:beat" ) == 0 ) {
tmp->action = Event::TIME_BAR_BEAT;

cJSON* beatJson = cJSON_GetObjectItem( binding, "beat" );
if ( !beatJson ) {
LUPPP_WARN("Binding metronome beat: doesn't have beat field");
delete tmp;
return 0;
}
tmp->beat = beatJson->valueint;

cJSON* dataList = cJSON_GetObjectItem( binding, "dataList" );
if ( !dataList ) {
LUPPP_WARN("Binding metronome beat: doesn't have dataList field");
delete tmp;
return 0;
}

tmp->dataListSize = cJSON_GetArraySize( dataList );
tmp->dataList = new unsigned char[tmp->dataListSize];

for(int i = 0; i < tmp->dataListSize; i++ ) {
cJSON* dataListItem = cJSON_GetArrayItem( dataList, i );
tmp->dataList[i] = dataListItem->valueint;
}

return tmp;
}

cJSON* statusJson = cJSON_GetObjectItem( binding, "status" );
cJSON* dataJson = cJSON_GetObjectItem( binding, "data" );
if ( !statusJson || !dataJson ) {
Expand Down
4 changes: 4 additions & 0 deletions src/controller/genericmidi.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public:
bool footswitchNextScene;
bool footswitchPrevScene;

virtual void setBarBeat(int ba, int be);


void reset();

Expand All @@ -86,6 +88,8 @@ public:
void setupBinding( LupppAction eventType, int midiStatus, int midiData, int track, int scene, int send, int active );
void removeBinding( int bindingID );

void midiConnect(jack_port_t* a, jack_port_t* b);

private:
STATUS stat;

Expand Down
4 changes: 2 additions & 2 deletions src/controller/nonseq.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void NonSeq::launchScene( int scene )
data[2] = scene;

//LUPPP_NOTE("NonSeq::launchScene() %i, %i, %i\n", data[0],data[1],data[2] );
writeMidi( data );
writeMidi( data, 3 );
}

std::string NonSeq::getName()
Expand All @@ -65,7 +65,7 @@ void NonSeq::setSceneState(int track, int scene, GridLogic::State s)
data[2] = track;

//LUPPP_NOTE("NonSeq::setSceneState() %i, %i, %i\n", data[0],data[1],data[2] );
writeMidi( data );
writeMidi( data, 3 );
}


Expand Down
15 changes: 15 additions & 0 deletions src/controllerupdater.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,18 @@ void ControllerUpdater::metronomeEnable(bool b)
{
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->metronomeEnable(b);
}

void ControllerUpdater::setBarBeat(int ba, int be)
{
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->setBarBeat(ba, be);
}

void ControllerUpdater::midiConnect(jack_port_t *a, jack_port_t *b)
{
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->midiConnect(a, b);
}

void ControllerUpdater::midiDisconnect(jack_port_t *a, jack_port_t *b)
{
for(unsigned int i = 0; i < c.size(); i++) c.at(i)->midiDisconnect(a, b);
}
6 changes: 6 additions & 0 deletions src/controllerupdater.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <vector>
#include <iostream>
#include <jack/jack.h>

#include "controller/controller.hxx"

Expand Down Expand Up @@ -87,6 +88,11 @@ public:

void metronomeEnable(bool b);

void setBarBeat(int ba, int be);

void midiConnect(jack_port_t* a, jack_port_t* b);
void midiDisconnect(jack_port_t* a, jack_port_t* b);

private:
std::vector<Controller*> c;
};
Expand Down
27 changes: 27 additions & 0 deletions src/event.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ enum EVENT_TYPE {
CONTROLLER_BINDING_MADE,
CONTROLLER_BINDING_REMOVE,

MIDI_CONNECT,

QUIT,

// for keeping loop index's inside the enum
Expand Down Expand Up @@ -1170,6 +1172,31 @@ public:
}
};

class EventMidiConnect : public EventBase
{
public:
int type()
{
return int(MIDI_CONNECT);
}
uint32_t size()
{
return sizeof(EventMidiConnect);
}

jack_port_id_t a;
jack_port_id_t b;
bool connect;

EventMidiConnect() {}
EventMidiConnect(jack_port_id_t a, jack_port_id_t b, int connect)
{
this->a = a;
this->b = b;
this->connect = connect;
}
};


#endif // LUPPP_EVENT_H

20 changes: 20 additions & 0 deletions src/eventhandlerdsp.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,26 @@ void handleDspEvents()
break;
}

case Event::MIDI_CONNECT: {
if ( availableRead >= sizeof(EventMidiConnect) ) {
EventMidiConnect ev;
jack_ringbuffer_read( rbToDsp, (char*)&ev, sizeof(EventMidiConnect) );

// get the jack ports, and notify controllers

jack_client_t* c = jack->getJackClientPointer();
jack_port_t* portA = jack_port_by_id( c, ev.a );
jack_port_t* portB = jack_port_by_id( c, ev.b );

if ( ev.connect > 0 ) {
jack->getControllerUpdater()->midiConnect( portA, portB );
} else {
jack->getControllerUpdater()->midiDisconnect( portA, portB );
}
}
break;
}

default: {
cout << "DSP: Unkown message!! Will clog ringbuffer" << endl;
// just do nothing
Expand Down
17 changes: 17 additions & 0 deletions src/jack.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ Jack::Jack( std::string name ) :
LUPPP_ERROR("%s","Error setting timebase callback");
}

if ( jack_set_port_connect_callback(client,
static_connect,
static_cast<void*>(this)) ) {
LUPPP_ERROR("%s","Error setting JACK connect callback");
}

//Controller* m = new AkaiAPC();

// TODO: Add GUI dialog to add controllers, and insert them into the controller map.
Expand Down Expand Up @@ -758,6 +764,12 @@ int Jack::timebase(jack_transport_state_t state,
return 0;
}

void Jack::connect(jack_port_id_t a, jack_port_id_t b, int connect)
{
EventMidiConnect e(a, b, connect);
writeToDspRingbuffer( &e );
}

int Jack::static_process(jack_nframes_t nframes, void *instance)
{
return static_cast<Jack*>(instance)->process(nframes);
Expand All @@ -771,3 +783,8 @@ int Jack::static_timebase(jack_transport_state_t state,
{
return static_cast<Jack*>(instance)->timebase(state,nframes, pos, newPos );
}

void Jack::static_connect(jack_port_id_t a, jack_port_id_t b, int connect, void *instance)
{
static_cast<Jack*>(instance)->connect(a, b, connect);
}
Loading