Browse Source

Generate MIDI with Gamepad driver, allow negative CC values in MIDI-CC

tags/v0.6.1
Andrew Belt 6 years ago
parent
commit
83652270aa
4 changed files with 57 additions and 15 deletions
  1. +4
    -1
      include/gamepad.hpp
  2. +3
    -2
      src/Core/MIDICCToCVInterface.cpp
  3. +48
    -12
      src/gamepad.cpp
  4. +2
    -0
      src/midi.cpp

+ 4
- 1
include/gamepad.hpp View File

@@ -12,11 +12,14 @@ const int GAMEPAD_DRIVER = -10;


struct GamepadInputDevice : MidiInputDevice { struct GamepadInputDevice : MidiInputDevice {
int deviceId; int deviceId;
std::vector<uint8_t> ccs;
void step();
void updateCc(int index, uint8_t cc);
}; };




struct GamepadInputDriver : MidiInputDriver { struct GamepadInputDriver : MidiInputDriver {
GamepadInputDevice gamepadInputDevices[16];
GamepadInputDevice devices[16];


GamepadInputDriver(); GamepadInputDriver();
std::vector<int> getDeviceIds() override; std::vector<int> getDeviceIds() override;


+ 3
- 2
src/Core/MIDICCToCVInterface.cpp View File

@@ -19,7 +19,7 @@ struct MIDICCToCVInterface : Module {
}; };


MidiInputQueue midiInput; MidiInputQueue midiInput;
uint8_t cvs[16];
int8_t cvs[16];
ExponentialFilter ccFilters[16]; ExponentialFilter ccFilters[16];


int learningId = -1; int learningId = -1;
@@ -64,7 +64,8 @@ struct MIDICCToCVInterface : Module {
// Set CV // Set CV
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (learnedCcs[i] == cc) { if (learnedCcs[i] == cc) {
cvs[i] = msg.value();
// Allow CC to be negative if the 8th bit is set
cvs[i] = msg.data2;
} }
} }
} break; } break;


+ 48
- 12
src/gamepad.cpp View File

@@ -6,9 +6,46 @@
namespace rack { namespace rack {




void GamepadInputDevice::step() {
if (!glfwJoystickPresent(deviceId))
return;
// Get gamepad state
int numAxes;
const float *axes = glfwGetJoystickAxes(deviceId, &numAxes);
int numButtons;
const unsigned char *buttons = glfwGetJoystickButtons(deviceId, &numButtons);
// Update state
ccs.resize(numAxes + numButtons);
for (int i = 0; i < numAxes; i++) {
// Allow CC value to go negative, but clamp at -127 instead of -128 for symmetry
updateCc(i, clamp((int) (axes[i] * 127), -127, 127));
}
for (int i = 0; i < numButtons; i++) {
updateCc(numAxes + i, buttons[i] ? 127 : 0);
}
}

void GamepadInputDevice::updateCc(int index, uint8_t cc) {
if ((int) ccs.size() < index)
return;

if (cc != ccs[index]) {
ccs[index] = cc;

// Send MIDI message
MidiMessage msg;
// MIDI channel 1
msg.cmd = (0xb << 4) | 0;
msg.data1 = index;
msg.data2 = ccs[index];
onMessage(msg);
}
}


GamepadInputDriver::GamepadInputDriver() { GamepadInputDriver::GamepadInputDriver() {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
gamepadInputDevices[i].deviceId = i;
devices[i].deviceId = i;
} }
} }


@@ -37,31 +74,30 @@ MidiInputDevice *GamepadInputDriver::getDevice(int deviceId) {
if (!(0 <= deviceId && deviceId < 16)) if (!(0 <= deviceId && deviceId < 16))
return NULL; return NULL;


return &gamepadInputDevices[deviceId];
return &devices[deviceId];
} }




static GamepadInputDriver *gamepadInputDriver = NULL;
static GamepadInputDriver *driver = NULL;




void gamepadStep() { void gamepadStep() {
// Check if the driver has been instantiated
if (!driver)
return;

for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (glfwJoystickPresent(i)) { if (glfwJoystickPresent(i)) {
const char *name = glfwGetJoystickName(i);
int numButtons;
const unsigned char *buttons = glfwGetJoystickButtons(i, &numButtons);
int numAxes;
const float *axes = glfwGetJoystickAxes(i, &numAxes);
debug("%d %s", i, name);
driver->devices[i].step();
} }
} }
} }


MidiInputDriver *gamepadGetInputDriver() { MidiInputDriver *gamepadGetInputDriver() {
if (!gamepadInputDriver) {
gamepadInputDriver = new GamepadInputDriver();
if (!driver) {
driver = new GamepadInputDriver();
} }
return gamepadInputDriver;
return driver;
} }






+ 2
- 0
src/midi.cpp View File

@@ -50,6 +50,7 @@ std::vector<int> MidiIO::getDriverIds() {


std::string MidiIO::getDriverName(int driverId) { std::string MidiIO::getDriverName(int driverId) {
switch (driverId) { switch (driverId) {
case -1: return "None";
case RtMidi::UNSPECIFIED: return "Unspecified"; case RtMidi::UNSPECIFIED: return "Unspecified";
case RtMidi::MACOSX_CORE: return "Core MIDI"; case RtMidi::MACOSX_CORE: return "Core MIDI";
case RtMidi::LINUX_ALSA: return "ALSA"; case RtMidi::LINUX_ALSA: return "ALSA";
@@ -179,6 +180,7 @@ void MidiInputQueue::onMessage(MidiMessage message) {
return; return;
} }


// Push to queue
if ((int) queue.size() < queueSize) if ((int) queue.size() < queueSize)
queue.push(message); queue.push(message);
} }


Loading…
Cancel
Save