MIPI - Physical Interface for MIDI Files
Loading...
Searching...
No Matches
MidiProcessor Class Reference

Standalone Class for processing midi files and saving/loading mipi files. Contains various getters to store and provide data about midi/mipi files. More...

#include <midi_processor.h>

Collaboration diagram for MidiProcessor:
Collaboration graph

Public Member Functions

 MidiProcessor ()
 Constructor that allocates internals.
 
 ~MidiProcessor ()
 Destructor.
 
int processMidiFile (std::string midi_file_path, std::string json_file_name)
 processes a midi file by saving all instruments (and their channels) to a set of vectors
 
std::vector< int > get_channels ()
 gets all channels
 
std::vector< int > get_instruments ()
 gets all instruments
 
std::vector< std::string > get_instrument_names ()
 gets all instrument names and their channels
 
std::vector< std::vector< int > > get_channel_notes ()
 gets all notes
 
std::vector< std::vector< double > > get_channel_note_timings ()
 gets all note timings
 
std::vector< std::vector< double > > get_channel_note_durations ()
 gets all note durations
 
double get_song_duration ()
 gets the song duration
 
std::vector< std::vector< int > > get_assigned_keys ()
 gets all assigned keys
 
std::vector< std::vector< int > > get_keyboard_values ()
 get keyboard values
 
std::vector< std::vector< int > > get_keyboard_indexs ()
 get keyboard indexs
 
bool load_json_file (std::string json_file_path)
 load JSON file
 

Private Member Functions

bool open_file (std::string midi_file_path)
 opens a selected midi file
 
bool process_instruments ()
 processes and stores all instruments/channels
 
bool process_channel_notes (int channel)
 processes and stores all notes that correspond to a specific channel
 
bool process_channel_notes_with_timings ()
 processes and stores all notes and their timings and remove dud channels
 
bool filter_chords ()
 filters chords down to only the root note
 
bool filter_trills ()
 filters trills and staggered chords down to only the first note
 
bool filter_overlapping_notes ()
 filters overlapping notes down to only the first note
 
bool process_song_duration ()
 process song duration
 
bool assign_keys ()
 key assignment function
 
bool trim_note_durations ()
 note duration trimming function
 
bool save_midi_data (std::string file_name)
 stores all data for current midi file in a storage file
 
bool debug_print_data ()
 prints all data to the console
 

Private Attributes

MidiFile midi
 MidiFile library.
 
const char * homeDir = getenv("HOME")
 home directory
 
double min_note_duration_gap = 50
 minimum note duration
 
double min_note_gap = 0.08
 minimum note gap
 
std::vector< int > channels
 current list of channels
 
std::vector< int > instruments
 current list of instruments
 
std::vector< std::vector< int > > notes
 current list of notes
 
std::vector< std::vector< double > > note_timeStamps
 current list of note_timeStamps
 
std::vector< std::vector< double > > note_durations
 current list of note_durations
 
double fileDuration
 current song duration
 
std::vector< std::vector< int > > assigned_keys
 current list of assigned keys for each channel
 
std::vector< std::vector< int > > keyboard_values
 current list of keyboard values for each channel
 
std::vector< std::vector< int > > keyboard_indexs
 current list of keyboard indexs for each channel
 

Detailed Description

Standalone Class for processing midi files and saving/loading mipi files. Contains various getters to store and provide data about midi/mipi files.

Author
Connor McGannon

This class contains the following accesible data:

  • Channels: A vector of all channels in the midi file
  • Instruments: A vector of all instruments in the midi file
  • Notes: A vector of all notes in the midi file, where each note is a vector of the note pitch and the note timing
  • Note Timings: A vector of all note timings in the midi file, where each note timing is a vector of the note timing and the note duration
  • Note Durations: A vector of all note durations in the midi file, where each note duration is a vector of the note duration and the note timing
  • Song Duration: The duration of the song in seconds
  • Assigned Keys: A vector of all assigned keys in the midi file, where each assigned key is a vector of the assigned key and the note timing
  • Keyboard Values: A vector of all keyboard values in the midi file, where each keyboard value is a vector of the keyboard value and the note timing
  • Keyboard Indexs: A vector of all keyboard indexs in the midi file, where each keyboard index is a vector of the keyboard index and the note timing

There are 3 filters that are applied to the data before it is saved to the mipi file. These are applied in the following order:

  • Chords: Notes that are played in succession are grouped together and only the highest note is kept
  • Trills: Notes that are played in succession are grouped together and only the first note is kept
  • Overlapping Notes: Notes that are completely overlap with each other the first note played is kept

    Todo:
    Add more documentation, make getter for vector of vectors of ints that stores index positions of notes in the keyboard values vectors

