Skip to content

Latest commit

 

History

History
289 lines (224 loc) · 7.23 KB

File metadata and controls

289 lines (224 loc) · 7.23 KB
Error in user YAML: (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1
---
show: step
version: 1.0 
enable_checker: true
- 本教程同步发布在: 
	- 个人网站: `https://oeasy.org` 
	- 蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
	- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
	- Gitee: `https://gitee.com/overmind1980/oeasypython` 
---

  • oeasy Python 0755
  • 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。

python_音频处理_midi制作

开始

  • 我们首先要从零开始
  • 安装midi软件
sudo apt update
yes | sudo apt install rosegarden

图片描述

  • 也可以直接运行

rosegarden

rosegarden
  • 运行成功

图片描述

  • 尝试使用python写mid文件

安装类库

pip install MIDIUtil
  • 安装成功后
    • 准备用python写midi文件

大调音阶

from midiutil import MIDIFile

# create MIDI file
midi_file = MIDIFile(1)

# add a track
track = 0
time = 0
midi_file.addTrackName(track, time, "Sample Track")
midi_file.addTempo(track, time, 120)

# add notes to the track
channel = 0
pitch = 60    # C3
duration = 1  # 1 beat
volume = 100  # max volume
for i in range(0, 8):
    midi_file.addNote(track, channel, pitch+i, time+i*duration, duration, volume)

# write MIDI file to disk
with open("output.mid", "wb") as output_file:
    midi_file.writeFile(output_file)
  • 运行之后
    • 尝试打开output.mid

打开效果

图片描述

  • 查看钢琴卷帘

图片描述

  • 可以修改为大调音阶吗?

大调音阶

from midiutil import MIDIFile

# create MIDI file
midi_file = MIDIFile(1)

# add a track
track = 0
time = 0
midi_file.addTrackName(track, time, "Sample Track")
midi_file.addTempo(track, time, 120)

# add notes to the track
channel = 0
pitch = 72    # C4
duration = 1  # 1 beat
volume = 100  # max volume
j = 0
for i in [0,2,4,5,7,9,11,12]:
    midi_file.addNote(track, channel, pitch+i, time+j*duration, duration, volume)
    j = j + 1

# write MIDI file to disk
with open("output.mid", "wb") as output_file:
    midi_file.writeFile(output_file)
  • 修改后结果

图片描述

  • 有更标准的写法吗?

帮助文档

firefox https://pypi.org/project/MIDIUtil/
  • 文档状态

图片描述

  • 可以跑跑其中的代码吗?

运行

#!/usr/bin/env python

from midiutil import MIDIFile

degrees  = [60, 62, 64, 65, 67, 69, 71, 72]  # MIDI note number
track    = 0
channel  = 0
time     = 0    # In beats
duration = 1    # In beats
tempo    = 60   # In BPM
volume   = 100  # 0-127, as per the MIDI standard

MyMIDI = MIDIFile(1)  # One track, defaults to format 1 (tempo track is created
                      # automatically)
MyMIDI.addTempo(track, time, tempo)

for i, pitch in enumerate(degrees):
    MyMIDI.addNote(track, channel, pitch, time + i, duration, volume)

with open("major-scale.mid", "wb") as output_file:
    MyMIDI.writeFile(output_file)
  • 输出了一系列的 大调音阶
    • major-scale

图片描述

  • 打开之后查看到mid状态
    • 确实是大调音阶

《梁祝》

from mido import MidiFile, MidiTrack, Message

# 创建一个新的 MIDI 文件
midi = MidiFile()

# 创建右手旋律轨道
melody_track = MidiTrack()
midi.tracks.append(melody_track)
melody_track.append(Message('program_change', program=0, time=0))

# 右手旋律(梁祝主题旋律)
right_hand_notes = [
    (64, 960), (67, 720), (69, 240),
    (72, 720), (74, 240), (69, 240), (72, 240), (67, 480),
    (79, 720), (84, 240), (81, 240), (79, 240), (76, 240), (79, 240),
    (74, 1920),
    (74, 480), (74, 240), (76, 240), (71, 480), (69, 480), 
    (67, 720), (69, 240), (72, 480), (74, 480),
    (64, 480), (72, 480), (69, 240), (67, 240), (69, 240), (72, 240),
    (67, 1920),
    (76,720),(79,240),(71,480),(74,480),
    (69,240),(72,240),(67,1440),
    (64,360),(67,120),(64,480),(67,240),(69,240),(71,240),(74,240),
    (69,1440),(67,240),(69,240),
    (72,720),(74,240),(79,480),(76,480),
    (74,480),(76,240),(74,240),(72,480),(69,240),(67,240),
    (64,960),(72,960),
    (69,360),(72,120),(69,240),(67,240),(64,240),(67,240),(69,240),(72,240),
    (67,1440),(76,240),(79,240),
    (74,240),(76,240),(74,240),(72,240),(71,480),(69,480),
    (67,1440),(64,240),(67,240),
    (62,240),(64,240),(62,240),(60,240),(59,480),(57,480),
    (55,1920),
]

# 左手伴奏(简单的低音进行)
left_hand_notes = [
    (36,480),(43,480),(45,480),(48,480),
    (40,480),(48,480),(45,480),(43,480),
    (36,480),(43,480),(45,480),(48,480),
    (43,480),(48,480),(50,480),(55,480),
    (41,240),(50,240),(53,240),(57,1200),
    (40,240),(47,240),(50,240),(52,240),(55,960),
    (45,240),(52,240),(57,240),(48,240),(52,960),
    (31,240),(38,240),(43,240),(48,240),(55,960),
    (52,240),(59,240),(62,240),(64,240),(55,960),
    (45,240),(52,240),(55,240),(57,240),(60,960),
    (40,240),(47,240),(50,240),(52,240),(55,960),
    (45,240),(52,240),(55,240),(57,240),(60,240),(64,240),(0,480),
    (36,240),(43,240),(45,240),(48,1200),
    (43,240),(50,240),(55,240),(57,1200),
    (45,240),(52,240),(55,240),(57,1200),
    (38,240),(45,240),(48,240),(50,240),(55,960),
    (31,240),(38,240),(43,240),(48,240),(55,480),(72,480),
    (69,480),(67,480),(62,480),(64,480),
    (55,1440),(60,480),
    (57,480),(55,480),(50,480),(52,480),
    (43,1920)
]

# 创建右手旋律轨道
for note, duration in right_hand_notes:
    melody_track.append(Message('note_on', note=note, velocity=80, time=0))
    melody_track.append(Message('note_off', note=note, velocity=80, time=duration))

# 创建左手轨道
bass_track = MidiTrack()
midi.tracks.append(bass_track)
bass_track.append(Message('program_change', program=0, time=0))

# 添加左手伴奏
for note, duration in left_hand_notes:
    bass_track.append(Message('note_on', note=note, velocity=60, time=0))
    bass_track.append(Message('note_off', note=note, velocity=60, time=duration))

# 创建中国传统打击乐轨道(通道 9)
drum_track = MidiTrack()
midi.tracks.append(drum_track)

drum_pattern = [
    (56, 960),  # 大鼓
    (57, 960),  # 小堂鼓
    (58, 480),  # 铙钹
    (59, 480),  # 木鱼
    (60, 960),  # 碰铃
    (61, 480),  # 云锣
    (56, 960), (58, 480), (59, 480), (57, 960), (60, 960), (61, 480)
]

# 让打击乐持续半首歌
drum_repeats = len(right_hand_notes) // len(drum_pattern) // 2

for _ in range(drum_repeats):
    for note, duration in drum_pattern:
        drum_track.append(Message('note_on', note=note, velocity=80, time=0, channel=9))
        drum_track.append(Message('note_off', note=note, velocity=80, time=duration, channel=9))

# 保存 MIDI 文件
midi.save('liangzhu_piano_with_traditional_drums.mid')
print("MIDI 文件已保存,包含左手伴奏和中国传统打击乐!")

总结

  • 这次从零开始
    • 安装了midi软件
    • 使用python制作了mid文件
  • 不过
    • 究竟什么是mid呢?🤔
  • 我们下次再说!👋

  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。