From 5ffb654ec9c3a13179d2bf448326174590646e04 Mon Sep 17 00:00:00 2001 From: EillesWan Date: Sun, 12 Feb 2023 17:34:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmethod3=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E9=95=BFbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Musicreater/__init__.py | 2 +- Musicreater/main.py | 45 +++++++----- example.py | 153 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 19 deletions(-) create mode 100644 example.py diff --git a/Musicreater/__init__.py b/Musicreater/__init__.py index 312d178..6473b31 100644 --- a/Musicreater/__init__.py +++ b/Musicreater/__init__.py @@ -19,7 +19,7 @@ Terms & Conditions: ../License.md from .main import * -__version__ = "0.3.1" +__version__ = "0.3.2" __all__ = [] __author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray")) diff --git a/Musicreater/main.py b/Musicreater/main.py index 0dc3653..6fc6d40 100644 --- a/Musicreater/main.py +++ b/Musicreater/main.py @@ -510,21 +510,7 @@ class midiConvert: # 我们来用通道统计音乐信息 for msg in self.midi: - # try: microseconds += msg.time * 1000 # 任何人都tm不要动这里,这里循环方式不是track,所以,这里的计时方式不一样 - # print(microseconds) - # except NameError: - # if self.debugMode: - # raise NotDefineTempoError("计算当前分数时出错 未定义参量 Tempo") - # else: - # microseconds += ( - # msg.time * 1000 # 任何人都tm不要动这里,这里循环方式不是track,所以,这里的计时方式不一样 - # ) - - # if msg.is_meta: - # if msg.type == "set_tempo": - # tempo = msg.tempo - # else: if not msg.is_meta: if self.debugMode: try: @@ -649,13 +635,13 @@ class midiConvert: if msg.time != 0: try: - microseconds += msg.time * tempo / self.midi.ticks_per_beat + microseconds += msg.time * tempo / self.midi.ticks_per_beat / 1000 # print(microseconds) except NameError: if self.debugMode: raise NotDefineTempoError("计算当前分数时出错 未定义参量 Tempo") else: - microseconds += (msg.time * mido.midifiles.midifiles.DEFAULT_TEMPO / self.midi.ticks_per_beat) + microseconds += (msg.time * mido.midifiles.midifiles.DEFAULT_TEMPO / self.midi.ticks_per_beat) / 1000 if msg.is_meta: if msg.type == "set_tempo": @@ -1212,13 +1198,13 @@ class midiConvert: if msg.time != 0: try: - microseconds += msg.time * tempo / self.midi.ticks_per_beat + microseconds += msg.time * tempo / self.midi.ticks_per_beat / 1000 # print(microseconds) except NameError: if self.debugMode: raise NotDefineTempoError("计算当前分数时出错 未定义参量 Tempo") else: - microseconds += (msg.time * mido.midifiles.midifiles.DEFAULT_TEMPO / self.midi.ticks_per_beat) + microseconds += (msg.time * mido.midifiles.midifiles.DEFAULT_TEMPO / self.midi.ticks_per_beat) / 1000 if msg.is_meta: if msg.type == "set_tempo": @@ -1464,6 +1450,29 @@ class midiConvert: return True, maxlen, maxscore + def to_mcstructure_file_with_delay( + self, + method: int = 1, + volume: float = 1.0, + speed: float = 1.0, + progressbar: Union[bool, tuple] = False, + player: str = "@a", + author: str = "Eilles", + max_height: int = 64, + ): + """ + 使用method指定的转换算法,将midi转换为BDX结构文件 + :param method: 转换算法 + :param author: 作者名称 + :param progressbar: 进度条,(当此参数为True时使用默认进度条,为其他的值为真的参数时识别为进度条自定义参数,为其他值为假的时候不生成进度条) + :param max_height: 生成结构最大高度 + :param volume: 音量,注意:这里的音量范围为(0,1],如果超出将被处理为正确值,其原理为在距离玩家 (1 / volume -1) 的地方播放音频 + :param speed: 速度,注意:这里的速度指的是播放倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed + :param player: 玩家选择器,默认为`@a` + :return 成功与否,成功返回(True,未经过压缩的源,结构占用大小),失败返回(False,str失败原因) + """ + pass + def to_BDX_file( self, method: int = 1, diff --git a/example.py b/example.py new file mode 100644 index 0000000..dd634b9 --- /dev/null +++ b/example.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- + +# 伶伦 开发交流群 861684859 + + +""" +音·创 (Musicreater) 演示程序 +是一款免费开源的针对《我的世界》的midi音乐转换库 +Musicreater (音·创) +A free open source library used for convert midi file into formats that is suitable for **Minecraft**. + +版权所有 © 2023 音·创 开发者 +Copyright © 2023 all the developers of Musicreater + +开源相关声明请见 ./License.md +Terms & Conditions: ./License.md +""" + +import os +import Musicreater + + + + +# 获取midi列表 +midi_path = input(f"请输入MIDI路径:") + + +# 获取输出地址 +out_path = input(f"请输入输出路径:") + +conversion = Musicreater.midiConvert() + + +def isMethodOK(sth: str): + if int(sth) in range(1, len(conversion.methods) + 1): + return int(sth) + else: + raise ValueError + + +convert_method = int(input(f"请输入转换算法[1~{len(conversion.methods)}]:")) + +# 选择输出格式 +fileFormat = int(input(f"请输入输出格式[BDX(1) 或 MCPACK(0)]:").lower()) +playerFormat = int(input(f"请选择播放方式[计分板(1) 或 延迟(0)]:").lower()) + + + + + +# 真假字符串判断 +def bool_str(sth: str) -> bool: + try: + return bool(float(sth)) + except ValueError: + if str(sth).lower() == "true": + return True + elif str(sth).lower() == "false": + return False + else: + raise ValueError("布尔字符串啊?") + +debug = False + +if os.path.exists("./demo_config.json"): + import json + + prompts = json.load(open("./demo_config.json", "r", encoding="utf-8")) + if prompts[-1] == "debug": + debug = True + prompts = prompts[:-1] +else: + prompts = [] + # 提示语 检测函数 错误提示语 + for args in [ + ( + f'输入音量:', + float, + ), + ( + f'输入播放速度:', + float, + ), + ( + f'是否启用进度条:', + bool_str, + ), + ( + f'计分板名称:', + str, + ) + if playerFormat == 1 + else ( + f'玩家选择器:', + str, + ), + ( + f'是否自动重置计分板:', + bool_str, + ) + if playerFormat == 1 + else (), + ( + f'作者名称:', + str, + ) + if fileFormat == 1 + else (), + ( + f'最大结构高度:', + int, + ) + if fileFormat == 1 + else (), + ]: + if args: + prompts.append(args[1](input(args[0]))) + +conversion = Musicreater.midiConvert(debug) + + +print(f"正在处理 {midi_path} :") +conversion.convert(midi_path, out_path) +if debug: + with open("./records.json", "a", encoding="utf-8") as f: + json.dump(conversion.toDICT(), f) + f.write(5 * "\n") +conversion_result = ( + conversion.to_mcpack(convert_method, *prompts) + if fileFormat == 0 + else ( + conversion.to_BDX_file(convert_method, *prompts) + if playerFormat == 1 + else conversion.to_BDX_file_with_delay(convert_method, *prompts) + ) +) + +if conversion_result[0]: + print( + f" 指令总长:{conversion_result[1]},最高延迟:{conversion_result[2]}{f''',结构大小{conversion_result[3]},最末坐标{conversion_result[4]}''' if fileFormat == 1 else ''}" + ) +else: + print(f"失败:{conversion_result}") + +exitSth = input("回车退出").lower() +if exitSth == "record": + import json + + with open("./demo_config.json", "w", encoding="utf-8") as f: + json.dump(prompts, f) +elif exitSth == "delrec": + os.remove("./demo_config.json")