Constructor & Destructor Documentation

◆ MidiProcessor()

MidiProcessor::MidiProcessor ( )

Constructor that allocates internals.

Standalone Class for processing midi files and saving/loading mipi files. Contains various getters to store and provide data about midi/mipi files.

Author
Connor McGannon

This class contains the following accesible data:

  • Channels: A vector of all channels in the midi file
  • Instruments: A vector of all instruments in the midi file
  • Notes: A vector of all notes in the midi file, where each note is a vector of the note pitch and the note timing
  • Note Timings: A vector of all note timings in the midi file, where each note timing is a vector of the note timing and the note duration
  • Note Durations: A vector of all note durations in the midi file, where each note duration is a vector of the note duration and the note timing
  • Song Duration: The duration of the song in seconds
  • Assigned Keys: A vector of all assigned keys in the midi file, where each assigned key is a vector of the assigned key and the note timing
  • Keyboard Values: A vector of all keyboard values in the midi file, where each keyboard value is a vector of the keyboard value and the note timing
  • Keyboard Indexs: A vector of all keyboard indexs in the midi file, where each keyboard index is a vector of the keyboard index and the note timing

There are 3 filters that are applied to the data before it is saved to the mipi file. These are:

  • Chords: Notes that are played in succession are grouped together and only the highest note is kept
  • Trills: Notes that are played in succession are grouped together and only the first note is kept
  • Overlapping Notes: Notes that are completely overlap with each other the first note played is kept

    Todo:
    Improve filters

Constructor that allocates internals

< current list of channels

< current list of instruments

< current list of notes

< current list of note_timeStamps

< current list of note_durations

< current song duration

< current list of assigned keys for each channel

< current list of keyboard values for each channel

< current list of keyboard indexs for each channel

◆ ~MidiProcessor()

MidiProcessor::~MidiProcessor ( )

Destructor.

Member Function Documentation

◆ assign_keys()

bool MidiProcessor::assign_keys ( )
private

key assignment function

Version
1
Date
14/04/2026
Returns
bool - returns true if the key assignment was successful and the assigned_keys vector is the same length as the "notes" vector after chord filtering.

This function is called by the process_midi_file method. On a per channel basis, it finds the average note in a channel, shifts the keyboard values to put the average as close to the middle C as possible, then assigns each note a keyboard value of a matching pitch. If a note is outside the bounds of the keyboard values it shifts it up or down octaves until it is within the bounds.

Here is the caller graph for this function:

◆ debug_print_data()

bool MidiProcessor::debug_print_data ( )
private

prints all data to the console

Returns
bool - returns true if the data was successfully printed

This function is called wherever the user wants to test the data. It prints all stored the data to the console.

Here is the caller graph for this function:

◆ filter_chords()

bool MidiProcessor::filter_chords ( )
private

filters chords down to only the root note

Version
1
Date
02/04/2026
Returns
bool - returns true if the chord filtering algorithm was successful and the "notes", "note_timeStamps", and "note_durations" vectors remain the same length

This function is called by the process_midi_file method. It removes overlapping timestamps and keeps either the highest or the lowest note on that time stamp depending on the instrument type (e.g. piano = high note, guitar = low note). The affected vectors are the "notes", "note_timeStamps", and "note_durations" vectors.

Here is the caller graph for this function:

◆ filter_overlapping_notes()

bool MidiProcessor::filter_overlapping_notes ( )
private

filters overlapping notes down to only the first note

Version
1
Date
07/05/2026
Returns
bool - returns true if the overlapping note filtering algorithm was successful and the "notes", "note_timeStamps", and "note_durations" vectors remain the same length

This function is called by the process_midi_file method. It removes notes that are played entirely within the duration of another note. The affected vectors are the "notes", "note_timeStamps", and "note_durations" vectors.

Here is the caller graph for this function:

◆ filter_trills()

bool MidiProcessor::filter_trills ( )
private

filters trills and staggered chords down to only the first note

Version
1
Date
07/05/2026
Returns
bool - returns true if the trill filtering algorithm was successful and the "notes", "note_timeStamps", and "note_durations" vectors remain the same length

This function is called by the process_midi_file method. It removes trills and staggered chords and keeps either the first note played. The affected vectors are the "notes", "note_timeStamps", and "note_durations" vectors.

Here is the caller graph for this function:

◆ get_assigned_keys()

