更加优秀的打击乐器判断!

This commit is contained in:
EillesWan 2023-01-02 14:28:25 +08:00
parent 2ebdf6be24
commit a74fd4b4de
9 changed files with 311 additions and 216 deletions

12
.gitignore vendored
View File

@ -1,16 +1,18 @@
# sth. can't open
/msctPkgver/secrets/*.py
/msctPkgver/secrets/*.c
# mystuff # mystuff
/.vscode /.vscode
*.mid *.mid
*.midi *.midi
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized
__pycache__/ __pycache__/
*.py[cod] *.pyc
*$py.class *$py.class
# C extensions
*.so
# Distribution / packaging # Distribution / packaging
.Python .Python
build/ build/

View File

@ -1,20 +1,22 @@
**注意,以下条款或版权声明应当且必须是高于此项目中任何其他声明的** **注意,以下条款或版权声明应当且必须是高于此项目中任何其他声明的**
1. 音·创的全部开发者享有其完整版权,开发者可以在任一时刻终止以后音·创源代码开放,若经由开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作 1. 音·创的全部开发者享有其完整版权,其开发者可以在任一时刻终止以后音·创源代码开放,若经由其开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作
2. 除部分代码特殊声明外音·创允许对其进行商业化使用但是需要经过音·创主要开发者诸葛亮与八卦阵、金羿的一致授权同时授权对象在商业化授权的使用过程中必须依照Apache2.0协议 2. 音·创或(及)其代码允许在 Apache2.0 协议的条款与说明下进行非商业使用
3. 若存在对于音·创包含的部分代码的特殊开源声明则此部分代码依照其特定的开源方式授权但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用则授权对象在商用时依照此部分的开发者所准许的方式或条款进行商用或默认依照Apache2.0协议进行商业化使用 3. 除部分代码特殊声明外,音·创允许对其或(及)其代码进行商业化使用,但是需要经过音·创主要开发者(诸葛亮与八卦阵、金羿)的一致授权,同时,授权对象在商业化授权的使用过程中必须依照 Apache2.0 协议的条款与说明
4. Apache2.0 协议的英文原文副本可见下文 4. 若存在对于音·创包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用,或默认依照 Apache2.0 协议进行商业化使用
5. Apache2.0 协议的英文原文副本可见下文
> The English Translation of the TERMS AND CONDITIONS above is listed below > The English Translation of the TERMS AND CONDITIONS above is listed below
>
> This translated version is for reference only and has no legal effect. > This translated version is for reference only and has no legal effect.
>
> The version with legal effect is the Chinese version above. > The version with legal effect is the Chinese version above.
**Note, The TERMS AND CONDITIONS below should and must be above all others in this project** **Note, The TERMS AND CONDITIONS below should and must be above all others in this project**
1. *Musicreater* is fully copyrighted by all its developers, the developers have the right to make *Musicreater* close sourced at any time. Operations are permitted under specific terms instructed by its developer(s). 1. *Musicreater* is fully copyrighted by all its developers, the developers have the right to make *Musicreater* close sourced at any time. Operations are permitted under specific terms instructed by its developer(s).
2. Commercial use of *Musicreater* is permitted under Apache License 2.0 with the unanimous permission of the steering developers of *Musicreater* (*bgArray*诸葛亮与八卦阵 and *Eilles*金羿). 2. Non-commercial use of *Musicreater* and(or) its source code is permitted under Apache License 2.0.
3. Commercial use of *Musicreater* is permitted under Apache License 2.0 with the unanimous permission of the steering developers of *Musicreater* (*bgArray*诸葛亮与八卦阵 and *Eilles*金羿).
4. *Musicreater* is open sourced under priority given: 4. *Musicreater* is open sourced under priority given:
1. License granted by the core developer(s) of a section after negotiation. 1. License granted by the core developer(s) of a section after negotiation.
2. Explicitly stated license. 2. Explicitly stated license.

View File

@ -4,21 +4,17 @@
# 音·创 开发交流群 861684859 # 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com # Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") # 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 请依照 Apache 2.0 许可证进行许可 # 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
""" """
· 库版 MIDI转换展示程序 · 库版 MIDI转换展示程序
Musicreater Package Version : Demo for Midi Conversion Musicreater Package Version : Demo for Midi Conversion
Copyright 2022 all the developers of Musicreater Copyright 2023 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
开源相关声明请见 ./Lisence.md
Terms & Conditions: ./Lisence.md
""" """
from msctPkgver.main import * from msctPkgver.main import *
@ -98,7 +94,8 @@ while True:
m = 1
'''采用的算法编号'''
if os.path.isdir(midipath): if os.path.isdir(midipath):
@ -107,8 +104,8 @@ if os.path.isdir(midipath):
print(f'正在操作{i}') print(f'正在操作{i}')
convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4]) convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4])
if outFormat == 0: if outFormat == 0:
convertion.tomcpack( print(convertion.tomcpack(
1, m,
isAutoReset isAutoReset
if isAutoReset != '' if isAutoReset != ''
else bool(int(input('是否自动重置计分板(1|0)'))), else bool(int(input('是否自动重置计分板(1|0)'))),
@ -116,10 +113,10 @@ if os.path.isdir(midipath):
sbname if sbname != '' else input('请输入计分板名称:'), sbname if sbname != '' else input('请输入计分板名称:'),
volume if volume != '' else float(input('请输入音量0-1')), volume if volume != '' else float(input('请输入音量0-1')),
speed if speed != '' else float(input('请输入速度倍率:')), speed if speed != '' else float(input('请输入速度倍率:')),
) ))
elif outFormat == 1: elif outFormat == 1:
convertion.toBDXfile( print(convertion.toBDXfile(
1, m,
author if author != '' else input('请输入作者:'), author if author != '' else input('请输入作者:'),
isProgress, isProgress,
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')), maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
@ -129,21 +126,21 @@ if os.path.isdir(midipath):
isAutoReset isAutoReset
if isAutoReset != '' if isAutoReset != ''
else bool(int(input('是否自动重置计分板(1|0)'))), else bool(int(input('是否自动重置计分板(1|0)'))),
) ))
else: else:
convertion.convert(midipath, outpath) convertion.convert(midipath, outpath)
if outFormat == 0: if outFormat == 0:
convertion.tomcpack( print(convertion.tomcpack(
1, m,
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0)'))), isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0)'))),
isProgress, isProgress,
sbname if sbname != '' else input('请输入计分板名称:'), sbname if sbname != '' else input('请输入计分板名称:'),
volume if volume != '' else float(input('请输入音量0-1')), volume if volume != '' else float(input('请输入音量0-1')),
speed if speed != '' else float(input('请输入速度倍率:')), speed if speed != '' else float(input('请输入速度倍率:')),
) ))
elif outFormat == 1: elif outFormat == 1:
convertion.toBDXfile( print(convertion.toBDXfile(
1, m,
author if author != '' else input('请输入作者:'), author if author != '' else input('请输入作者:'),
isProgress, isProgress,
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')), maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
@ -151,4 +148,4 @@ else:
volume if volume != '' else float(input('请输入音量0-1')), volume if volume != '' else float(input('请输入音量0-1')),
speed if speed != '' else float(input('请输入速度倍率:')), speed if speed != '' else float(input('请输入速度倍率:')),
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0)'))), isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0)'))),
) ))

View File

@ -1,5 +1,22 @@
# -*- coding: utf-8 -*-
# THIS PROGRAM IS ONLY A TEST EXAMPLE # THIS PROGRAM IS ONLY A TEST EXAMPLE
# 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
"""
· 库版 MIDI转换展示程序
Musicreater Package Version : Demo for Midi Conversion
Copyright 2023 all the developers of Musicreater
开源相关声明请见 ./Lisence.md
Terms & Conditions: ./Lisence.md
"""
from msctPkgver.main import * from msctPkgver.main import *

View File

@ -4,22 +4,17 @@
# 音·创 开发交流群 861684859 # 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com # Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") # 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 请依照 Apache 2.0 许可证进行许可 # 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
""" """
· 库版 MIDI转换示例程序 · 库版 MIDI转换示例程序
Musicreater Package Version : Demo for Midi Conversion Musicreater Package Version : Demo for Midi Conversion
Copyright 2022 all the developers of Musicreater Copyright 2023 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
开源相关声明请见 ./Lisence.md
Terms & Conditions: ./Lisence.md
""" """
languages = { languages = {
@ -52,7 +47,7 @@ languages = {
"Re-Enter": "请重新输入", "Re-Enter": "请重新输入",
"Dealing": "正在处理", "Dealing": "正在处理",
"FileNotFound": "文件(夹)不存在", "FileNotFound": "文件(夹)不存在",
"ChooseOutPath": "请输入输出路径", "ChooseOutPath": "请输入结果输出路径",
"EnterSelecter": "请输入播放者选择器", "EnterSelecter": "请输入播放者选择器",
"Saying": "言·论", "Saying": "言·论",
} }
@ -267,19 +262,24 @@ def ipt(
return MainConsole.input("", password=password, stream=stream) return MainConsole.input("", password=password, stream=stream)
def formatipt(notice: str, fun: function, errnote: str): def formatipt(notice: str, fun, errnote: str = "", *extraArg):
'''循环输入,以某种格式
notice: 输入时的提示
fun: 格式函数
errnote: 输入不符格式时的提示
*extraArg: 对于函数的其他参数'''
while True: while True:
result = ipt(notice) result = ipt(notice)
try: try:
result = fun(result) funresult = fun(result, *extraArg)
break break
except: except:
prt(errnote) prt(errnote)
continue continue
return result return result, funresult
# 获取midi列表
while True: while True:
midipath = ipt(f"{_('ChoosePath')}{_(':')}").lower() midipath = ipt(f"{_('ChoosePath')}{_(':')}").lower()
if os.path.exists(midipath): if os.path.exists(midipath):
@ -301,7 +301,15 @@ while True:
continue continue
break break
# 获取输出地址
outpath = formatipt(
f"{_('ChooseOutPath')}{_(':')}",
os.path.exists,
f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}",
).lower()
# 选择输出格式
while True: while True:
fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower() fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower()
if fileFormat in ('0', 'mcpack'): if fileFormat in ('0', 'mcpack'):

View File

@ -4,29 +4,23 @@
# 音·创 开发交流群 861684859 # 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com # Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") # 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需转载或借鉴 请依照 Apache 2.0 许可证进行许可 # 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
__version__ = '0.0.1' __version__ = '0.1.0'
__all__ = [] __all__ = []
__author__ = (('金羿', 'Eilles Wan'), ('诸葛亮与八卦阵', 'bgArray'), ('鸣凤鸽子', 'MingFengPigeon')) __author__ = (('金羿', 'Eilles Wan'), ('诸葛亮与八卦阵', 'bgArray'), ('鸣凤鸽子', 'MingFengPigeon'))
""" """
· 库版 (Musicreater Package Version) · 库版 (Musicreater Package Version)
是一款免费开源的针对我的世界基岩版的midi音乐转换库 是一款免费开源的针对我的世界基岩版的midi音乐转换库
注意除了此源文件以外任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
Musicreater pkgver (Package Version · 库版) Musicreater pkgver (Package Version · 库版)
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**. 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
Copyright © 2022 all the developers of Musicreater Copyright 2023 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
开源相关声明请见 ../Lisence.md
Terms & Conditions: ../Lisence.md
""" """

View File

@ -4,30 +4,19 @@
# 音·创 开发交流群 861684859 # 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com # Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") # 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可 # 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
""" """
· 库版 (Musicreater Package Version) · 库版 (Musicreater Package Version)
是一款免费开源的针对我的世界基岩版的midi音乐转换库 是一款免费开源的针对我的世界基岩版的midi音乐转换库
注意除了此源文件以外任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
Musicreater pkgver (Package Version · 库版) Musicreater pkgver (Package Version · 库版)
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**. 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
Copyright 2022 all the developers of Musicreater Copyright 2023 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License'); 开源相关声明请见 ../Lisence.md
you may not use this file except in compliance with the License. Terms & Conditions: ../Lisence.md
You may obtain a copy of the License at
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.
""" """

View File

@ -4,25 +4,19 @@
# 音·创 开发交流群 861684859 # 音·创 开发交流群 861684859
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com # Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon") # 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可 # 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
""" """
· 库版 (Musicreater Package Version) · 库版 (Musicreater Package Version)
是一款免费开源的针对我的世界基岩版的midi音乐转换库 是一款免费开源的针对我的世界基岩版的midi音乐转换库
注意包括此源文件任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
Musicreater pkgver (Package Version · 库版) Musicreater pkgver (Package Version · 库版)
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**. A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
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 Copyright 2023 all the developers of Musicreater
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
开源相关声明请见 ../Lisence.md
Terms & Conditions: ../Lisence.md
""" """
import os import os
@ -59,7 +53,9 @@ def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
class SingleNote: class SingleNote:
def __init__(self, instrument: int, pitch: int, velocity, startTime, lastTime): def __init__(
self, instrument: int, pitch: int, velocity, startTime: int, lastTime: int
):
"""用于存储单个音符的类 """用于存储单个音符的类
:param instrument 乐器编号 :param instrument 乐器编号
:param pitch 音符编号 :param pitch 音符编号
@ -68,17 +64,24 @@ class SingleNote:
此处的时间是用从乐曲开始到当前的毫秒数 此处的时间是用从乐曲开始到当前的毫秒数
:param lastTime 音符延续时间(ms)""" :param lastTime 音符延续时间(ms)"""
self.instrument = instrument self.instrument = instrument
'''乐器编号'''
self.note = pitch self.note = pitch
'''音符编号'''
self.velocity = velocity self.velocity = velocity
'''力度/响度'''
self.startTime = startTime self.startTime = startTime
'''开始之时 ms'''
self.lastTime = lastTime self.lastTime = lastTime
'''音符持续时间 ms'''
@property @property
def inst(self): def inst(self):
'''乐器编号'''
return self.instrument return self.instrument
@property @property
def pitch(self): def pitch(self):
'''音符编号'''
return self.note return self.note
def __str__(self): def __str__(self):
@ -310,23 +313,82 @@ class midiConvert:
a = ("note.flute", 5) a = ("note.flute", 5)
return a return a
def __bitInst2IDwithX(self, instrumentID:int): def __bitInst2IDwithX(self, instrumentID):
# 感谢Dislink的网页转换页面的代码给我抄 try:
return ("note.bd", 7) try:
return {
34: ('note.bd', 7),
35: ('note.bd', 7),
36: ('note.hat', 7),
37: ('note.snare', 7),
38: ('note.snare', 7),
39: ('note.snare', 7),
40: ('note.hat', 7),
41: ('note.snare', 7),
42: ('note.hat', 7),
43: ('note.snare', 7),
44: ('note.snare', 7),
45: ('note.bell', 4),
46: ('note.snare', 7),
47: ('note.snare', 7),
48: ('note.bell', 4),
49: ('note.hat', 7),
50: ('note.bell', 4),
51: ('note.bell', 4),
52: ('note.bell', 4),
53: ('note.bell', 4),
54: ('note.bell', 4),
55: ('note.bell', 4),
56: ('note.snare', 7),
57: ('note.hat', 7),
58: ('note.chime', 4),
59: ('note.iron_xylophone', 6),
60: ('note.bd', 7),
61: ('note.bd', 7),
62: ('note.xylophone', 4),
63: ('note.xylophone', 4),
64: ('note.xylophone', 4),
65: ('note.hat', 7),
66: ('note.bell', 4),
67: ('note.bell', 4),
68: ('note.hat', 7),
69: ('note.hat', 7),
70: ('note.flute', 5),
71: ('note.flute', 5),
72: ('note.hat', 7),
73: ('note.hat', 7),
74: ('note.xylophone', 4),
75: ('note.hat', 7),
76: ('note.hat', 7),
77: ('note.xylophone', 4),
78: ('note.xylophone', 4),
79: ('note.bell', 4),
80: ('note.bell', 4),
}[instrumentID]
except:
return ("note.bd", 7)
except:
print("WARN", "无法导入打击乐器列表动态链接库可能是不支持当前及其环境打击乐器使用Dislink算法代替。")
if instrumentID == 55:
return ("note.cow_bell", 5)
elif instrumentID in [41, 43, 45]:
return ("note.hat", 7)
elif instrumentID in [36, 37, 39]:
return ("note.snare", 7)
else:
return ("note.bd", 7)
def __score2time(self, score: int): def __score2time(self, score: int):
return str(int(int(score / 20) / 60)) + ":" + str(int(int(score / 20) % 60)) return str(int(int(score / 20) / 60)) + ":" + str(int(int(score / 20) % 60))
def __formProgressBar( def __formProgressBar(
self, self,
maxscore: int, maxscore: int,
scoreboardname: str, scoreboardname: str,
progressbar: tuple = ( progressbar: tuple = (
r"%%N [ %%s/%^s %%% __________ %%t|%^t ]", r"%%N [ %%s/%^s %%% __________ %%t|%^t ]",
("§e=§r", "§7=§r"), ("§e=§r", "§7=§r"),
), ),
) -> list: ) -> list:
pgsstyle = progressbar[0] pgsstyle = progressbar[0]
@ -345,7 +407,7 @@ class midiConvert:
""" """
def __replace( def __replace(
s: str, tobeReplaced: str, replaceWith: str, times: int, other: str s: str, tobeReplaced: str, replaceWith: str, times: int, other: str
): ):
if times == 0: if times == 0:
return s.replace(tobeReplaced, other) return s.replace(tobeReplaced, other)
@ -420,16 +482,16 @@ class midiConvert:
return finalprgsbar return finalprgsbar
def __formCMDblk( def __formCMDblk(
self, self,
command: str, command: str,
particularValue: int, particularValue: int,
impluse: int = 0, impluse: int = 0,
condition: bool = False, condition: bool = False,
needRedstone: bool = True, needRedstone: bool = True,
tickDelay: int = 0, tickDelay: int = 0,
customName: str = "", customName: str = "",
executeOnFirstTick: bool = False, executeOnFirstTick: bool = False,
trackOutput: bool = True, trackOutput: bool = True,
): ):
""" """
使用指定项目返回指定的指令方块放置指令项 使用指定项目返回指定的指令方块放置指令项
@ -492,7 +554,7 @@ class midiConvert:
return block return block
def _toCmdList_m1( def _toCmdList_m1(
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0 self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0
) -> list: ) -> list:
""" """
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表 使用Dislink Sforza的转换思路将midi转换为我的世界命令列表
@ -534,7 +596,10 @@ class midiConvert:
except NameError: except NameError:
raise NotDefineTempoError("计算当前分数时出错 未定义参量 Tempo") raise NotDefineTempoError("计算当前分数时出错 未定义参量 Tempo")
maxscore = max(maxscore, nowscore) maxscore = max(maxscore, nowscore)
soundID, _X = self.__Inst2soundIDwithX(instrumentID) if msg.channel == 9:
soundID, _X = self.__bitInst2IDwithX(instrumentID)
else:
soundID, _X = self.__Inst2soundIDwithX(instrumentID)
# /playsound <sound: string> [player: target] [position: x y z] # /playsound <sound: string> [player: target] [position: x y z]
# [volume: float] [pitch: float] [minimumVolume: float] # [volume: float] [pitch: float] [minimumVolume: float]
@ -554,7 +619,7 @@ class midiConvert:
+ str(nowscore) + str(nowscore)
+ "}" + "}"
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ " + f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ "
f"{msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}" f"{msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}"
) )
commands += 1 commands += 1
if len(singleTrack) != 0: if len(singleTrack) != 0:
@ -563,12 +628,11 @@ class midiConvert:
return [tracks, commands, maxscore] return [tracks, commands, maxscore]
# 原本这个算法的转换效果应该和上面的算法相似的 # 原本这个算法的转换效果应该和上面的算法相似的
# 但不好意思 我增加了泛音功能
def _toCmdList_m2( def _toCmdList_m2(
self, self,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
MaxVolume: float = 1.0, MaxVolume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
) -> list: ) -> list:
""" """
使用金羿的转换思路将midi转换为我的世界命令列表 使用金羿的转换思路将midi转换为我的世界命令列表
@ -624,7 +688,7 @@ class midiConvert:
) )
elif (msg.type == "note_on" and msg.velocity == 0) or ( elif (msg.type == "note_on" and msg.velocity == 0) or (
msg.type == "note_off" msg.type == "note_off"
): ):
channels[msg.channel].append(("NoteE", msg.note, microseconds)) channels[msg.channel].append(("NoteE", msg.note, microseconds))
@ -656,6 +720,7 @@ class midiConvert:
if channels.index(track) == 0: if channels.index(track) == 0:
CheckFirstChannel = True CheckFirstChannel = True
SpecialBits = False
elif channels.index(track) == 9: elif channels.index(track) == 9:
SpecialBits = True SpecialBits = True
else: else:
@ -693,19 +758,15 @@ class midiConvert:
return [tracks, cmdAmount, maxScore] return [tracks, cmdAmount, maxScore]
# 这才是加了线性插值的算法 # 简单的单音填充
# 此算法有巨大问题
# 暂时无法使用
# 已经经过验证 需要再次修改
# 等一段时间后我来通知
def _toCmdList_m3( def _toCmdList_m3(
self, self,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
MaxVolume: float = 1.0, MaxVolume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
) -> list: ) -> list:
""" """
使用金羿的转换思路将midi转换为我的世界命令列表并使用线性插值算法优化音量 使用金羿的转换思路将midi转换为我的世界命令列表并使用完全填充算法优化音感
:param scoreboardname: 我的世界的计分板名称 :param scoreboardname: 我的世界的计分板名称
:param MaxVolume: 音量注意这里的音量范围为(0,1]如果超出将被处理为正确值其原理为在距离玩家 (1 / volume -1) 的地方播放音频 :param MaxVolume: 音量注意这里的音量范围为(0,1]如果超出将被处理为正确值其原理为在距离玩家 (1 / volume -1) 的地方播放音频
:param speed: 速度注意这里的速度指的是播放倍率其原理为在播放音频的时候每个音符的播放时间除以 speed :param speed: 速度注意这里的速度指的是播放倍率其原理为在播放音频的时候每个音符的播放时间除以 speed
@ -758,7 +819,7 @@ class midiConvert:
) )
elif (msg.type == "note_on" and msg.velocity == 0) or ( elif (msg.type == "note_on" and msg.velocity == 0) or (
msg.type == "note_off" msg.type == "note_off"
): ):
channels[msg.channel].append(("NoteE", msg.note, microseconds)) channels[msg.channel].append(("NoteE", msg.note, microseconds))
@ -822,11 +883,18 @@ class midiConvert:
result = [] result = []
totalCount = int(note.lastTime / 500000) totalCount = int(note.lastTime / 500)
for i in range(totalCount): for i in range(totalCount):
result.append((note.startTime + i * 500000, note.instrument, note.pitch, note.velocity, result.append(
MaxVolume * ((totalCount - i) / totalCount))) (
note.startTime + i * 500,
note.instrument,
note.pitch,
note.velocity,
MaxVolume * ((totalCount - i) / totalCount),
)
)
return result return result
@ -838,8 +906,12 @@ class midiConvert:
if note_channels.index(track) == 0: if note_channels.index(track) == 0:
CheckFirstChannel = True CheckFirstChannel = True
SpecialBits = False
elif note_channels.index(track) == 9:
SpecialBits = True
else: else:
CheckFirstChannel = False CheckFirstChannel = False
SpecialBits = False
nowTrack = [] nowTrack = []
@ -849,11 +921,12 @@ class midiConvert:
# 应该是计算的时候出了点小问题 # 应该是计算的时候出了点小问题
# 我们应该用一个MC帧作为时间单位而不是半秒 # 我们应该用一个MC帧作为时间单位而不是半秒
soundID, _X = self.__Inst2soundIDwithX(everynote[1]) if SpecialBits:
soundID, _X = self.__bitInst2IDwithX(InstID)
else:
soundID, _X = self.__Inst2soundIDwithX(InstID)
score_now = round( score_now = round(everynote[0] / speed / 50000)
everynote[0] / speed / 50000
)
maxScore = max(maxScore, score_now) maxScore = max(maxScore, score_now)
@ -872,11 +945,11 @@ class midiConvert:
return [tracks, cmdAmount, maxScore] return [tracks, cmdAmount, maxScore]
def _toCmdList_withDelay_m1( def _toCmdList_withDelay_m1(
self, self,
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
player: str = "@a", player: str = "@a",
isMixedWithPrograssBar=False, isMixedWithPrograssBar=False,
) -> list: ) -> list:
""" """
使用Dislink Sforza的转换思路将midi转换为我的世界命令列表并输出每个音符之后的延迟 使用Dislink Sforza的转换思路将midi转换为我的世界命令列表并输出每个音符之后的延迟
@ -948,7 +1021,7 @@ class midiConvert:
""" """
def __replace( def __replace(
s: str, tobeReplaced: str, replaceWith: str, times: int, other: str s: str, tobeReplaced: str, replaceWith: str, times: int, other: str
): ):
if times == 0: if times == 0:
return s.replace(tobeReplaced, other) return s.replace(tobeReplaced, other)
@ -1049,13 +1122,13 @@ class midiConvert:
return math.ceil(math.sqrt(math.ceil(total / maxHeight))) return math.ceil(math.sqrt(math.ceil(total / maxHeight)))
def tomcpack( def tomcpack(
self, self,
method: int = 1, method: int = 1,
isAutoReset: bool = False, isAutoReset: bool = False,
progressbar=None, progressbar=None,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
) -> bool or tuple: ) -> bool or tuple:
""" """
使用method指定的转换算法将midi转换为我的世界mcpack格式的包 使用method指定的转换算法将midi转换为我的世界mcpack格式的包
@ -1083,7 +1156,7 @@ class midiConvert:
# 写入manifest.json # 写入manifest.json
if not os.path.exists(f"{self.outputPath}/temp/manifest.json"): if not os.path.exists(f"{self.outputPath}/temp/manifest.json"):
with open( with open(
f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8" f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8"
) as f: ) as f:
f.write( f.write(
'{\n "format_version": 1,\n "header": {\n "description": "' '{\n "format_version": 1,\n "header": {\n "description": "'
@ -1100,7 +1173,7 @@ class midiConvert:
) )
else: else:
with open( with open(
f"{self.outputPath}/temp/manifest.json", "r", encoding="utf-8" f"{self.outputPath}/temp/manifest.json", "r", encoding="utf-8"
) as manifest: ) as manifest:
data = json.loads(manifest.read()) data = json.loads(manifest.read())
data["header"][ data["header"][
@ -1124,9 +1197,9 @@ class midiConvert:
"function mscplay/track" + str(cmdlist.index(track) + 1) + "\n" "function mscplay/track" + str(cmdlist.index(track) + 1) + "\n"
) )
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/track{cmdlist.index(track) + 1}.mcfunction", f"{self.outputPath}/temp/functions/mscplay/track{cmdlist.index(track) + 1}.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.write("\n".join(track)) f.write("\n".join(track))
indexfile.writelines( indexfile.writelines(
@ -1137,12 +1210,12 @@ class midiConvert:
+ scoreboardname + scoreboardname
+ " 1\n", + " 1\n",
( (
"scoreboard players reset @a[scores={" "scoreboard players reset @a[scores={"
+ scoreboardname + scoreboardname
+ "=" + "="
+ str(maxscore + 20) + str(maxscore + 20)
+ "..}]" + "..}]"
+ f" {scoreboardname}\n" + f" {scoreboardname}\n"
) )
if isAutoReset if isAutoReset
else "", else "",
@ -1153,18 +1226,18 @@ class midiConvert:
if progressbar: if progressbar:
if progressbar: if progressbar:
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction", f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.writelines( f.writelines(
"\n".join(self.__formProgressBar(maxscore, scoreboardname)) "\n".join(self.__formProgressBar(maxscore, scoreboardname))
) )
else: else:
with open( with open(
f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction", f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction",
"w", "w",
encoding="utf-8", encoding="utf-8",
) as f: ) as f:
f.writelines( f.writelines(
"\n".join( "\n".join(
@ -1185,15 +1258,15 @@ class midiConvert:
return (True, f"转换完成,总长度{maxlen}") return (True, f"转换完成,总长度{maxlen}")
def toBDXfile( def toBDXfile(
self, self,
method: int = 1, method: int = 1,
author: str = "Eilles", author: str = "Eilles",
progressbar=False, progressbar=False,
maxheight: int = 64, maxheight: int = 64,
scoreboardname: str = "mscplay", scoreboardname: str = "mscplay",
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
isAutoReset: bool = False, isAutoReset: bool = False,
): ):
""" """
使用method指定的转换算法将midi转换为BDX结构文件 使用method指定的转换算法将midi转换为BDX结构文件
@ -1207,23 +1280,26 @@ class midiConvert:
:param isAutoReset: 是否自动重置计分板 :param isAutoReset: 是否自动重置计分板
:return 成功与否成功返回(True,未经过压缩的源,结构占用大小)失败返回(False,str失败原因) :return 成功与否成功返回(True,未经过压缩的源,结构占用大小)失败返回(False,str失败原因)
""" """
try: # try:
cmdlist, totalcount, maxScore = self.methods[method - 1]( cmdlist, totalcount, maxScore = self.methods[method - 1](
scoreboardname, volume, speed scoreboardname, volume, speed
) )
except: # except Exception as E:
return (False, f"无法找到算法ID{method}对应的转换算法") # return (False, f"无法找到算法ID{method}对应的转换算法: {E}")
if not os.path.exists(self.outputPath): if not os.path.exists(self.outputPath):
os.makedirs(self.outputPath) os.makedirs(self.outputPath)
with open(os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")), "w+") as f: with open(
os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")),
"w+",
) as f:
f.write("BD@") f.write("BD@")
_bytes = ( _bytes = (
b"BDX\x00" b"BDX\x00"
+ author.encode("utf-8") + author.encode("utf-8")
+ b" & Musicreater\x00\x01command_block\x00" + b" & Musicreater\x00\x01command_block\x00"
) )
key = { key = {
@ -1252,12 +1328,12 @@ class midiConvert:
if isAutoReset: if isAutoReset:
commands += ( commands += (
"scoreboard players reset @a[scores={" "scoreboard players reset @a[scores={"
+ scoreboardname + scoreboardname
+ "=" + "="
+ str(maxScore + 20) + str(maxScore + 20)
+ "}] " + "}] "
+ scoreboardname + scoreboardname
) )
# 此处是对于仅有 True 的参数和自定义参数的判断 # 此处是对于仅有 True 的参数和自定义参数的判断
@ -1274,13 +1350,13 @@ class midiConvert:
cmd, cmd,
(1 if yforward else 0) (1 if yforward else 0)
if ( if (
((nowy != 0) and (not yforward)) ((nowy != 0) and (not yforward))
or ((yforward) and (nowy != maxheight)) or ((yforward) and (nowy != maxheight))
) )
else (3 if zforward else 2) else (3 if zforward else 2)
if ( if (
((nowz != 0) and (not zforward)) ((nowz != 0) and (not zforward))
or ((zforward) and (nowz != _sideLength)) or ((zforward) and (nowz != _sideLength))
) )
else 5, else 5,
impluse=2, impluse=2,
@ -1302,7 +1378,7 @@ class midiConvert:
nowz += 1 if zforward else -1 nowz += 1 if zforward else -1
if ((nowz > _sideLength) and (zforward)) or ( if ((nowz > _sideLength) and (zforward)) or (
(nowz < 0) and (not zforward) (nowz < 0) and (not zforward)
): ):
nowz -= 1 if zforward else -1 nowz -= 1 if zforward else -1
zforward = not zforward zforward = not zforward
@ -1316,20 +1392,23 @@ class midiConvert:
_bytes += key[y][int(yforward)] _bytes += key[y][int(yforward)]
with open(os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")), "ab+") as f: with open(
os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")),
"ab+",
) as f:
f.write(brotli.compress(_bytes + b"XE")) f.write(brotli.compress(_bytes + b"XE"))
return (True, _bytes, (nowx, maxheight, _sideLength)) return (True, totalcount, maxScore, _bytes, (nowx, maxheight, _sideLength))
def toBDXfile_withDelay( def toBDXfile_withDelay(
self, self,
method: int = 1, method: int = 1,
author: str = "Eilles", author: str = "Eilles",
progressbar=False, progressbar=False,
maxheight: int = 64, maxheight: int = 64,
volume: float = 1.0, volume: float = 1.0,
speed: float = 1.0, speed: float = 1.0,
player: str = "@a", player: str = "@a",
): ):
""" """
使用method指定的转换算法将midi转换为BDX结构文件 使用method指定的转换算法将midi转换为BDX结构文件
@ -1353,13 +1432,16 @@ class midiConvert:
if not os.path.exists(self.outputPath): if not os.path.exists(self.outputPath):
os.makedirs(self.outputPath) os.makedirs(self.outputPath)
with open(os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")), "w+") as f: with open(
os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")),
"w+",
) as f:
f.write("BD@") f.write("BD@")
_bytes = ( _bytes = (
b"BDX\x00" b"BDX\x00"
+ author.encode("utf-8") + author.encode("utf-8")
+ b" & Musicreater\x00\x01command_block\x00" + b" & Musicreater\x00\x01command_block\x00"
) )
key = { key = {
@ -1386,13 +1468,13 @@ class midiConvert:
cmd, cmd,
(1 if yforward else 0) (1 if yforward else 0)
if ( if (
((nowy != 0) and (not yforward)) ((nowy != 0) and (not yforward))
or ((yforward) and (nowy != maxheight)) or ((yforward) and (nowy != maxheight))
) )
else (3 if zforward else 2) else (3 if zforward else 2)
if ( if (
((nowz != 0) and (not zforward)) ((nowz != 0) and (not zforward))
or ((zforward) and (nowz != _sideLength)) or ((zforward) and (nowz != _sideLength))
) )
else 5, else 5,
impluse=2, impluse=2,
@ -1414,7 +1496,7 @@ class midiConvert:
nowz += 1 if zforward else -1 nowz += 1 if zforward else -1
if ((nowz > _sideLength) and (zforward)) or ( if ((nowz > _sideLength) and (zforward)) or (
(nowz < 0) and (not zforward) (nowz < 0) and (not zforward)
): ):
nowz -= 1 if zforward else -1 nowz -= 1 if zforward else -1
zforward = not zforward zforward = not zforward
@ -1428,11 +1510,15 @@ class midiConvert:
_bytes += key[y][int(yforward)] _bytes += key[y][int(yforward)]
with open(os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")), "ab+") as f: with open(
os.path.abspath(os.path.join(self.outputPath, f"{self.midFileName}.bdx")),
"ab+",
) as f:
f.write(brotli.compress(_bytes + b"XE")) f.write(brotli.compress(_bytes + b"XE"))
return (True, _bytes, (nowx, maxheight, _sideLength)) return (True, _bytes, (nowx, maxheight, _sideLength))
# def isProgressBar(pgbarLike:str): # def isProgressBar(pgbarLike:str):
# '''判断所输入数据是否为进度条式样数据 # '''判断所输入数据是否为进度条式样数据
# 注意,使用本函数时不得直接放在 if 后,正确用法如下: # 注意,使用本函数时不得直接放在 if 后,正确用法如下:

BIN
msctPkgver/secrets.7z Normal file

Binary file not shown.