diff --git a/demo_convert.py b/demo_convert.py index 02cc805..b41d3b5 100644 --- a/demo_convert.py +++ b/demo_convert.py @@ -19,11 +19,6 @@ Musicreater Package Version : Demo for Midi Conversion http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. """ from msctPkgver.main import * diff --git a/magicDemo.py b/magicDemo.py index 6c54c48..6096be0 100644 --- a/magicDemo.py +++ b/magicDemo.py @@ -42,6 +42,8 @@ languages = { "ChoosePlayer": "请选择播放方式[计分板(1) 或 延迟(0)]", "ChoosePath": "请输入MIDI路径或所在文件夹", "WhetherArgEntering": "是否为文件夹内文件的转换统一参数[是(1) 或 否(0)]", + "EnterArgs": "请输入转换参数", + "noteofArgs": "注:文件夹内的全部midi将统一以此参数转换", "ChooseSbReset": "是否自动重置计分板[是(1) 或 否(0)]", "WhetherCstmProgressBar": "是否自定义进度条[是(1) 或 否(0)]", "EnterProgressBarStyle": "请输入进度条样式", @@ -63,7 +65,6 @@ languages = { import sys - if sys.argv.__len__() > 0: currentLang = sys.argv[0] if not currentLang in languages.keys(): @@ -74,54 +75,48 @@ else: def _(__): ''' - :ChooseFileFormat 请输入输出格式[bdx(1)或mcpack(0)] - :ChoosePlayer 请选择播放方式[计分板(1) 或 延迟(0)] - :ChoosePath 请输入midi路径或所在文件夹 - :WhetherArgEntering 是否为文件夹内文件的转换统一参数[是1 或 否0] - :ChooseSbReset 是否自动重置计分板[1或0]: - :WhetherCstmProgressBar 是否自定义进度条 - :EnterProgressBarStyle 请输入进度条样式 - :EnterSbName 请输入计分板名称 - :EnterVolume 请输入音量大小(0~1) - :EnterSpeed 请输入速度倍率 - :EnterAuthor 请输入作者 - :EnterMaxHeight 请输入指令结构最大生成高度 - :ErrEnter 输入错误 - :Re-Enter 请重新输入 - :Dealing 正在处理 - :FileNotFound 文件不存在 - :ChooseOutPath 请输入输出路径 - :EnterSelecter 请输入播放者选择器 - :Saying 箴言 + `languages` ''' return languages[currentLang][__] -from msctPkgver.main import * import os +import random +import datetime + +from msctPkgver.main import * try: from rich.console import Console except ModuleNotFoundError as E: - if input("您需要安装 Rich 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y','1'): + if input("您需要安装 Rich 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'): os.system("pip install Rich -i https://mirrors.aliyun.com/pypi/") from rich.console import Console else: raise E -MainConsole = Console() +try: + import zhdate +except ModuleNotFoundError as E: + if input("您需要安装 zhdate 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'): + os.system("pip install zhdate -i https://mirrors.aliyun.com/pypi/") + import zhdate + else: + raise E try: import requests except ModuleNotFoundError as E: - if input("您需要安装 requests 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y','1'): + if input("您需要安装 requests 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'): os.system("pip install requests -i https://mirrors.aliyun.com/pypi/") import requests else: raise E +MainConsole = Console() + MainConsole.print( "[#121110 on #F0F2F4] ", style="#121110 on #F0F2F4", @@ -129,13 +124,14 @@ MainConsole.print( ) +# 显示大标题 MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF") MainConsole.rule( title="[bold #AB70FF]Welcome to Independent Musicreater Convernter", characters="-" ) -import random +# 显示箴言部分 MainConsole.print( "[#121110 on #F0F2F4]" + random.choice( @@ -150,12 +146,12 @@ MainConsole.print( ) -from typing import Any, Optional, TextIO, Literal +from typing import Any, Literal, Optional, TextIO JustifyMethod = Literal["default", "left", "center", "right", "full"] OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"] - +# 高级的打印函数 def prt( *objects: Any, sep: str = " ", @@ -211,7 +207,7 @@ def prt( prt(f"{_('LangChd')}{_(':')}{_(currentLang)}") - +# 高级的输入函数 def ipt( *objects: Any, sep: str = " ", @@ -275,6 +271,18 @@ def ipt( return MainConsole.input("", password=password, stream=stream) +def formatipt(notice: str, fun: function, errnote: str): + while True: + result = ipt(notice) + try: + result = fun(result) + break + except: + prt(errnote) + continue + return result + + while True: midipath = ipt(f"{_('ChoosePath')}{_(':')}").lower() @@ -282,7 +290,13 @@ while True: if os.path.isfile(midipath): midis = (midipath,) elif os.path.isdir(midipath): - midis = tuple((os.path.join(midipath,i) for i in os.listdir(midipath) if i.lower().endswith('.mid') or i.lower().endswith('.midi'))) + midis = tuple( + ( + os.path.join(midipath, i) + for i in os.listdir(midipath) + if i.lower().endswith('.mid') or i.lower().endswith('.midi') + ) + ) else: prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") continue @@ -292,29 +306,21 @@ while True: break - while True: fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower() - if fileFormat in ('0','mcpack'): + if fileFormat in ('0', 'mcpack'): fileFormat = 0 + prt(_("EnterArgs")) if len(midis) > 1: - while True: - isFirstArgs = ipt(f"{_('WhetherArgEntering')}{_(':')}").lower() - if isFirstArgs in ('0','否'): - isFirstArgs = 0 - elif isFirstArgs in ('1','是'): - isFirstArgs = 1 - else: - prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") - continue - break - elif fileFormat in ('1','bdx'): + prt(_("noteofArgs")) + + elif fileFormat in ('1', 'bdx'): fileFormat = 1 while True: playerFormat = ipt(f"{_('ChoosePlayer')}{_(':')}").lower() - if playerFormat in ('0','延迟'): + if playerFormat in ('0', '延迟'): playerFormat = 0 - elif playerFormat in ('1','计分板'): + elif playerFormat in ('1', '计分板'): playerFormat = 1 else: prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") @@ -330,6 +336,4 @@ if fileFormat == 0: pass - - MainConsole.input() diff --git a/msctPkgver/__init__.py b/msctPkgver/__init__.py index a2bef6c..da608e1 100644 --- a/msctPkgver/__init__.py +++ b/msctPkgver/__init__.py @@ -40,3 +40,6 @@ from .main import * print('此Midi转换功能由音·创开发者开发,版权归参与开发的人员共同所有。') print('Copyright © 2022 all the developers of Musicreater') +print("不妨试试Mid-BDX转换网页:在线的多功能Midi转换器") +print("https://dislink.github.io/midi2bdx/") + diff --git a/msctPkgver/main.py b/msctPkgver/main.py index c7cb558..bdc752d 100644 --- a/msctPkgver/main.py +++ b/msctPkgver/main.py @@ -10,10 +10,10 @@ """ 音·创 库版 (Musicreater Package Version) 是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库 -注意!除了此源文件以外,任何属于此仓库以及此项目的文件均依照Apache许可证进行许可 +注意!包括此源文件,任何属于此仓库以及此项目的文件均依照Apache许可证进行许可 Musicreater pkgver (Package Version 音·创 库版) A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**. -Note! Except for this source file, all the files in this repository and this project are licensed under Apache License 2.0 +Note! Including this source file, all the files in this repository and this project are licensed under Apache License 2.0 Copyright 2022 all the developers of Musicreater @@ -23,11 +23,6 @@ Note! Except for this source file, all the files in this repository and this pro http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an 'AS IS' BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. """ import os @@ -118,6 +113,21 @@ tempo * amount_of_beats => 毫秒数 tempo * tick / ticks_per_beat => 毫秒数 +########### + +seconds per tick: +(tempo / 1000000.0) / ticks_per_beat + +seconds: +tick * tempo / 1000000.0 / ticks_per_beat + +microseconds: +tick * tempo / 1000.0 / ticks_per_beat + +gameticks: +tick * tempo / 1000000.0 / ticks_per_beat * 一秒多少游戏刻 + + """ @@ -161,7 +171,7 @@ class midiConvert: 贝斯bass、迪吉里杜管didgeridoo的时候为8 长笛flute、牛铃cou_bell的时候为5 钟琴bell、管钟chime、木琴xylophone的时候为4 - 而存在一些打击乐器basedrum、hat、snare,没有音域,则没有X,那么我们返回7即可 + 而存在一些打击乐器bd(basedrum)、hat、snare,没有音域,则没有X,那么我们返回7即可 :param instrumentID: midi的乐器ID default: 如果instrumentID不在范围内,返回的默认我的世界乐器名称 :return: (str我的世界乐器名, int转换算法中的X)""" @@ -283,23 +293,29 @@ class midiConvert: 113: ("note.bell", 4), 114: ("note.harp", 6), 115: ("note.cow_bell", 5), - 116: ("note.basedrum", 7), # 打击乐器无音域 + 116: ("note.bd", 7), # 打击乐器无音域 117: ("note.bass", 8), 118: ("note.bit", 6), - 119: ("note.basedrum", 7), # 打击乐器无音域 + 119: ("note.bd", 7), # 打击乐器无音域 120: ("note.guitar", 7), 121: ("note.harp", 6), 122: ("note.harp", 6), 123: ("note.harp", 6), 124: ("note.harp", 6), 125: ("note.hat", 7), # 打击乐器无音域 - 126: ("note.basedrum", 7), # 打击乐器无音域 + 126: ("note.bd", 7), # 打击乐器无音域 127: ("note.snare", 7), # 打击乐器无音域 }[instrumentID] except BaseException: - a = ("note.harp", 6) + a = ("note.flute", 5) return a + def __bitInst2IDwithX(self, instrumentID:int): + # 感谢Dislink的网页转换页面的代码给我抄 + return ("note.bd", 7) + + + def __score2time(self, score: int): return str(int(int(score / 20) / 60)) + ":" + str(int(int(score / 20) % 60)) @@ -534,7 +550,8 @@ class midiConvert: return [tracks, commands, maxscore] - # 这与上面的算法几乎没有差别 甚至更慢了一点 但是是为了线性插值做准备 + # 原本这个算法的转换效果应该和上面的算法相似的 + # 但不好意思 我增加了泛音功能 def _toCmdList_m2( self, scoreboardname: str = "mscplay", @@ -627,8 +644,11 @@ class midiConvert: if channels.index(track) == 0: CheckFirstChannel = True + elif channels.index(track) == 9: + SpecialBits = True else: CheckFirstChannel = False + SpecialBits = False nowTrack = [] @@ -638,8 +658,11 @@ class midiConvert: InstID = msg[1] elif msg[0] == "NoteS": - - soundID, _X = self.__Inst2soundIDwithX(InstID) + + if SpecialBits: + soundID, _X = self.__bitInst2IDwithX(InstID) + else: + soundID, _X = self.__Inst2soundIDwithX(InstID) score_now = round(msg[-1] / float(speed) / 50000) maxScore = max(maxScore, score_now)