Browse Source

native updates

tags/1.9.4
falkTX 11 years ago
parent
commit
e5052339a4
7 changed files with 319 additions and 141 deletions
  1. +21
    -17
      source/backend/carla_native.h
  2. +6
    -10
      source/backend/native/bypass.c
  3. +130
    -0
      source/backend/native/midi-split.c
  4. +0
    -94
      source/backend/native/midi-split.cpp
  5. +113
    -0
      source/backend/native/midi-through.c
  6. +44
    -19
      source/backend/native/zynaddsubfx.cpp
  7. +5
    -1
      source/includes/carla_midi.h

+ 21
- 17
source/backend/carla_native.h View File

@@ -39,21 +39,6 @@ extern "C" {
typedef void* HostHandle; typedef void* HostHandle;
typedef void* PluginHandle; typedef void* PluginHandle;


const uint32_t PLUGIN_IS_RTSAFE = 1 << 0;
const uint32_t PLUGIN_IS_SYNTH = 1 << 1;
const uint32_t PLUGIN_HAS_GUI = 1 << 2;
const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 3;

const uint32_t PARAMETER_IS_OUTPUT = 1 << 0;
const uint32_t PARAMETER_IS_ENABLED = 1 << 1;
const uint32_t PARAMETER_IS_AUTOMABLE = 1 << 2;
const uint32_t PARAMETER_IS_BOOLEAN = 1 << 3;
const uint32_t PARAMETER_IS_INTEGER = 1 << 4;
const uint32_t PARAMETER_IS_LOGARITHMIC = 1 << 5;
const uint32_t PARAMETER_USES_SAMPLE_RATE = 1 << 6;
const uint32_t PARAMETER_USES_SCALEPOINTS = 1 << 7;
const uint32_t PARAMETER_USES_CUSTOM_TEXT = 1 << 8;

typedef enum _PluginCategory { typedef enum _PluginCategory {
PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category. PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category.
PLUGIN_CATEGORY_SYNTH = 1, //!< A synthesizer or generator. PLUGIN_CATEGORY_SYNTH = 1, //!< A synthesizer or generator.
@@ -66,6 +51,25 @@ typedef enum _PluginCategory {
PLUGIN_CATEGORY_OTHER = 8 //!< Misc plugin (used to check if the plugin has a category). PLUGIN_CATEGORY_OTHER = 8 //!< Misc plugin (used to check if the plugin has a category).
} PluginCategory; } PluginCategory;


typedef enum _PluginHints {
PLUGIN_IS_RTSAFE = 1 << 0,
PLUGIN_IS_SYNTH = 1 << 1,
PLUGIN_HAS_GUI = 1 << 2,
PLUGIN_USES_SINGLE_THREAD = 1 << 3
} PluginHints;

typedef enum _ParameterHints {
PARAMETER_IS_OUTPUT = 1 << 0,
PARAMETER_IS_ENABLED = 1 << 1,
PARAMETER_IS_AUTOMABLE = 1 << 2,
PARAMETER_IS_BOOLEAN = 1 << 3,
PARAMETER_IS_INTEGER = 1 << 4,
PARAMETER_IS_LOGARITHMIC = 1 << 5,
PARAMETER_USES_SAMPLE_RATE = 1 << 6,
PARAMETER_USES_SCALEPOINTS = 1 << 7,
PARAMETER_USES_CUSTOM_TEXT = 1 << 8
} ParameterHints;

typedef struct _ParameterScalePoint { typedef struct _ParameterScalePoint {
const char* label; const char* label;
float value; float value;
@@ -85,7 +89,7 @@ typedef struct _ParameterRanges {
#define PARAMETER_RANGES_DEFAULT_STEP_LARGE 0.1f #define PARAMETER_RANGES_DEFAULT_STEP_LARGE 0.1f


typedef struct _Parameter { typedef struct _Parameter {
uint32_t hints;
ParameterHints hints;
const char* name; const char* name;
const char* unit; const char* unit;
ParameterRanges ranges; ParameterRanges ranges;
@@ -145,7 +149,7 @@ typedef struct _HostDescriptor {


typedef struct _PluginDescriptor { typedef struct _PluginDescriptor {
const PluginCategory category; const PluginCategory category;
const uint32_t hints;
const PluginHints hints;
const uint32_t audioIns; const uint32_t audioIns;
const uint32_t audioOuts; const uint32_t audioOuts;
const uint32_t midiIns; const uint32_t midiIns;


+ 6
- 10
source/backend/native/bypass.c View File

@@ -17,8 +17,6 @@


#include "carla_native.h" #include "carla_native.h"


#include <string.h> // for memcpy

static PluginHandle bypass_instantiate(const PluginDescriptor* _this_, HostDescriptor* host) static PluginHandle bypass_instantiate(const PluginDescriptor* _this_, HostDescriptor* host)
{ {
// dummy, return non-NULL // dummy, return non-NULL
@@ -37,8 +35,6 @@ static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuf
for (uint32_t i=0; i < frames; i++) for (uint32_t i=0; i < frames; i++)
*in++ = *out++; *in++ = *out++;


//memcpy(out, in, sizeof(float)*frames);

return; return;


// unused // unused
@@ -51,19 +47,20 @@ static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuf


static const PluginDescriptor bypassDesc = { static const PluginDescriptor bypassDesc = {
.category = PLUGIN_CATEGORY_NONE, .category = PLUGIN_CATEGORY_NONE,
.hints = /*PLUGIN_IS_RTSAFE*/0,
.hints = PLUGIN_IS_RTSAFE,
.audioIns = 1, .audioIns = 1,
.audioOuts = 1, .audioOuts = 1,
.midiIns = 0, .midiIns = 0,
.midiOuts = 0, .midiOuts = 0,
.parameterIns = 0, .parameterIns = 0,
.parameterOuts = 0, .parameterOuts = 0,
.name = "ByPass",
.label = "bypass",
.maker = "falkTX",
.copyright = "GNU GPL v2+",
.name = "ByPass",
.label = "bypass",
.maker = "falkTX",
.copyright = "GNU GPL v2+",


.instantiate = bypass_instantiate, .instantiate = bypass_instantiate,
.cleanup = NULL,


.get_parameter_count = NULL, .get_parameter_count = NULL,
.get_parameter_info = NULL, .get_parameter_info = NULL,
@@ -86,7 +83,6 @@ static const PluginDescriptor bypassDesc = {


.activate = NULL, .activate = NULL,
.deactivate = NULL, .deactivate = NULL,
.cleanup = NULL,
.process = bypass_process .process = bypass_process
}; };




+ 130
- 0
source/backend/native/midi-split.c View File

@@ -0,0 +1,130 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_midi.h"
#include "carla_native.h"

#include <stdlib.h>

typedef struct _MidiSplitHandle {
HostDescriptor* host;
} MidiSplitHandle;

static PluginHandle midiSplit_instantiate(const PluginDescriptor* _this_, HostDescriptor* host)
{
MidiSplitHandle* const handle = (MidiSplitHandle*)malloc(sizeof(MidiSplitHandle));

if (handle)
{
handle->host = host;
return handle;
}

return NULL;

// unused
(void)_this_;
}

static void midiSplit_cleanup(PluginHandle handle)
{
free((MidiSplitHandle*)handle);
}

static void midiSplit_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents)
{
HostDescriptor* const host = ((MidiSplitHandle*)handle)->host;
MidiEvent tmpEvent;

for (uint32_t i=0; i < midiEventCount; i++)
{
const MidiEvent* const midiEvent = &midiEvents[i];

const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent->data);
const uint8_t channel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent->data);

if (channel >= MAX_MIDI_CHANNELS)
continue;

tmpEvent.port = channel;
tmpEvent.time = midiEvent->time;
tmpEvent.data[0] = status;
tmpEvent.data[1] = midiEvent->data[1];
tmpEvent.data[2] = midiEvent->data[2];

host->write_midi_event(host, &tmpEvent);
}

return;

// unused
(void)inBuffer;
(void)outBuffer;
(void)frames;
}

// -----------------------------------------------------------------------

static const PluginDescriptor midiSplitDesc = {
.category = PLUGIN_CATEGORY_UTILITY,
.hints = PLUGIN_IS_RTSAFE,
.audioIns = 0,
.audioOuts = 0,
.midiIns = 1,
.midiOuts = 16,
.parameterIns = 0,
.parameterOuts = 0,
.name = "MIDI Split",
.label = "midiSplit",
.maker = "falkTX",
.copyright = "GNU GPL v2+",

.instantiate = midiSplit_instantiate,
.cleanup = midiSplit_cleanup,

.get_parameter_count = NULL,
.get_parameter_info = NULL,
.get_parameter_value = NULL,
.get_parameter_text = NULL,

.get_midi_program_count = NULL,
.get_midi_program_info = NULL,

.set_parameter_value = NULL,
.set_midi_program = NULL,
.set_custom_data = NULL,

.ui_show = NULL,
.ui_idle = NULL,

.ui_set_parameter_value = NULL,
.ui_set_midi_program = NULL,
.ui_set_custom_data = NULL,

.activate = NULL,
.deactivate = NULL,
.process = midiSplit_process
};

// -----------------------------------------------------------------------

void carla_register_native_plugin_midiSplit()
{
carla_register_native_plugin(&midiSplitDesc);
}

// -----------------------------------------------------------------------

+ 0
- 94
source/backend/native/midi-split.cpp View File

@@ -1,94 +0,0 @@
/*
* Carla Native Plugins
* Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_native.hpp"

#include <cstring>

class MidiSplitPlugin : public PluginDescriptorClass
{
public:
MidiSplitPlugin(const HostDescriptor* const host)
: PluginDescriptorClass(host)
{
}

~MidiSplitPlugin()
{
}

protected:
// -------------------------------------------------------------------
// Plugin process calls

void process(float**, float**, const uint32_t, const uint32_t midiEventCount, const MidiEvent* const midiEvents)
{
for (uint32_t i=0; i < midiEventCount; i++)
{
memcpy(&m_midiEvent, &midiEvents[i], sizeof(MidiEvent));

const uint8_t status = m_midiEvent.data[0] & 0xF0;
const uint8_t channel = status & 0x0F;

CARLA_ASSERT(channel < 16);

if (channel >= 16)
continue;

m_midiEvent.port = channel;
m_midiEvent.data[0] = status;

writeMidiEvent(&m_midiEvent);
}
}

// -------------------------------------------------------------------

private:
MidiEvent m_midiEvent;

PluginDescriptorClassEND(MidiSplitPlugin)

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiSplitPlugin)
};

// -----------------------------------------------------------------------

static const PluginDescriptor midiSplitDesc = {
/* category */ PLUGIN_CATEGORY_UTILITY,
/* hints */ PLUGIN_IS_RTSAFE,
/* audioIns */ 0,
/* audioOuts */ 0,
/* midiIns */ 1,
/* midiOuts */ 16,
/* paramIns */ 0,
/* paramOuts */ 0,
/* name */ "MIDI Split",
/* label */ "midiSplit",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
PluginDescriptorFILL(MidiSplitPlugin)
};

// -----------------------------------------------------------------------

void carla_register_native_plugin_midiSplit()
{
carla_register_native_plugin(&midiSplitDesc);
}

// -----------------------------------------------------------------------

+ 113
- 0
source/backend/native/midi-through.c View File

@@ -0,0 +1,113 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the COPYING file
*/

#include "carla_midi.h"
#include "carla_native.h"

#include <stdlib.h>

typedef struct _MidiThroughHandle {
HostDescriptor* host;
} MidiThroughHandle;

static PluginHandle midiThrough_instantiate(const PluginDescriptor* _this_, HostDescriptor* host)
{
MidiThroughHandle* const handle = (MidiThroughHandle*)malloc(sizeof(MidiThroughHandle));

if (handle)
{
handle->host = host;
return handle;
}

return NULL;

// unused
(void)_this_;
}

static void midiThrough_cleanup(PluginHandle handle)
{
free((MidiThroughHandle*)handle);
}

static void midiThrough_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents)
{
HostDescriptor* const host = ((MidiThroughHandle*)handle)->host;

for (uint32_t i=0; i < midiEventCount; i++)
host->write_midi_event(host, &midiEvents[i]);

return;

// unused
(void)inBuffer;
(void)outBuffer;
(void)frames;
}

// -----------------------------------------------------------------------

static const PluginDescriptor midiThroughDesc = {
.category = PLUGIN_CATEGORY_NONE,
.hints = PLUGIN_IS_RTSAFE,
.audioIns = 0,
.audioOuts = 0,
.midiIns = 1,
.midiOuts = 1,
.parameterIns = 0,
.parameterOuts = 0,
.name = "MIDI Through",
.label = "midiThrough",
.maker = "falkTX",
.copyright = "GNU GPL v2+",

.instantiate = midiThrough_instantiate,
.cleanup = midiThrough_cleanup,

.get_parameter_count = NULL,
.get_parameter_info = NULL,
.get_parameter_value = NULL,
.get_parameter_text = NULL,

.get_midi_program_count = NULL,
.get_midi_program_info = NULL,

.set_parameter_value = NULL,
.set_midi_program = NULL,
.set_custom_data = NULL,

.ui_show = NULL,
.ui_idle = NULL,

.ui_set_parameter_value = NULL,
.ui_set_midi_program = NULL,
.ui_set_custom_data = NULL,

.activate = NULL,
.deactivate = NULL,
.process = midiThrough_process
};

// -----------------------------------------------------------------------

void carla_register_native_plugin_midiThrough()
{
carla_register_native_plugin(&midiThroughDesc);
}

// -----------------------------------------------------------------------

+ 44
- 19
source/backend/native/zynaddsubfx.cpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla Native Plugins * Carla Native Plugins
* Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -9,7 +9,7 @@
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* For a full copy of the GNU General Public License see the COPYING file * For a full copy of the GNU General Public License see the COPYING file
@@ -25,7 +25,9 @@
#include "zynaddsubfx/Misc/Master.h" #include "zynaddsubfx/Misc/Master.h"
#include "zynaddsubfx/Misc/Util.h" #include "zynaddsubfx/Misc/Util.h"


//Dummy variables and functions for linking purposes
#include <ctime>

// Dummy variables and functions for linking purposes
class WavFile; class WavFile;
namespace Nio { namespace Nio {
bool start(void){return 1;} bool start(void){return 1;}
@@ -46,10 +48,9 @@ public:
}; };


ZynAddSubFxPlugin(const HostDescriptor* const host) ZynAddSubFxPlugin(const HostDescriptor* const host)
: PluginDescriptorClass(host)
: PluginDescriptorClass(host),
m_master(new Master)
{ {
m_master = new Master;

// refresh banks // refresh banks
m_master->bank.rescanforbanks(); m_master->bank.rescanforbanks();


@@ -67,7 +68,7 @@ public:
if (insName.empty() || insName[0] == '\0' || insName[0] == ' ') if (insName.empty() || insName[0] == '\0' || insName[0] == ' ')
continue; continue;


ProgramInfo pInfo = { i, instrument, CarlaString(insName.c_str()) };
ProgramInfo pInfo(i, instrument, insName.c_str());
m_programs.push_back(pInfo); m_programs.push_back(pInfo);
} }
} }
@@ -127,6 +128,8 @@ protected:


float getParameterValue(const uint32_t index) float getParameterValue(const uint32_t index)
{ {
CARLA_ASSERT(index < getParameterCount());

switch (index) switch (index)
{ {
#if 0 #if 0
@@ -168,9 +171,15 @@ protected:


void setParameterValue(const uint32_t index, const float value) void setParameterValue(const uint32_t index, const float value)
{ {
CARLA_ASSERT(index < getParameterCount());

switch (index) switch (index)
{ {
} }

return;

// unused, TODO
Q_UNUSED(value); Q_UNUSED(value);
} }


@@ -181,7 +190,7 @@ protected:
if (program >= BANK_SIZE) if (program >= BANK_SIZE)
return; return;


const std::string bankdir = m_master->bank.banks[bank].dir;
const std::string bankdir(m_master->bank.banks[bank].dir);


if (! bankdir.empty()) if (! bankdir.empty())
{ {
@@ -204,11 +213,17 @@ protected:


void process(float**, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) void process(float**, float** const outBuffer, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents)
{ {
if (pthread_mutex_trylock(&m_master->mutex) != 0)
{
carla_zeroFloat(outBuffer[0], frames);
carla_zeroFloat(outBuffer[1], frames);
return;
}

uint32_t fromFrame = 0; uint32_t fromFrame = 0;
uint32_t eventIndex = 0; uint32_t eventIndex = 0;
uint32_t nextEventFrame = 0; uint32_t nextEventFrame = 0;
uint32_t toFrame = 0; uint32_t toFrame = 0;
pthread_mutex_lock(&m_master->mutex);


do { do {
// Find the time of the next event, if any // Find the time of the next event, if any
@@ -237,26 +252,26 @@ protected:
// Now process any event(s) at the current timing point // Now process any event(s) at the current timing point
while (eventIndex < midiEventCount && midiEvents[eventIndex].time == toFrame) while (eventIndex < midiEventCount && midiEvents[eventIndex].time == toFrame)
{ {
uint8_t status = midiEvents[eventIndex].data[0];
uint8_t channel = status & 0x0F;
const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvents[eventIndex].data);
const uint8_t channel = MIDI_GET_CHANNEL_FROM_DATA(midiEvents[eventIndex].data);


if (MIDI_IS_STATUS_NOTE_OFF(status)) if (MIDI_IS_STATUS_NOTE_OFF(status))
{ {
uint8_t note = midiEvents[eventIndex].data[1];
const uint8_t note = midiEvents[eventIndex].data[1];


m_master->noteOff(channel, note); m_master->noteOff(channel, note);
} }
else if (MIDI_IS_STATUS_NOTE_ON(status)) else if (MIDI_IS_STATUS_NOTE_ON(status))
{ {
uint8_t note = midiEvents[eventIndex].data[1];
uint8_t velo = midiEvents[eventIndex].data[2];
const uint8_t note = midiEvents[eventIndex].data[1];
const uint8_t velo = midiEvents[eventIndex].data[2];


m_master->noteOn(channel, note, velo); m_master->noteOn(channel, note, velo);
} }
else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status)) else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
{ {
uint8_t note = midiEvents[eventIndex].data[1];
uint8_t pressure = midiEvents[eventIndex].data[2];
const uint8_t note = midiEvents[eventIndex].data[1];
const uint8_t pressure = midiEvents[eventIndex].data[2];


m_master->polyphonicAftertouch(channel, note, pressure); m_master->polyphonicAftertouch(channel, note, pressure);
} }
@@ -277,10 +292,18 @@ private:
uint32_t bank; uint32_t bank;
uint32_t prog; uint32_t prog;
CarlaString name; CarlaString name;

ProgramInfo(uint32_t bank_, uint32_t prog_, const char* name_)
: bank(bank_),
prog(prog_),
name(name_) {}

ProgramInfo() = delete;
}; };

std::vector<ProgramInfo> m_programs; std::vector<ProgramInfo> m_programs;


Master* m_master;
Master* const m_master;


public: public:
static int s_instanceCount; static int s_instanceCount;
@@ -299,8 +322,8 @@ public:
config.cfg.SampleRate = synth->samplerate; config.cfg.SampleRate = synth->samplerate;
config.cfg.GzipCompression = 0; config.cfg.GzipCompression = 0;


sprng(time(NULL));
denormalkillbuf = new float [synth->buffersize];
sprng(std::time(nullptr));
denormalkillbuf = new float[synth->buffersize];
for (int i=0; i < synth->buffersize; i++) for (int i=0; i < synth->buffersize; i++)
denormalkillbuf[i] = (RND - 0.5f) * 1e-16; denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
} }
@@ -321,6 +344,8 @@ public:
synth = nullptr; synth = nullptr;
} }
} }

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ZynAddSubFxPlugin)
}; };


int ZynAddSubFxPlugin::s_instanceCount = 0; int ZynAddSubFxPlugin::s_instanceCount = 0;


+ 5
- 1
source/includes/carla_midi.h View File

@@ -1,6 +1,6 @@
/* /*
* Carla common MIDI code * Carla common MIDI code
* Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -37,6 +37,10 @@
#define MIDI_IS_STATUS_AFTERTOUCH(status) (((status) & 0xF0) == MIDI_STATUS_AFTERTOUCH) #define MIDI_IS_STATUS_AFTERTOUCH(status) (((status) & 0xF0) == MIDI_STATUS_AFTERTOUCH)
#define MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) (((status) & 0xF0) == MIDI_STATUS_PITCH_WHEEL_CONTROL) #define MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) (((status) & 0xF0) == MIDI_STATUS_PITCH_WHEEL_CONTROL)


// MIDI Utils
#define MIDI_GET_STATUS_FROM_DATA(data) ((data[0]) & 0xF0)
#define MIDI_GET_CHANNEL_FROM_DATA(data) ((data[0]) & 0x0F)

// Control Change Messages List // Control Change Messages List
#define MIDI_CONTROL_BANK_SELECT 0x00 // 0-127, MSB #define MIDI_CONTROL_BANK_SELECT 0x00 // 0-127, MSB
#define MIDI_CONTROL_MODULATION_WHEEL 0x01 // 0-127, MSB #define MIDI_CONTROL_MODULATION_WHEEL 0x01 // 0-127, MSB


Loading…
Cancel
Save