Browse Source

Add CALLBACK_PLUGIN_RENAMED opcode; minor midiseq rework

tags/1.9.4
falkTX 11 years ago
parent
commit
d5f5ac47a9
4 changed files with 275 additions and 208 deletions
  1. +33
    -28
      source/backend/CarlaBackend.hpp
  2. +199
    -152
      source/backend/native/midi-sequencer.cpp
  3. +14
    -0
      source/carla.py
  4. +29
    -28
      source/carla_shared.py

+ 33
- 28
source/backend/CarlaBackend.hpp View File

@@ -409,13 +409,18 @@ enum CallbackType {
*/ */
CALLBACK_PLUGIN_REMOVED = 2, CALLBACK_PLUGIN_REMOVED = 2,


/*!
* A plugin has been renamed.
*/
CALLBACK_PLUGIN_RENAMED = 3,

/*! /*!
* A parameter value has been changed. * A parameter value has been changed.
* *
* \param value1 Parameter index * \param value1 Parameter index
* \param value3 Value * \param value3 Value
*/ */
CALLBACK_PARAMETER_VALUE_CHANGED = 3,
CALLBACK_PARAMETER_VALUE_CHANGED = 4,


/*! /*!
* A parameter default has been changed. * A parameter default has been changed.
@@ -423,7 +428,7 @@ enum CallbackType {
* \param value1 Parameter index * \param value1 Parameter index
* \param value3 Default value * \param value3 Default value
*/ */
CALLBACK_PARAMETER_DEFAULT_CHANGED = 4,
CALLBACK_PARAMETER_DEFAULT_CHANGED = 5,


/*! /*!
* A parameter's MIDI channel has been changed. * A parameter's MIDI channel has been changed.
@@ -431,7 +436,7 @@ enum CallbackType {
* \param value1 Parameter index * \param value1 Parameter index
* \param value2 MIDI channel * \param value2 MIDI channel
*/ */
CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 5,
CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 6,


/*! /*!
* A parameter's MIDI CC has been changed. * A parameter's MIDI CC has been changed.
@@ -439,14 +444,14 @@ enum CallbackType {
* \param value1 Parameter index * \param value1 Parameter index
* \param value2 MIDI CC * \param value2 MIDI CC
*/ */
CALLBACK_PARAMETER_MIDI_CC_CHANGED = 6,
CALLBACK_PARAMETER_MIDI_CC_CHANGED = 7,


/*! /*!
* The current program has has been changed. * The current program has has been changed.
* *
* \param value1 Program index * \param value1 Program index
*/ */
CALLBACK_PROGRAM_CHANGED = 7,
CALLBACK_PROGRAM_CHANGED = 8,


/*! /*!
* The current MIDI program has been changed. * The current MIDI program has been changed.
@@ -454,7 +459,7 @@ enum CallbackType {
* \param value1 MIDI bank * \param value1 MIDI bank
* \param value2 MIDI program * \param value2 MIDI program
*/ */
CALLBACK_MIDI_PROGRAM_CHANGED = 8,
CALLBACK_MIDI_PROGRAM_CHANGED = 9,


/*! /*!
* A note has been pressed. * A note has been pressed.
@@ -463,7 +468,7 @@ enum CallbackType {
* \param value2 Note * \param value2 Note
* \param value3 Velocity * \param value3 Velocity
*/ */
CALLBACK_NOTE_ON = 9,
CALLBACK_NOTE_ON = 10,


/*! /*!
* A note has been released. * A note has been released.
@@ -471,7 +476,7 @@ enum CallbackType {
* \param value1 Channel * \param value1 Channel
* \param value2 Note * \param value2 Note
*/ */
CALLBACK_NOTE_OFF = 10,
CALLBACK_NOTE_OFF = 11,


/*! /*!
* The plugin's custom GUI state has changed. * The plugin's custom GUI state has changed.
@@ -481,32 +486,32 @@ enum CallbackType {
* 1: GUI has been shown\n * 1: GUI has been shown\n
* -1: GUI has crashed and should not be shown again * -1: GUI has crashed and should not be shown again
*/ */
CALLBACK_SHOW_GUI = 11,
CALLBACK_SHOW_GUI = 12,


/*! /*!
* The plugin needs update. * The plugin needs update.
*/ */
CALLBACK_UPDATE = 12,
CALLBACK_UPDATE = 13,


/*! /*!
* The plugin's data/information has changed. * The plugin's data/information has changed.
*/ */
CALLBACK_RELOAD_INFO = 13,
CALLBACK_RELOAD_INFO = 14,


/*! /*!
* The plugin's parameters have changed. * The plugin's parameters have changed.
*/ */
CALLBACK_RELOAD_PARAMETERS = 14,
CALLBACK_RELOAD_PARAMETERS = 15,


/*! /*!
* The plugin's programs have changed. * The plugin's programs have changed.
*/ */
CALLBACK_RELOAD_PROGRAMS = 15,
CALLBACK_RELOAD_PROGRAMS = 16,


/*! /*!
* The plugin's state has changed. * The plugin's state has changed.
*/ */
CALLBACK_RELOAD_ALL = 16,
CALLBACK_RELOAD_ALL = 17,


/*! /*!
* Canvas client added * Canvas client added
@@ -514,14 +519,14 @@ enum CallbackType {
* \param value1 Client ID * \param value1 Client ID
* \param valueStr Client Name * \param valueStr Client Name
*/ */
CALLBACK_PATCHBAY_CLIENT_ADDED = 17,
CALLBACK_PATCHBAY_CLIENT_ADDED = 18,


/*! /*!
* Canvas client removed * Canvas client removed
* *
* \param value1 Client ID * \param value1 Client ID
*/ */
CALLBACK_PATCHBAY_CLIENT_REMOVED = 18,
CALLBACK_PATCHBAY_CLIENT_REMOVED = 19,


/*! /*!
* Canvas client renamed * Canvas client renamed
@@ -529,7 +534,7 @@ enum CallbackType {
* \param value1 Client ID * \param value1 Client ID
* \param valueStr New Client name * \param valueStr New Client name
*/ */
CALLBACK_PATCHBAY_CLIENT_RENAMED = 19,
CALLBACK_PATCHBAY_CLIENT_RENAMED = 20,


/*! /*!
* Canvas port added * Canvas port added
@@ -538,14 +543,14 @@ enum CallbackType {
* \param value2 Port ID * \param value2 Port ID
* \param valueStr Port name * \param valueStr Port name
*/ */
CALLBACK_PATCHBAY_PORT_ADDED = 20,
CALLBACK_PATCHBAY_PORT_ADDED = 21,


/*! /*!
* Canvas port remvoed * Canvas port remvoed
* *
* \param value1 Port ID * \param value1 Port ID
*/ */
CALLBACK_PATCHBAY_PORT_REMOVED = 21,
CALLBACK_PATCHBAY_PORT_REMOVED = 22,


/*! /*!
* Canvas port renamed * Canvas port renamed
@@ -553,7 +558,7 @@ enum CallbackType {
* \param value1 Port ID * \param value1 Port ID
* \param valueStr New Port name * \param valueStr New Port name
*/ */
CALLBACK_PATCHBAY_PORT_RENAMED = 22,
CALLBACK_PATCHBAY_PORT_RENAMED = 23,


/*! /*!
* Canvas port connection added * Canvas port connection added
@@ -561,7 +566,7 @@ enum CallbackType {
* \param value1 Output port ID * \param value1 Output port ID
* \param value2 Input port ID * \param value2 Input port ID
*/ */
CALLBACK_PATCHBAY_CONNECTION_ADDED = 23,
CALLBACK_PATCHBAY_CONNECTION_ADDED = 24,


/*! /*!
* Canvas port connection removed * Canvas port connection removed
@@ -569,37 +574,37 @@ enum CallbackType {
* \param value1 Output port ID * \param value1 Output port ID
* \param value2 Input port ID * \param value2 Input port ID
*/ */
CALLBACK_PATCHBAY_CONNECTION_REMOVED = 24,
CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25,


/*! /*!
* Non-Session-Manager Announce message. * Non-Session-Manager Announce message.
*/ */
CALLBACK_NSM_ANNOUNCE = 25,
CALLBACK_NSM_ANNOUNCE = 26,


/*! /*!
* Non-Session-Manager Open message #1. * Non-Session-Manager Open message #1.
*/ */
CALLBACK_NSM_OPEN1 = 26,
CALLBACK_NSM_OPEN1 = 27,


/*! /*!
* Non-Session-Manager Open message #2. * Non-Session-Manager Open message #2.
*/ */
CALLBACK_NSM_OPEN2 = 27,
CALLBACK_NSM_OPEN2 = 28,


/*! /*!
* Non-Session-Manager Save message. * Non-Session-Manager Save message.
*/ */
CALLBACK_NSM_SAVE = 28,
CALLBACK_NSM_SAVE = 29,


/*! /*!
* An error occurred, show last error to user. * An error occurred, show last error to user.
*/ */
CALLBACK_ERROR = 29,
CALLBACK_ERROR = 30,


/*! /*!
* The engine has crashed or malfunctioned and will no longer work. * The engine has crashed or malfunctioned and will no longer work.
*/ */
CALLBACK_QUIT = 30
CALLBACK_QUIT = 31
}; };


