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 {
int deviceId;
std::vector<uint8_t> ccs;
void step();
void updateCc(int index, uint8_t cc);
};


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

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


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

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

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

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


+ 48
- 12
src/gamepad.cpp View File

@@ -6,9 +6,46 @@
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() {
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))
return NULL;

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


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


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

for (int i = 0; i < 16; 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() {
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) {
switch (driverId) {
case -1: return "None";
case RtMidi::UNSPECIFIED: return "Unspecified";
case RtMidi::MACOSX_CORE: return "Core MIDI";
case RtMidi::LINUX_ALSA: return "ALSA";
@@ -179,6 +180,7 @@ void MidiInputQueue::onMessage(MidiMessage message) {
return;
}

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


Loading…
Cancel
Save