Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Open MIDI file
- print("NOTE: The midi file must be in the same directory as this .exe file!", "\n")
- fil = input("Enter the name of the midi file you want analysed: ")
- if fil[-4] + fil[-3] + fil[-2] + fil[-1] != ".mid":
- fil += ".mid"
- mFile = open(fil, 'rb')
- print("\n" + "Analysing", fil, "\n")
- # Checks if file is MIDI
- hChunk = mFile.read(4)
- if hChunk != b'MThd':
- raise ValueError('Not a MIDI file')
- contents = mFile.read()
- # Close MIDI file again
- mFile.close()
- # Number of bytes in the MIDI file
- midi_len = len(contents)
- # Puts all bytes into this list
- midi_bytes = []
- for i in range(0, midi_len):
- byte = "x{:02X}".format(contents[i])
- midi_bytes.append(byte)
- # To compare integers with given values you can just do : contents[i]==0x4d
- # ---------------HEADER CHUNK--------------- #
- # Find Format, number of tracks, 'delta time' of MIDI
- for i in range(0, 10): # Header chunck is 14 bytes long (first 4 was removed)
- if i == 5: # Checks format
- if midi_bytes[i] == "x00":
- print("Format: Single track", "\n")
- elif midi_bytes[i] == "x01":
- print("Format: Multiple track", "\n")
- elif midi_bytes[i] == "x02":
- print("Format: Multiple song (i.e. a series of single track songs)", "\n")
- if i == 7: # Finds number of tracks in MIDI
- num_track = int(midi_bytes[i][1:3], 16)
- print("Number of tracks:", num_track, "\n")
- if i == 8: #Finds delta timing
- n = midi_bytes[i][1:3] + midi_bytes[i + 1][1:3]
- num_delta = int(n, 16)
- print("Number of ticks per quater note:", num_delta, "\n")
- # ------------------END--------------------- #
- # Remove head chunk - no longer needed
- for i in range(0, 10):
- del midi_bytes[0]
- # --------------TRACK CHUNK----------------- #
- # INFO
- # All the differant keys
- keys = {
- '0 C': 0,
- '1 C#': 0,
- '2 D': 0,
- '3 D#': 0,
- '4 E': 0,
- '5 F': 0,
- '6 F#': 0,
- '7 G': 0,
- '8 G#': 0,
- '9 A': 0,
- 'A A#': 0,
- 'B B': 0
- }
- for i in range(0, len(midi_bytes) - 3): # iterates through the midi (without head chunk)
- # Looks for start of track chunk (MTrk)
- if midi_bytes[i][1:3] + \
- midi_bytes[i + 1][1:3] + \
- midi_bytes[i + 2][1:3] + \
- midi_bytes[i + 3][1:3] == "4D54726B":
- # Found a track chunk
- # How long is the chunk?
- len_of_chunk = int(midi_bytes[i + 4][1:3] +
- midi_bytes[i + 5][1:3] +
- midi_bytes[i + 6][1:3] +
- midi_bytes[i + 7][1:3], 16)
- # print("debug - chunk found") #DEBUG
- # iterates through that chunk (from 8 bytes after chunk start to length of chunk + 8 (from the 8 after))
- for j in range(9, len_of_chunk + 8):
- # Looks for keys
- bit = int(midi_bytes[j][1:3], 16)
- if midi_bytes[j - 1][1] == "8" and bit <= 127:
- # print(bit) # For debugging
- if bit % 12 == 0:
- # C found
- keys["0 C"] += 1
- elif bit % 12 == 1:
- # C# found
- keys["1 C#"] += 1
- elif bit % 12 == 2:
- # D found
- keys["2 D"] += 1
- elif bit % 12 == 3:
- # D# found
- keys["3 D#"] += 1
- elif bit % 12 == 4:
- # E found
- keys["4 E"] += 1
- elif bit % 12 == 5:
- # F found
- keys["5 F"] += 1
- elif bit % 12 == 6:
- # F# found
- keys["6 F#"] += 1
- elif bit % 12 == 7:
- # G found
- keys["7 G"] += 1
- elif bit % 12 == 8:
- # G# found
- keys["8 G#"] += 1
- elif bit % 12 == 9:
- # A found
- keys["9 A"] += 1
- elif bit % 12 == 10:
- # A# found
- keys["A A#"] += 1
- elif bit % 12 == 11:
- # B found
- keys["B B"] += 1
- keys_in_total = 0
- # Find the total amount of keys by adding them together
- for k, v in keys.items():
- keys_in_total += v
- # Print it in a pretty fashion
- for k, v in sorted(keys.items()):
- percent = round((v / keys_in_total) * 50) # To make it print in percent
- leftover = 50 - percent
- if len(k) == 4: # This if statement just makes the output prettier
- print(k[2::], "|", "#" * percent + "." * leftover, "|", v)
- else: # Maybe change # to █ ?
- print(k[2::], "", "|", "#" * percent + "." * leftover, "|", v)
- print("\n" + "Notes in total:", keys_in_total)
- # DOESNT WORK ON CRY ME A RIVER !?
- # print(midi_bytes)
- # Stops it from closing instantly
- input("\n" + "Press 'Enter' to exit")
Advertisement
Add Comment
Please, Sign In to add comment