what kind of encoding does a standard midi file use?

  • Last Update :
  • Techknowledgy :

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!')

Suggestion : 2

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!')

Suggestion : 3

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']

Suggestion : 4

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-- -- -- -- - >
A quick list of possible MIDI pitches and their HEX code:
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
1._
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-- -- -- -- - >
A quick list of possible MIDI pitches and their HEX code:
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)
3._
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
Converting from the MIDI
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;
}
6._
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
Converting from the MIDI
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;
}
'running status'
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
4._
MIDI Header

Trk 1 Header
Trk 1 data
Trk 1 footer

Trk 2 Header
Trk 2 data
Trk 2 footer