阅读量:1
pip install mido
Downloading mido-1.3.2-py3-none-any.whl (54 kB)
Downloading packaging-23.2-py3-none-any.whl (53 kB)
Installing collected packages: packaging, mido
Successfully installed mido-1.3.2 packaging-23.2
pip intall pygame
pygame 2.5.2
安装文档 D:/Python39/Lib/site-packages/pygame/docs/generated/index.html
编写 test1_mido.py 如下
# -*- coding: utf-8 -*- from mido import Message, MidiFile, MidiTrack mid = MidiFile() # 创建MIDI文件 track = MidiTrack() # 创建一个音轨 mid.tracks.append(track) track.append(Message("program_change", channel=0, program=2, time=0)) # 创建各个音符,并添加到音轨中 map1 = {'C4':60, 'D4':62, 'E4':64, 'F4':65, 'G4':67, 'A4':69, 'B4':71, 'C5':72} # do: C4 = 60 track.append(Message("note_on", note=60, velocity=96, time=0)) track.append(Message("note_off", note=60, velocity=0, time=500)) # re: D4 = 62 track.append(Message("note_on", note=62, velocity=96, time=0)) track.append(Message("note_off", note=62, velocity=0, time=500)) # mi: E4 = 64 track.append(Message("note_on", note=64, velocity=96, time=0)) track.append(Message("note_off", note=64, velocity=0, time=500)) # fa: F4 = 65 track.append(Message("note_on", note=65, velocity=96, time=0)) track.append(Message("note_off", note=65, velocity=0, time=500)) # sol:G4 = 67 track.append(Message("note_on", note=67, velocity=96, time=0)) track.append(Message("note_off", note=67, velocity=0, time=500)) # la: A4 = 69 track.append(Message("note_on", note=69, velocity=96, time=0)) track.append(Message("note_off", note=69, velocity=0, time=500)) # si: B4 = 71 track.append(Message("note_on", note=71, velocity=96, time=0)) track.append(Message("note_off", note=71, velocity=0, time=500)) # do^: C5 = 72 track.append(Message("note_on", note=72, velocity=96, time=0)) track.append(Message("note_off", note=72, velocity=0, time=500)) mid.save("test1.mid")
运行 python test1_mido.py 生成文件 test1.mid
查看 mid文件内容 (Message),编写 mido_msg.py 如下
# -*- coding: utf-8 -*- """ https://mido.readthedocs.io/en/latest/ """ import os import sys from tkinter import filedialog from mido import MidiFile # main() if len(sys.argv) ==1: filetypes = [('mid file','.mid')] f1 = filedialog.askopenfilename(initialdir='D:/Music', filetypes=filetypes) elif len(sys.argv) ==2: f1 = sys.argv[1] else: print('usage: python mido_msg.py file1.mid') sys.exit(1) if not os.path.exists(f1): print(f"{f1} is not exists.") sys.exit(2) fn,ext = os.path.splitext(f1) if ext.lower() != '.mid': print('ext is not .mid ') sys.exit(2) # mid = MidiFile(f1) with MidiFile(f1) as mid: for msg in mid: print(msg)
运行 python mido_msg.py happy_birthday.mid
编写 play_mid.py 如下
# -*- coding: utf-8 -*- import os import sys import time from tkinter import filedialog import traceback import pygame from pygame import mixer def mixer_init(): freq = 44100 bitsize = -16 channels = 2 buffer = 2048 mixer.init(freq, bitsize, channels, buffer) # optional volume 0 to 1.0 mixer.music.set_volume(0.9) def play_mid(file): if mixer.music.get_busy(): mixer.music.fadeout(1000) mixer.music.stop() clock = pygame.time.Clock() try: mixer.music.load(file) except: print(traceback.format_exc()) mixer.music.play() while mixer.music.get_busy(): clock.tick(30) # main() if len(sys.argv) ==1: filetypes = [('mid file','.mid')] f1 = filedialog.askopenfilename(initialdir='D:/Music', filetypes=filetypes) elif len(sys.argv) ==2: f1 = sys.argv[1] else: print('usage: python play_mid.py file1.mid') sys.exit(1) if not os.path.exists(f1): print(f"{f1} is not exists.") sys.exit(2) fn,ext = os.path.splitext(f1) if ext.lower() not in ('.mid','.mp3'): print('ext is not (.mid , .mp3)') sys.exit(2) time1 = time.time() print(f1) mixer_init() try: play_mid(f1) except KeyboardInterrupt as ex: # if user hits Ctrl+C then exit # (works only in console mode) mixer.music.fadeout(1000) mixer.music.stop() raise SystemExit from ex mixer.music.stop() time2 = time.time() print("run time: %.3f s" % (time2-time1))
运行 python play_mid.py test1.mid
详细参阅:Python编曲实践(一):通过Mido和PyGame来编写和播放单轨MIDI文件
MidiEditor 打开 test1.mid 文件