/*! /*!


+ 199
- 152
source/backend/native/midi-sequencer.cpp View File

@@ -25,26 +25,33 @@
#define MAX_PREALLOCATED_EVENT_COUNT 1000 #define MAX_PREALLOCATED_EVENT_COUNT 1000


struct RawMidiEvent { struct RawMidiEvent {
unsigned char data[MAX_EVENT_DATA_SIZE];
//size_t dataSize;
uint32_t time;
//double value; // used for special events
uint8_t data[MAX_EVENT_DATA_SIZE];
size_t size;
uint32_t time;

RawMidiEvent()
: data{0},
size(0),
time(0) {}
}; };


class MidiSequencerPlugin : public PluginDescriptorClass
class MidiPattern
{ {
public: public:
MidiSequencerPlugin(const HostDescriptor* const host)
: PluginDescriptorClass(host),
fWantInEvents(false)
MidiPattern(const HostDescriptor* const host)
: kHost(host),
fStartTime(0),
fDuration(0)
{ {
CARLA_ASSERT(host != nullptr);

// TEST SONG (unsorted to test RtList API) // TEST SONG (unsorted to test RtList API)


uint32_t m = 44; uint32_t m = 44;


fOutEvents.addControl(0*m, 0, 7, 99);
fOutEvents.addControl(0*m, 0, 10, 63);
fOutEvents.addProgram(0*m, 0, 0, 0);
addControl(0*m, 0, 7, 99);
addControl(0*m, 0, 10, 63);
addProgram(0*m, 0, 0, 0);


// 6912 On ch=1 n=60 v=90 // 6912 On ch=1 n=60 v=90
// 7237 Off ch=1 n=60 v=90 // 7237 Off ch=1 n=60 v=90
@@ -52,9 +59,9 @@ public:
// 7621 Off ch=1 n=62 v=90 // 7621 Off ch=1 n=62 v=90
// 7680 On ch=1 n=64 v=90 // 7680 On ch=1 n=64 v=90
// 8005 Off ch=1 n=64 v=90 // 8005 Off ch=1 n=64 v=90
fOutEvents.addNote(6912*m, 0, 60, 90, 325*m);
fOutEvents.addNote(7680*m, 0, 64, 90, 325*m);
fOutEvents.addNote(7296*m, 0, 62, 90, 325*m);
addNote(6912*m, 0, 60, 90, 325*m);
addNote(7680*m, 0, 64, 90, 325*m);
addNote(7296*m, 0, 62, 90, 325*m);


// 1152 On ch=1 n=62 v=90 // 1152 On ch=1 n=62 v=90
// 1477 Off ch=1 n=62 v=90 // 1477 Off ch=1 n=62 v=90
@@ -62,9 +69,9 @@ public:
// 1861 Off ch=1 n=64 v=90 // 1861 Off ch=1 n=64 v=90
// 1920 On ch=1 n=64 v=90 // 1920 On ch=1 n=64 v=90
// 2245 Off ch=1 n=64 v=90 // 2245 Off ch=1 n=64 v=90
fOutEvents.addNote(1152*m, 0, 62, 90, 325*m);
fOutEvents.addNote(1920*m, 0, 64, 90, 325*m);
fOutEvents.addNote(1536*m, 0, 64, 90, 325*m);
addNote(1152*m, 0, 62, 90, 325*m);
addNote(1920*m, 0, 64, 90, 325*m);
addNote(1536*m, 0, 64, 90, 325*m);


// 3840 On ch=1 n=62 v=90 // 3840 On ch=1 n=62 v=90
// 4491 Off ch=1 n=62 v=90 // 4491 Off ch=1 n=62 v=90
@@ -72,9 +79,9 @@ public:
// 4933 Off ch=1 n=64 v=90 // 4933 Off ch=1 n=64 v=90
// 4992 On ch=1 n=67 v=90 // 4992 On ch=1 n=67 v=90
// 5317 Off ch=1 n=67 v=90 // 5317 Off ch=1 n=67 v=90
fOutEvents.addNote(3840*m, 0, 62, 90, 650*m);
fOutEvents.addNote(4992*m, 0, 67, 90, 325*m);
fOutEvents.addNote(4608*m, 0, 64, 90, 325*m);
addNote(3840*m, 0, 62, 90, 650*m);
addNote(4992*m, 0, 67, 90, 325*m);
addNote(4608*m, 0, 64, 90, 325*m);


// 0 On ch=1 n=64 v=90 // 0 On ch=1 n=64 v=90
// 325 Off ch=1 n=64 v=90 // 325 Off ch=1 n=64 v=90
@@ -82,13 +89,13 @@ public:
// 709 Off ch=1 n=62 v=90 // 709 Off ch=1 n=62 v=90
// 768 On ch=1 n=60 v=90 // 768 On ch=1 n=60 v=90
//1093 Off ch=1 n=60 v=90 //1093 Off ch=1 n=60 v=90
fOutEvents.addNote( 0*m, 0, 64, 90, 325*m);
fOutEvents.addNote(768*m, 0, 60, 90, 325*m);
fOutEvents.addNote(384*m, 0, 62, 90, 325*m);
addNote( 0*m, 0, 64, 90, 325*m);
addNote(768*m, 0, 60, 90, 325*m);
addNote(384*m, 0, 62, 90, 325*m);


// 10752 On ch=1 n=60 v=90 // 10752 On ch=1 n=60 v=90
// 12056 Off ch=1 n=60 v=90 // 12056 Off ch=1 n=60 v=90
fOutEvents.addNote(10752*m, 0, 60, 90, 650*m);
addNote(10752*m, 0, 60, 90, 650*m);


// 5376 On ch=1 n=67 v=90 // 5376 On ch=1 n=67 v=90
// 6027 Off ch=1 n=67 v=90 // 6027 Off ch=1 n=67 v=90
@@ -96,9 +103,9 @@ public:
// 6469 Off ch=1 n=64 v=90 // 6469 Off ch=1 n=64 v=90
// 6528 On ch=1 n=62 v=90 // 6528 On ch=1 n=62 v=90
// 6853 Off ch=1 n=62 v=90 // 6853 Off ch=1 n=62 v=90
fOutEvents.addNote(5376*m, 0, 67, 90, 650*m);
fOutEvents.addNote(6144*m, 0, 64, 90, 325*m);
fOutEvents.addNote(6528*m, 0, 62, 90, 325*m);
addNote(5376*m, 0, 67, 90, 650*m);
addNote(6144*m, 0, 64, 90, 325*m);
addNote(6528*m, 0, 62, 90, 325*m);


// 8064 On ch=1 n=64 v=90 // 8064 On ch=1 n=64 v=90
// 8389 Off ch=1 n=64 v=90 // 8389 Off ch=1 n=64 v=90
@@ -106,9 +113,9 @@ public:
// 9099 Off ch=1 n=64 v=90 // 9099 Off ch=1 n=64 v=90
// 9216 On ch=1 n=62 v=90 // 9216 On ch=1 n=62 v=90
// 9541 Off ch=1 n=62 v=90 // 9541 Off ch=1 n=62 v=90
fOutEvents.addNote(8064*m, 0, 64, 90, 325*m);
fOutEvents.addNote(8448*m, 0, 64, 90, 650*m);
fOutEvents.addNote(9216*m, 0, 62, 90, 325*m);
addNote(8064*m, 0, 64, 90, 325*m);
addNote(8448*m, 0, 64, 90, 650*m);
addNote(9216*m, 0, 62, 90, 325*m);


// 9600 On ch=1 n=62 v=90 // 9600 On ch=1 n=62 v=90
// 9925 Off ch=1 n=62 v=90 // 9925 Off ch=1 n=62 v=90
@@ -116,9 +123,9 @@ public:
// 10309 Off ch=1 n=64 v=90 // 10309 Off ch=1 n=64 v=90
// 10368 On ch=1 n=62 v=90 // 10368 On ch=1 n=62 v=90
// 10693 Off ch=1 n=62 v=90 // 10693 Off ch=1 n=62 v=90
fOutEvents.addNote(9600*m, 0, 62, 90, 325*m);
fOutEvents.addNote(9984*m, 0, 64, 90, 325*m);
fOutEvents.addNote(10368*m, 0, 62, 90, 325*m);
addNote(9600*m, 0, 62, 90, 325*m);
addNote(9984*m, 0, 64, 90, 325*m);
addNote(10368*m, 0, 62, 90, 325*m);


// 2304 On ch=1 n=64 v=90 // 2304 On ch=1 n=64 v=90
// 2955 Off ch=1 n=64 v=90 // 2955 Off ch=1 n=64 v=90
@@ -126,14 +133,166 @@ public:
// 3397 Off ch=1 n=62 v=90 // 3397 Off ch=1 n=62 v=90
// 3456 On ch=1 n=62 v=90 // 3456 On ch=1 n=62 v=90
// 3781 Off ch=1 n=62 v=90 // 3781 Off ch=1 n=62 v=90
fOutEvents.addNote(2304*m, 0, 64, 90, 650*m);
fOutEvents.addNote(3072*m, 0, 62, 90, 325*m);
fOutEvents.addNote(3456*m, 0, 62, 90, 325*m);
addNote(2304*m, 0, 64, 90, 650*m);
addNote(3072*m, 0, 62, 90, 325*m);
addNote(3456*m, 0, 62, 90, 325*m);

for (auto it = fData.begin(); it.valid(); it.next())
{
const RawMidiEvent* const rawMidiEvent(*it);

carla_stdout("Got event %02X @%i", rawMidiEvent->data[0], rawMidiEvent->time);
}
}

~MidiPattern()
{
fData.clear();
}

void addControl(const uint32_t time, const uint8_t channel, const uint8_t control, const uint8_t value)
{
RawMidiEvent* ctrlEvent(new RawMidiEvent());
ctrlEvent->data[0] = MIDI_STATUS_CONTROL_CHANGE | (channel & 0x0F);
ctrlEvent->data[1] = control;
ctrlEvent->data[2] = value;
ctrlEvent->size = 3;
ctrlEvent->time = time;

appendAt(ctrlEvent, time);
}

void addProgram(const uint32_t time, const uint8_t channel, const uint8_t bank, const uint8_t program)
{
RawMidiEvent* bankEvent(new RawMidiEvent());
bankEvent->data[0] = MIDI_STATUS_CONTROL_CHANGE | (channel & 0x0F);
bankEvent->data[1] = MIDI_CONTROL_BANK_SELECT;
bankEvent->data[2] = bank;
bankEvent->size = 3;
bankEvent->time = time;

RawMidiEvent* programEvent(new RawMidiEvent());
programEvent->data[0] = MIDI_STATUS_PROGRAM_CHANGE | (channel & 0x0F);
programEvent->data[1] = program;
programEvent->size = 2;
programEvent->time = time;

appendAt(bankEvent, time);
appendAt(programEvent, time);
}

void addNote(const uint32_t time, const uint8_t channel, const uint8_t pitch, const uint8_t velocity, const uint32_t duration)
{
RawMidiEvent* noteOnEvent(new RawMidiEvent());
noteOnEvent->data[0] = MIDI_STATUS_NOTE_ON | (channel & 0x0F);
noteOnEvent->data[1] = pitch;
noteOnEvent->data[2] = velocity;
noteOnEvent->size = 3;
noteOnEvent->time = time;

RawMidiEvent* noteOffEvent(new RawMidiEvent());
noteOffEvent->data[0] = MIDI_STATUS_NOTE_OFF | (channel & 0x0F);
noteOffEvent->data[1] = pitch;
noteOffEvent->data[2] = velocity;
noteOffEvent->size = 3;
noteOffEvent->time = time+duration;

appendAt(noteOnEvent, time);
appendAt(noteOffEvent, time+duration);
}

void play(uint32_t timePosFrame, uint32_t frames)
{
if (! fMutex.tryLock())
return;

MidiEvent midiEvent;

for (auto it = fData.begin(); it.valid(); it.next())
{
const RawMidiEvent* const rawMidiEvent(*it);

if (timePosFrame > rawMidiEvent->time)
continue;
if (timePosFrame + frames <= rawMidiEvent->time)
continue;

midiEvent.port = 0;
midiEvent.time = rawMidiEvent->time-timePosFrame;
midiEvent.data[0] = rawMidiEvent->data[0];
midiEvent.data[1] = rawMidiEvent->data[1];
midiEvent.data[2] = rawMidiEvent->data[2];

writeMidiEvent(&midiEvent);
}

fMutex.unlock();
}

private:
const HostDescriptor* const kHost;

uint32_t fStartTime;
uint32_t fDuration;

CarlaMutex fMutex;
NonRtList<const RawMidiEvent*> fData;

void appendAt(const RawMidiEvent* const event, const uint32_t time)
{
if (fData.isEmpty())
{
fMutex.lock();
fData.append(event);
fMutex.unlock();
return;
}

uint32_t lastTime = 0;

for (auto it = fData.begin(); it.valid(); it.next())
{
const RawMidiEvent* const oldEvent(*it);

if (lastTime > time)
{
fMutex.lock();
fData.insertAt(event, it);
fMutex.unlock();
return;
}

lastTime = oldEvent->time;
}

if (time >= lastTime)
{
fMutex.lock();
fData.append(event);
fMutex.unlock();
}
else
carla_stderr2("MidiPattern::appendAt() failed for time %i", time);
}

void writeMidiEvent(const MidiEvent* const event)
{
kHost->write_midi_event(kHost->handle, event);
}
};

class MidiSequencerPlugin : public PluginDescriptorClass
{
public:
MidiSequencerPlugin(const HostDescriptor* const host)
: PluginDescriptorClass(host),
fWantInEvents(false),
fMidiOut(host)
{
} }


~MidiSequencerPlugin() ~MidiSequencerPlugin()
{ {
fOutEvents.data.clear();
} }


protected: protected:
@@ -175,32 +334,8 @@ protected:
} }
} }


if (! timePos->playing)
return;
if (! fOutEvents.mutex.tryLock())
return;

{
MidiEvent midiEvent;

for (auto it = fOutEvents.data.begin(); it.valid(); it.next())
{
RawMidiEvent* const rawMidiEvent(*it);

if (timePos->frame > rawMidiEvent->time || timePos->frame + frames <= rawMidiEvent->time)
continue;

midiEvent.port = 0;
midiEvent.time = rawMidiEvent->time-timePos->frame;
midiEvent.data[0] = rawMidiEvent->data[0];
midiEvent.data[1] = rawMidiEvent->data[1];
midiEvent.data[2] = rawMidiEvent->data[2];

writeMidiEvent(&midiEvent);
}
}

fOutEvents.mutex.unlock();
if (timePos->playing)
fMidiOut.play(timePos->frame, frames);
} }


private: private:
@@ -240,95 +375,7 @@ private:


} fInEvents; } fInEvents;


struct OutRtEvents {
CarlaMutex mutex;
NonRtList<RawMidiEvent*> data;

void appendAt(RawMidiEvent* event, uint32_t time)
{
if (data.isEmpty())
{
mutex.lock();
data.append(event);
mutex.unlock();
return;
}

uint32_t lastTime = 0;

for (auto it = data.begin(); it.valid(); it.next())
{
RawMidiEvent* const oldEvent(*it);

if (lastTime > time)
{
mutex.lock();
data.insertAt(event, it);
mutex.unlock();
return;
}

lastTime = oldEvent->time;
}

if (time >= lastTime)
{
mutex.lock();
data.append(event);
mutex.unlock();
}
else
carla_stderr2("MidiSequencerPlugin::appendAt() failed for time %i", time);
}

void addControl(uint32_t time, uint8_t channel, uint8_t control, uint8_t value)
{
RawMidiEvent* ctrlEvent(new RawMidiEvent);
ctrlEvent->data[0] = MIDI_STATUS_CONTROL_CHANGE | (channel & 0x0F);
ctrlEvent->data[1] = control;
ctrlEvent->data[2] = value;
ctrlEvent->time = time;

appendAt(ctrlEvent, time);
}

void addProgram(uint32_t time, uint8_t channel, uint8_t bank, uint8_t program)
{
RawMidiEvent* bankEvent(new RawMidiEvent);
bankEvent->data[0] = MIDI_STATUS_CONTROL_CHANGE | (channel & 0x0F);
bankEvent->data[1] = MIDI_CONTROL_BANK_SELECT;
bankEvent->data[2] = bank;
bankEvent->time = time;

RawMidiEvent* programEvent(new RawMidiEvent);
programEvent->data[0] = MIDI_STATUS_PROGRAM_CHANGE | (channel & 0x0F);
programEvent->data[1] = program;
programEvent->data[2] = 0;
programEvent->time = time;

appendAt(bankEvent, time);
appendAt(programEvent, time);
}

void addNote(uint32_t time, uint8_t channel, uint8_t pitch, uint8_t velocity, uint32_t duration)
{
RawMidiEvent* noteOnEvent(new RawMidiEvent);
noteOnEvent->data[0] = MIDI_STATUS_NOTE_ON | (channel & 0x0F);
noteOnEvent->data[1] = pitch;
noteOnEvent->data[2] = velocity;
noteOnEvent->time = time;

RawMidiEvent* noteOffEvent(new RawMidiEvent);
noteOffEvent->data[0] = MIDI_STATUS_NOTE_OFF | (channel & 0x0F);
noteOffEvent->data[1] = pitch;
noteOffEvent->data[2] = velocity;
noteOffEvent->time = time+duration;

appendAt(noteOnEvent, time);
appendAt(noteOffEvent, time+duration);
}

} fOutEvents;
MidiPattern fMidiOut;


PluginDescriptorClassEND(MidiSequencerPlugin) PluginDescriptorClassEND(MidiSequencerPlugin)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiSequencerPlugin) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiSequencerPlugin)


+ 14
- 0
source/carla.py View File

@@ -643,6 +643,7 @@ class CarlaMainW(QMainWindow):
self.connect(self, SIGNAL("DebugCallback(int, int, int, double, QString)"), SLOT("slot_handleDebugCallback(int, int, int, double, QString)")) self.connect(self, SIGNAL("DebugCallback(int, int, int, double, QString)"), SLOT("slot_handleDebugCallback(int, int, int, double, QString)"))
self.connect(self, SIGNAL("PluginAddedCallback(int)"), SLOT("slot_handlePluginAddedCallback(int)")) self.connect(self, SIGNAL("PluginAddedCallback(int)"), SLOT("slot_handlePluginAddedCallback(int)"))
self.connect(self, SIGNAL("PluginRemovedCallback(int)"), SLOT("slot_handlePluginRemovedCallback(int)")) self.connect(self, SIGNAL("PluginRemovedCallback(int)"), SLOT("slot_handlePluginRemovedCallback(int)"))
self.connect(self, SIGNAL("PluginRenamedCallback(int, QString)"), SLOT("slot_handlePluginRenamedCallback(int, QString)"))
self.connect(self, SIGNAL("ParameterValueChangedCallback(int, int, double)"), SLOT("slot_handleParameterValueChangedCallback(int, int, double)")) self.connect(self, SIGNAL("ParameterValueChangedCallback(int, int, double)"), SLOT("slot_handleParameterValueChangedCallback(int, int, double)"))
self.connect(self, SIGNAL("ParameterDefaultChangedCallback(int, int, double)"), SLOT("slot_handleParameterDefaultChangedCallback(int, int, double)")) self.connect(self, SIGNAL("ParameterDefaultChangedCallback(int, int, double)"), SLOT("slot_handleParameterDefaultChangedCallback(int, int, double)"))
self.connect(self, SIGNAL("ParameterMidiChannelChangedCallback(int, int, int)"), SLOT("slot_handleParameterMidiChannelChangedCallback(int, int, int)")) self.connect(self, SIGNAL("ParameterMidiChannelChangedCallback(int, int, int)"), SLOT("slot_handleParameterMidiChannelChangedCallback(int, int, int)"))
@@ -1060,6 +1061,17 @@ class CarlaMainW(QMainWindow):
if self.fPluginCount == 0: if self.fPluginCount == 0:
self.ui.act_plugin_remove_all.setEnabled(False) self.ui.act_plugin_remove_all.setEnabled(False)


@pyqtSlot(int, str)
def slot_handlePluginRenamedCallback(self, pluginId, newName):
if pluginId >= self.fPluginCount:
return

pwidget = self.fPluginList[pluginId]
if pwidget is None:
return

pwidget.ui.label_name.setText(newName)

@pyqtSlot(int, int, float) @pyqtSlot(int, int, float)
def slot_handleParameterValueChangedCallback(self, pluginId, parameterId, value): def slot_handleParameterValueChangedCallback(self, pluginId, parameterId, value):
if pluginId >= self.fPluginCount: if pluginId >= self.fPluginCount:
@@ -1471,6 +1483,8 @@ def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr):
Carla.gui.emit(SIGNAL("PluginAddedCallback(int)"), pluginId) Carla.gui.emit(SIGNAL("PluginAddedCallback(int)"), pluginId)
elif action == CALLBACK_PLUGIN_REMOVED: elif action == CALLBACK_PLUGIN_REMOVED:
Carla.gui.emit(SIGNAL("PluginRemovedCallback(int)"), pluginId) Carla.gui.emit(SIGNAL("PluginRemovedCallback(int)"), pluginId)
elif action == CALLBACK_PLUGIN_RENAMED:
Carla.gui.emit(SIGNAL("PluginRenamedCallback(int, QString)"), pluginId, valueStr)
elif action == CALLBACK_PARAMETER_VALUE_CHANGED: elif action == CALLBACK_PARAMETER_VALUE_CHANGED:
Carla.gui.emit(SIGNAL("ParameterValueChangedCallback(int, int, double)"), pluginId, value1, value3) Carla.gui.emit(SIGNAL("ParameterValueChangedCallback(int, int, double)"), pluginId, value1, value3)
elif action == CALLBACK_PARAMETER_DEFAULT_CHANGED: elif action == CALLBACK_PARAMETER_DEFAULT_CHANGED:


+ 29
- 28
source/carla_shared.py View File

@@ -282,34 +282,35 @@ OPTION_PATH_BRIDGE_VST_X11 = 25
CALLBACK_DEBUG = 0 CALLBACK_DEBUG = 0
CALLBACK_PLUGIN_ADDED = 1 CALLBACK_PLUGIN_ADDED = 1
CALLBACK_PLUGIN_REMOVED = 2 CALLBACK_PLUGIN_REMOVED = 2
CALLBACK_PARAMETER_VALUE_CHANGED = 3
CALLBACK_PARAMETER_DEFAULT_CHANGED = 4
CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 5
CALLBACK_PARAMETER_MIDI_CC_CHANGED = 6
CALLBACK_PROGRAM_CHANGED = 7
CALLBACK_MIDI_PROGRAM_CHANGED = 8
CALLBACK_NOTE_ON = 9
CALLBACK_NOTE_OFF = 10
CALLBACK_SHOW_GUI = 11
CALLBACK_UPDATE = 12
CALLBACK_RELOAD_INFO = 13
CALLBACK_RELOAD_PARAMETERS = 14
CALLBACK_RELOAD_PROGRAMS = 15
CALLBACK_RELOAD_ALL = 16
CALLBACK_PATCHBAY_CLIENT_ADDED = 17
CALLBACK_PATCHBAY_CLIENT_REMOVED = 18
CALLBACK_PATCHBAY_CLIENT_RENAMED = 19
CALLBACK_PATCHBAY_PORT_ADDED = 20
CALLBACK_PATCHBAY_PORT_REMOVED = 21
CALLBACK_PATCHBAY_PORT_RENAMED = 22
CALLBACK_PATCHBAY_CONNECTION_ADDED = 23
CALLBACK_PATCHBAY_CONNECTION_REMOVED = 24
CALLBACK_NSM_ANNOUNCE = 25
CALLBACK_NSM_OPEN1 = 26
CALLBACK_NSM_OPEN2 = 27
CALLBACK_NSM_SAVE = 28
CALLBACK_ERROR = 29
CALLBACK_QUIT = 30
CALLBACK_PLUGIN_RENAMED = 3
CALLBACK_PARAMETER_VALUE_CHANGED = 4
CALLBACK_PARAMETER_DEFAULT_CHANGED = 5
CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 6
CALLBACK_PARAMETER_MIDI_CC_CHANGED = 7
CALLBACK_PROGRAM_CHANGED = 8
CALLBACK_MIDI_PROGRAM_CHANGED = 9
CALLBACK_NOTE_ON = 10
CALLBACK_NOTE_OFF = 11
CALLBACK_SHOW_GUI = 12
CALLBACK_UPDATE = 13
CALLBACK_RELOAD_INFO = 14
CALLBACK_RELOAD_PARAMETERS = 15
CALLBACK_RELOAD_PROGRAMS = 16
CALLBACK_RELOAD_ALL = 17
CALLBACK_PATCHBAY_CLIENT_ADDED = 18
CALLBACK_PATCHBAY_CLIENT_REMOVED = 19
CALLBACK_PATCHBAY_CLIENT_RENAMED = 20
CALLBACK_PATCHBAY_PORT_ADDED = 21
CALLBACK_PATCHBAY_PORT_REMOVED = 22
CALLBACK_PATCHBAY_PORT_RENAMED = 23
CALLBACK_PATCHBAY_CONNECTION_ADDED = 24
CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25
CALLBACK_NSM_ANNOUNCE = 26
CALLBACK_NSM_OPEN1 = 27
CALLBACK_NSM_OPEN2 = 28
CALLBACK_NSM_SAVE = 29
CALLBACK_ERROR = 30
CALLBACK_QUIT = 31


# Process Mode # Process Mode
PROCESS_MODE_SINGLE_CLIENT = 0 PROCESS_MODE_SINGLE_CLIENT = 0


Loading…
Cancel
Save