python编写的midi制作软件
更新时间:2024-01-25 13:56:01 阅读量: 教育文库 文档下载
- python midi推荐度:
- 相关推荐
用Python编写的Mid音频制作软件
源代码如下:
#Midi.py:
#This file can be used to simply turn MidiTxt file to Mid file. #Author:loupen #Date:2010-7-20
#If you want to use it, you must write the MidiTxt file by some rules. #Read the document to learn more.
from struct import * #Three global variables TrackBegin=[] TrackEnd=[] ToneFore=1
#write the MidiHeader def MidiHeader(buffer):
buffer.write(pack('ccccBBBB','M','T','h','d',0,0,0,6)) def msg(buffer,tracks,deltatime): if deltatime>0xff:
buffer.write(pack('BBBBBB',0,1,0,tracks,deltatime>>8,deltatime&0xff)) else:
buffer.write(pack('BBBBBB',0,1,0,tracks,0,deltatime))
return buffer.tell()-3
#write the header and tail of tracks def TrackHeader(buffer,list):
buffer.write(pack('cccc','M','T','r','k')) list.append(buffer.tell()) buffer.write(pack('i',0))
def TrackTail(buffer,list):
buffer.write(pack('BBBB',0,0xff,0x2f,0)) list.append(buffer.tell())
#Set the pulse , instrument and controller def SetSpeed(buffer,time): time=60.0/int(time) time=int(time*(10**6))
buffer.write(pack('BBBBBBB',0,0xff,0x51,3,time>>16,(time&0xff00)>>8,time&0xff)) return 1
#The words , FenZi and FenMu , are from Chinese . ~O~
def SetPulse(buffer,FenZi,FenMu):
QQ: 750825502 E-mail: loupen@yeah.net
FenZi=int(FenZi) FenMu=int(FenMu) if FenMu==2: FenMu=1 elif FenMu==4: FenMu=2 elif FenMu==8: FenMu=3 else: return 0
buffer.write(pack('BBBBBBBB',0,0xff,0x58,4,int(FenZi),int(FenMu),0x18,0x08)) return 1
def SetTone(buffer):
buffer.write(pack('BBBBBB',0,0xff,0x59,2,0,0)) return 1
def SetNumOrder(buffer,time):
buffer.write(pack('BBBB',time>>24,(time&0xff0000)>>16,(time&0xff00)>>8,time&0xff))
def SetTrackNum(buffer,ad,n): buffer.seek(ad)
buffer.write(pack('B',n+1))
def SetInstrument(buffer,trackNum,ITNum): trackNum=int(trackNum) trackNum+=0xc0
buffer.write(pack('BBB',0,trackNum,ITNum))
def SetController(buffer,trackNum,CtrNum): trackNum=int(trackNum) trackNum+=0xb0
buffer.write(pack('BBBB',0,trackNum,11,CtrNum)) buffer.write(pack('BBB',0,0xa,0x40))
def SetVolume(buffer,trackNum,S): trackNum=int(trackNum) trackNum+=0xb0 if S=='H':
buffer.write(pack('BBBB',0,trackNum,7,0x7f)) buffer.write(pack('BBB',0,0xa,0x40)) if S=='L':
buffer.write(pack('BBBB',0,trackNum,7,80)) buffer.write(pack('BBB',0,0xa,0x40))
QQ: 750825502 E-mail: loupen@yeah.net
def SetChanYin(buffer,trackNum): trackNum=int(trackNum) trackNum+=0xb0
buffer.write(pack('BBBB',0,trackNum,1,127))
#imitate the function of buffer in C
def readNext(buffer): while True:
a=buffer.read(1) if a in [' ','\\n']: pass else: return a
#def seekFore(buffer,offset):
# buffer.seek(buffer.tell()-offset)
#Use the following two functions to deal with the events
def liftup(buffer,time,note): time=int(time) if time>=128:
buffer.write(pack('BBBB',0x80|(time>>7),0x7f&time,note,0)) else:
buffer.write(pack('BBB',time,note,0))
def pressdown(buffer,num,dict,mark,note,force): global ToneFore
a=dict[note]+(5+mark)*12 if ToneFore==1: num+=0x90
buffer.write(pack('BBBB',0,num,a,force)) else:
buffer.write(pack('BBB',0,a,force)) ToneFore=a
def main(lp):
track=1;deltatime=120 speed='';temp=0
begin=0;mark=0;time=deltatime
TrackNum=[0,1,2,3];ITNum=lp;CtrNum=0x7f dict={'0':0,'1':0,'2':2,'3':4,'4':5,'5':7,'6':9,'7':11} pTxt=open(r'.\\1.txt') s=\
QQ: 750825502 E-mail: loupen@yeah.net
pMid=open(s,'wb')
if pTxt.read(6)!=\
print \ pMid.close() pTxt.close() return 0 while True:
if pTxt.read(1)=='|':
FenMu=pTxt.read(1) pTxt.seek(pTxt.tell()-3) FenZi=pTxt.read(1) n=0
while n<8:
if readNext(pTxt)=='<':break n+=1 if n==8:
print \ pMid.close() pTxt.close() return 0 break n=0
a=readNext(pTxt) while a!='>': speed+=a
a=readNext(pTxt) MidiHeader(pMid)
track=msg(pMid,0,deltatime) TrackHeader(pMid,TrackBegin) SetPulse(pMid,FenZi,FenMu) SetTone(pMid)
SetSpeed(pMid,speed) TrackTail(pMid,TrackEnd) pMid.seek(TrackBegin[0])
SetNumOrder(pMid,TrackEnd[0]-TrackBegin[0]-4) pMid.seek(TrackEnd[0]) a=readNext(pTxt) while a=='[':
pTxt.readline()
TrackHeader(pMid,TrackBegin)
SetInstrument(pMid,TrackNum[n],ITNum[n]) SetController(pMid,TrackNum[n],CtrNum) a=readNext(pTxt) n+=1
QQ: 750825502 E-mail: loupen@yeah.net
while True: if a=='|':
a=readNext(pTxt) if a=='|':
a=readNext(pTxt) if a in ['[','']:
global ToneFore ToneFore=-1;break elif a=='\\'': mark+=1
a=readNext(pTxt) elif a=='.':
if begin==0: mark-=1 elif begin==1: time*=3.0/2
liftup(pMid,time,ToneFore) begin=0 elif begin==2:
a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ time*=3.0/2 time+=temp
liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0 else:continue a=readNext(pTxt) elif a=='Y':
time=deltatime/2 a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ if begin==2:time+=temp liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0
a=readNext(pTxt) elif a=='E':
time=deltatime/4 a=pTxt.read(1) if a in [' ','|']:
QQ: 750825502 E-mail: loupen@yeah.net
if a=='|':
print \ if begin==2:time+=temp liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0
a=readNext(pTxt) elif a=='S':
time=deltatime/8 a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ if begin==2:time+=temp liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0
a=readNext(pTxt) elif '7'>=a>='0': if begin==0:
if a=='0': force=0 else: force=100
pressdown(pMid,TrackNum[n-1],dict,mark,a,force) time=deltatime mark=0;begin=1 a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ liftup(pMid,time,ToneFore) begin=0
a=readNext(pTxt) elif begin==2:
time=deltatime a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ time+=temp
liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0
a=readNext(pTxt) elif a=='^':
QQ: 750825502 E-mail: loupen@yeah.net
begin=2 temp+=time
a=readNext(pTxt) elif a=='-':
a=pTxt.read(1) if a in [' ','|']: if a=='|':
print \ time+=temp
liftup(pMid,time,ToneFore) begin=0;temp=0 mark=0
a=readNext(pTxt) elif a=='*':
SetVolume(pMid,TrackNum[n-1],'H') ToneFore=1
a=readNext(pTxt) elif a==',':
SetVolume(pMid,TrackNum[n-1],'L') ToneFore=1
a=readNext(pTxt) elif a=='W':
SetChanYin(pMid,TrackNum[n-1]) ToneFore=1
a=readNext(pTxt) else:
print \ pMid.close() pTxt.close() return 0
TrackTail(pMid,TrackEnd) pMid.seek(TrackBegin[n])
SetNumOrder(pMid,TrackEnd[n]-TrackBegin[n]-4) pMid.seek(TrackEnd[n]) SetTrackNum(pMid,track,n) pMid.close() pTxt.close()
print \以上文件存为midi.py。 #test.py: import midi i=1 z=[]
QQ: 750825502 E-mail: loupen@yeah.net
j=int(input(\while i<=j:
tmp=input(\ z.append(int(tmp)) i+=1 midi.main(z)
以上文件存为test.py。 以下为mid文本范例【赛马】:
<2|4> <120> [1]
|| 6. 3E 5E | 6. 3E 5E | 6. 3E 5E | 6. 3E 5E | 6E 5E 3E 5E 6E 5E 3E 5E | 6E 5E 3E 5E 6E 5E 3E 5E | 6Y 5E 6E 6Y 5E 6E |
6Y 5E 6E 6Y 5E 6E | .6Y 3Y 1Y .6Y | 3Y 6Y 5Y 3Y | 2E 3E 2E 1E 2E 3E 2E 1E | 2E 3E 2E 1E 2E 3E 2E 1E | .6Y 3Y 1Y .6Y | 3Y 6Y 5Y 3Y |
2E 3E 2E 1E 2E 3E 2E 1E | 2E 3E 2E 1E 2E 3E 2E 1E | 2. .6E 1E | 2. .6E 1E | 2. .6E 1E | 2. .6E 1E | 2E 3E 2E 1E 2E 3E 2E 1E |
2E 3E 2E 1E 2E 3E 2E 1E | 2Y 1E 2E 2Y 1E 2E | 2Y 1E 2E 2Y 1E 2E | .6 6 | 5 3 | 2 5 | 3 1 | .6 6 | 5 3 | 2 5 | 3 1 | .6. 1E 2E | .6. 1E 2E | .6. 1E 2E | .6. 1E 2E | .6E 2E 1E 2E .6E 2E 1E 2E | .6E 2E 1E 2E .6E 2E 1E 2E |
.6 .6Y .6Y | .6^ .6 | 3 6Y. '1E | 5. 3Y | 5Y 6Y '1Y. '3E | 6^ 6 | 3 6Y. '1E | 5 5Y 3Y | 2Y 3Y 6Y 5Y | 3^ 3 | 5 6Y. '1E |
1. .6Y | 2Y 3Y 6Y 5Y | 3 3Y 2Y | 1Y. 2E 3Y 5Y | 6 .6 | 2Y 3Y 1Y. 3E | .6^ .6 | 3Y 3E 3E 6Y '1Y | 5Y 5E 5E 5Y 3Y |
5Y 5E 6E '1Y '2E '1E | 6Y 6E 6E 6Y .6Y | 3Y 3E 3E 6Y '1Y | 5Y 5E 5E 5Y 3Y | 2Y 2E 3E 6Y 5Y | 3Y 3E 5E 3Y .6Y | 5Y 5E 5E 6Y '1Y |
1Y 1E 1E 1Y .6Y | 2Y 2E 3E 6Y 5Y | 3Y 3E 5E 3Y 2Y | 1E .6E 1E 2E 3E 2E 3E 5E | 6E 5E 6E '1E 5E 6E 5E 3E | 2E 3E 2E 1E 2E 1E .6E 1E | .6 6 |
0Y .6Y 1Y 3Y | 0Y .6Y 1Y 3Y | 0Y 2Y .7Y 2Y | .6Y 3Y 1Y 3Y | 0Y .6Y 1Y 3Y | 0Y .6Y 1Y 3Y | 0Y 2Y .7Y 2Y | .6Y 3Y 1Y 3Y | 0Y .6Y 1Y 3Y |
0Y .6Y 1Y 3Y | 0Y 2Y .7Y 2Y | .6Y 3Y 1Y 3Y | 0Y 5Y 3Y 2Y | 1Y 2Y 1Y .6 | 2Y 2Y 3Y 1Y | .6. 3E 5E | .6. 3E 5E | .6. 3E 5E |
.6. 3E 5E | .6. 1E 2E | 3E 2E 3E 5E 6E '1E 6E 5E | 3E 2E 3E 5E 6E '1E 6E 5E | 3E 5E 3E 2E 1Y 3Y | .6. 1E 2E | 3E 2E 3E 5E 6E '1E 6E 5E | 3E 2E 3E 5E 6E '1E 6E 5E |
3E 5E 3E 2E 1Y 3Y | .6. 3E 6E | '1Y 6Y 6Y '3Y | '1Y 6Y 6Y 3Y | '1Y 6Y 6Y '3Y | '1Y 6Y 6Y 3Y | 1Y .6E 1E 2Y 1E 2E | 3Y 2E 3E 5Y 3E 5E |
5Y 3E 5E 6Y 5E 6E | '1Y 6E '1E '2Y '1E '2E | '3E '2E '1E '2E '3E '2E '1E '2E | '3E '2E '1E '2E '3E '2E '1E '2E | '3E '2E '1E '2E '3E '2E '1E '2E | '3E '2E '1E '2E '3E '2E '3E '5E | '6^ '6^ | '6^ '6^ | '6^ '6 | '6 0 | 6 6 | .6^ .6 ||
上述文件存为1.txt,和midi.py , test.py放在同一个文件夹下,运行test.py Tracks为文本中[]的个数,instrument为乐器号取值范围为0-127. 注:后附mid文本编辑规范。
QQ: 750825502 E-mail: loupen@yeah.net
附录
Midi文本需按以下格式书写。
////////////////////////////////////////////////////////////////////////////////////////////////////// ||1. ''2. ..3. 4^ -^ - #5 b6 7Y. ''1Y^ -^ -||
#1。'表示升高一个八度。[''1]表示比1高两个八度。
#2。.在音符前表示降低一个八度。如[..6]表示比6低两个八度。 #3。.在音符后表示付点音符。如[6.] #4。Y表示8分音符,即“一条横线”。如[6Y] #5。E表示16分音符,即“二条横线”。如[6E] #6。S表示32分音符,即“三条横线”。如[6S] #7。#表示升高半音 #8。b表示降低半音
#9。-表示延长一个四分音符。如[6^ -]
#10。^表示两个相同的音相连。如6 -表示为6^ - 注:
1。对于表示升降的符号['],[.]后需紧接音符。 2。附点音符[.],[^]需紧接在音符之后。 [^]前后两个音必须相同,即[6^ 6]或[6^ -] 3。[Y],[E],[S]需紧接在音符之后。 4。空格的作用非常重要,慎用。 音符后接空格表示此音符已结束。
5。其他功能,像控制器之类,还有待完善!对于升降音因为很少用就忽略了。编辑后的文本需以1.txt命名。
本人刚学python不足之处请高手指教。本文代码在wm5 sp手机上编辑和测试。
QQ: 750825502 E-mail: loupen@yeah.net
正在阅读:
python编写的midi制作软件01-25
教学指导和习题答案03-01
艺术作文之艺术特色学校汇报材料03-02
物业服务经典总结04-07
浅析污水处理风机的选型与能耗的关系03-20
2022人教版选修《语言文字应用》练习题淡妆浓抹总相宜 语言的色04-19
中国机制木炭行业市场调查研究报告(目录) - 图文12-19
大学生课余生活调查报告06-03
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 制作软件
- 编写
- python
- midi