std::vector< std::vector< int > > MidiProcessor::get_assigned_keys ( )

gets all assigned keys

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors ints. Each vector contains assigned keys for 1 channel, which correspond to a note on the keyboard values vector.

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors ints. Each vector contains assigned keys for 1 channel, which correspond to a note on the keyboard values vector.

◆ get_channel_note_durations()

std::vector< std::vector< double > > MidiProcessor::get_channel_note_durations ( )

gets all note durations

Returns
std::vector<std::vector<double>> - A vector of vectors of doubles.

This function returns a vector of vectors of doubles. Each vector contains note durations for 1 channel.

◆ get_channel_note_timings()

std::vector< std::vector< double > > MidiProcessor::get_channel_note_timings ( )

gets all note timings

Returns
std::vector<std::vector<double>> - A vector of vectors of doubles.

This function returns a vector of vectors of doubles. Each vector contains note time stamps for 1 channel.

◆ get_channel_notes()

std::vector< std::vector< int > > MidiProcessor::get_channel_notes ( )

gets all notes

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors of ints. Each vector contains notes for 1 channel as it is written in the midi file.

◆ get_channels()

std::vector< int > MidiProcessor::get_channels ( )

gets all channels

Returns
std::vector<int> - A vector of all channels in the midi file

This function returns a vector of integers. Each integer is a channel number

Here is the caller graph for this function:

◆ get_instrument_names()

std::vector< std::string > MidiProcessor::get_instrument_names ( )

gets all instrument names and their channels

Returns
std::vector<std::string> - A vector of all instrument names and their channel numbers

This function returns a vector of strings. Each string is the name of an instrument and its channel number

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_instruments()

std::vector< int > MidiProcessor::get_instruments ( )

gets all instruments

Returns
std::vector<int> - A vector of all instruments in the midi file

This function returns a vector of integers. Each integer is an instrument number

◆ get_keyboard_indexs()

std::vector< std::vector< int > > MidiProcessor::get_keyboard_indexs ( )

get keyboard indexs

gets all keyboard indexs

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors of ints. Each vector contains the indexs for the notes of the assigned keys as they appear in the keyboard values vector. The indexs of these keys match the corresponding indexs for the key position vector.

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors of ints. Each vector contains the indexs for the notes of the assigned keys as they appear in the keyboard values vector. The indexs of these keys match the corresponding indexs for the key position vector.

◆ get_keyboard_values()

std::vector< std::vector< int > > MidiProcessor::get_keyboard_values ( )

get keyboard values

gets all keyboard values

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors of ints. Each vector contains the 37 assigned keyboard values for 1 channel. The indexs of these keys match the corresponding indexs for the key position vector.

Returns
std::vector<std::vector<int>> - A vector of vectors of ints.

This function returns a vector of vectors of ints. Each vector contains the 37 assigned keyboard values for 1 channel. The indexs of these keys match the corresponding indexs for the key position vector.

◆ get_song_duration()

double MidiProcessor::get_song_duration ( )

gets the song duration

Returns
double - The duration of the song in seconds

This function returns the duration of the song in seconds.

Returns
double - The duration of the song in seconds

This function returns the duration of the song in seconds.

Here is the caller graph for this function:

◆ load_json_file()

bool MidiProcessor::load_json_file ( std::string  json_file_path)

load JSON file

Parameters
[in]std::string- the name of the mipi file that should be loaded into the class variables (e.g. "filename.mipi")
Returns
bool - returns TRUE if file was successfully loaded and false otherwise

This function clears the class variables and repopulates all the variables with the data from selected mipi file.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_file()

bool MidiProcessor::open_file ( std::string  midi_file_path)
private

opens a selected midi file

Parameters
[in]std::string- the midi file path that is to be accessed and processed
Returns
bool - returns true if the midi file was successfully opened and read

This function is called by the process_midi_file method. It opens and reads a midi file. It also runs a time analysis and a note on/off pairing method from the midifile library.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_channel_notes()

bool MidiProcessor::process_channel_notes ( int  channel)
private

processes and stores all notes that correspond to a specific channel

Returns
bool - returns true if there were no errors while extracting channel notes

This function processes the notes for 1 channel at a time as specified by the input parameter storing them into the notes vector

Deprecated:
This function has been functionally replaced by "process_channel_notes_with_timings" and is no longer used as of 26/03/2026
Returns
bool - returns true if there were no errors while extracting channel notes

This function processes the notes for 1 channel at a time as specified by the input parameter storing them into the notes vector

