mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2024-11-11 01:27:35 +08:00
快好了,不急不急
This commit is contained in:
parent
3921190832
commit
813186bef9
@ -103,6 +103,9 @@ while True:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if os.path.isdir(midipath):
|
||||
for i in os.listdir(midipath):
|
||||
if i.lower().endswith('.mid'):
|
||||
|
139
docs/功能使用说明.md
139
docs/功能使用说明.md
@ -16,7 +16,7 @@
|
||||
|
||||
0. 安装 Python3.6+
|
||||
|
||||
首先需要下载Python的安装包
|
||||
首先需要下载Python的安装包,最好是 *Python3.8*,因为作者就用的是这个版本
|
||||
|
||||
> [下载64位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
> [下载32位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
@ -46,27 +46,31 @@
|
||||
|
||||
打开了终端之后,请在终端中输入以下指令
|
||||
|
||||
`pip install mido -i https://mirrors.aliyun.com/pypi/simple/`
|
||||
|
||||
`pip install brotli -i https://mirrors.aliyun.com/pypi/simple/`
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
### 本工具的下载与使用
|
||||
|
||||
2. 下载本代码库以及演示程序
|
||||
0. 下载本代码库以及演示程序
|
||||
|
||||
- 若您使用git,请直接克隆本仓库:
|
||||
|
||||
`git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git
|
||||
```
|
||||
|
||||
- 若您不使用git,可以在[*码云*(Gitee)](https://gitee.com/EillesWan/Musicreater.git)或[*GitHub*](https://github.com/EillesWan/Musicreater.git)下载zip包,或者[加入QQ群聊861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr),在群文件中获取。
|
||||
|
||||
<img src=" https://foruda.gitee.com/images/1659972440341216712/下载.png" >
|
||||
|
||||
|
||||
3. 开始使用
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,例如,打开命令行,请进入到目录下,在地址框内输入`cmd`:
|
||||
|
||||
@ -75,10 +79,10 @@
|
||||
|
||||
执行以下命令:(选择你需要的)
|
||||
|
||||
`python demo_convert.py`
|
||||
|
||||
`python demo_convert_bdx_byDelay.py`
|
||||
|
||||
```bash
|
||||
python demo_convert.py
|
||||
python demo_convert_bdx_byDelay.py
|
||||
```
|
||||
|
||||
### 补充错误说明
|
||||
|
||||
@ -94,7 +98,116 @@
|
||||
|
||||
感谢群友Mono帮我们发现这个问题
|
||||
|
||||
2. 参数补充说明
|
||||
## Linux操作系统
|
||||
|
||||
|
||||
### 运行环境安装
|
||||
|
||||
0. 安装并检验Python运行环境
|
||||
|
||||
一般的Linux发行版都有安装Python环境,我们只需要保证其版本即可,理论上 ≥Python3.6 都可以运行我们的库
|
||||
|
||||
我们可以使用
|
||||
|
||||
```bash
|
||||
python -V
|
||||
```
|
||||
|
||||
来查看 Python 版本,如下
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665120915821957090/429561fd_9911226.png>
|
||||
|
||||
- 非必要环节
|
||||
|
||||
如果你跟作者一样,觉得 Python 3.10+ 太难用很烦人的话,那真是皆大欢喜,让我们一起来回退版本吧!
|
||||
|
||||
- pacman 包管理器(多用于Arch Linux上)
|
||||
|
||||
让我们先来把 python3 加入忽略升级的列表中,使用`vim`修改`/etc/pacman.conf`,在`IgnorePkg`后加上`python3`
|
||||
|
||||
```bash
|
||||
sudo vim /etc/pacman.conf
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665124611490335193/5e99ca26_9911226.png>
|
||||
|
||||
然后我们开始从[Arch Achieve](https://archive.archlinux.org/packages/)上找Python的版本列表。(*这里说明一下,在Arch中,Python默认指的是Python3,而与其他某些Linux发行版中Python默认指代Python2不同,所以在Arch Achieve中也是如此。*)我这里找到的是[Python3.8.6](https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst),于是我们用`pacman`把她下载下来:
|
||||
|
||||
```bash
|
||||
sudo pacman -U https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665126362769399903/ea4b9598_9911226.png>
|
||||
|
||||
完美!
|
||||
|
||||
接着,我们来确认,Python自带的包管理器pip是否安装到位:
|
||||
|
||||
```bash
|
||||
python -m pip # 确认pip是否安装
|
||||
# 当这个命令输入后有长段提示出现则为已经安装
|
||||
|
||||
# 如果返回如下,那么则pip尚未安装
|
||||
/usr/bin/python: No module named pip
|
||||
# 可以使用如下命令来安装pip
|
||||
sudo pacman -S python-pip
|
||||
# 安装完成后记得验证
|
||||
python -m pip
|
||||
|
||||
|
||||
# 如果还是失败,那么就需要用其他工具安装pip:
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
# 安装完成后一定要验证!!!
|
||||
python -m pip
|
||||
```
|
||||
|
||||
确认完成之后,我们来安装一下依赖库:
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
### 本代码库的下载与使用
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py
|
||||
python demo_convert_bdx_byDelay.py
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 其他说明
|
||||
|
||||
## 参数补充说明
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
|
||||
|
||||
@ -120,7 +233,7 @@
|
||||
|
||||
|
||||
|
||||
# 对于 进度条自定义 功能的说明
|
||||
## 对于 进度条自定义 功能的说明
|
||||
|
||||
因为我们提供了可以自动转换进度条的功能,因此在这里给出进度条自定义参数的详细解释。
|
||||
|
||||
|
69
msctPkgver/exceptions.py
Normal file
69
msctPkgver/exceptions.py
Normal file
@ -0,0 +1,69 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
注意!除了此源文件以外,任何属于此仓库以及此项目的文件均依照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
|
||||
|
||||
Copyright 2022 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
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
class MSCTBaseException(Exception):
|
||||
"""音·创库版本的所有错误均继承于此"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
||||
def 喵(self,):
|
||||
for i in self.args:
|
||||
print(i+"喵!")
|
||||
|
||||
def crash_it(self):
|
||||
raise self
|
||||
|
||||
|
||||
class CrossNoteError(MSCTBaseException):
|
||||
'''同通道下同音符交叉出现所产生的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class NotDefineTempoError(MSCTBaseException):
|
||||
'''没有Tempo设定导致时间无法计算的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class MidiDestroyedError(MSCTBaseException):
|
||||
'''Midi文件损坏'''
|
||||
pass
|
||||
|
||||
class ChannelOverFlowError(MSCTBaseException):
|
||||
'''一个midi中含有过多的通道(应≤16)'''
|
||||
pass
|
||||
|
||||
|
||||
|
@ -99,41 +99,12 @@ def _toCmdList_m1(
|
||||
|
||||
|
||||
|
||||
|
||||
import mido
|
||||
|
||||
|
||||
def delete_extra_zero(n: float) -> int or float:
|
||||
"""
|
||||
删除多余的0
|
||||
————————————————
|
||||
版权声明:本文为CSDN博主「XerCis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
原文链接:https://blog.csdn.net/lly1122334/article/details/108770141
|
||||
删除小数点后多余的0
|
||||
:param n: input
|
||||
:return: output
|
||||
"""
|
||||
n = '{:g}'.format(n)
|
||||
n = float(n) if '.' in n else int(n) # 含小数点转float否则int
|
||||
return n
|
||||
|
||||
|
||||
def bpm_by_MetaMessage_Set_tempo(tmp: int) -> int or float:
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
class NoteMessage:
|
||||
def __init__(self, channel, pitch, velocity, startT, lastT, midi, now_bpm, change_bpm=None):
|
||||
@ -202,14 +173,9 @@ def load(mid: mido.MidiFile):
|
||||
print(ticks)
|
||||
if msg.is_meta is True and msg.type == "set_tempo":
|
||||
recent_change_bpm = bpm
|
||||
bpm = bpm_by_MetaMessage_Set_tempo(msg.tempo)
|
||||
bpm = 60000000 / msg.tempo
|
||||
is_change_bpm = True
|
||||
# print((ticks * 92) / (mid.ticks_per_beat * 50000))
|
||||
# MC_tick = delete_extra_zero(round_up(
|
||||
# (ticks * 92) / (mid.ticks_per_beat * 50000)
|
||||
# ))
|
||||
# print(MC_tick)
|
||||
# print(ticks / mid.ticks_per_beat / 92 * 60)
|
||||
|
||||
if msg.type == 'note_on' and msg.velocity != 0:
|
||||
noteOn.append([msg, msg.note, ticks])
|
||||
if type_[1] is True:
|
||||
|
@ -38,6 +38,8 @@ import uuid
|
||||
import shutil
|
||||
import math
|
||||
|
||||
from .exceptions import *
|
||||
|
||||
|
||||
def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||
"""使用compression指定的算法打包目录为zip文件\n
|
||||
@ -62,9 +64,9 @@ def makeZip(sourceDir, outFilename, compression=8, exceptFile=None):
|
||||
|
||||
|
||||
class midiConvert:
|
||||
def __init__(self):
|
||||
def __init__(self, debug: bool = False):
|
||||
"""简单的midi转换类,将midi文件转换为我的世界结构或者包"""
|
||||
pass
|
||||
self.debugMode = debug
|
||||
|
||||
def convert(self, midiFile: str, outputPath: str):
|
||||
"""转换前需要先运行此函数来获取基本信息"""
|
||||
@ -228,8 +230,7 @@ class midiConvert:
|
||||
return a
|
||||
|
||||
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(
|
||||
self,
|
||||
@ -257,11 +258,8 @@ class midiConvert:
|
||||
"""
|
||||
|
||||
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:
|
||||
return s.replace(tobeReplaced, other)
|
||||
if times == s.count(tobeReplaced):
|
||||
@ -322,19 +320,15 @@ class midiConvert:
|
||||
countof_s = int((i + 1) / maxscore * pgblength)
|
||||
|
||||
finalprgsbar.append(
|
||||
"title @a[scores={" +
|
||||
scoreboardname +
|
||||
"=" +
|
||||
str(
|
||||
i +
|
||||
1) +
|
||||
"}] actionbar " +
|
||||
__replace(
|
||||
nowstr,
|
||||
"_",
|
||||
progressbar[1][0],
|
||||
countof_s,
|
||||
progressbar[1][1]))
|
||||
"title @a[scores={"
|
||||
+ scoreboardname
|
||||
+ "="
|
||||
+ str(i + 1)
|
||||
+ "}] actionbar "
|
||||
+ __replace(
|
||||
nowstr, "_", progressbar[1][0], countof_s, progressbar[1][1]
|
||||
)
|
||||
)
|
||||
|
||||
return finalprgsbar
|
||||
|
||||
@ -394,8 +388,7 @@ class midiConvert:
|
||||
|
||||
:return:str
|
||||
"""
|
||||
block = b"\x24" + \
|
||||
particularValue.to_bytes(2, byteorder="big", signed=False)
|
||||
block = b"\x24" + particularValue.to_bytes(2, byteorder="big", signed=False)
|
||||
|
||||
for i in [
|
||||
impluse.to_bytes(4, byteorder="big", signed=False),
|
||||
@ -412,10 +405,8 @@ class midiConvert:
|
||||
return block
|
||||
|
||||
def _toCmdList_m1(
|
||||
self,
|
||||
scoreboardname: str = "mscplay",
|
||||
volume: float = 1.0,
|
||||
speed: float = 1.0) -> list:
|
||||
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0
|
||||
) -> list:
|
||||
"""
|
||||
使用Dislink Sforza的转换思路,将midi转换为我的世界命令列表
|
||||
:param scoreboardname: 我的世界的计分板名称
|
||||
@ -449,31 +440,33 @@ class midiConvert:
|
||||
# print("TT")
|
||||
instrumentID = msg.program
|
||||
if msg.type == "note_on" and msg.velocity != 0:
|
||||
try:
|
||||
nowscore = round(
|
||||
(ticks * tempo)
|
||||
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
||||
)
|
||||
except NameError:
|
||||
raise NotDefineTempoError('计算当前分数时出错 未定义参量')
|
||||
maxscore = max(maxscore, nowscore)
|
||||
soundID, _X = self.__Inst2soundIDwithX(instrumentID)
|
||||
singleTrack.append(
|
||||
"execute @a[scores={" +
|
||||
str(scoreboardname) +
|
||||
"=" +
|
||||
str(nowscore) +
|
||||
"}" +
|
||||
f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
|
||||
"execute @a[scores={"
|
||||
+ str(scoreboardname)
|
||||
+ "="
|
||||
+ str(nowscore)
|
||||
+ "}"
|
||||
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}"
|
||||
)
|
||||
commands += 1
|
||||
if len(singleTrack) != 0:
|
||||
tracks.append(singleTrack)
|
||||
|
||||
return [tracks, commands, maxscore]
|
||||
|
||||
# 值得注意的是,我这里没有修改
|
||||
# 值得注意的是,我这里没有修改多少
|
||||
def _toCmdList_m2(
|
||||
self,
|
||||
scoreboardname: str = "mscplay",
|
||||
volume: float = 1.0,
|
||||
speed: float = 1.0) -> list:
|
||||
self, scoreboardname: str = "mscplay", MaxVolume: float = 1.0, speed: float = 1.0
|
||||
) -> list:
|
||||
"""
|
||||
使用金羿的转换思路,将midi转换为我的世界命令列表,使用线性方法调整音量
|
||||
:param scoreboardname: 我的世界的计分板名称
|
||||
@ -482,14 +475,18 @@ class midiConvert:
|
||||
:return: tuple(命令列表, 命令个数, 计分板最大值)
|
||||
"""
|
||||
tracks = []
|
||||
if volume > 1:
|
||||
volume = 1
|
||||
if volume <= 0:
|
||||
volume = 0.001
|
||||
if MaxVolume > 1:
|
||||
MaxVolume = 1
|
||||
if MaxVolume <= 0:
|
||||
MaxVolume = 0.001
|
||||
|
||||
commands = 0
|
||||
maxscore = 0
|
||||
|
||||
# 一个midi中仅有16通道 我们通过通道来识别而不是音轨
|
||||
channels = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]
|
||||
|
||||
|
||||
for i, track in enumerate(self.midi.tracks):
|
||||
|
||||
ticks = 0
|
||||
@ -508,33 +505,7 @@ class midiConvert:
|
||||
# print("TT")
|
||||
instrumentID = msg.program
|
||||
if msg.type == 'note_on' and msg.velocity != 0:
|
||||
noteOn.append([msg, msg.note, ticks])
|
||||
elif type_[1] is True:
|
||||
if msg.type == 'note_on' and msg.velocity == 0:
|
||||
for u in noteOn:
|
||||
index = 0
|
||||
if u[1] == msg.note:
|
||||
lastMessage = u[0]
|
||||
lastTick = u[2]
|
||||
break
|
||||
index += 1
|
||||
trackS.append(
|
||||
NoteMessage(
|
||||
msg.channel,
|
||||
msg.note,
|
||||
lastMessage.velocity,
|
||||
lastTick,
|
||||
ticks - lastTick,
|
||||
mid,
|
||||
)
|
||||
)
|
||||
# print(noteOn)
|
||||
# print(index)
|
||||
try:
|
||||
noteOn.pop(index)
|
||||
except IndexError:
|
||||
noteOn.pop(index - 1)
|
||||
if msg.type == "note_on" and msg.velocity != 0:
|
||||
|
||||
nowscore = round(
|
||||
(ticks * tempo)
|
||||
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
||||
@ -542,12 +513,13 @@ class midiConvert:
|
||||
maxscore = max(maxscore, nowscore)
|
||||
soundID, _X = self.__Inst2soundIDwithX(instrumentID)
|
||||
singleTrack.append(
|
||||
"execute @a[scores={" +
|
||||
str(scoreboardname) +
|
||||
"=" +
|
||||
str(nowscore) +
|
||||
"}" +
|
||||
f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
|
||||
"execute @a[scores={"
|
||||
+ str(scoreboardname)
|
||||
+ "="
|
||||
+ str(nowscore)
|
||||
+ "}"
|
||||
+ f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / MaxVolume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}"
|
||||
)
|
||||
commands += 1
|
||||
if len(singleTrack) != 0:
|
||||
tracks.append(singleTrack)
|
||||
@ -576,7 +548,8 @@ class midiConvert:
|
||||
if volume <= 0:
|
||||
volume = 0.001
|
||||
|
||||
if isMixedWithPrograssBar:
|
||||
# 此处是对于仅有 True 的参数和自定义参数的判断
|
||||
if isMixedWithPrograssBar == True:
|
||||
isMixedWithPrograssBar = (
|
||||
r"▶ %%N [ %%s/%^s %%% __________ %%t|%^t ]",
|
||||
("§e=§r", "§7=§r"),
|
||||
@ -607,7 +580,8 @@ class midiConvert:
|
||||
)
|
||||
except BaseException:
|
||||
tracks[nowtick] = [
|
||||
f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}", ]
|
||||
f"execute {player} ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}",
|
||||
]
|
||||
|
||||
allticks = list(tracks.keys())
|
||||
|
||||
@ -629,11 +603,8 @@ class midiConvert:
|
||||
"""
|
||||
|
||||
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:
|
||||
return s.replace(tobeReplaced, other)
|
||||
if times == s.count(tobeReplaced):
|
||||
@ -699,12 +670,12 @@ class midiConvert:
|
||||
if ids[r"%%s"]:
|
||||
nowstr = nowstr.replace(r"%%s", str(allticks[i] + 1))
|
||||
if ids[r"%%t"]:
|
||||
nowstr = nowstr.replace(
|
||||
r"%%t", self.__score2time(
|
||||
allticks[i] + 1))
|
||||
nowstr = nowstr.replace(r"%%t", self.__score2time(allticks[i] + 1))
|
||||
if ids[r"%%%"]:
|
||||
nowstr = nowstr.replace(r"%%%", str(
|
||||
int((allticks[i] + 1) / allticks[-1] * 10000) / 100) + "%", )
|
||||
nowstr = nowstr.replace(
|
||||
r"%%%",
|
||||
str(int((allticks[i] + 1) / allticks[-1] * 10000) / 100) + "%",
|
||||
)
|
||||
|
||||
countof_s = int((allticks[i] + 1) / allticks[-1] * pgblength)
|
||||
|
||||
@ -752,8 +723,7 @@ class midiConvert:
|
||||
:return 成功与否,成功返回(True,True),失败返回(False,str失败原因)
|
||||
"""
|
||||
if method == 1:
|
||||
cmdlist, _a, maxscore = self._toCmdList_m1(
|
||||
scoreboardname, volume, speed)
|
||||
cmdlist, _a, maxscore = self._toCmdList_m1(scoreboardname, volume, speed)
|
||||
else:
|
||||
return (False, f"无法找到算法ID{method}对应的转换算法")
|
||||
del _a
|
||||
@ -768,17 +738,19 @@ class midiConvert:
|
||||
with open(
|
||||
f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8"
|
||||
) as f:
|
||||
f.write('{\n "format_version": 1,\n "header": {\n "description": "' +
|
||||
self.midFileName +
|
||||
' Pack : behavior pack",\n "version": [ 0, 0, 1 ],\n "name": "' +
|
||||
self.midFileName +
|
||||
'Pack",\n "uuid": "' +
|
||||
str(uuid.uuid4()) +
|
||||
'"\n },\n "modules": [\n {\n "description": "' +
|
||||
f"the Player of the Music {self.midFileName}" +
|
||||
'",\n "type": "data",\n "version": [ 0, 0, 1 ],\n "uuid": "' +
|
||||
str(uuid.uuid4()) +
|
||||
'"\n }\n ]\n}')
|
||||
f.write(
|
||||
'{\n "format_version": 1,\n "header": {\n "description": "'
|
||||
+ self.midFileName
|
||||
+ ' Pack : behavior pack",\n "version": [ 0, 0, 1 ],\n "name": "'
|
||||
+ self.midFileName
|
||||
+ 'Pack",\n "uuid": "'
|
||||
+ str(uuid.uuid4())
|
||||
+ '"\n },\n "modules": [\n {\n "description": "'
|
||||
+ f"the Player of the Music {self.midFileName}"
|
||||
+ '",\n "type": "data",\n "version": [ 0, 0, 1 ],\n "uuid": "'
|
||||
+ str(uuid.uuid4())
|
||||
+ '"\n }\n ]\n}'
|
||||
)
|
||||
else:
|
||||
with open(
|
||||
f"{self.outputPath}/temp/manifest.json", "r", encoding="utf-8"
|
||||
@ -792,14 +764,14 @@ class midiConvert:
|
||||
data["modules"][0]["description"] = "None"
|
||||
data["modules"][0]["uuid"] = str(uuid.uuid4())
|
||||
manifest.close()
|
||||
open(f"{self.outputPath}/temp/manifest.json", "w",
|
||||
encoding="utf-8").write(json.dumps(data))
|
||||
open(f"{self.outputPath}/temp/manifest.json", "w", encoding="utf-8").write(
|
||||
json.dumps(data)
|
||||
)
|
||||
|
||||
# 将命令列表写入文件
|
||||
indexfile = open(
|
||||
f"{self.outputPath}/temp/functions/index.mcfunction",
|
||||
"w",
|
||||
encoding="utf-8")
|
||||
f"{self.outputPath}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||
)
|
||||
for track in cmdlist:
|
||||
indexfile.write(
|
||||
"function mscplay/track" + str(cmdlist.index(track) + 1) + "\n"
|
||||
@ -839,10 +811,8 @@ class midiConvert:
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
f.writelines(
|
||||
"\n".join(
|
||||
self.__formProgressBar(
|
||||
maxscore,
|
||||
scoreboardname)))
|
||||
"\n".join(self.__formProgressBar(maxscore, scoreboardname))
|
||||
)
|
||||
else:
|
||||
with open(
|
||||
f"{self.outputPath}/temp/functions/mscplay/progressShow.mcfunction",
|
||||
@ -860,9 +830,8 @@ class midiConvert:
|
||||
indexfile.close()
|
||||
|
||||
makeZip(
|
||||
f"{self.outputPath}/temp/",
|
||||
self.outputPath +
|
||||
f"/{self.midFileName}.mcpack")
|
||||
f"{self.outputPath}/temp/", self.outputPath + f"/{self.midFileName}.mcpack"
|
||||
)
|
||||
|
||||
shutil.rmtree(f"{self.outputPath}/temp/")
|
||||
|
||||
@ -943,8 +912,9 @@ class midiConvert:
|
||||
+ scoreboardname
|
||||
)
|
||||
|
||||
# 此处是对于仅有 True 的参数和自定义参数的判断
|
||||
if progressbar:
|
||||
if progressbar:
|
||||
if progressbar == True:
|
||||
commands += self.__formProgressBar(maxScore, scoreboardname)
|
||||
else:
|
||||
commands += self.__formProgressBar(
|
||||
@ -976,8 +946,7 @@ class midiConvert:
|
||||
|
||||
nowy += 1 if yforward else -1
|
||||
|
||||
if ((nowy > maxheight) and (yforward)) or (
|
||||
(nowy < 0) and (not yforward)):
|
||||
if ((nowy > maxheight) and (yforward)) or ((nowy < 0) and (not yforward)):
|
||||
nowy -= 1 if yforward else -1
|
||||
|
||||
yforward = not yforward
|
||||
@ -1027,8 +996,7 @@ class midiConvert:
|
||||
"""
|
||||
|
||||
if method == 1:
|
||||
cmdlist = self._toCmdList_withDelay_m1(
|
||||
volume, speed, player, progressbar)
|
||||
cmdlist = self._toCmdList_withDelay_m1(volume, speed, player, progressbar)
|
||||
else:
|
||||
return (False, f"无法找到算法ID {method} 对应的转换算法")
|
||||
|
||||
@ -1088,8 +1056,7 @@ class midiConvert:
|
||||
|
||||
nowy += 1 if yforward else -1
|
||||
|
||||
if ((nowy > maxheight) and (yforward)) or (
|
||||
(nowy < 0) and (not yforward)):
|
||||
if ((nowy > maxheight) and (yforward)) or ((nowy < 0) and (not yforward)):
|
||||
nowy -= 1 if yforward else -1
|
||||
|
||||
yforward = not yforward
|
||||
|
Loading…
Reference in New Issue
Block a user