Closed rualark closed 7 years ago
I don't think that RtMidi should handle this. RtMidi is a MIDI I/O library and so only concerned with the transport layer, so to speak, not with generating or parsing MIDI data.
What about creating a library that will use RtMidi for sending timestamped events in a separate thread and clean up on close sending note offs?
Today I created a prototype for this inside an MGen project: https://github.com/rualark/MGen/blob/master/MGen/MidiOut.cpp https://github.com/rualark/MGen/blob/master/MGen/MidiOut.h
P.S. One important thing to note: I use PmTimestamp and PmEvent structures from portmidi library here. I think these can easily be exctacted from portmidi so that this library does not depend on portmidi.
I do something similar (the separate thread thing) in Python with python-rtmidi, e.g. here.
Hi, I agree with @SpotlightKid that this goes beyond RtMidi, and should be implemented on another layer. However, it could be pretty trivial, something like:
#include <stdio.h>
#include <RtMidi.h>
class NoteTracker
{
public:
RtMidiOut midiOut;
char notesOn[127] = {};
void noteOff(int note) { printf("turned off %d\n", note); notesOn[note] = 0; /*midiOut.sendMessage(...);*/ }
void note(int note, int volume) { printf("turned on %d\n", note); notesOn[note] = 1; /*midiOut.sendMessage(...);*/ }
~NoteTracker() { printf("cleaning up notes..\n"); for (int i=0; i<127; i++) if (notesOn[i]) noteOff(i); }
};
int main()
{
NoteTracker t;
t.note(4, 0x7F);
t.note(10, 0x7F);
t.noteOff(4);
t.note(20, 0x7F);
}
prints,
turned on 4
turned on 10
turned off 4
turned on 20
cleaning up notes..
turned off 10
turned off 20
Does this answer the issue?
Yes, it is close. But not exactly, because it mutes only one channel.
My solution mutes all channels: https://github.com/rualark/MGen/blob/master/MGen/MidiOut.cpp https://github.com/rualark/MGen/blob/master/MGen/MidiOut.h
Yes, I was just giving a brief example of an approach, in fact the difference in these choices (all channels, one channel, etc) confirms to me that this is outside the scope of RtMidi. I'll close, thanks.
rtMidi is not sending Note OFF while closing OUT port:
void MidiOutWinMM :: closePort( void ) { if ( connected_ ) { WinMidiData data = static_cast<WinMidiData > (apiData); midiOutReset( data->outHandle ); midiOutClose( data->outHandle ); connected = false; } }
Do you think it is a good idea to add this function? What is the best way to send all notes off? A single command (status=123) or track notes that were playing and send note off for all of these notes?