Error in user YAML: (<unknown>): could not find expected ':' while scanning a simple key at line 3 column 1
---
- oeasy Python 0117
- 这是 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`
---
二维列表_midi深入_列表_音符四要素_嵌套_embeded
配套视频
上次 我们了解了 无序
排序 可以 让列表 有序
随机 可以 让列表 无序
无序有序都用
方法名
功能说明
append
追加 列表项
extend
拓展 列表
lst = []
lst.extend([0, 1])
lst
lst.append([0, 1])
lst
type(lst)
len(lst)
lst[0]
lst[1]
lst[2]
lst[3]
lst
lst[2]
type(lst[2])
len(lst[2])
lst[2]
lst[2][0]
lst[2][1]
from mido import Message, MidiFile, MidiTrack
# 音符对应字典,按简谱 1 - 7 对应 C 调下的音符(1=C 时的对应)
# 修改核心:将原F调的音符数值调整为C调对应值
NOTE_MAP = {
'1': 60, '2': 62, '3': 64, '4': 65,
'5': 67, '6': 69, '7': 71, '_5': 55 # 低音5对应C调低八度的5
}
# 根据简谱和对应时值构建旋律,这里 '-' 表示延长一拍(原旋律结构不变)
MELODY = [
['1', 1], ['2', 1], ['3', 1], ['1', 1], # 两只老虎
['1', 1], ['2', 1], ['3', 1], ['1', 1], # 两只老虎
['3', 1], ['4', 1], ['5', 2], # 跑的快
['3', 1], ['4', 1], ['5', 2], # 跑得快
['5', 0.5], ['6', 0.5], ['5', 0.5], ['4', 0.5], ['3', 1], ['1', 1], # 一只没有眼睛
['5', 0.5], ['6', 0.5], ['5', 0.5], ['4', 0.5], ['3', 1], ['1', 1], # 一只没有尾巴
['2', 1], ['_5', 1], ['1', 2], # 真奇怪
['2', 1], ['_5', 1], ['1', 2], # 真奇怪
]
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
ticks_per_beat = 480 # 标准 MIDI 时钟,每拍 480 ticks
current_time = 0 # 时间增量
for note_info in MELODY:
note_name = note_info[0]
beats = note_info[1]
if note_name == '-':
# 处理延长音,增加时间增量
current_time += int(beats * ticks_per_beat)
continue
note = NOTE_MAP[note_name]
duration = int(beats * ticks_per_beat)
# 发送音符开启(当前时间增量)和关闭(持续时间)
track.append(Message('note_on', note=note, velocity=64, time=current_time))
track.append(Message('note_off', note=note, velocity=64, time=duration))
current_time = 0 # 每个音符独立,无间隔
mid.save('two_tigers_c调.mid')
print("已生成《两只老虎》C 调 MIDI 文件:two_tigers_c调.mid")
# 音符对应字典,按简谱 1 - 7 对应 F 调下的音符(1=F 时的对应)
NOTE_MAP = {
'1' : 65 , '2' : 67 , '3' : 69 , '4' : 70 ,
'5' : 72 , '6' : 74 , '7' : 76 , '_5' : 60
}
要素
定义
影响因素
作用
举例
音高
音符的高低
发声体振动频率
构建旋律与和声框架
钢琴从左到右音高渐高
时长
音符发声持续的时间
发声体振动持续时长
时间上的长短比例 形成节奏
全音符、四分音符
音强
音符发声的强弱程度
发声体振动幅度
情感起伏 动态变化
激昂用强音 轻柔 用弱音
音色
音符声音的特色
发声体的材质、结构、发声方式等
赋予声音独特个性
钢琴清脆明亮 二胡悠扬
from mido import Message , MidiFile , MidiTrack
# 音符对应字典(F调)
NOTE_MAP = {'_5' : 60 , '1' : 65 , '2' : 67 , '3' : 69 , '4' : 70 , '5' : 72 , '6' : 74 , '7' : 76 }
# 定义强弱规律(四四拍:强=90,弱=50,次强=70,最弱=40)
BEAT_VELOCITY = {
1 : 90 , # 第一拍(强)
2 : 50 , # 第二拍(弱)
3 : 70 , # 第三拍(次强)
4 : 50 # 第四拍(弱)
}
# 带节拍位置的旋律(格式:[音符, 时值, 节拍位置],节拍位置从1开始)
MELODY = [
# 两只老虎(四四拍,每小节4拍)
['1' , 1 , 1 ], ['2' , 1 , 2 ], ['3' , 1 , 3 ], ['1' , 1 , 4 ], # 第一小节
['1' , 1 , 1 ], ['2' , 1 , 2 ], ['3' , 1 , 3 ], ['1' , 1 , 4 ], # 第二小节
['3' , 1 , 1 ], ['4' , 1 , 2 ], ['5' , 2 , 3 ], # 第三小节(第三拍延长2拍,占第3、4拍)
['3' , 1 , 1 ], ['4' , 1 , 2 ], ['5' , 2 , 3 ], # 第四小节
['5' , 0.5 , 1 ], ['6' , 0.5 , 2 ], ['5' , 0.5 , 3 ], ['4' , 0.5 , 4 ], ['3' , 1 , 1 ], ['1' , 1 , 2 ], # 第五小节
['5' , 0.5 , 1 ], ['6' , 0.5 , 2 ], ['5' , 0.5 , 3 ], ['4' , 0.5 , 4 ], ['3' , 1 , 1 ], ['1' , 1 , 2 ], # 第六小节
['2' , 1 , 1 ], ['_5' , 1 , 2 ], ['1' , 2 , 3 ], # 第七小节
['2' , 1 , 1 ], ['_5' , 1 , 2 ], ['1' , 2 , 3 ], # 第八小节
]
mid = MidiFile ()
track = MidiTrack ()
mid .tracks .append (track )
ticks_per_beat = 480
current_time = 0
current_beat = 1 # 记录当前节拍位置(每小节从1开始)
for note_info in MELODY :
note_name , beats , beat_pos = note_info
if note_name == '-' :
# 处理延长音
current_time += int (beats * ticks_per_beat )
current_beat = (current_beat + int (beats )) % 4 # 更新节拍位置(4拍循环)
continue
# 获取音强(velocity),若节拍位置超出预设,默认中等音量64
velocity = BEAT_VELOCITY .get (beat_pos , 64 )
note = NOTE_MAP [note_name ]
duration = int (beats * ticks_per_beat )
# 发送音符消息(带音强)
track .append (Message ('note_on' , note = note , velocity = velocity , time = current_time ))
track .append (Message ('note_off' , note = note , velocity = velocity , time = duration ))
# 更新节拍位置(每拍前进1,超过4则重置为1)
current_beat = (beat_pos + int (beats )) % 4 if int (beats ) == 1 else (beat_pos + int (beats )) # 处理连音符
current_time = 0 # 音符间无间隔
mid .save ('two_tigers_f调_强弱.mid' )
print ("已生成带强弱规律的MIDI文件:two_tigers_f调_强弱.mid" )
# 定义强弱规律(四四拍:强=90,弱=50,次强=70,最弱=40)
BEAT_VELOCITY = {
1: 50, # 第一拍(弱)
2: 70, # 第二拍(强)
3: 40, # 第三拍(最弱)
4: 90 # 第四拍(次强)
}
# 带节拍位置的旋律(格式:[音符, 时值, 节拍位置],节拍位置从1开始)
MELODY = [
# 两只老虎(四四拍,每小节4拍)
['1', 1, 1], ['2', 1, 2], ['3', 1, 3], ['1', 1, 4], # 第一小节
['1', 1, 1], ['2', 1, 2], ['3', 1, 3], ['1', 1, 4], # 第二小节
['3', 1, 1], ['4', 1, 2], ['5', 2, 4], # 第三小节(第三拍延长2拍,占第3、4拍)
['3', 1, 1], ['4', 1, 2], ['5', 2, 4], # 第四小节
['5', 0.5, 1], ['6', 0.5, 2], ['5', 0.5, 3], ['4', 0.5, 4], ['3', 1, 1], ['1', 1, 4], # 第五小节
['5', 0.5, 1], ['6', 0.5, 2], ['5', 0.5, 3], ['4', 0.5, 4], ['3', 1, 1], ['1', 1, 4], # 第六小节
['2', 1, 1], ['_5', 1, 2], ['1', 2, 4], # 第七小节
['2', 1, 1], ['_5', 1, 2], ['1', 2, 4], # 第八小节
]
编码
对应乐器
编码
对应乐器
0
大钢琴(声学钢琴)
64
合成铜管2
1
明亮的钢琴
65
高音萨克斯
2
电钢琴
66
中音萨克斯
3
酒吧钢琴
67
次中音萨克斯
4
柔和的电钢琴
68
上低音萨克斯
5
加合唱效果的电钢琴
69
双簧管
6
羽管键琴(拨弦古钢琴)
70
英国管
7
科拉维科特琴(击弦古钢琴)
71
大管
8
钢片琴
72
单簧管
9
钟琴
73
短笛
10
八音盒
74
长笛
11
颤音琴
75
竖笛
12
马林巴
76
排笛
13
木琴
77
吹瓶口
14
管钟
78
尺八
15
大扬琴
79
哨
16
击杆风琴
80
洋埙
17
打击式风琴
81
合成主音1(方波)
18
摇滚风琴
82
合成主音2(锯齿波)
19
教堂风琴
83
合成主音3(汽笛风琴)
20
簧管风琴
84
合成主音4(吹管)
21
手风琴
85
合成主音5(吉他)
22
口琴
86
合成主音6(人声)
23
探戈手风琴
87
合成主音7(五度)
24
尼龙弦吉他
88
合成主音8(低音加主音)
25
钢弦吉他
89
合成柔音1(新时代)
26
爵士电吉他
90
合成柔音2(暖音)
27
清音电吉他
91
合成柔音3(复合成)
28
闷音电吉他
92
合成柔音4(合唱)
29
加驱动效果的电吉他
93
合成柔音5(弓弦)
30
加失真效果的电吉他
94
合成柔音6(金属)
31
吉他和音
95
合成柔音7(光环)
32
大贝司(声学贝司)
96
合成柔音8(扫弦)
33
电贝司(指弹)
97
合成特效1(雨)
34
电贝司(拨片)
98
合成特效2(音轨)
35
无品贝司
99
合成特效3(水晶)
36
掌击贝司1
100
合成特效4(大气)
37
掌击贝司2
101
合成特效5(亮音)
38
电子合成贝司1
102
合成特效6(小妖)
39
电子合成贝司2
103
合成特效7(回声)
40
小提琴
104
合成特效8(科幻)
41
中提琴
105
锡塔尔
42
大提琴
106
班卓
43
低音大提琴
107
三味线
44
弦乐群颤音音色
108
筝
45
弦乐群拨弦音色
109
卡林巴
46
竖琴
110
风笛
47
定音鼓
111
古提琴
48
弦乐合奏音色1
112
唢呐
49
弦乐合奏音色2
113
铃铛
50
合成弦乐1
114
拉丁打铃
51
合成弦乐2
115
钢鼓
52
合唱“啊”音
116
木块
53
人声“嘟”音
117
太鼓
54
合成人声
118
嗵鼓
55
乐队打击乐
119
合成鼓
56
小号
120
镲波形反转
57
长号
121
磨弦声
58
大号
122
呼吸声
59
弱音小号
123
海浪声
60
圆号
124
鸟鸣声
61
铜管组
125
电话铃声
62
合成铜管1
126
/
from mido import Message, MidiFile, MidiTrack
# 音符对应字典(F调)
NOTE_MAP = {'_5': 60, '1': 65, '2': 67, '3': 69, '4': 70, '5': 72, '6': 74, '7': 76}
# 定义强弱规律(四四拍:强=90,弱=50,次强=70,最弱=40)
BEAT_VELOCITY = {
1: 50, # 第一拍(弱)
2: 70, # 第二拍(强)
3: 40, # 第三拍(最弱)
4: 90 # 第四拍(次强)
}
# 带节拍位置的旋律(格式:[音符, 时值, 节拍位置],节拍位置从1开始)
MELODY = [
# 两只老虎(四四拍,每小节4拍)
['1', 1, 1], ['2', 1, 2], ['3', 1, 3], ['1', 1, 4], # 第一小节
['1', 1, 1], ['2', 1, 2], ['3', 1, 3], ['1', 1, 4], # 第二小节
['3', 1, 1], ['4', 1, 2], ['5', 2, 3], # 第三小节(5占第3、4拍,节拍位置修正为3)
['3', 1, 1], ['4', 1, 2], ['5', 2, 3], # 第四小节
['5', 0.5, 1], ['6', 0.5, 2], ['5', 0.5, 3], ['4', 0.5, 4], ['3', 1, 1], ['1', 1, 3], # 第五小节
['5', 0.5, 1], ['6', 0.5, 2], ['5', 0.5, 3], ['4', 0.5, 4], ['3', 1, 1], ['1', 1, 3], # 第六小节
['2', 1, 1], ['_5', 1, 2], ['1', 2, 3], # 第七小节
['2', 1, 1], ['_5', 1, 2], ['1', 2, 3], # 第八小节
]
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
# 核心修改:添加小号音色选择(MIDI乐器编号:56 = 小号(Trumpet),编号从0开始)
# 乐器编号参考:0=钢琴, 56=小号, 60=萨克斯, 64=长号
track.append(Message('program_change', program=55, time=0)) # 55是小号的MIDI编号(0-based)
ticks_per_beat = 480
current_time = 0
current_beat = 1 # 记录当前节拍位置(每小节从1开始)
for note_info in MELODY:
note_name, beats, beat_pos = note_info
if note_name == '-':
# 处理延长音
current_time += int(beats * ticks_per_beat)
# 正确更新节拍位置(模4后若为0则等于4)
current_beat = (current_beat + int(beats)) % 4
if current_beat == 0:
current_beat = 4
continue
# 获取对应节拍的音量强度
velocity = BEAT_VELOCITY.get(beat_pos, 64)
note = NOTE_MAP[note_name]
duration = int(beats * ticks_per_beat)
# 发送音符开启/关闭消息(带指定音量)
track.append(Message('note_on', note=note, velocity=velocity, time=current_time))
track.append(Message('note_off', note=note, velocity=velocity, time=duration))
# 修正节拍位置更新逻辑,确保循环正确
current_beat = (beat_pos + int(beats)) % 4
if current_beat == 0:
current_beat = 4
current_time = 0 # 音符间无间隔
mid.save('two_tigers_f调_强弱_小号.mid')
print("已生成带强弱规律的小号音色MIDI文件:two_tigers_f调_强弱_小号.mid")
要素
定义
影响因素
作用
举例
音高
音符的高低
发声体振动频率
构建旋律与和声框架
钢琴从左到右音高渐高
时长
音符发声持续的时间
发声体振动持续时长
时间上的长短比例 形成节奏
全音符、四分音符
音强
音符发声的强弱程度
发声体振动幅度
情感起伏 动态变化
激昂用强音 轻柔 用弱音
音色
音符声音的特色
发声体的材质、结构、发声方式等
赋予声音独特个性
钢琴清脆明亮 二胡悠扬
每个音符 都有自己的四要素
二维列表 还能怎么玩呢?🤔
下次再说 👋
配套视频
本文来自 oeasy Python 系统教程。
想完整、扎实学 Python,
搜索 oeasy 即可。