Yes, you would need to find the corresponding note-off for each note-on in the MIDI_EVENT_NOTE events to get the note lengths. For example, something like this:
DWORD eventc = BASS_MIDI_StreamGetEvents(handle, -1, MIDI_EVENT_NOTE, NULL); // get number of note events
BASS_MIDI_EVENT *events = new BASS_MIDI_EVENT[eventc]; // allocate event array
BASS_MIDI_StreamGetEvents(handle, -1, MIDI_EVENT_NOTE, events); // get the events
for (int a = 0; a < eventc; a++) {
int vel = HIBYTE(events[a].param); // the velocity
if (vel) { // a note-on
int key = LOBYTE(events[a].param); // the key
int chan = events[a].chan; // the channel
int len = -1;
// look for the note-off
for (int b = a + 1; b < eventc; b++)
if (events[b].param == key && events[b].chan == chan) { // found it
len = events[b].tick - events[a].tick; // the length in ticks
break;
}
printf("pos:%d chan:%d key:%d vel:%d len:%d\n", events[a].tick, chan, key, vel, len);
}
}
delete[] events;
If you have BASS_MIDI_NOTEOFF1 enabled then you can account for that by invalidating the used note-offs so that they aren't used again:
if (events[b].param == key && events[b].chan == chan) { // found it
len = events[b].tick - events[a].tick; // the length in ticks
events[b].chan = -1; // invalidate this note-off
break;
}