This commit is contained in:
EillesWan 2025-05-26 17:36:24 +08:00
commit 50373b05d0
8 changed files with 202 additions and 47 deletions

View File

@ -22,8 +22,8 @@ The Licensor of Musicreater("this project") is Eilles, bgArray.
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
__version__ = "2.3.1"
__vername__ = "新增部分新可指定的默认值"
__version__ = "2.3.2"
__vername__ = "支持神羽资源包"
__author__ = (
("金羿", "Eilles"),
("诸葛亮与八卦阵", "bgArray"),

View File

@ -33,6 +33,9 @@ from .utils import *
class FutureMidiConvertKamiRES(MidiConvert):
"""
神羽资源包之测试支持
"""
@staticmethod
def to_music_note_channels(
midi: mido.MidiFile,
@ -212,6 +215,154 @@ class FutureMidiConvertKamiRES(MidiConvert):
)
def to_command_list_in_score(
self,
scoreboard_name: str = "mscplay",
) -> Tuple[List[List[MineCommand]], int, int]:
"""
将midi转换为我的世界命令列表
Parameters
----------
scoreboard_name: str
我的世界的计分板名称
Returns
-------
tuple( list[list[MineCommand指令,... ],... ], int指令数量, int音乐时长游戏刻 )
"""
command_channels = []
command_amount = 0
max_score = 0
# 此处 我们把通道视为音轨
for channel in self.channels.values():
# 如果当前通道为空 则跳过
if not channel:
continue
this_channel = []
for note in channel:
max_score = max(max_score, note.start_tick)
(
mc_sound_ID,
relative_coordinates,
volume_percentage,
mc_pitch,
) = minenote_to_command_paramaters(
note,
pitch_deviation=self.music_deviation,
)
this_channel.append(
MineCommand(
(
self.execute_cmd_head.format(
"@a[scores=({}={})]".format(
scoreboard_name, note.start_tick
)
.replace("(", r"{")
.replace(")", r"}")
)
+ r"playsound {} @s ^{} ^{} ^{} {} {} {}".format(
mc_sound_ID,
*relative_coordinates,
volume_percentage,
1.0,
self.minimum_volume,
)
),
annotation=(
"{}播放{}".format(
mctick2timestr(note.start_tick),
mc_sound_ID,
)
),
),
)
command_amount += 1
if this_channel:
self.music_command_list.extend(this_channel)
command_channels.append(this_channel)
return command_channels, command_amount, max_score
def to_command_list_in_delay(
self,
player_selector: str = "@a",
) -> Tuple[List[MineCommand], int, int]:
"""
将midi转换为我的世界命令列表并输出每个音符之后的延迟
Parameters
----------
player_selector: str
玩家选择器默认为`@a`
Returns
-------
tuple( list[MineCommand指令,...], int音乐时长游戏刻, int最大同时播放的指令数量 )
"""
notes_list: List[MineNote] = sorted(
[i for j in self.channels.values() for i in j],
key=lambda note: note.start_tick,
)
# 此处 我们把通道视为音轨
self.music_command_list = []
multi = max_multi = 0
delaytime_previous = 0
for note in notes_list:
if (tickdelay := (note.start_tick - delaytime_previous)) == 0:
multi += 1
else:
max_multi = max(max_multi, multi)
multi = 0
(
mc_sound_ID,
relative_coordinates,
volume_percentage,
mc_pitch,
) = minenote_to_command_paramaters(
note,
pitch_deviation=self.music_deviation,
)
self.music_command_list.append(
MineCommand(
command=(
self.execute_cmd_head.format(player_selector)
+ r"playsound {} @s ^{} ^{} ^{} {} {} {}".format(
mc_sound_ID,
*relative_coordinates,
volume_percentage,
1.0,
self.minimum_volume,
)
),
annotation=(
"{}播放音{}".format(
mctick2timestr(note.start_tick),
mc_sound_ID,
)
),
tick_delay=tickdelay,
),
)
delaytime_previous = note.start_tick
return self.music_command_list, notes_list[-1].start_tick, max_multi + 1
class FutureMidiConvertJavaE(MidiConvert):
def form_java_progress_bar(

View File

@ -326,7 +326,8 @@ def midi_msgs_to_minenote_using_kami_respack(
using_original = False
if not percussive_ and (0 <= inst_ <= 119):
mc_sound_ID = "{}{}.{}".format(
inst_, "d" if duration_ < 500_000 else "c", note_
# inst_, "d" if duration_ < 500_000 else "c", note_
inst_, "d", note_
)
elif percussive_ and (27 <= inst_ <= 87):
mc_sound_ID = "-1d.{}".format(inst_)

View File

@ -1,6 +1,7 @@
import Musicreater
import Musicreater.experiment
import Musicreater.plugin
# import Musicreater.previous
from Musicreater.plugin.addonpack import (
to_addon_pack_in_delay,

View File

@ -51,6 +51,7 @@
dev = [
"TrimMCStruct <= 0.0.5.9",
"brotli >= 1.0.0",
"dill",
"rich",
"pyinstaller",
"twine",
@ -91,3 +92,4 @@
[tool.pdm.version]
source = "file"
path = "Musicreater/__init__.py"

View File

@ -1,42 +0,0 @@
# -*- coding: utf-8 -*-
import setuptools
import os
# from Musicreater import __version__
os.chdir(os.path.dirname(os.path.abspath(__file__)))
with open("./requirements.txt", "r", encoding="utf-8") as fh:
dependences = fh.read().strip().split("\n")
with open("./README_EN.md", "r", encoding="utf-8") as fh:
long_description = fh.read().replace(
"./docs/", "https://github.com/TriM-Organization/Musicreater/blob/master/docs/"
)
setuptools.setup(
name="Musicreater",
version="2.2.4",
author="金羿Eilles, bgArray, 鱼旧梦ElapsingDreams",
author_email="TriM-Organization@hotmail.com",
description="A free open source library used for dealing with **Minecraft** digital musics.\n一款开源《我的世界》数字音频支持库。",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/TriM-Organization/Musicreater",
packages=setuptools.find_packages(),
classifiers=[
"Intended Audience :: Developers",
"Natural Language :: Chinese (Simplified)",
# "License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Topic :: Multimedia",
"Topic :: Multimedia :: Sound/Audio :: MIDI",
],
# 需要安装的依赖
install_requires=dependences,
python_requires=">=3.8",
license=open("./LICENSE.md", "r", encoding="utf-8").read(),
)

View File

@ -1,2 +1,33 @@
import Musicreater.experiment
import Musicreater.plugin
import Musicreater.plugin.mcstructfile
pass
msct = Musicreater.experiment.FutureMidiConvertKamiRES.from_midi_file(
input("midi路径:"), old_exe_format=False
)
opt = input("输出路径:")
print(
"乐器使用情况",
)
for name in set(
sorted(
[
n.split(".")[0].replace("c", "").replace("d", "")
for n in msct.note_count_per_instrument.keys()
]
)
):
print("\t", name, flush=True)
print(
"\n输出:",
Musicreater.plugin.mcstructfile.to_mcstructure_file_in_delay(
msct,
opt,
# Musicreater.plugin.ConvertConfig(input("输出路径:"),),
max_height=32,
),
)

13
uv.lock generated
View File

@ -1,5 +1,5 @@
version = 1
revision = 1
revision = 2
requires-python = ">=3.8, <4.0"
resolution-markers = [
"python_full_version >= '3.10'",
@ -314,6 +314,15 @@ wheels = [
{ url = "https://mirror.nju.edu.cn/pypi/web/packages/57/ff/f3b4b2d007c2a646b0f69440ab06224f9cf37a977a72cdb7b50632174e8a/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390" },
]
[[package]]
name = "dill"
version = "0.4.0"
source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }
sdist = { url = "https://mirror.nju.edu.cn/pypi/web/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0" }
wheels = [
{ url = "https://mirror.nju.edu.cn/pypi/web/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049" },
]
[[package]]
name = "docutils"
version = "0.20.1"
@ -575,6 +584,7 @@ dependencies = [
[package.optional-dependencies]
dev = [
{ name = "brotli" },
{ name = "dill" },
{ name = "pyinstaller" },
{ name = "rich" },
{ name = "trimmcstruct" },
@ -589,6 +599,7 @@ full = [
requires-dist = [
{ name = "brotli", marker = "extra == 'dev'", specifier = ">=1.0.0" },
{ name = "brotli", marker = "extra == 'full'", specifier = ">=1.0.0" },
{ name = "dill", marker = "extra == 'dev'" },
{ name = "mido", specifier = ">=1.3" },
{ name = "pyinstaller", marker = "extra == 'dev'" },
{ name = "rich", marker = "extra == 'dev'" },