Deprecated:
This function has been functionally replaced by "process_channel_notes_with_timings" and is no longer used as of 26/03/2026
Here is the call graph for this function:

◆ process_channel_notes_with_timings()

bool MidiProcessor::process_channel_notes_with_timings ( )
private

processes and stores all notes and their timings and remove dud channels

Returns
bool - returns true if there were no errors while extracting channel notes

This function is called by the process_midi_file method. It processes the notes along with their timestamps and durations (in seconds) for, storing them into the notes, note_timestamps, and note_durations vectors respectively. It then removes any channels with no notes

< list of dud channels

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_instruments()

bool MidiProcessor::process_instruments ( )
private

processes and stores all instruments/channels

Returns
bool - returns true if all instruments for each channel were successfully extracted

This function is called by the process_midi_file method. It extracts the instrument ID number for each channel from the midi file and stores it in the instruments vector

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_song_duration()

bool MidiProcessor::process_song_duration ( )
private

process song duration

processes song duration

Returns
bool - returns true if the song duration was successfully extracted

This function is called by the process_midi_file method. It extracts the songs maximum duration by analysing each channels delta times and converting them into seconds. Stores the duration in the "duration" variable.

Returns
bool - returns true if the song duration was successfully extracted

This function is called by the process_midi_file method. It extracts the songs maximum duration by analysing each channels delta times and converting them into seconds. Stores the duration in the "duration" variable.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ processMidiFile()

int MidiProcessor::processMidiFile ( std::string  midi_file_path,
std::string  json_file_name 
)

processes a midi file by saving all instruments (and their channels) to a set of vectors

Parameters
[in]std::string- midi_file_path The path to the midi file to be processed
[in]std::string- json_file_name The name of the json file to be saved
Returns
int - returns 0 if there were no issues processing or saving the data.

This function opens the provided midi file, fully processes it, and saves all the data to a mipi file which can be reloaded. It is not neccesary to load a mipi file that was just processed as processing populates the variables.

Parameters
[in]std::string- midi_file_path The path to the midi file to be processed
[in]std::string- json_file_name The name of the json file to be saved
Returns
int - returns 0 if there were no issues processing or saving the data. Any other number means an error occured

This function opens the provided midi file, fully processes it, and saves all the data to a mipi file which can be reloaded. It is not neccesary to load a mipi file that was just processed as processing populates the variables.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ save_midi_data()

bool MidiProcessor::save_midi_data ( std::string  file_name)
private

stores all data for current midi file in a storage file

Parameters
[in]std::string- the name of the file the data will be saved to.
Returns
bool - returns true if the data was successfully saved

This function is called by the process_midi_file method. It creates a file of the specified name and saves all the data to it in a JSON format.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ trim_note_durations()

bool MidiProcessor::trim_note_durations ( )
private

note duration trimming function

Version
1
Date
05/05/2026
Returns
bool - returns true if the note duration trimming was successful and the "note_durations" vector is the same length as the "notes" vector.

This function is called by the process_midi_file method. It checks the durations of each note and whether they overlap with the next and if so it trims it down such that the note ends just before the next note starts.

Here is the caller graph for this function:

Member Data Documentation

◆ assigned_keys

std::vector<std::vector<int> > MidiProcessor::assigned_keys
private

current list of assigned keys for each channel

◆ channels

std::vector<int> MidiProcessor::channels
private

current list of channels

◆ fileDuration

double MidiProcessor::fileDuration
private

current song duration

◆ homeDir

const char* MidiProcessor::homeDir = getenv("HOME")
private

home directory

◆ instruments

std::vector<int> MidiProcessor::instruments
private

current list of instruments

◆ keyboard_indexs

std::vector<std::vector<int> > MidiProcessor::keyboard_indexs
private

current list of keyboard indexs for each channel

◆ keyboard_values

std::vector<std::vector<int> > MidiProcessor::keyboard_values
private

current list of keyboard values for each channel

◆ midi

MidiFile MidiProcessor::midi
private

MidiFile library.

◆ min_note_duration_gap

double MidiProcessor::min_note_duration_gap = 50
private

minimum note duration

◆ min_note_gap

double MidiProcessor::min_note_gap = 0.08
private

minimum note gap

◆ note_durations

std::vector<std::vector<double> > MidiProcessor::note_durations
private

current list of note_durations

◆ note_timeStamps

std::vector<std::vector<double> > MidiProcessor::note_timeStamps
private

current list of note_timeStamps

◆ notes

std::vector<std::vector<int> > MidiProcessor::notes
private

current list of notes


The documentation for this class was generated from the following files: