Music is visualized everyday – but is there any accuracy to its representation?
Can sound be accurately represented? If so, what does it look like? How is accuracy measured? While not fully satisfied with the answers found to these questions, Python’s mido package shed light on the how sound and color may be linked through defining binned heatmaps by key signature.
Decoding
The exercise began by decoding openly-sourced MIDI data.
- Note Number (Pitch): Represents pitch values from 0 to 127, with 60 as Middle C.
Midointerprets it using thenoteproperty, providing easy access to note names and octaves. - Velocity: Ranges 0 to 127, indicating key strike intensity.
Midoextracts velocity through thevelocityproperty, allowing precise control over note dynamics. - Control Change: Carries values 0 to 127, modulating parameters like volume.
Midodissects control change messages using thecontrolattribute for targeted parameter adjustment. - Program Change: Values 0 to 127 for instrument presets.
Midointerprets program change with theprogramattribute, facilitating dynamic instrument selection. - Pitch Bend: Employs two 7-bit values for pitch modulation.
Midodecodes pitch bend using thepitchattribute, capturing nuanced pitch variations. - Aftertouch (Pressure): Ranges 0 to 127, measuring key pressure.
Midoextracts aftertouch data through theaftertouchattribute, enabling sensitivity adjustments. - Channel: MIDI channels 1 to 16.
Midosegregates channels using thechannelproperty, simplifying the handling of multiple independent streams of MIDI data.
In this case, Tame Impala’s Elephant was analyzed for its extract notes, their timing, velocity, key signature, and pitch bend to visualize the distribution of notes.
Keys determined histogram coloration with bars representative of note frequency colored consistently by note across scales.

Heatmaps
The collected note data was used to create a heatmap using seaborn and matplotlib. The heatmap visualizes note occurrences over time, providing admittedly lean but accurate insights into the composition’s structure.
Normalization
To enhance the visual clarity of the heatmap, then data was normalized to range of note values present in the song. MIDI has 128 possible outputs but 88 typically represented values. Most songs, have between 15 and 60. Noizo’s Baby Baby, for example, has 47.

Looping
Due to popular curiosity, the process was optimized using a for loop to extract MIDI inputs from a folder path and output PNGs to specified folder. Additionally, to allow for the comparison of musical attributes among songs, all songs obtained from a folder path had their musical attributes exported to a CSV…for further analysis.

Specifying Color
In heatmap mass production, the question of color accuracy reappeared. Colors were initially sourced from the University of Minnesota. Their matching to note values failed in songs which I later discovered to be in B major like the Arctic Monkeys’ Dancing Shoes or Cage the Elephant’s Back Against the Wall.

Methodology
On a quest to redefine the colors I initially entrusted to note values, I kept seaborn and matplotlib close by. Trial and error with plotly softened the color outputs from the initial heavy saturations to a new mapping closer to the spectral cmap.
- Import Statements
midopandasmatplotlib (pyplot, colors)seabornosnumpy
- Variable Definitions
folder path, file titledef process_midi(midi_file, current_tempo, ticks_per_beat, current_time_in_seconds, current_key_signature, current_pitch_bend, current_minute, minute_data, midi_data, heatmap_data)
- Utility Functions
def midi_to_key_with_major(note_number)def create_colormap(hex_color)
- Main Function
def main():current_tempo, current_time_in_seconds, current_key_signature, current_pitch_bend, current_minute, midi_data, heatmap_data = process_midi( midi_file, current_tempo, ticks_per_beat, current_time_in_seconds, current_key_signature, current_pitch_bend, current_minute, minute_data, midi_data, heatmap_data )heatmap = heatmap_data.pivot_table(index='Note', columns='TimeInSeconds', aggfunc='size', fill_value=0)key_colors = {}sns.histplot(data=heatmap_data, x='Note', hue='Note', multiple="stack", palette=key_colors, edgecolor='black')output_file_path_svg = f'[path]\midis_to_csvs{midi_file_title[:-4]}_normalized.svg'

Conclusion
While unable to confirm if sound can accurately be represented, the mido package can be leveraged to develop an individual’s note palette. More work is to be done to add complexity to visualizations and elucidate patterns from pitch and channel variables.
This methodology is valuable for musicians, composers, or anyone interested in exploring the structure and visual translation of MIDI-based music compositions. It bridges the gap between raw MIDI data and meaningful visualizations, enhancing the interpretability of musical content.