Hello,
I am using ofxMidi to use midi events to draw certain objects to the screen in the draw() method the same way as in this example: https://github.com/danomatika/ofxMidi/blob/master/exampleInput/src/ofApp.cpp.
The problem is, however, that when I press keys faster than the time it takes for one draw() function to execute, it only registers the last key I pressed, not all that weren’t rendered the previous frame. How would it be possible to implement this? I assume the keyPressed() bypasses this issue, but I cannot figure out looking at the source code to do it.
Any help would be appreciated.
Hello @macusual,
Can we see your ofApp::newMidiMessage(ofxMidiMessage& msg)
?
The keyPressed() in only for keyboard input, not midi input.
Best,
V
My ofApp::newMidiMessage is implemented the same way as in the example, like this:
void ofApp::newMidiMessage(ofxMidiMessage& message)
{
msg = message;
}
With having expressions like this in the ofApp::draw() method (or update() – doesn’t make a difference):
float h = ofMap(msg.value, 0, 127, 0.0, 1.0);
if (msg.control == 1) swirl.setHue(h);
Hello,
First check if your app runs at 60 fps (ofSetFrameRate(60))
Assuming your app runs @ 60 fps: when you’re sending midi messages very fast (approx < 16/20ms between each, this is fast!), your app could discard some, as it can not operate fast enough to process them. The variable msg is declared as a member variable, so it lives throughout your whole app. Since midi messages follow each other very fast, the newMidiMessage callback has already rewritten the msg variable, overwriting the previous one.
A possible and effective way to store midi messages so that your update/draw loop can iterate over them, processing each, could be:
ofApp.h
#include <queue>
std::queue<ofxMidiMessage> messages; // good container for FIFO
ofApp.cpp
//--------------------------------------------------------------
void ofApp::draw(){
// iterate over all received message and do something...
while (!messages.empty()) {
printf("%lu messages to process.\n", messages.size());
ofxMidiMessage mes = messages.front();
std::cout << "Pitch: " << mes.pitch << std::endl;
messages.pop();
}
}
//--------------------------------------------------------------
void ofApp::newMidiMessage(ofxMidiMessage& msg) {
// store in queue
messages.push(msg);
}
Best,
V
That’s an elegant solution. I’ll try it out now, thanks!