Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0756
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在:
- 个人网站: `https://oeasy.org`
- 蓝桥云课: `https://www.lanqiao.cn/courses/3584`
- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
- Gitee: `https://gitee.com/overmind1980/oeasypython`
---- 可以要求 某种鼓点 比如中国风 布鲁斯 鼓点之类的
from pretty_midi import PrettyMIDI, Instrument, Note
import random
# 创建MIDI对象
midi = PrettyMIDI(resolution=480, initial_tempo=92)
# 只保留鼓的音色配置
instruments = {
'drums': Instrument(0, is_drum=True)
}
# 鼓组编程 (更复杂的后朋克节奏)
def add_drums():
time = 0
# 4小节循环
for _ in range(4):
# 底鼓 (不规则节奏)
kick_pattern = [0, 0.75, 1.5, 2.25, 3, 3.5]
for t in kick_pattern:
instruments['drums'].notes.append(
Note(velocity=100 + int(20 * random.random()),
pitch=36,
start=time + t,
end=time + t + 0.1))
# 军鼓 (带切分)
snare_pattern = [1.0, 2.5, 3.75]
for t in snare_pattern:
instruments['drums'].notes.append(
Note(velocity=90,
pitch=38,
start=time + t,
end=time + t + 0.1))
# 踩镲 (十六分音符但随机省略)
for i in range(16):
if random.random() > 0.3: # 70%概率出现
instruments['drums'].notes.append(
Note(velocity=40 + int(30 * random.random()),
pitch=42,
start=time + i * 0.25,
end=time + i * 0.25 + 0.05))
# 桶鼓填充 (每小节结尾)
if random.random() > 0.7: # 30%概率加花
for pitch, t in zip([41, 43, 45], [3.5, 3.75, 3.875]):
instruments['drums'].notes.append(
Note(velocity=80,
pitch=pitch,
start=time + t,
end=time + t + 0.1))
time += 4 # 每小节4拍
# 构建完整结构
add_drums() # 0-16小节
# 添加鼓轨道
midi.instruments.append(instruments['drums'])
# 修改保存路径为绝对路径
midi.write('/Users/easyo/Downloads/oeasy/drums_only.mid')
print(f"鼓组MIDI已生成!文件保存在:drums_only.mid")
from pretty_midi import PrettyMIDI, Instrument, Note
import random
import numpy as np
# 创建MIDI对象 - 稍慢的节奏适合叙事性
midi = PrettyMIDI(resolution=480, initial_tempo=92)
# 音色配置 (更丰富的配器)
instruments = {
'drums': Instrument(0, is_drum=True),
'bass': Instrument(program=34), # 指弹贝斯
'rhythm_guitar': Instrument(program=29), # 过载吉他
'lead_guitar': Instrument(program=26), # 清音吉他(万能青年旅店风格)
'synth_pad': Instrument(program=89), # 温暖合成背景
'brass': Instrument(program=61), # 铜管(用于副歌高潮)
'vocal': Instrument(program=53) # 合唱人声
}
# 鼓组编程 (更复杂的后朋克节奏)
def add_drums():
time = 0
# 4小节循环
for _ in range(4):
# 底鼓 (不规则节奏)
kick_pattern = [0, 0.75, 1.5, 2.25, 3, 3.5]
for t in kick_pattern:
instruments['drums'].notes.append(
Note(velocity=100 + int(20 * random.random()),
pitch=36,
start=time + t,
end=time + t + 0.1))
# 军鼓 (带切分)
snare_pattern = [1.0, 2.5, 3.75]
for t in snare_pattern:
instruments['drums'].notes.append(
Note(velocity=90,
pitch=38,
start=time + t,
end=time + t + 0.1))
# 踩镲 (十六分音符但随机省略)
for i in range(16):
if random.random() > 0.3: # 70%概率出现
instruments['drums'].notes.append(
Note(velocity=40 + int(30 * random.random()),
pitch=42,
start=time + i * 0.25,
end=time + i * 0.25 + 0.05))
# 桶鼓填充 (每小节结尾)
if random.random() > 0.7: # 30%概率加花
for pitch, t in zip([41, 43, 45], [3.5, 3.75, 3.875]):
instruments['drums'].notes.append(
Note(velocity=80,
pitch=pitch,
start=time + t,
end=time + t + 0.1))
time += 4 # 每小节4拍
# 贝斯线 (带滑音和切分)
def add_bass():
time = 0
# C小调进行
chord_progression = [
(48, 0, 1.5), # C (根音)
(46, 1.5, 0.5), # Bb (经过音)
(48, 2.0, 1.0), # C
(51, 3.0, 1.0) # Eb
]
for _ in range(4): # 重复4次
for note_info in chord_progression:
pitch, offset, duration = note_info
# 加入随机微调增加人性化
actual_pitch = pitch + int(0.5 - random.random())
instruments['bass'].notes.append(
Note(velocity=70 + int(20 * random.random()),
pitch=actual_pitch,
start=time + offset,
end=time + offset + duration))
# 50%概率加入滑音
if random.random() > 0.5 and duration > 0.5:
instruments['bass'].notes.append(
Note(velocity=50,
pitch=actual_pitch + 3,
start=time + offset + duration - 0.1,
end=time + offset + duration))
time += 4
# 吉他部分 (万能青年旅店式的分解和弦)
def add_guitars():
time = 0
# C小调 + F小调交替
chord_voicings = [
[48, 51, 55, 60], # Cm
[53, 56, 60, 65], # Fm
[51, 55, 58, 63], # Eb
[50, 53, 57, 62] # Ddim
]
for _ in range(8): # 8小节
current_chord = chord_voicings[time // 4 % len(chord_voicings)]
# 节奏吉他 (强力和弦)
if time % 8 < 4: # 前4小节强力和弦
instruments['rhythm_guitar'].notes.append(
Note(velocity=100,
pitch=current_chord[0],
start=time,
end=time + 0.5))
instruments['rhythm_guitar'].notes.append(
Note(velocity=90,
pitch=current_chord[1],
start=time,
end=time + 0.5))
# 主音吉他 (分解和弦)
arpeggio_pattern = [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
for i, t in enumerate(arpeggio_pattern):
note_idx = i % len(current_chord)
instruments['lead_guitar'].notes.append(
Note(velocity=60 + int(20 * random.random()),
pitch=current_chord[note_idx] + 12, # 高八度
start=time + t,
end=time + t + 0.2))
# 30%概率加入装饰音
if random.random() > 0.7:
instruments['lead_guitar'].notes.append(
Note(velocity=40,
pitch=current_chord[note_idx] + 10,
start=time + t - 0.05,
end=time + t))
time += 4
# 合成器背景 (脆莓风格的氛围铺底)
def add_synth():
time = 0
chord_progression = [
[48, 51, 55], # Cm
[53, 56, 60], # Fm
[51, 55, 58], # Eb
[50, 53, 57] # Ddim
]
for _ in range(4): # 4次循环
for chord in chord_progression:
# 长持续音
for note in chord:
instruments['synth_pad'].notes.append(
Note(velocity=50,
pitch=note + 24, # 低两个八度
start=time,
end=time + 4))
instruments['synth_pad'].notes.append(
Note(velocity=40,
pitch=note + 36, # 高一个八度
start=time,
end=time + 4))
# 高频点缀
if random.random() > 0.5:
instruments['synth_pad'].notes.append(
Note(velocity=30,
pitch=chord[1] + 48,
start=time + 2,
end=time + 2.5))
time += 4
# 铜管部分 (副歌高潮)
def add_brass():
time = 16 # 从第16小节开始
melody = [
(60, 0.5), (62, 0.5), (63, 1.0), # C-D-Eb
(65, 0.25), (63, 0.25), (62, 0.5), # G-Eb-D
(60, 2.0) # C(长音)
]
for _ in range(2): # 重复2次
current_time = time
for note, duration in melody:
instruments['brass'].notes.append(
Note(velocity=100,
pitch=note,
start=current_time,
end=current_time + duration))
current_time += duration
# 加入和声层
instruments['brass'].notes.append(
Note(velocity=80,
pitch=note - 3,
start=time,
end=time + 4))
time += 4
# 人声模拟 (合唱效果)
def add_vocal():
time = 8 # 从第8小节进入
vocal_melody = [
(60, 1.0), (62, 0.5), (60, 0.5), # C-D-C
(58, 1.0), (60, 1.0), # Bb-C
(55, 2.0) # G(长音)
]
for _ in range(4): # 4次循环
current_time = time
for note, duration in vocal_melody:
# 主旋律
instruments['vocal'].notes.append(
Note(velocity=90,
pitch=note + 12,
start=current_time,
end=current_time + duration))
# 和声(随机三度/五度)
harmony_pitch = note + [3, 4, 7][int(random.random() * 3)]
instruments['vocal'].notes.append(
Note(velocity=70,
pitch=harmony_pitch + 12,
start=current_time,
end=current_time + duration))
current_time += duration
time += 4
# 构建完整结构
add_drums() # 0-16小节
add_bass() # 0-16小节
add_guitars() # 0-32小节
add_synth() # 0-16小节
add_brass() # 16-24小节(副歌)
add_vocal() # 8-24小节
# 添加所有轨道
for inst in instruments.values():
midi.instruments.append(inst)
# 保存文件
midi.write('wanqing_style.mid')
print("万能青年旅店 x 脆莓风格MIDI已生成!")
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。