Skip to content

Commit

Permalink
MIDI File: allow for filtering when querying notes.
Browse files Browse the repository at this point in the history
  • Loading branch information
kosua20 committed Aug 23, 2023
1 parent cd63c5b commit 86d5609
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 12 deletions.
12 changes: 7 additions & 5 deletions src/midi/MIDIFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "MIDIFile.h"
#include "../helpers/System.h"
#include "../rendering/State.h"

MIDIFile::MIDIFile(){};

Expand Down Expand Up @@ -106,9 +107,10 @@ MIDIFile::MIDIFile(const std::string & filePath){
}

// Compute duration.
FilterOptions noFilter;
for(const auto & track : _tracks){
std::vector<MIDINote> notes;
track.getNotes(notes, NoteType::ALL);
track.getNotes(notes, NoteType::ALL, noFilter);
for(const auto & note : notes){
_duration = (std::max)(_duration, note.start + note.duration);
}
Expand Down Expand Up @@ -169,18 +171,18 @@ void MIDIFile::mergeTracks(){

}

void MIDIFile::getNotes(std::vector<MIDINote> & notes, NoteType type, size_t track) const {
void MIDIFile::getNotes(std::vector<MIDINote> & notes, NoteType type, const FilterOptions& filter, size_t track) const {
if(track >= _tracks.size()){
return;
}
_tracks[track].getNotes(notes, type);
_tracks[track].getNotes(notes, type, filter );
}

void MIDIFile::getNotesActive(ActiveNotesArray & actives, double time, size_t track) const {
void MIDIFile::getNotesActive(ActiveNotesArray & actives, double time, const FilterOptions& filter, size_t track) const {
if(track >= _tracks.size()){
return;
}
_tracks[track].getNotesActive(actives, time);
_tracks[track].getNotesActive(actives, time, filter);
}

void MIDIFile::getPedalsActive(float & damper, float &sostenuto, float &soft, float &expression, double time, size_t track) const {
Expand Down
4 changes: 2 additions & 2 deletions src/midi/MIDIFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class MIDIFile {

void print() const;

void getNotes(std::vector<MIDINote>& notes, NoteType type, size_t track) const;
void getNotes(std::vector<MIDINote>& notes, NoteType type, const FilterOptions& filter, size_t track) const;

void getNotesActive(ActiveNotesArray& actives, double time, size_t track) const;
void getNotesActive(ActiveNotesArray& actives, double time, const FilterOptions& filter, size_t track) const;

void getPedalsActive(float &damper, float &sostenuto, float &soft, float &expression, double time, size_t track) const;

Expand Down
11 changes: 8 additions & 3 deletions src/midi/MIDITrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cmath>
#include <algorithm>
#include "../rendering/SetOptions.h"
#include "../rendering/State.h"

// We will have to keep track of active notes per-channel.
struct NoteKey {
Expand Down Expand Up @@ -185,21 +186,23 @@ void MIDITrack::extractNotes(const std::vector<MIDITempo> & tempos, uint16_t uni
}
}

void MIDITrack::getNotes(std::vector<MIDINote> & notes, NoteType type) const {
void MIDITrack::getNotes(std::vector<MIDINote> & notes, NoteType type, const FilterOptions& filter ) const {
notes.clear();

notes.reserve( _notes.size() );
for(auto& note : _notes){
const bool isMin = noteIsMinor[note.note % 12];
const short shiftId = (note.note/12) * 7 + noteShift[note.note % 12];
if(type == NoteType::ALL || (type == NoteType::MINOR && isMin) || (type == NoteType::MAJOR && !isMin)){
if( !filter.accepts( note.track, note.channel ) )
continue;
notes.push_back(note);
notes.back().note = shiftId;
}
}

}

void MIDITrack::getNotesActive(ActiveNotesArray & actives, double time) const {
void MIDITrack::getNotesActive(ActiveNotesArray & actives, double time, const FilterOptions& filter ) const {
// Reset all notes.
for(int i = 0; i < int(actives.size()); ++i){
actives[i].enabled = false;
Expand All @@ -208,6 +211,8 @@ void MIDITrack::getNotesActive(ActiveNotesArray & actives, double time) const {
for(size_t i = 0; i < count; ++i){
auto& note = _notes[i];
if(note.start <= time && note.start+note.duration >= time){
if( !filter.accepts( note.track, note.channel ) )
continue;
auto & actNote = actives[note.note];
actNote.enabled = true;
actNote.duration = float(note.duration);
Expand Down
6 changes: 4 additions & 2 deletions src/midi/MIDITrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

typedef std::array<ActiveNoteInfos, 128> ActiveNotesArray;

struct FilterOptions;

class MIDITrack {
public:

Expand All @@ -16,9 +18,9 @@ class MIDITrack {

void print() const;

void getNotes(std::vector<MIDINote> & notes, NoteType type) const;
void getNotes(std::vector<MIDINote> & notes, NoteType type, const FilterOptions& filter ) const;

void getNotesActive(ActiveNotesArray & actives, double time) const;
void getNotesActive(ActiveNotesArray & actives, double time, const FilterOptions& filter ) const;

void normalizePedalVelocity();

Expand Down

0 comments on commit 86d5609

Please sign in to comment.