python:用 mido 生成 midi文件,用 pygame 播放 mid文件

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

mido 官网文档

pip intall pygame

pygame 2.5.2

安装文档 D:/Python39/Lib/site-packages/pygame/docs/generated/index.html

编写 test1_mido.py 如下

python 复制代码
# -*- 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))
# do: C4 = 60
track.append(Message("note_on", note=60, velocity=80, time=500))
track.append(Message("note_off", note=60, velocity=80, time=500))
# re: D4 = 62 
track.append(Message("note_on", note=62, velocity=80, time=500))
track.append(Message("note_off", note=62, velocity=80, time=500))
# mi: E4 = 64
track.append(Message("note_on", note=64, velocity=80, time=500))
track.append(Message("note_off", note=64, velocity=80, time=500))
# fa: F4 = 65
track.append(Message("note_on", note=65, velocity=80, time=500))
track.append(Message("note_off", note=65, velocity=80, time=500))
# sol:G4 = 67
track.append(Message("note_on", note=67, velocity=80, time=500))
track.append(Message("note_off", note=67, velocity=80, time=500))
# la: A4 = 69
track.append(Message("note_on", note=69, velocity=80, time=500))
track.append(Message("note_off", note=69, velocity=80, time=500))
# si: B4 = 71
track.append(Message("note_on", note=71, velocity=80, time=500))
track.append(Message("note_off", note=71, velocity=80, time=500))
# do: C5 = 72
track.append(Message("note_on", note=72, velocity=80, time=500))
track.append(Message("note_off", note=72, velocity=80, time=500))

mid.save("test1.mid")

运行 python test1_mido.py 生成文件 test1.mid

编写 play_mid.py 如下

python 复制代码
# -*- coding: utf-8 -*-
import os
import sys
import traceback
import pygame
from pygame import mixer

def mixer_init():
    freq = 44100
    bitsize = -16
    channels = 2
    buffer = 1024
    mixer.init(freq, bitsize, channels, buffer)
    # optional volume 0 to 1.0
    mixer.music.set_volume(0.9)

def play_mid(file):
    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) ==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)

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()

运行 python play_mid.py test1.mid

详细参阅:Python编曲实践(一):通过Mido和PyGame来编写和播放单轨MIDI文件

MidiEditor 打开 test1.mid 文件

相关推荐
听风吹等浪起1 天前
用Python和Pygame从零实现坦克大战
开发语言·python·pygame
智算菩萨1 天前
【Pygame】第8章 文字渲染与字体系统(支持中文字体)
开发语言·python·pygame
智算菩萨1 天前
【Pygame】第20章 从0到1构建贪吃蛇:基于Pygame的游戏架构与状态机设计实战(有超详细中文注释)
python·游戏·pygame
智算菩萨1 天前
【Pygame】第23章 平台跳跃游戏:基于有限状态机的2D平台物理模拟与摄像机视口管理系统(有超详细中文注释供大家学习)
python·游戏·pygame
智算菩萨2 天前
【Pygame】第10章 游戏状态管理与场景切换机制
python·游戏·pygame
智算菩萨2 天前
【Pygame】第15章 游戏人工智能基础、行为控制与寻路算法实现
人工智能·游戏·pygame
智算菩萨2 天前
【Pygame】第17章 游戏用户界面系统与菜单交互设计实现
游戏·ui·pygame
智算菩萨2 天前
【Pygame】第19章 网络多人游戏基础与局域网联机原理
网络·python·游戏·pygame
智算菩萨2 天前
【Pygame】第16章 游戏存档系统设计与数据持久化实现
jvm·游戏·pygame
智算菩萨2 天前
【Pygame】第14章 摄像机系统与游戏视口控制技术
python·游戏·pygame