Open the file in binary mode instead:
with open(midifile, 'rb') as mfile:
leader = mfile.read(4)
if leader != b 'MThd':
raise ValueError('Not a MIDI file!')
MIDI files are binary content. By anycodings_python opening the file as a text file however, anycodings_python Python applies the default system anycodings_python encoding in trying to decode the text as anycodings_python Unicode.,To open a file in binary mode in Python, anycodings_python pass a string containing "b" as the anycodings_python second argument to open().,You'd have to study the MIDI standard anycodings_python file format if you wanted to learn more anycodings_python from the file. Also see What is the anycodings_python structure of a MIDI file?,It's a binary file, it's not text using anycodings_python a text encoding like you seem to expect.
Here's what brought this question up:
with open(path + "/OneChance1.mid") as f:
for line in f.readline():
print(line)
Open the file in binary mode instead:
with open(midifile, 'rb') as mfile:
leader = mfile.read(4)
if leader != b 'MThd':
raise ValueError('Not a MIDI file!')
The following figure shows various symbolic music representations of the first twelve notes of Beethoven's Fifth including a sheet music representation, a MIDI representation (in a simplified, tabular form), and a piano-roll representation.,PrettyMIDI also offers functionality to synthesize the MIDI data with sinusoidal sounds, without paying attention to the actual instruments playing the notes., Following Section 1.2.2 of [Müller, FMP, Springer 2015], we have in this a notebook a look at the MIDI standard, which is often used to encode symbolic music. ,The next example reads and visualizes a MIDI file for the beginning of the four-voice Fugue BWV 846 in C major by Johann Sebastian Bach. In the MIDI file, the four voices (soprano, alto, tenor, basso) are encoded by four different MIDI channels.
import os
import sys
from matplotlib
import pyplot as plt
from matplotlib
import patches
from matplotlib
import colors
import pretty_midi
import pandas as pd
import IPython.display as ipd
sys.path.append('..')
import libfmp.c1
fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F13a_Beethoven_FateMotive_Sibelius-Tracks.mid')
midi_data = pretty_midi.PrettyMIDI(fn)
midi_list = []
for instrument in midi_data.instruments:
for note in instrument.notes:
start = note.start
end = note.end
pitch = note.pitch
velocity = note.velocity
midi_list.append([start, end, pitch, velocity, instrument.name])
midi_list = sorted(midi_list, key = lambda x: (x[0], x[2]))
df = pd.DataFrame(midi_list, columns = ['Start', 'End', 'Pitch', 'Velocity', 'Instrument'])
html = df.to_html(index = False)
ipd.HTML(html)
Fs = 22050 audio_data = midi_data.synthesize(fs = Fs) ipd.Audio(audio_data, rate = Fs)
def midi_to_list(midi): "" "Convert a midi file to a list of note events Notebook: C1 / C1S2_MIDI.ipynb Args: midi(str or pretty_midi.pretty_midi.PrettyMIDI): Either a path to a midi file or PrettyMIDI object Returns: score(list): A list of note events where each note is specified as `` [start, duration, pitch, velocity, label] `` "" " if isinstance(midi, str): midi_data = pretty_midi.pretty_midi.PrettyMIDI(midi) elif isinstance(midi, pretty_midi.pretty_midi.PrettyMIDI): midi_data = midi else: raise RuntimeError('midi must be a path to a midi file or pretty_midi.PrettyMIDI') score = [] for instrument in midi_data.instruments: for note in instrument.notes: start = note.start duration = note.end - start pitch = note.pitch velocity = note.velocity / 128. score.append([start, duration, pitch, velocity, instrument.name]) return score score = midi_to_list(midi_data) libfmp.c1.visualize_piano_roll(score, figsize = (8, 3), velocity_alpha = True);
fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.mid')
midi_data = pretty_midi.PrettyMIDI(fn)
score = midi_to_list(midi_data)
libfmp.c1.visualize_piano_roll(score, figsize = (8, 3), velocity_alpha = True);
fn_in = os.path.join('..', 'data', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.mid')
fn_out = os.path.join('..', 'output', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.csv')
midi_data = pretty_midi.PrettyMIDI(fn_in)
score = midi_to_list(midi_data)
df = pd.DataFrame(score, columns = ['Start', 'Duration', 'Pitch', 'Velocity', 'Instrument'])
df.to_csv(fn_out, sep = ';', quoting = 2, float_format = '%.3f', index = False)
print('Score as list:')
print(score[0: 3])
print('\n')
print('Score as pandas DataFrame')
print(df.loc[0: 2,: ])
print('\n')
print('Score as CSV')
print(fn_out)
with open(fn_out, 'r', encoding = 'utf-8') as file:
csv_str = file.readlines()
print(csv_str[0: 4])
Score as list: [
[6.724133, 0.5172410000000003, 67, 0.59375, 'Soprano'],
[7.241374, 0.5172410000000003, 69, 0.6015625, 'Soprano'],
[7.758615000000001, 0.5172410000000003, 71, 0.609375, 'Soprano']
]
Score as pandas DataFrame
Start Duration Pitch Velocity Instrument
0 6.724133 0.517241 67 0.593750 Soprano
1 7.241374 0.517241 69 0.601562 Soprano
2 7.758615 0.517241 71 0.609375 Soprano
Score as CSV.. / output / C1 / FMP_C1_F12_Bach_BWV846_Sibelius - Tracks.csv['"Start";"Duration";"Pitch";"Velocity";"Instrument"\n', '"6.724";"0.517";67;"0.594";"Soprano"\n', '"7.241";"0.517";69;"0.602";"Soprano"\n', '"7.759";"0.517";71;"0.609";"Soprano"\n']
The MIDI Specification ,MIDI File Parsing (nice and simple)
MIDI section < -- -- -- -- -- -- - MIDI Header-- -- -- -- -- -- -- - > < -- -- - Track Header-- -- > < -Track data - > {
Track out >
Byte number 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21[22 to x][x + 1 to x + 4]
Byte data 4 D 54 68 64 00 00 00 06 00 01 00 01 00 80 4 D 54 72 6 B 00 00 00 0 A blah blah.....00 FF 2 F 00
MIDI section A-- -- -- -- - > B-- -- -- -- - > C-- - > D-- - > E-- - > F-- -- -- -- - > G-- -- -- -- - > H-- -- -- -- -- -- > I-- -- -- -- - >
7 F = G9 7 E = Gb9 7 D = F9 7 C = E9 7 B = Eb9 7 A = D9 79 = Db9 78 = C9 77 = B8 76 = Bb8 75 = A8 74 = Ab8 73 = G8 72 = Gb8 71 = F8 70 = E8 6 F = Eb8 6 E = D8 6 D = Db8 6 C = C8 6 B = B7 6 A = Bb7 69 = A7 68 = Ab7 67 = G7 66 = Gb7 65 = F7 64 = E7 63 = Eb7 62 = D7 61 = Db7 60 = C7 5 F = B6 5 E = Bb6 5 D = A6 5 C = Ab6 5 B = G6 5 A = Gb6 59 = F6 58 = E6 57 = Eb6 56 = D6 55 = Db6 54 = C6 53 = B5 52 = Bb5 51 = A5 50 = Ab5 4 F = G5 4 E = Gb5 4 D = F5 4 C = E5 4 B = Eb5 4 A = D5 49 = Db5 48 = C5 47 = B4 46 = Bb4 45 = A4 44 = Ab4 43 = G4 42 = Gb4 41 = F4 40 = E4 3 F = Eb4 3 E = D4 3 D = Db4 3 C = C4 3 B = B3 3 A = Bb3 39 = A3 38 = Ab3 37 = G3 36 = Gb3 35 = F3 34 = E3 33 = Eb3 32 = D3 31 = Db3 30 = C3 2 F = B2 2 E = Bb2 2 D = A2 2 C = Ab2 2 B = G2 2 A = Gb2 29 = F2 28 = E2 27 = Eb2 26 = D2 25 = Db2 24 = C2 23 = B1 22 = Bb1 21 = A1 20 = Ab1 1 F = G1 1 E = Gb1 1 D = F1 1 C = E1 1 B = Eb1 1 A = D1 19 = Db1 18 = C1 17 = B0 16 = Bb0 15 = A0 14 = Ab0 13 = G0 12 = Gb0 11 = F0 10 = E0 0 F = Eb0 0 E = D0 0 D = Db0 0 C = C0 0B = B(-1) 0 A = Bb(-1) 09 = A(-1) 08 = Ab(-1) 07 = G(-1) 06 = Gb(-1) 05 = F(-1) 04 = E(-1) 03 = Eb(-1) 02 = D(-1) 01 = Db(-1) 00 = C(-1)
Event < -- - W-- - > < -- - X-- - > < -- - Y-- - > < -- - Z-- - > ...
Byte no.1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
00 90 3 C 60 7 F 90 3 E 60 7 F 90 40 60 7 F B0 7 B 00
MIDI section < -- -- -- -- -- -- - MIDI Header-- -- -- -- -- -- -- - > < -- -- - Track Header-- -- > < -Track data - > {
Track out >
Byte number 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21[22 to x][x + 1 to x + 4]
Byte data 4 D 54 68 64 00 00 00 06 00 01 00 01 00 80 4 D 54 72 6 B 00 00 00 0 A blah blah.....00 FF 2 F 00
MIDI section A-- -- -- -- - > B-- -- -- -- - > C-- - > D-- - > E-- - > F-- -- -- -- - > G-- -- -- -- - > H-- -- -- -- -- -- > I-- -- -- -- - >
7 F = G9 7 E = Gb9 7 D = F9 7 C = E9 7 B = Eb9 7 A = D9 79 = Db9 78 = C9 77 = B8 76 = Bb8 75 = A8 74 = Ab8 73 = G8 72 = Gb8 71 = F8 70 = E8 6 F = Eb8 6 E = D8 6 D = Db8 6 C = C8 6 B = B7 6 A = Bb7 69 = A7 68 = Ab7 67 = G7 66 = Gb7 65 = F7 64 = E7 63 = Eb7 62 = D7 61 = Db7 60 = C7 5 F = B6 5 E = Bb6 5 D = A6 5 C = Ab6 5 B = G6 5 A = Gb6 59 = F6 58 = E6 57 = Eb6 56 = D6 55 = Db6 54 = C6 53 = B5 52 = Bb5 51 = A5 50 = Ab5 4 F = G5 4 E = Gb5 4 D = F5 4 C = E5 4 B = Eb5 4 A = D5 49 = Db5 48 = C5 47 = B4 46 = Bb4 45 = A4 44 = Ab4 43 = G4 42 = Gb4 41 = F4 40 = E4 3 F = Eb4 3 E = D4 3 D = Db4 3 C = C4 3 B = B3 3 A = Bb3 39 = A3 38 = Ab3 37 = G3 36 = Gb3 35 = F3 34 = E3 33 = Eb3 32 = D3 31 = Db3 30 = C3 2 F = B2 2 E = Bb2 2 D = A2 2 C = Ab2 2 B = G2 2 A = Gb2 29 = F2 28 = E2 27 = Eb2 26 = D2 25 = Db2 24 = C2 23 = B1 22 = Bb1 21 = A1 20 = Ab1 1 F = G1 1 E = Gb1 1 D = F1 1 C = E1 1 B = Eb1 1 A = D1 19 = Db1 18 = C1 17 = B0 16 = Bb0 15 = A0 14 = Ab0 13 = G0 12 = Gb0 11 = F0 10 = E0 0 F = Eb0 0 E = D0 0 D = Db0 0 C = C0 0B = B(-1) 0 A = Bb(-1) 09 = A(-1) 08 = Ab(-1) 07 = G(-1) 06 = Gb(-1) 05 = F(-1) 04 = E(-1) 03 = Eb(-1) 02 = D(-1) 01 = Db(-1) 00 = C(-1)
Event < -- - W-- - > < -- - X-- - > < -- - Y-- - > < -- - Z-- - > ...
Byte no.1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
00 90 3 C 60 7 F 90 3 E 60 7 F 90 40 60 7 F B0 7 B 00
timestamp value to decimal in Java
int midiDecTime2normalTime(int[] n) {
int l = n.length;
int t = 0;
for (int i = 0; i < l - 1; i++) {
t += (n[i] - 128) * Math.pow(2, 7 * (l - i - 1));
}
t += n[l - 1];
return t;
}
Event < -- - W-- - > < -- - X-- - > < -- - Y-- - > < -- - Z-- - > ...
Byte no.1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
00 90 3 C 60 7 F 90 3 E 60 7 F 90 40 60 7 F B0 7 B 00
timestamp value to decimal in Java
int midiDecTime2normalTime(int[] n) {
int l = n.length;
int t = 0;
for (int i = 0; i < l - 1; i++) {
t += (n[i] - 128) * Math.pow(2, 7 * (l - i - 1));
}
t += n[l - 1];
return t;
}
Instead of ..... 80 00 90 3 C 60 81 00 90 3 E 60 81 00 90 40 60 81 00 B0 7 B 00...we could 've written it as: 80 00 90 3 C 60 81 00 3 E 60 81 00 40 60 81 00 B0 7 B 00
MIDI Header chunk: 4 D 54 68 64 00 00 00 06 00 01 00 01 00 80 4 D 54 72 6 B
MIDI Track chunk: 00 00 00 16 80 00 90 3 C 60 81 00 3 E 60 81 00 40 60 81 00 B0 7 B 00 00 FF 2 F 00
MIDI Header
Trk 1 Header
Trk 1 data
Trk 1 footer
Trk 2 Header
Trk 2 data
Trk 2 footer