| @@ -40,50 +40,56 @@ CARLA_BACKEND_START_NAMESPACE | |||||
| void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept | void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept | ||||
| { | { | ||||
| size = 0; | |||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| case kEngineControlEventTypeNull: | case kEngineControlEventTypeNull: | ||||
| break; | break; | ||||
| case kEngineControlEventTypeParameter: | case kEngineControlEventTypeParameter: | ||||
| if (MIDI_IS_CONTROL_BANK_SELECT(param)) | |||||
| if (param >= MAX_MIDI_VALUE) | |||||
| { | |||||
| // out of bounds. do nothing | |||||
| } | |||||
| else if (MIDI_IS_CONTROL_BANK_SELECT(param)) | |||||
| { | { | ||||
| size = 3; | size = 3; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = MIDI_CONTROL_BANK_SELECT; | data[1] = MIDI_CONTROL_BANK_SELECT; | ||||
| data[2] = static_cast<uint8_t>(value); | |||||
| data[2] = uint8_t(carla_fixValue<float>(0.0f, float(MAX_MIDI_VALUE-1), value)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| size = 3; | size = 3; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = static_cast<uint8_t>(param); | data[1] = static_cast<uint8_t>(param); | ||||
| data[2] = uint8_t(value * 127.0f); | |||||
| data[2] = uint8_t(carla_fixValue<float>(0.0f, 1.0f, value) * float(MAX_MIDI_VALUE-1)); | |||||
| } | } | ||||
| break; | break; | ||||
| case kEngineControlEventTypeMidiBank: | case kEngineControlEventTypeMidiBank: | ||||
| size = 3; | size = 3; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = MIDI_CONTROL_BANK_SELECT; | data[1] = MIDI_CONTROL_BANK_SELECT; | ||||
| data[2] = static_cast<uint8_t>(param); | |||||
| data[2] = uint8_t(carla_fixValue<uint16_t>(0, MAX_MIDI_VALUE-1, param)); | |||||
| break; | break; | ||||
| case kEngineControlEventTypeMidiProgram: | case kEngineControlEventTypeMidiProgram: | ||||
| size = 2; | size = 2; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE + channel); | |||||
| data[1] = static_cast<uint8_t>(param); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = uint8_t(carla_fixValue<uint16_t>(0, MAX_MIDI_VALUE-1, param)); | |||||
| break; | break; | ||||
| case kEngineControlEventTypeAllSoundOff: | case kEngineControlEventTypeAllSoundOff: | ||||
| size = 2; | size = 2; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | ||||
| break; | break; | ||||
| case kEngineControlEventTypeAllNotesOff: | case kEngineControlEventTypeAllNotesOff: | ||||
| size = 2; | size = 2; | ||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); | |||||
| data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -18,7 +18,7 @@ BASE_FLAGS += -isystem ../modules | |||||
| ANSI_FLAGS = $(BASE_FLAGS) -DBUILD_ANSI_TEST | ANSI_FLAGS = $(BASE_FLAGS) -DBUILD_ANSI_TEST | ||||
| ANSI_FLAGS += -ansi -pedantic -pedantic-errors -Waggregate-return | ANSI_FLAGS += -ansi -pedantic -pedantic-errors -Waggregate-return | ||||
| ANSI_FLAGS += -I../backend -I../includes | ANSI_FLAGS += -I../backend -I../includes | ||||
| # ANSI_FLAGS += -L../backend -lcarla_standalone2 | |||||
| ANSI_FLAGS += -L../backend -lcarla_standalone2 | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| @@ -33,7 +33,7 @@ PEDANTIC_CXX_FLAGS += -isystem /opt/kxstudio/include | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # TARGETS = ansi-pedantic-test_c ansi-pedantic-test_c99 ansi-pedantic-test_cxx ansi-pedantic-test_cxx11 | |||||
| TARGETS = ansi-pedantic-test_c ansi-pedantic-test_c99 ansi-pedantic-test_cxx ansi-pedantic-test_cxx11 | |||||
| TARGETS += CarlaString PipeServer Print RtLinkedList RtLinkedListGnu Utils | TARGETS += CarlaString PipeServer Print RtLinkedList RtLinkedListGnu Utils | ||||
| all: $(TARGETS) | all: $(TARGETS) | ||||
| @@ -62,6 +62,10 @@ PipeServer: PipeServer.cpp ../utils/CarlaPipeUtils.hpp | |||||
| $(CXX) $< $(PEDANTIC_CXX_FLAGS) -o $@ | $(CXX) $< $(PEDANTIC_CXX_FLAGS) -o $@ | ||||
| # valgrind ./$@ | # valgrind ./$@ | ||||
| Misc: Misc.cpp | |||||
| $(CXX) $< $(PEDANTIC_CXX_FLAGS) -L../backend -lcarla_standalone2 -o $@ | |||||
| env LD_LIBRARY_PATH=../backend valgrind ./$@ | |||||
| Print: Print.cpp ../utils/CarlaUtils.hpp | Print: Print.cpp ../utils/CarlaUtils.hpp | ||||
| $(CXX) $< $(PEDANTIC_CXX_FLAGS) -o $@ | $(CXX) $< $(PEDANTIC_CXX_FLAGS) -o $@ | ||||
| valgrind ./$@ | valgrind ./$@ | ||||
| @@ -0,0 +1,144 @@ | |||||
| /* | |||||
| * Carla Tests | |||||
| * Copyright (C) 2013-2014 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 doc/GPL.txt file. | |||||
| */ | |||||
| #include "CarlaEngine.hpp" | |||||
| #include "CarlaMIDI.h" | |||||
| #include "CarlaUtils.hpp" | |||||
| CARLA_BACKEND_USE_NAMESPACE | |||||
| void testControlEventDump() | |||||
| { | |||||
| uint8_t size; | |||||
| uint8_t data[3]; | |||||
| EngineControlEvent e; | |||||
| // test null event | |||||
| e.type = kEngineControlEventTypeNull; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 0); | |||||
| // test regular param event (half value) | |||||
| e.type = kEngineControlEventTypeParameter; | |||||
| e.param = MIDI_CONTROL_MODULATION_WHEEL; | |||||
| e.value = 0.5f; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 3); | |||||
| assert(data[0] == MIDI_STATUS_CONTROL_CHANGE); | |||||
| assert(data[1] == MIDI_CONTROL_MODULATION_WHEEL); | |||||
| assert(data[2] == (MAX_MIDI_VALUE-1)/2); | |||||
| // test regular param event (out of bounds positive) | |||||
| e.value = 9.0f; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == MAX_MIDI_VALUE-1); | |||||
| // test regular param event (out of bounds negative) | |||||
| e.value = -11.0f; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == 0); | |||||
| // test bad param as bank select | |||||
| e.param = MIDI_CONTROL_BANK_SELECT; | |||||
| e.value = 100; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 3); | |||||
| assert(data[1] == MIDI_CONTROL_BANK_SELECT); | |||||
| assert(data[2] == 100); | |||||
| // test bad param as bank select (out of bounds index positive) | |||||
| e.value = 9999; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == MAX_MIDI_VALUE-1); | |||||
| // test bad param as bank select (out of bounds index negative) | |||||
| e.value = -9999; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == 0); | |||||
| // test bad param (out of bounds index) | |||||
| e.param = 999; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 0); | |||||
| // test regular midi-bank event | |||||
| e.type = kEngineControlEventTypeMidiBank; | |||||
| e.param = 11; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 3); | |||||
| assert(data[0] == MIDI_STATUS_CONTROL_CHANGE); | |||||
| assert(data[1] == MIDI_CONTROL_BANK_SELECT); | |||||
| assert(data[2] == 11); | |||||
| // test bad midi-bank event (out of bounds) | |||||
| e.param = 300; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == MAX_MIDI_VALUE-1); | |||||
| // test bad midi-bank event (out of bounds #2) | |||||
| e.param = 32867; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[2] == MAX_MIDI_VALUE-1); | |||||
| // test regular midi-program event | |||||
| e.type = kEngineControlEventTypeMidiProgram; | |||||
| e.param = 15; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 2); | |||||
| assert(data[0] == MIDI_STATUS_PROGRAM_CHANGE); | |||||
| assert(data[1] == 15); | |||||
| // test bad midi-program event (out of bounds) | |||||
| e.param = 299; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(data[1] == MAX_MIDI_VALUE-1); | |||||
| // test regular all-sound-off event | |||||
| e.type = kEngineControlEventTypeAllSoundOff; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 2); | |||||
| assert(data[0] == MIDI_STATUS_CONTROL_CHANGE); | |||||
| assert(data[1] == MIDI_CONTROL_ALL_SOUND_OFF); | |||||
| // test regular all-notes-off event | |||||
| e.type = kEngineControlEventTypeAllNotesOff; | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(size == 2); | |||||
| assert(data[0] == MIDI_STATUS_CONTROL_CHANGE); | |||||
| assert(data[1] == MIDI_CONTROL_ALL_NOTES_OFF); | |||||
| // test channel bit | |||||
| e.dumpToMidiData(0, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 0); | |||||
| e.dumpToMidiData(1, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 1); | |||||
| e.dumpToMidiData(15, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 15); | |||||
| e.dumpToMidiData(16, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 0); | |||||
| e.dumpToMidiData(17, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 1); | |||||
| e.dumpToMidiData(31, size, data); | |||||
| assert(MIDI_GET_CHANNEL_FROM_DATA(data) == 15); | |||||
| } | |||||
| int main() | |||||
| { | |||||
| testControlEventDump(); | |||||
| return 0; | |||||
| } | |||||