| @@ -39,21 +39,6 @@ extern "C" { | |||
| typedef void* HostHandle; | |||
| 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 { | |||
| PLUGIN_CATEGORY_NONE = 0, //!< Null plugin category. | |||
| 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). | |||
| } 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 { | |||
| const char* label; | |||
| float value; | |||
| @@ -85,7 +89,7 @@ typedef struct _ParameterRanges { | |||
| #define PARAMETER_RANGES_DEFAULT_STEP_LARGE 0.1f | |||
| typedef struct _Parameter { | |||
| uint32_t hints; | |||
| ParameterHints hints; | |||
| const char* name; | |||
| const char* unit; | |||
| ParameterRanges ranges; | |||
| @@ -145,7 +149,7 @@ typedef struct _HostDescriptor { | |||
| typedef struct _PluginDescriptor { | |||
| const PluginCategory category; | |||
| const uint32_t hints; | |||
| const PluginHints hints; | |||
| const uint32_t audioIns; | |||
| const uint32_t audioOuts; | |||
| const uint32_t midiIns; | |||
| @@ -17,8 +17,6 @@ | |||
| #include "carla_native.h" | |||
| #include <string.h> // for memcpy | |||
| static PluginHandle bypass_instantiate(const PluginDescriptor* _this_, HostDescriptor* host) | |||
| { | |||
| // 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++) | |||
| *in++ = *out++; | |||
| //memcpy(out, in, sizeof(float)*frames); | |||
| return; | |||
| // unused | |||
| @@ -51,19 +47,20 @@ static void bypass_process(PluginHandle handle, float** inBuffer, float** outBuf | |||
| static const PluginDescriptor bypassDesc = { | |||
| .category = PLUGIN_CATEGORY_NONE, | |||
| .hints = /*PLUGIN_IS_RTSAFE*/0, | |||
| .hints = PLUGIN_IS_RTSAFE, | |||
| .audioIns = 1, | |||
| .audioOuts = 1, | |||
| .midiIns = 0, | |||
| .midiOuts = 0, | |||
| .parameterIns = 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, | |||
| .cleanup = NULL, | |||
| .get_parameter_count = NULL, | |||
| .get_parameter_info = NULL, | |||
| @@ -86,7 +83,6 @@ static const PluginDescriptor bypassDesc = { | |||
| .activate = NULL, | |||
| .deactivate = NULL, | |||
| .cleanup = NULL, | |||
| .process = bypass_process | |||
| }; | |||
| @@ -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); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -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); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * 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, | |||
| * 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. | |||
| * | |||
| * 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/Util.h" | |||
| //Dummy variables and functions for linking purposes | |||
| #include <ctime> | |||
| // Dummy variables and functions for linking purposes | |||
| class WavFile; | |||
| namespace Nio { | |||
| bool start(void){return 1;} | |||
| @@ -46,10 +48,9 @@ public: | |||
| }; | |||
| ZynAddSubFxPlugin(const HostDescriptor* const host) | |||
| : PluginDescriptorClass(host) | |||
| : PluginDescriptorClass(host), | |||
| m_master(new Master) | |||
| { | |||
| m_master = new Master; | |||
| // refresh banks | |||
| m_master->bank.rescanforbanks(); | |||
| @@ -67,7 +68,7 @@ public: | |||
| if (insName.empty() || insName[0] == '\0' || insName[0] == ' ') | |||
| continue; | |||
| ProgramInfo pInfo = { i, instrument, CarlaString(insName.c_str()) }; | |||
| ProgramInfo pInfo(i, instrument, insName.c_str()); | |||
| m_programs.push_back(pInfo); | |||
| } | |||
| } | |||
| @@ -127,6 +128,8 @@ protected: | |||
| float getParameterValue(const uint32_t index) | |||
| { | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| switch (index) | |||
| { | |||
| #if 0 | |||
| @@ -168,9 +171,15 @@ protected: | |||
| void setParameterValue(const uint32_t index, const float value) | |||
| { | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| switch (index) | |||
| { | |||
| } | |||
| return; | |||
| // unused, TODO | |||
| Q_UNUSED(value); | |||
| } | |||
| @@ -181,7 +190,7 @@ protected: | |||
| if (program >= BANK_SIZE) | |||
| return; | |||
| const std::string bankdir = m_master->bank.banks[bank].dir; | |||
| const std::string bankdir(m_master->bank.banks[bank].dir); | |||
| 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) | |||
| { | |||
| 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 eventIndex = 0; | |||
| uint32_t nextEventFrame = 0; | |||
| uint32_t toFrame = 0; | |||
| pthread_mutex_lock(&m_master->mutex); | |||
| do { | |||
| // Find the time of the next event, if any | |||
| @@ -237,26 +252,26 @@ protected: | |||
| // Now process any event(s) at the current timing point | |||
| 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)) | |||
| { | |||
| uint8_t note = midiEvents[eventIndex].data[1]; | |||
| const uint8_t note = midiEvents[eventIndex].data[1]; | |||
| m_master->noteOff(channel, note); | |||
| } | |||
| 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); | |||
| } | |||
| 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); | |||
| } | |||
| @@ -277,10 +292,18 @@ private: | |||
| uint32_t bank; | |||
| uint32_t prog; | |||
| 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; | |||
| Master* m_master; | |||
| Master* const m_master; | |||
| public: | |||
| static int s_instanceCount; | |||
| @@ -299,8 +322,8 @@ public: | |||
| config.cfg.SampleRate = synth->samplerate; | |||
| 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++) | |||
| denormalkillbuf[i] = (RND - 0.5f) * 1e-16; | |||
| } | |||
| @@ -321,6 +344,8 @@ public: | |||
| synth = nullptr; | |||
| } | |||
| } | |||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ZynAddSubFxPlugin) | |||
| }; | |||
| int ZynAddSubFxPlugin::s_instanceCount = 0; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * 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 | |||
| * 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_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 | |||
| #define MIDI_CONTROL_BANK_SELECT 0x00 // 0-127, MSB | |||
| #define MIDI_CONTROL_MODULATION_WHEEL 0x01 // 0-127, MSB | |||