diff --git a/include/gamepad.hpp b/include/gamepad.hpp index cd0f71ed..de059cd7 100644 --- a/include/gamepad.hpp +++ b/include/gamepad.hpp @@ -13,8 +13,8 @@ const int GAMEPAD_DRIVER = -10; struct GamepadInputDevice : MidiInputDevice { int deviceId; std::vector ccs; + std::vector notes; void step(); - void updateCc(int index, uint8_t cc); }; diff --git a/include/util/common.hpp b/include/util/common.hpp index f09f18b5..2cb67495 100644 --- a/include/util/common.hpp +++ b/include/util/common.hpp @@ -160,19 +160,26 @@ void systemOpenBrowser(std::string url); // logger.cpp //////////////////// +enum LoggerLevel { + DEBUG_LEVEL = 0, + INFO_LEVEL, + WARN_LEVEL, + FATAL_LEVEL +}; + void loggerInit(); void loggerDestroy(); /** Do not use this function directly. Use the macros below. */ -void loggerLog(const char *level, const char *file, int line, const char *format, ...); +void loggerLog(LoggerLevel level, const char *file, int line, const char *format, ...); /** Example usage: debug("error: %d", errno); will print something like [0.123 debug myfile.cpp:45] error: 67 */ -#define debug(format, ...) loggerLog("debug", __FILE__, __LINE__, format, ##__VA_ARGS__) -#define info(format, ...) loggerLog("info", __FILE__, __LINE__, format, ##__VA_ARGS__) -#define warn(format, ...) loggerLog("warn", __FILE__, __LINE__, format, ##__VA_ARGS__) -#define fatal(format, ...) loggerLog("fatal", __FILE__, __LINE__, format, ##__VA_ARGS__) +#define debug(format, ...) loggerLog(DEBUG_LEVEL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define info(format, ...) loggerLog(INFO_LEVEL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define warn(format, ...) loggerLog(WARN_LEVEL, __FILE__, __LINE__, format, ##__VA_ARGS__) +#define fatal(format, ...) loggerLog(FATAL_LEVEL, __FILE__, __LINE__, format, ##__VA_ARGS__) //////////////////// // Thread functions diff --git a/src/Core/MIDITriggerToCVInterface.cpp b/src/Core/MIDITriggerToCVInterface.cpp index c73c066a..82e232cd 100644 --- a/src/Core/MIDITriggerToCVInterface.cpp +++ b/src/Core/MIDITriggerToCVInterface.cpp @@ -95,6 +95,7 @@ struct MIDITriggerToCVInterface : Module { pressNote(msg.note()); } else { + // Many stupid keyboards send a "note on" command with 0 velocity to mean "note release" releaseNote(msg.note()); } } break; diff --git a/src/gamepad.cpp b/src/gamepad.cpp index dfacc53e..b4e4c186 100644 --- a/src/gamepad.cpp +++ b/src/gamepad.cpp @@ -14,31 +14,38 @@ void GamepadInputDevice::step() { const float *axes = glfwGetJoystickAxes(deviceId, &numAxes); int numButtons; const unsigned char *buttons = glfwGetJoystickButtons(deviceId, &numButtons); - // Update state - ccs.resize(numAxes + numButtons); + + // Convert axes to MIDI CC + ccs.resize(numAxes); 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); + int8_t cc = clamp((int) (axes[i] * 127), -127, 127); + if (cc != ccs[i]) { + ccs[i] = cc; + + // Send MIDI message + MidiMessage msg; + // MIDI channel 1 + msg.cmd = (0xb << 4) | 0; + msg.data1 = i; + msg.data2 = ccs[i]; + onMessage(msg); + } } -} -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); + // Convert buttons to MIDI notes + notes.resize(numButtons); + for (int i = 0; i < numButtons; i++) { + bool note = !!buttons[i]; + if (note != notes[i]) { + notes[i] = note; + + MidiMessage msg; + msg.cmd = ((note ? 0x9 : 0x8) << 4); + msg.data1 = i; + msg.data2 = 127; + onMessage(msg); + } } } diff --git a/src/main.cpp b/src/main.cpp index 6cba8c13..db99a1b5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,10 @@ using namespace rack; int main(int argc, char* argv[]) { randomInit(); loggerInit(); + debug("Hello world!"); + info("Hello world!"); + warn("Hello world!"); + fatal("Hello world!"); info("Rack %s", gApplicationVersion.c_str()); diff --git a/src/util/logger.cpp b/src/util/logger.cpp index 893e3146..e109a989 100644 --- a/src/util/logger.cpp +++ b/src/util/logger.cpp @@ -24,17 +24,34 @@ void loggerDestroy() { #endif } -static void loggerLogVa(const char *level, const char *file, int line, const char *format, va_list args) { - +static const char* const loggerText[] = { + "debug", + "info", + "warn", + "fatal" +}; + +static const int loggerColor[] = { + 35, + 34, + 33, + 31 +}; + +static void loggerLogVa(LoggerLevel level, const char *file, int line, const char *format, va_list args) { auto nowTime = std::chrono::high_resolution_clock::now(); int duration = std::chrono::duration_cast(nowTime - startTime).count(); - fprintf(logFile, "[%.03f %s %s:%d] ", duration / 1000.0, level, file, line); + if (logFile == stderr) + fprintf(logFile, "\x1B[%dm", loggerColor[level]); + fprintf(logFile, "[%.03f %s %s:%d] ", duration / 1000.0, loggerText[level], file, line); + if (logFile == stderr) + fprintf(logFile, "\x1B[0m"); vfprintf(logFile, format, args); fprintf(logFile, "\n"); fflush(logFile); } -void loggerLog(const char *level, const char *file, int line, const char *format, ...) { +void loggerLog(LoggerLevel level, const char *file, int line, const char *format, ...) { va_list args; va_start(args, format); loggerLogVa(level, file, line, format, args); @@ -51,28 +68,28 @@ void loggerLog(const char *level, const char *file, int line, const char *format void debug(const char *format, ...) { va_list args; va_start(args, format); - loggerLogVa("debug", "", 0, format, args); + loggerLogVa(DEBUG_LEVEL, "", 0, format, args); va_end(args); } void info(const char *format, ...) { va_list args; va_start(args, format); - loggerLogVa("info", "", 0, format, args); + loggerLogVa(INFO_LEVEL, "", 0, format, args); va_end(args); } void warn(const char *format, ...) { va_list args; va_start(args, format); - loggerLogVa("warn", "", 0, format, args); + loggerLogVa(WARN_LEVEL, "", 0, format, args); va_end(args); } void fatal(const char *format, ...) { va_list args; va_start(args, format); - loggerLogVa("fatal", "", 0, format, args); + loggerLogVa(FATAL_LEVEL, "", 0, format, args); va_end(args); }