废话不多说直接上源码:
import time
from pykeyboard.windows import PyKeyboard
k_index = {'1': 'q',
'2': 'w',
'3': 'e',
'4': 'r',
'5': 't',
'6': 'y',
'7': 'u',
'1+': '1',
'2+': '2',
'3+': '3',
'4+': '4',
'5+': '5',
'6+': '6',
'7+': '7',
'1++': 112,
'2++': 113,
'3++': 114,
'4++': 115,
'5++': 116,
'6++': 117,
'7++': 118,
'1-': 'a',
'2-': 's',
'3-': 'd',
'4-': 'f',
'5-': 'g',
'6-': 'h',
'7-': 'j',
'1--': 'z',
'2--': 'x',
'3--': 'c',
'4--': 'v',
'5--': 'b',
'6--': 'n',
'7--': 'm',
'#1': 'i',
'#2': 'o',
'#4': 'p',
'#5': 101,
'#6': 102,
'#1+': '8',
'#2+': '9',
'#4+': '0',
'#5+': 104,
'#6+': 105,
'#1++': 119,
'#2++': 120,
'#4++': 121,
'#5++': 106,
'#6++': 42,
'#1-': 'k',
'#2-': 'l',
'#4-': ';',
'#5-': 98,
'#6-': 99,
'#1--': ',',
'#2--': '.',
'#4--': '/',
'#5--': 96,
'#6--': 110,
'0': '+'
}
yin_xu = {'1': '#1',
'2': '#2',
'3': '4',
'4': '#4',
'5': '#5',
'6': '#6',
'7': '1+',
'1+': '#1+',
'2+': '#2+',
'3+': '4+',
'4+': '#4+',
'5+': '#5+',
'6+': '#6+',
'7+': '1++',
'1++': '#1++',
'2++': '#2++',
'3++': '4++',
'4++': '#4++',
'5++': '#5++',
'6++': '#6++',
'7++': '1+++',
'1-': '#1-',
'2-': '#2-',
'3-': '4-',
'4-': '#4-',
'5-': '#5-',
'6-': '#6-',
'7-': '1',
'1--': '#1--',
'2--': '#2--',
'3--': '4--',
'4--': '#4--',
'5--': '#5--',
'6--': '#6--',
'7--': '1-',
'#1': '2',
'#2': '3',
'#4': '5',
'#5': '6',
'#6': '7',
'#1+': '2+',
'#2+': '3+',
'#4+': '5+',
'#5+': '6+',
'#6+': '7+',
'#1++': '2++',
'#2++': '3++',
'#4++': '5++',
'#5++': '6++',
'#6++': '7++',
'#1-': '2-',
'#2-': '3-',
'#4-': '5-',
'#5-': '6-',
'#6-': '7-',
'#1--': '2--',
'#2--': '3--',
'#4--': '5--',
'#5--': '6--',
'#6--': '7--',
}
yin_xu_ni = dict(zip(yin_xu.values(), yin_xu.keys()))
diao_ci={'Ab':-4,'A':-3,'Bb':-2,'B':-1,'C':0,'Db':1,'D':2,'Eb':3,'E':4,'F':5,'F#':6,'G':7,'Gb':6}
def get_yf(j):
tmp = ''
ts = 0
r = []
j = j.replace(' ', '')
tiaoguo=0
for c in j:
if tiaoguo==0:
if c in '1234567':
if ts:
tmp += c
ts = 0
else:
if tmp != '':
r.append(tmp)
tmp = c
elif c in 'ABCDEFG':
if tmp != '':
r.append(tmp)
tmp=c
elif c in 'abcdefg':
tmp += c
elif c == '=':
if tmp != '':
r.append(tmp)
tmp = j[j.index('='):j.index(')')+1]
tiaoguo=len(tmp)-1
elif c == '#':
if tmp != '':
r.append(tmp)
tmp = c
ts = 1
elif c == '/':
break
else:
tmp += c
else:
tiaoguo-=1
if tmp != '':
r.append(tmp)
return ' '.join(r)
def zhuan_diao(diao,yin,pian_yi):
# global diao_ci,yin_xu
if qiang_zhi_c==0:
if yin in k_index:
if diao in diao_ci and diao!='c':
py_tmp=diao_ci[diao]+pian_yi
if py_tmp>=0:
for i in range(py_tmp):
if yin in yin_xu:
yin=yin_xu[yin]
else:
print('缺音序:',yin)
else:
for i in range(abs(py_tmp)):
if yin in yin_xu:
yin=yin_xu_ni[yin]
else:
print('缺音序:',yin)
return yin
def xian_b(t_tmp, max_t, sv, ev):
if sv == ev:
return sv
if t_tmp >= max_t:
return ev
return sv + (ev - sv) / max_t * t_tmp
def yan_zou(path, play_start=0,max_play=1000000, jg=1, e_wai_bei_su=1,diao_pian_yi=0):
time.sleep(5) # 等待5秒后开始执行
with open(path) as f:
pu = f.read().split('\n')
print('乐谱加载完成...')
ge_qu = {}
for i in range(len(pu)):
pu[i] = get_yf(pu[i])
print('乐谱整理完成...')
# print(pu)
for p in range(len(pu)):
if pu[p] != '':
ge_qu[p] = pu[p].split(' ')
print('乐谱准备就绪!')
# jg = eval(pu[0])
da_diao='C'
k = PyKeyboard()
print('开始演奏!')
for i in range(play_start, len(pu)):
if i in ge_qu:
print(i, ge_qu[i])
an_jian_huan_cun=[]
shi_ji_yin=[]
for c in ge_qu[i]:
zhen_c=zhuan_diao(da_diao,c,diao_pian_yi)
if zhen_c in k_index:
an_jian_huan_cun.append(k_index[zhen_c])
shi_ji_yin.append(zhen_c)
elif c in diao_ci:
da_diao=c
print('设定大调:', c)
elif c[0] == '=':
jg = eval(c[1:])
print('设定速度:', jg)
else:
print(i, c)
k.press_keys(an_jian_huan_cun)
print('音:',shi_ji_yin)
time.sleep(jg * e_wai_bei_su)
if i>=max_play:
break
qiang_zhi_c=0
yan_zou('远空.txt') # A+
使用前需要安装windows下的键盘事件模块“PyKeyboard”。
可能是“pip install PyKeyboard”安装,有点记不清了,知道的朋友可以评论里反馈一下。
谱子的话我讲解一下吧:
1、速度:
=1/(简谱上的速度符号/(拍子分子*拍子分母))
假设远空简谱上标识的速度是96,拍子是3/4拍,那么谱子文件的定义就是:
=1/(96/12)
原理是计算出每个拍子的间隔,程序好停顿相应长的时间…
2、大调(不是专业人士,可能并不这么称呼……无所谓啦)
“大调”其实就是将音高区间的基准进行一个偏移。
这个看着谱子上的来就行,谱子上是多少,就填多少,比如《远空》是D大调,那谱子就是:D
3、音高
中文吧的钢琴按键只能从7–到7++。没错,在C大调的基准下,我把正常的音高命为:1234567,高音一个点:1+2+3+4+5+6+7+,高两个点:1++2++3++4++……以此类推,低音就是1-2-3-4-……以此类推。#4、#4+、#4–类似的。
4、谱子
一个正常的谱子,至少有三个基石组成:
速度、大调、音高
有了这三个,就差骨架时间序列了。
谱子文件里,每一行是一个单位时间间隔后弹出的音符。和弦可以排在同一行。一行里也可以有新的速度和新的大调
5、其它乐理知识
就只有靠大伙百度了。这里哈里分享一首钢琴曲翻译后的谱子。如需更多谱子……可以自写或私信或评论联系哈里试试……哈里正在试着搭建自己的个人博客,可能会放上去哈哈。
6、注释
”/“符后面的同行内容程序会自动忽略
废话不多说,《远空》:(乐理知识有限,有翻译不到位的地方……也没办法)
文件名(请和Py脚本放在同一目录):远空.txt
D=1/(96/12)
3+1+64-
6+
/6+4-
5+3+1+3-
2+
/2+3-
3+1+64-
6+
1++
/1++4-
5++
/5++
7+5+3+3-
1++
7+
5+/3-
2+
3+/3-
5+
/5+
6
5
6314-
3+
7523-
1+
7
5
6412-
7
1+
2+
5+71-
6+
5+
6314--
3+
5+2+53--
7
5
632--
6-
#42
#537-
3+
7
644--
1-
4-
1
3+
753--
7--
3-
1+5-
75-
5
6432--
6--
2-
76-
1+6-
2+
5+71--
6+1-
5+3-
5-
7-5-
644--
1-
4-
1
3+1
5+2+53--
7--
73-
5-
57-
6326--
3-
6-
5
7
66--
3-
6-
#1
/6#1//p2s
3+
5+
6+4-
1
631
5+
6+
5+3-
2
527-
2+
3+5-
2
5+2+76
7/2
1+6-
3
531
1+
2+
3+2-
6-
641
3+
2+
3+
2+3-
7-
527-
1+
2+
3+4-
1
4+3
6
5+3
1
#5+3+
7-
6+3
#5
7+6+3+7
6+4-
1
631
5+
6+
5+3-
2
527-
2+
3+4-
1
5+3
5
7+3
1++6-
3
2++531
3++
3++2-
6-
1
2
2++4
1++
7+3-
7-
2
5
5+3
7+
1++4-
1
3
6
7+3
6+
#5+3-
7-
6+2
#5
7+#6-
3++4-
1
631
2++3
1++
7+3-
7-
5+2
5
3+3
6+6--
3-
6-
5
3
1
6-
/6-
414-
6
1+
27-3-
7
2+
36-3-
1+
3+
/3+36-3-////////p3s
3++4-
6+
1++
6+
1++
6+
1++/4-
6+
2++
6+
1++
6+
3++3-
6+
1++
6+
1++
6+
1++/3-
6+
2++
6+
1++
6+
3++4-
6+
1++
6+
1++
6+
1++/4-
6+
2++
6+
1++
6+
3++3-
6+
1++
6+
1++/3-
6+
2++/3-
6+
5++
6+
2++
6+
3++314-
6+
1++
6+
1++
6+
1++/314-
6+
2++
6+
1++
6+
3++26-3-
6+
1++
6+
1++
6+
1++/26-3-
6+
2++
6+
1++
6+
3++314-
6+
1++
6+
1++
6+
1++/314-
6+
2++
6+
1++
6+
3++26-3-
6+
1++
6+
1++
6+
2++/26-3-
6+
5++
6+
2++
6+
6+4
6
1+
6
3++1+
6
7+3
5
7
1++6
7+7
5+5
6+4
6
1+
7+6
1++1+
2++6
5++3
6++5
5++3
5
7
5
6+4
6
1+
6
3++1+
6
5++3
5
7+7
5
5+7
5
6+4
6
1+
6
1+
6
1+
6
3++
2+
6
7+
1+
6
6+4////p4s
6
1+
6
3++1+
6
7+3
5
7
1++5
7+7
5+5
6+4
6
1+
7+6
1++1+
2++6
5++3
6++5
5++3
5
7
5
6+4
6
1+
6
3++1+
6
5++3
5
7+7
5
5+7
5
6+4
6
1+
5+6
7+1+
6
6+1+
6
2+
6
1+
6
6416-
3+1+6
5+3+1+
3++1++5+4-
6
1
3
5++3++1++6-
1
3
6
1+++5++3++1
3
6
1+
6+
3+
1+
6
3+3
5+5
6+4+1+64--
1-
3-
6-
5+53-
6+61-
5+3+753--
7--
3-
5-
2+53-
7--
3+755--
2-
5+755-
7-
755-
2-
1+631-
3-
5-
7-
1+5-
2+3-
3+1+62--
6--
1-
3+4-
2+1-
3+6--
2+753--
7--
3-
5-
1+3-
2+7--
3+1+64--
1-
4+63-
6-
5+63-
1-
#5+3+73--
7--
6+2+73-
#5-
7+5+3+77-
6+4+1+4--
1-
3-
6-
5+3-
6+1-
5+2+73--
7--
3-
5-
2+753-
7--
3+755--
2-
5+755-
6-
7+3+75-
2-
1++6+3+6--
2-
2++6+3+5-
7-
3++6+3+5-
3-
3++6+4+2--
6--
1-
3++4+4-
2++1-
1++6--
7+5+3+3--
7--
3-
5-
5+3+3-
7+7--
1++6+4+4--
1-
3-
2++4+6-
7+3-
6+1-
#5+3+3--
7--
6+3+3-
#5-
7+5+3+7-
3++6+4+4--
1-
3-
3++4+6-
2++7-
1++1
7+2+3--
7--
5+73-
5-
3+77-
6+3+1+6--
3-
6-
7-
1
2
3/////////p5s
5
6
7
1+
2+
6314-
7527-3-
16-3-
1+++1++
7++7+
5++5+
3++3+
2++2+
1++1+
/1++1+
3++6+1+4
3++
2++
3++
5++5+73
7+
5+
3++6+1+4
3++
2++
6++
7++2+3
1+++
7++
5++
2++
3++6+1+4
2++
1++
7+73
/7+
5+
7-3-/5+
3+
/3+7-3-
=1/(96/6)
76-
#1+
3+
6+
/6+
/6+
/6+6-
/6+6-
以上~