3 Star 3 Fork 3

bgArrayOrganization / audio_scoreTransFotmat

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
midPack.py 6.66 KB
一键复制 编辑 原始数据 按行查看 历史
bgArray 提交于 2022-07-17 17:50 . 先存个档,正在大更新
import mido
import objectStateConstants
import numpy
# import ASTF_class
debug = objectStateConstants.ObjectStateConstant() # 项目数据加载
def loadMid(InMid, IN_ASTF):
midi = mido.MidiFile(InMid)
midiBPM_ergodic_algorithm(midi)
tracks = []
tempo = 0
for i, track in enumerate(midi.tracks):
ticks = 0 # 绝对tick数
instrumentID = -1
singleTrack = []
for msg in track:
debug.dp(msg)
ticks += msg.time
MC_tick = round_up(ticks * tempo) / (midi.ticks_per_beat * 50000)
# 这个时间算法由Dislink Sforza提供
# 原代码归属于musicreater的pkgver包
if msg.is_meta:
if msg.type == "copyright":
IN_ASTF.detailInformation["information"]["scoreMetaMessage"]["copyright"] = msg.text
IN_ASTF.detailInformation["information"]["midMetaMessage"]["midiCopyright"] = msg.text
if msg.type == 'set_tempo':
tempo = msg.tempo
bpm_by_MetaMessage_Set_tempo(tempo)
if msg.type == "time_signature":
pass
if msg.type == "key_signature":
key = [msg.key, msg.time]
if msg.type == "end_of_track":
pass
else:
if msg.type == 'program_change':
instrumentID = msg.program
if msg.type == 'note_on' and msg.velocity != 0:
pass
if msg.type == "note_off":
pass
singleTrack.append(msg)
if instrumentID == -1:
trackInfo = {"MidiControlTrack": singleTrack}
else:
trackInfo = {"MidiNotesTrack": singleTrack}
tracks.append(trackInfo)
def mt2gt(mt, tpb_a, bpm_a):
return round(mt / tpb_a / bpm_a * 60)
def midiBPM_ergodic_algorithm(mid: mido.MidiFile):
"""
一个测试mid bpm 的函数,采用遍历获取,在正常每小节都有音符的mid中效果较好,仅供参考。
A function that's used to test and get midi's bpm.
Using traversal acquisition, the effect is better in the mid with notes in each normal section,
which is for reference only.
:param mid: 一个mido的mid文件类
A class of mido.MidiFile
:return: bpm
This algorithm is made by ©bgArray.
算法版权归©诸葛亮与八卦阵所有。
"""
long = mid.length
tpb = mid.ticks_per_beat
bpm = 20
gotV = 0
for track in mid.tracks:
global_time = 0
for msg in track:
global_time += msg.time
if msg.type == "note_on" and msg.velocity > 0:
gotV = mt2gt(global_time, tpb, bpm)
errorV = numpy.fabs(gotV - long)
last_dic = {bpm: errorV}
if last_dic.get(bpm) > errorV:
last_dic = {bpm: errorV}
bpm += 2
while True:
for track in mid.tracks:
global_time = 0
for msg in track:
global_time += msg.time
if msg.type == "note_on" and msg.velocity > 0:
gotV = mt2gt(global_time, tpb, bpm)
errorV = numpy.fabs(gotV - long)
try:
if last_dic.get(bpm - 2) > errorV:
last_dic = {bpm: errorV}
except TypeError:
pass
bpm += 2
if bpm >= 252:
break
debug.dp(list(last_dic.keys())[0])
return list(last_dic.keys())[0]
def bpm_by_MetaMessage_Set_tempo(tmp: int):
"""
midi文件tempo事件bpm算法。
A function that's used to compute the bpm of a midiFile,
which algorithm is made up of midiFile's tempo meta message.
:param tmp:输入mid的metaMessage中速度tempo值
input the tempo value which is in the tempo meta message.
:return:bpm
This algorithm is made by ©bgArray.
算法版权归©诸葛亮与八卦阵所有。
"""
second = tmp / 1000000
bpm = delete_extra_zero(60 / second)
debug.dp(bpm)
return bpm
def delete_extra_zero(n: float):
"""
————————————————
版权声明:本文为CSDN博主「XerCis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lly1122334/article/details/108770141
删除小数点后多余的0
"""
n = '{:g}'.format(n)
n = float(n) if '.' in n else int(n) # 含小数点转float否则int
return n
# 四舍五入
def round_up(num, power=0):
"""
实现精确四舍五入,包含正、负小数多种场景
原文链接:https://blog.csdn.net/wcl1800/article/details/115229069
:param num: 需要四舍五入的小数
:param power: 四舍五入位数,支持0-∞
:return: 返回四舍五入后的结果
"""
try:
print(1 / 0)
except ZeroDivisionError:
digit = 10 ** power
num2 = float(int(num * digit))
# 处理正数,power不为0的情况
if num >= 0 and power != 0:
tag = num * digit - num2 + 1 / (digit * 10)
if tag >= 0.5:
return (num2 + 1) / digit
else:
return num2 / digit
# 处理正数,power为0取整的情况
elif num >= 0 and power == 0:
tag = num * digit - int(num)
if tag >= 0.5:
return (num2 + 1) / digit
else:
return num2 / digit
# 处理负数,power为0取整的情况
elif power == 0 and num < 0:
tag = num * digit - int(num)
if tag <= -0.5:
return (num2 - 1) / digit
else:
return num2 / digit
# 处理负数,power不为0的情况
else:
tag = num * digit - num2 - 1 / (digit * 10)
if tag <= -0.5:
return (num2 - 1) / digit
else:
return num2 / digit
# ---------------
# 尘封的往事
# if __name__ == '__main__':
# loadMid(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\同道殊途.mid")
# def compute(mid: mido.MidiFile):
# answer = 60000000 / mid.ticks_per_beat
# print(answer)
# return answer
# try:
# # print(tempo)
# # print((ticks * tempo))
# # print(((midi.ticks_per_beat * float(tempo)) * 50000))
# mcTick = round(
# (ticks * tempo) / (midi.ticks_per_beat * 50000) # * float(tempo)
# )
# print(mcTick)
# except ZeroDivisionError:
# mcTick = 0
# print(mcTick)
Python
1
https://gitee.com/bg-array-organization/audio_score-trans-fotmat.git
git@gitee.com:bg-array-organization/audio_score-trans-fotmat.git
bg-array-organization
audio_score-trans-fotmat
audio_scoreTransFotmat
master

搜索帮助