mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2024-11-11 01:27:35 +08:00
进一步优化结构,提高插件兼容
This commit is contained in:
parent
95c0ff1b47
commit
d4925e4d75
@ -17,7 +17,7 @@ Terms & Conditions: License.md in the root directory
|
|||||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||||
|
|
||||||
|
|
||||||
__version__ = "2.0.0-alpha"
|
__version__ = "2.0.0-beta"
|
||||||
__vername__ = "全新组织架构"
|
__vername__ = "全新组织架构"
|
||||||
__author__ = (
|
__author__ = (
|
||||||
("金羿", "Eilles Wan"),
|
("金羿", "Eilles Wan"),
|
||||||
@ -34,6 +34,7 @@ __all__ = [
|
|||||||
"MineNote",
|
"MineNote",
|
||||||
"MineCommand",
|
"MineCommand",
|
||||||
"SingleNoteBox",
|
"SingleNoteBox",
|
||||||
|
"ProgressBarStyle",
|
||||||
# "TimeStamp", 未来功能
|
# "TimeStamp", 未来功能
|
||||||
# 默认值
|
# 默认值
|
||||||
"DEFAULT_PROGRESSBAR_STYLE",
|
"DEFAULT_PROGRESSBAR_STYLE",
|
||||||
|
@ -385,6 +385,23 @@ MC_PERCUSSION_INSTRUMENT_LIST: List[str] = [
|
|||||||
]
|
]
|
||||||
"""打击乐器列表"""
|
"""打击乐器列表"""
|
||||||
|
|
||||||
|
MC_PITCHED_INSTRUMENT_LIST: List[str] = [
|
||||||
|
"note.harp",
|
||||||
|
"note.pling",
|
||||||
|
"note.guitar",
|
||||||
|
"note.iron_xylophone",
|
||||||
|
"note.bell",
|
||||||
|
"note.xylophone",
|
||||||
|
"note.chime",
|
||||||
|
"note.banjo",
|
||||||
|
"note.flute",
|
||||||
|
"note.bass",
|
||||||
|
"note.didgeridoo",
|
||||||
|
"note.bit",
|
||||||
|
"note.cow_bell",
|
||||||
|
]
|
||||||
|
"""乐音乐器列表"""
|
||||||
|
|
||||||
MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
||||||
"note.bass": ("planks",),
|
"note.bass": ("planks",),
|
||||||
"note.snare": ("sand",),
|
"note.snare": ("sand",),
|
||||||
@ -425,7 +442,7 @@ MM_INSTRUMENT_RANGE_TABLE: Dict[str, Tuple[Tuple[int, int], int]] = {
|
|||||||
"note.banjo": ((42, 66), 54),
|
"note.banjo": ((42, 66), 54),
|
||||||
"note.flute": ((54, 78), 66),
|
"note.flute": ((54, 78), 66),
|
||||||
"note.bass": ((18, 42), 30),
|
"note.bass": ((18, 42), 30),
|
||||||
"note.snare": ((-1, 128), 0), # 实际上是 0~127
|
"note.snare": ((-1, 128), 0), # 实际上是 0~127
|
||||||
"note.didgeridoo": ((18, 42), 30),
|
"note.didgeridoo": ((18, 42), 30),
|
||||||
"mob.zombie.wood": ((-1, 128), 0),
|
"mob.zombie.wood": ((-1, 128), 0),
|
||||||
"note.bit": ((42, 66), 54),
|
"note.bit": ((42, 66), 54),
|
||||||
@ -439,6 +456,30 @@ MM_INSTRUMENT_RANGE_TABLE: Dict[str, Tuple[Tuple[int, int], int]] = {
|
|||||||
}
|
}
|
||||||
"""不同乐器的音域偏离对照表"""
|
"""不同乐器的音域偏离对照表"""
|
||||||
|
|
||||||
|
MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
||||||
|
"note.harp": 6,
|
||||||
|
"note.pling": 6,
|
||||||
|
"note.guitar": 7,
|
||||||
|
"note.iron_xylophone": 6,
|
||||||
|
"note.bell": 4,
|
||||||
|
"note.xylophone": 4,
|
||||||
|
"note.chime": 4,
|
||||||
|
"note.banjo": 6,
|
||||||
|
"note.flute": 5,
|
||||||
|
"note.bass": 8,
|
||||||
|
"note.snare": -1,
|
||||||
|
"note.didgeridoo": 8,
|
||||||
|
"mob.zombie.wood": -1,
|
||||||
|
"note.bit": 6,
|
||||||
|
"note.hat": -1,
|
||||||
|
"note.bd": -1,
|
||||||
|
"firework.blast": -1,
|
||||||
|
"firework.twinkle": -1,
|
||||||
|
"fire.ignite": -1,
|
||||||
|
"note.cow_bell": 5,
|
||||||
|
}
|
||||||
|
"""不同乐器的音调偏离对照表"""
|
||||||
|
|
||||||
# Midi乐器对MC乐器对照表
|
# Midi乐器对MC乐器对照表
|
||||||
|
|
||||||
MM_CLASSIC_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
|
MM_CLASSIC_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
|
||||||
|
@ -47,12 +47,12 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
# 临时用的插值计算函数
|
# 临时用的插值计算函数
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _linear_note(
|
def _linear_note(
|
||||||
_note: SingleNote,
|
_note: MineNote,
|
||||||
_apply_time_division: float = 100,
|
_apply_time_division: float = 10,
|
||||||
) -> List[SingleNote]:
|
) -> List[MineNote]:
|
||||||
"""传入音符数据,返回以半秒为分割的插值列表
|
"""传入音符数据,返回分割后的插值列表
|
||||||
:param _note: SingleNote 音符
|
:param _note: SingleNote 音符
|
||||||
:param _apply_time_division: int 间隔毫秒数
|
:param _apply_time_division: int 间隔帧数
|
||||||
:return list[tuple(int开始时间(毫秒), int乐器, int音符, int力度(内置), float音量(播放)),]"""
|
:return list[tuple(int开始时间(毫秒), int乐器, int音符, int力度(内置), float音量(播放)),]"""
|
||||||
|
|
||||||
if _note.percussive:
|
if _note.percussive:
|
||||||
@ -63,21 +63,24 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
totalCount = int(_note.duration / _apply_time_division)
|
totalCount = int(_note.duration / _apply_time_division)
|
||||||
|
|
||||||
if totalCount == 0:
|
if totalCount == 0:
|
||||||
|
print(_note.extra_info)
|
||||||
return [
|
return [
|
||||||
_note,
|
_note,
|
||||||
]
|
]
|
||||||
# print(totalCount)
|
# print(totalCount)
|
||||||
|
|
||||||
result: List[SingleNote] = []
|
result: List[MineNote] = []
|
||||||
|
|
||||||
for _i in range(totalCount):
|
for _i in range(totalCount):
|
||||||
result.append(
|
result.append(
|
||||||
SingleNote(
|
MineNote(
|
||||||
instrument=_note.inst,
|
mc_sound_name=_note.sound_name,
|
||||||
pitch=_note.pitch,
|
midi_pitch=_note.note_pitch,
|
||||||
velocity=_note.velocity,
|
midi_velocity=_note.velocity,
|
||||||
startime=int(_note.start_time + _i * (_note.duration / totalCount)),
|
start_time=int(
|
||||||
lastime=int(_note.duration / totalCount),
|
_note.start_tick + _i * (_note.duration / totalCount)
|
||||||
|
),
|
||||||
|
last_time=int(_note.duration / totalCount),
|
||||||
track_number=_note.track_no,
|
track_number=_note.track_no,
|
||||||
is_percussion=_note.percussive,
|
is_percussion=_note.percussive,
|
||||||
extra_information=_note.extra_info,
|
extra_information=_note.extra_info,
|
||||||
@ -116,54 +119,68 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
for channel in self.channels.values():
|
for channel in self.channels.values():
|
||||||
for note in channel:
|
for note in channel:
|
||||||
note.set_info(
|
note.set_info(
|
||||||
single_note_to_note_parameters(
|
minenote_to_command_paramaters(
|
||||||
note,
|
note,
|
||||||
(
|
pitch_deviation=self.music_deviation,
|
||||||
self.percussion_note_referrence_table
|
|
||||||
if note.percussive
|
|
||||||
else self.pitched_note_reference_table
|
|
||||||
),
|
|
||||||
deviation=0,
|
|
||||||
volume_percentage=(
|
|
||||||
(max_volume) if note.track_no == 0 else (max_volume * 0.9)
|
|
||||||
),
|
|
||||||
volume_processing_method=self.volume_processing_function,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not note.percussive:
|
if not note.percussive:
|
||||||
notes_list.extend(self._linear_note(note, note.extra_info[3] * 500))
|
notes_list.extend(self._linear_note(note,1 * note.extra_info[3]))
|
||||||
else:
|
else:
|
||||||
notes_list.append(note)
|
notes_list.append(note)
|
||||||
|
|
||||||
notes_list.sort(key=lambda a: a.start_time)
|
notes_list.sort(key=lambda a: a.start_tick)
|
||||||
|
|
||||||
self.music_command_list = []
|
self.music_command_list = []
|
||||||
multi = max_multi = 0
|
multi = max_multi = 0
|
||||||
delaytime_previous = 0
|
delaytime_previous = 0
|
||||||
|
|
||||||
for note in notes_list:
|
for note in notes_list:
|
||||||
delaytime_now = round(note.start_time / speed / 50)
|
if (tickdelay := (note.start_tick - delaytime_previous)) == 0:
|
||||||
if (tickdelay := (delaytime_now - delaytime_previous)) == 0:
|
|
||||||
multi += 1
|
multi += 1
|
||||||
else:
|
else:
|
||||||
max_multi = max(max_multi, multi)
|
max_multi = max(max_multi, multi)
|
||||||
multi = 0
|
multi = 0
|
||||||
|
(
|
||||||
|
mc_sound_ID,
|
||||||
|
relative_coordinates,
|
||||||
|
volume_percentage,
|
||||||
|
mc_pitch,
|
||||||
|
) = note.extra_info
|
||||||
self.music_command_list.append(
|
self.music_command_list.append(
|
||||||
MineCommand(
|
MineCommand(
|
||||||
self.execute_cmd_head.format(player_selector)
|
command=(
|
||||||
+ r"playsound {} @s ^ ^ ^{} {} {}".format(*note.extra_info),
|
self.execute_cmd_head.format(player_selector)
|
||||||
tick_delay=tickdelay,
|
+ r"playsound {} @s ^{} ^{} ^{} {} {} {}".format(
|
||||||
annotation="在{}播放{}%的{}音".format(
|
mc_sound_ID,
|
||||||
mctick2timestr(delaytime_now),
|
*relative_coordinates,
|
||||||
max_volume * 100,
|
volume_percentage,
|
||||||
"{}:{}".format(note.extra_info[0], note.extra_info[3]),
|
1.0 if note.percussive else mc_pitch,
|
||||||
|
self.minium_volume,
|
||||||
|
)
|
||||||
),
|
),
|
||||||
)
|
annotation=(
|
||||||
|
"在{}播放噪音{}".format(
|
||||||
|
mctick2timestr(note.start_tick),
|
||||||
|
mc_sound_ID,
|
||||||
|
)
|
||||||
|
if note.percussive
|
||||||
|
else "在{}播放乐音{}".format(
|
||||||
|
mctick2timestr(note.start_tick),
|
||||||
|
"{}:{:.2f}".format(mc_sound_ID, mc_pitch),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
tick_delay=tickdelay,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
delaytime_previous = delaytime_now
|
delaytime_previous = note.start_tick
|
||||||
|
|
||||||
return self.music_command_list, round(notes_list[-1].start_time / speed / 50), max_multi + 1
|
return (
|
||||||
|
self.music_command_list,
|
||||||
|
notes_list[-1].start_tick + notes_list[-1].duration,
|
||||||
|
max_multi + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FutureMidiConvertM5(MidiConvert):
|
class FutureMidiConvertM5(MidiConvert):
|
||||||
|
@ -70,13 +70,6 @@ tick * tempo / 1000000.0 / ticks_per_beat * 一秒多少游戏刻
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# VoidMido = Union[mido.MidiFile, None] # void mido
|
|
||||||
# """
|
|
||||||
# 空Midi类类型
|
|
||||||
# """
|
|
||||||
# 已经成为历史了
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class MusicSequence:
|
class MusicSequence:
|
||||||
"""
|
"""
|
||||||
@ -92,23 +85,23 @@ class MusicSequence:
|
|||||||
total_note_count: int
|
total_note_count: int
|
||||||
"""音符总数"""
|
"""音符总数"""
|
||||||
|
|
||||||
used_instrument: List[str]
|
note_count_per_instrument: Dict[str, int]
|
||||||
"""所使用的乐器"""
|
"""所使用的乐器"""
|
||||||
|
|
||||||
minium_volume: float
|
minium_volume: float
|
||||||
"""乐曲最小音量"""
|
"""乐曲最小音量"""
|
||||||
|
|
||||||
music_deviation: float
|
music_deviation: float
|
||||||
"""乐曲音调偏移"""
|
"""全曲音调偏移"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name_of_music: str,
|
name_of_music: str,
|
||||||
channels_of_notes: MineNoteChannelType,
|
channels_of_notes: MineNoteChannelType,
|
||||||
music_note_count: Optional[int] = None,
|
music_note_count: Optional[int] = None,
|
||||||
used_instrument_of_music: Optional[List[str]] = None,
|
note_used_per_instrument: Optional[Dict[str, int]] = None,
|
||||||
minium_volume_of_music: float = 0.1,
|
minium_volume_of_music: float = 0.1,
|
||||||
deviation: Optional[float] = None,
|
deviation_value: Optional[float] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
《我的世界》音符序列类
|
《我的世界》音符序列类
|
||||||
@ -135,26 +128,21 @@ class MusicSequence:
|
|||||||
self.channels = channels_of_notes
|
self.channels = channels_of_notes
|
||||||
self.minium_volume = minium_volume_of_music
|
self.minium_volume = minium_volume_of_music
|
||||||
|
|
||||||
if used_instrument_of_music is None or music_note_count is None:
|
if (note_used_per_instrument is None) or (music_note_count is None):
|
||||||
kp = [i.sound_name for j in self.channels.values() for i in j]
|
kp = [i.sound_name for j in self.channels.values() for i in j]
|
||||||
self.total_note_count = (
|
self.total_note_count = (
|
||||||
len(kp) if music_note_count is None else music_note_count
|
len(kp) if music_note_count is None else music_note_count
|
||||||
)
|
)
|
||||||
self.used_instrument = (
|
self.note_count_per_instrument = (
|
||||||
list(set(kp))
|
dict([(it, kp.count(it)) for it in set(kp)])
|
||||||
if used_instrument_of_music is None
|
if note_used_per_instrument is None
|
||||||
else used_instrument_of_music
|
else note_used_per_instrument
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self.total_note_count = music_note_count
|
||||||
|
self.note_count_per_instrument = note_used_per_instrument
|
||||||
|
|
||||||
self.music_deviation = (
|
self.music_deviation = 0 if deviation_value is None else deviation_value
|
||||||
self.guess_deviation(
|
|
||||||
self.total_note_count,
|
|
||||||
len(self.used_instrument),
|
|
||||||
music_channels=self.channels,
|
|
||||||
)
|
|
||||||
if deviation is None
|
|
||||||
else deviation
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_mido(
|
def from_mido(
|
||||||
@ -168,35 +156,28 @@ class MusicSequence:
|
|||||||
minium_vol: float = 0.1,
|
minium_vol: float = 0.1,
|
||||||
volume_processing_function: FittingFunctionType = natural_curve,
|
volume_processing_function: FittingFunctionType = natural_curve,
|
||||||
default_tempo: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
default_tempo: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
||||||
devation_guess_enabled: bool = True,
|
deviation: float = 0,
|
||||||
):
|
):
|
||||||
note_channels, note_count_total, inst_note_count, qualified_inst_note_count = (
|
(
|
||||||
cls.to_music_note_channels(
|
note_channels,
|
||||||
midi=mido_file,
|
note_count_total,
|
||||||
speed=speed_multiplier,
|
inst_note_count, # qualified_inst_note_count,
|
||||||
pitched_note_rtable=pitched_note_referance_table,
|
) = cls.to_music_note_channels(
|
||||||
percussion_note_rtable=percussion_note_referance_table,
|
midi=mido_file,
|
||||||
default_tempo_value=default_tempo,
|
speed=speed_multiplier,
|
||||||
vol_processing_function=volume_processing_function,
|
pitched_note_rtable=pitched_note_referance_table,
|
||||||
ignore_mismatch_error=mismatch_error_ignorance,
|
percussion_note_rtable=percussion_note_referance_table,
|
||||||
)
|
default_tempo_value=default_tempo,
|
||||||
|
vol_processing_function=volume_processing_function,
|
||||||
|
ignore_mismatch_error=mismatch_error_ignorance,
|
||||||
)
|
)
|
||||||
return cls(
|
return cls(
|
||||||
name_of_music=midi_music_name,
|
name_of_music=midi_music_name,
|
||||||
channels_of_notes=note_channels,
|
channels_of_notes=note_channels,
|
||||||
music_note_count=note_count_total,
|
music_note_count=note_count_total,
|
||||||
used_instrument_of_music=list(inst_note_count.keys()),
|
note_used_per_instrument=inst_note_count,
|
||||||
minium_volume_of_music=minium_vol,
|
minium_volume_of_music=minium_vol,
|
||||||
deviation=(
|
deviation_value=deviation,
|
||||||
cls.guess_deviation(
|
|
||||||
note_count_total,
|
|
||||||
len(inst_note_count),
|
|
||||||
inst_note_count,
|
|
||||||
qualified_inst_note_count,
|
|
||||||
)
|
|
||||||
if devation_guess_enabled
|
|
||||||
else 0
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def set_min_volume(self, volume_value: int):
|
def set_min_volume(self, volume_value: int):
|
||||||
@ -215,30 +196,31 @@ class MusicSequence:
|
|||||||
self.channels[channel_no].sort(key=lambda note: note.start_tick)
|
self.channels[channel_no].sort(key=lambda note: note.start_tick)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def guess_deviation(
|
def guess_deviation_wasted(
|
||||||
total_note_count: int,
|
total_note_count: int,
|
||||||
total_instrument_count: int,
|
total_instrument_count: int,
|
||||||
note_count_per_instruments: Optional[Dict[str, int]] = None,
|
note_count_per_instrument: Optional[Dict[str, int]] = None,
|
||||||
qualified_note_count_per_instruments: Optional[Dict[str, int]] = None,
|
qualified_note_count_per_instrument: Optional[Dict[str, int]] = None,
|
||||||
music_channels: Optional[MineNoteChannelType] = None,
|
music_channels: Optional[MineNoteChannelType] = None,
|
||||||
) -> float:
|
) -> float:
|
||||||
|
"""已废弃"""
|
||||||
if (
|
if (
|
||||||
note_count_per_instruments is None
|
note_count_per_instrument is None
|
||||||
or qualified_note_count_per_instruments is None
|
or qualified_note_count_per_instrument is None
|
||||||
):
|
):
|
||||||
if music_channels is None:
|
if music_channels is None:
|
||||||
raise ValueError("参数不足,算逑!")
|
raise ValueError("参数不足,算逑!")
|
||||||
note_count_per_instruments = {}
|
note_count_per_instrument = {}
|
||||||
qualified_note_count_per_instruments = {}
|
qualified_note_count_per_instrument = {}
|
||||||
for this_note in [k for j in music_channels.values() for k in j]:
|
for this_note in [k for j in music_channels.values() for k in j]:
|
||||||
if this_note.sound_name in note_count_per_instruments.keys():
|
if this_note.sound_name in note_count_per_instrument.keys():
|
||||||
note_count_per_instruments[this_note.sound_name] += 1
|
note_count_per_instrument[this_note.sound_name] += 1
|
||||||
qualified_note_count_per_instruments[
|
qualified_note_count_per_instrument[
|
||||||
this_note.sound_name
|
this_note.sound_name
|
||||||
] += is_note_in_diapason(this_note)
|
] += is_note_in_diapason(this_note)
|
||||||
else:
|
else:
|
||||||
note_count_per_instruments[this_note.sound_name] = 1
|
note_count_per_instrument[this_note.sound_name] = 1
|
||||||
qualified_note_count_per_instruments[this_note.sound_name] = int(
|
qualified_note_count_per_instrument[this_note.sound_name] = int(
|
||||||
is_note_in_diapason(this_note)
|
is_note_in_diapason(this_note)
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
@ -251,9 +233,9 @@ class MusicSequence:
|
|||||||
/ total_note_count
|
/ total_note_count
|
||||||
- MM_INSTRUMENT_RANGE_TABLE[inst][-1]
|
- MM_INSTRUMENT_RANGE_TABLE[inst][-1]
|
||||||
)
|
)
|
||||||
* (note_count - qualified_note_count_per_instruments[inst])
|
* (note_count - qualified_note_count_per_instrument[inst])
|
||||||
)
|
)
|
||||||
for inst, note_count in note_count_per_instruments.items()
|
for inst, note_count in note_count_per_instrument.items()
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
/ total_instrument_count
|
/ total_instrument_count
|
||||||
@ -269,7 +251,7 @@ class MusicSequence:
|
|||||||
percussion_note_rtable: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
percussion_note_rtable: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
||||||
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
||||||
vol_processing_function: FittingFunctionType = natural_curve,
|
vol_processing_function: FittingFunctionType = natural_curve,
|
||||||
) -> Tuple[MineNoteChannelType, int, Dict[str, int], Dict[str, int]]:
|
) -> Tuple[MineNoteChannelType, int, Dict[str, int]]: # , Dict[str, int]]:
|
||||||
"""
|
"""
|
||||||
将midi解析并转换为频道音符字典
|
将midi解析并转换为频道音符字典
|
||||||
|
|
||||||
@ -291,8 +273,8 @@ class MusicSequence:
|
|||||||
midi_channels: MineNoteChannelType = empty_midi_channels(staff=[])
|
midi_channels: MineNoteChannelType = empty_midi_channels(staff=[])
|
||||||
tempo = default_tempo_value
|
tempo = default_tempo_value
|
||||||
note_count = 0
|
note_count = 0
|
||||||
note_count_per_instruments: Dict[str, int] = {}
|
note_count_per_instrument: Dict[str, int] = {}
|
||||||
qualified_note_count_per_instruments: Dict[str, int] = {}
|
# qualified_note_count_per_instruments: Dict[str, int] = {}
|
||||||
|
|
||||||
# 我们来用通道统计音乐信息
|
# 我们来用通道统计音乐信息
|
||||||
# 但是是用分轨的思路的
|
# 但是是用分轨的思路的
|
||||||
@ -382,19 +364,16 @@ class MusicSequence:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
note_count += 1
|
note_count += 1
|
||||||
if (
|
if that_note.sound_name in note_count_per_instrument.keys():
|
||||||
that_note.sound_name
|
note_count_per_instrument[that_note.sound_name] += 1
|
||||||
in note_count_per_instruments.keys()
|
# qualified_note_count_per_instruments[
|
||||||
):
|
# that_note.sound_name
|
||||||
note_count_per_instruments[that_note.sound_name] += 1
|
# ] += is_note_in_diapason(that_note)
|
||||||
qualified_note_count_per_instruments[
|
|
||||||
that_note.sound_name
|
|
||||||
] += is_note_in_diapason(that_note)
|
|
||||||
else:
|
else:
|
||||||
note_count_per_instruments[that_note.sound_name] = 1
|
note_count_per_instrument[that_note.sound_name] = 1
|
||||||
qualified_note_count_per_instruments[
|
# qualified_note_count_per_instruments[
|
||||||
that_note.sound_name
|
# that_note.sound_name
|
||||||
] = int(is_note_in_diapason(that_note))
|
# ] = int(is_note_in_diapason(that_note))
|
||||||
else:
|
else:
|
||||||
if ignore_mismatch_error:
|
if ignore_mismatch_error:
|
||||||
print(
|
print(
|
||||||
@ -431,8 +410,8 @@ class MusicSequence:
|
|||||||
return (
|
return (
|
||||||
channels,
|
channels,
|
||||||
note_count,
|
note_count,
|
||||||
note_count_per_instruments,
|
note_count_per_instrument,
|
||||||
qualified_note_count_per_instruments,
|
# qualified_note_count_per_instruments,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -463,7 +442,7 @@ class MidiConvert(MusicSequence):
|
|||||||
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
||||||
pitched_note_rtable: MidiInstrumentTableType = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
pitched_note_rtable: MidiInstrumentTableType = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
||||||
percussion_note_rtable: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
percussion_note_rtable: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
||||||
enable_devation_guess: bool = True,
|
# enable_devation_guess: bool = True,
|
||||||
enable_old_exe_format: bool = False,
|
enable_old_exe_format: bool = False,
|
||||||
minium_volume: float = 0.1,
|
minium_volume: float = 0.1,
|
||||||
vol_processing_function: FittingFunctionType = natural_curve,
|
vol_processing_function: FittingFunctionType = natural_curve,
|
||||||
@ -505,7 +484,7 @@ class MidiConvert(MusicSequence):
|
|||||||
minium_vol=minium_volume,
|
minium_vol=minium_volume,
|
||||||
volume_processing_function=vol_processing_function,
|
volume_processing_function=vol_processing_function,
|
||||||
default_tempo=default_tempo_value,
|
default_tempo=default_tempo_value,
|
||||||
devation_guess_enabled=enable_devation_guess,
|
# devation_guess_enabled=enable_devation_guess,
|
||||||
mismatch_error_ignorance=ignore_mismatch_error,
|
mismatch_error_ignorance=ignore_mismatch_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -518,7 +497,7 @@ class MidiConvert(MusicSequence):
|
|||||||
default_tempo: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
default_tempo: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
||||||
pitched_note_table: MidiInstrumentTableType = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
pitched_note_table: MidiInstrumentTableType = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
||||||
percussion_note_table: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
percussion_note_table: MidiInstrumentTableType = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
||||||
devation_guess_enabled: bool = True,
|
# devation_guess_enabled: bool = True,
|
||||||
old_exe_format: bool = False,
|
old_exe_format: bool = False,
|
||||||
min_volume: float = 0.1,
|
min_volume: float = 0.1,
|
||||||
vol_processing_func: FittingFunctionType = natural_curve,
|
vol_processing_func: FittingFunctionType = natural_curve,
|
||||||
@ -560,13 +539,13 @@ class MidiConvert(MusicSequence):
|
|||||||
default_tempo_value=default_tempo,
|
default_tempo_value=default_tempo,
|
||||||
pitched_note_rtable=pitched_note_table,
|
pitched_note_rtable=pitched_note_table,
|
||||||
percussion_note_rtable=percussion_note_table,
|
percussion_note_rtable=percussion_note_table,
|
||||||
enable_devation_guess=devation_guess_enabled,
|
# enable_devation_guess=devation_guess_enabled,
|
||||||
enable_old_exe_format=old_exe_format,
|
enable_old_exe_format=old_exe_format,
|
||||||
minium_volume=min_volume,
|
minium_volume=min_volume,
|
||||||
vol_processing_function=vol_processing_func,
|
vol_processing_function=vol_processing_func,
|
||||||
)
|
)
|
||||||
except (ValueError, TypeError) as E:
|
except (ValueError, TypeError) as E:
|
||||||
raise MidiDestroyedError(f"文件{midi_file_path}损坏:{E}")
|
raise MidiDestroyedError(f"文件{midi_file_path}可能损坏:{E}")
|
||||||
except FileNotFoundError as E:
|
except FileNotFoundError as E:
|
||||||
raise FileNotFoundError(f"文件{midi_file_path}不存在:{E}")
|
raise FileNotFoundError(f"文件{midi_file_path}不存在:{E}")
|
||||||
|
|
||||||
@ -584,13 +563,13 @@ class MidiConvert(MusicSequence):
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
maxscore: int
|
max_score: int
|
||||||
midi的乐器ID
|
midi的乐器ID
|
||||||
|
|
||||||
scoreboard_name: str
|
scoreboard_name: str
|
||||||
所使用的计分板名称
|
所使用的计分板名称
|
||||||
|
|
||||||
progressbar_style: tuple
|
progressbar_style: ProgressBarStyle
|
||||||
此参数详见 ../docs/库的生成与功能文档.md#进度条自定义
|
此参数详见 ../docs/库的生成与功能文档.md#进度条自定义
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -1004,6 +983,93 @@ class MidiConvert(MusicSequence):
|
|||||||
|
|
||||||
return self.music_command_list, notes_list[-1].start_tick, max_multi + 1
|
return self.music_command_list, notes_list[-1].start_tick, max_multi + 1
|
||||||
|
|
||||||
|
def to_command_list_in_delay_devided_by_instrument(
|
||||||
|
self,
|
||||||
|
player_selector: str = "@a",
|
||||||
|
) -> Tuple[Dict[str, List[MineCommand]], int, Dict[str, int]]:
|
||||||
|
"""
|
||||||
|
将midi转换为我的世界命令列表,并输出每个音符之后的延迟
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
player_selector: str
|
||||||
|
玩家选择器,默认为`@a`
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Tuple[Dict[str, 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,
|
||||||
|
)
|
||||||
|
|
||||||
|
command_dict: Dict[str, List[MineCommand]] = dict(
|
||||||
|
[(inst, []) for inst in self.note_count_per_instrument.keys()]
|
||||||
|
)
|
||||||
|
multi: Dict[str, int] = dict(
|
||||||
|
[(inst, 0) for inst in self.note_count_per_instrument.keys()]
|
||||||
|
)
|
||||||
|
max_multi: Dict[str, int] = dict(
|
||||||
|
[(inst, 0) for inst in self.note_count_per_instrument.keys()]
|
||||||
|
)
|
||||||
|
delaytime_previous: Dict[str, int] = dict(
|
||||||
|
[(inst, 0) for inst in self.note_count_per_instrument.keys()]
|
||||||
|
)
|
||||||
|
|
||||||
|
for note in notes_list:
|
||||||
|
if (
|
||||||
|
tickdelay := (note.start_tick - delaytime_previous[note.sound_name])
|
||||||
|
) == 0:
|
||||||
|
multi[note.sound_name] += 1
|
||||||
|
else:
|
||||||
|
max_multi[note.sound_name] = max(
|
||||||
|
max_multi[note.sound_name], multi[note.sound_name]
|
||||||
|
)
|
||||||
|
multi[note.sound_name] = 0
|
||||||
|
|
||||||
|
(
|
||||||
|
mc_sound_ID,
|
||||||
|
relative_coordinates,
|
||||||
|
volume_percentage,
|
||||||
|
mc_pitch,
|
||||||
|
) = minenote_to_command_paramaters(
|
||||||
|
note,
|
||||||
|
pitch_deviation=self.music_deviation,
|
||||||
|
)
|
||||||
|
|
||||||
|
command_dict[note.sound_name].append(
|
||||||
|
MineCommand(
|
||||||
|
command=(
|
||||||
|
self.execute_cmd_head.format(player_selector)
|
||||||
|
+ r"playsound {} @s ^{} ^{} ^{} {} {} {}".format(
|
||||||
|
mc_sound_ID,
|
||||||
|
*relative_coordinates,
|
||||||
|
volume_percentage,
|
||||||
|
1.0 if note.percussive else mc_pitch,
|
||||||
|
self.minium_volume,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
annotation=(
|
||||||
|
"在{}播放噪音{}".format(
|
||||||
|
mctick2timestr(note.start_tick),
|
||||||
|
mc_sound_ID,
|
||||||
|
)
|
||||||
|
if note.percussive
|
||||||
|
else "在{}播放乐音{}".format(
|
||||||
|
mctick2timestr(note.start_tick),
|
||||||
|
"{}:{:.2f}".format(mc_sound_ID, mc_pitch),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
tick_delay=tickdelay,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
delaytime_previous[note.sound_name] = note.start_tick
|
||||||
|
|
||||||
|
self.music_command_list = [j for i in command_dict.values() for j in i]
|
||||||
|
return command_dict, notes_list[-1].start_tick, max_multi
|
||||||
|
|
||||||
def copy_important(self):
|
def copy_important(self):
|
||||||
dst = MidiConvert.from_mido_obj(
|
dst = MidiConvert.from_mido_obj(
|
||||||
midi_obj=mido.MidiFile(),
|
midi_obj=mido.MidiFile(),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
存放非音·创本体的附加内容(插件?)
|
存放非音·创本体的附加功能件
|
||||||
|
|
||||||
版权所有 © 2024 音·创 开发者
|
版权所有 © 2024 音·创 开发者
|
||||||
Copyright © 2024 all the developers of Musicreater
|
Copyright © 2024 all the developers of Musicreater
|
||||||
@ -16,7 +16,7 @@ Terms & Conditions: License.md in the root directory
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
# 通用
|
# 通用
|
||||||
"ConvertConfig",
|
# "ConvertConfig",
|
||||||
"bottem_side_length_of_smallest_square_bottom_box",
|
"bottem_side_length_of_smallest_square_bottom_box",
|
||||||
# 打包
|
# 打包
|
||||||
"compress_zipfile",
|
"compress_zipfile",
|
||||||
@ -43,7 +43,7 @@ __all__ = [
|
|||||||
]
|
]
|
||||||
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"))
|
__author__ = (("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"))
|
||||||
|
|
||||||
from .main import ConvertConfig
|
# from .main import ConvertConfig
|
||||||
|
|
||||||
from .archive import compress_zipfile, behavior_mcpack_manifest
|
from .archive import compress_zipfile, behavior_mcpack_manifest
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ __all__ = [
|
|||||||
"to_addon_pack_in_delay",
|
"to_addon_pack_in_delay",
|
||||||
"to_addon_pack_in_score",
|
"to_addon_pack_in_score",
|
||||||
"to_addon_pack_in_repeater",
|
"to_addon_pack_in_repeater",
|
||||||
|
"to_addon_pack_in_repeater_divided_by_instrument",
|
||||||
]
|
]
|
||||||
__author__ = (("金羿", "Eilles Wan"),)
|
__author__ = (("金羿", "Eilles Wan"),)
|
||||||
|
|
||||||
@ -25,4 +26,5 @@ from .main import (
|
|||||||
to_addon_pack_in_delay,
|
to_addon_pack_in_delay,
|
||||||
to_addon_pack_in_repeater,
|
to_addon_pack_in_repeater,
|
||||||
to_addon_pack_in_score,
|
to_addon_pack_in_score,
|
||||||
|
to_addon_pack_in_repeater_divided_by_instrument,
|
||||||
)
|
)
|
||||||
|
@ -16,12 +16,12 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
from TrimMCStruct import Structure
|
|
||||||
|
|
||||||
from ...main import MidiConvert
|
from ...main import MidiConvert
|
||||||
from ..archive import behavior_mcpack_manifest, compress_zipfile
|
from ..archive import behavior_mcpack_manifest, compress_zipfile
|
||||||
from ..main import ConvertConfig
|
from ...subclass import ProgressBarStyle
|
||||||
|
from ...types import Optional, Literal
|
||||||
from ..mcstructure import (
|
from ..mcstructure import (
|
||||||
|
Structure,
|
||||||
COMPABILITY_VERSION_117,
|
COMPABILITY_VERSION_117,
|
||||||
COMPABILITY_VERSION_119,
|
COMPABILITY_VERSION_119,
|
||||||
commands_to_redstone_delay_structure,
|
commands_to_redstone_delay_structure,
|
||||||
@ -32,7 +32,8 @@ from ..mcstructure import (
|
|||||||
|
|
||||||
def to_addon_pack_in_score(
|
def to_addon_pack_in_score(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
|
progressbar_style: Optional[ProgressBarStyle],
|
||||||
scoreboard_name: str = "mscplay",
|
scoreboard_name: str = "mscplay",
|
||||||
auto_reset: bool = False,
|
auto_reset: bool = False,
|
||||||
) -> Tuple[int, int]:
|
) -> Tuple[int, int]:
|
||||||
@ -43,8 +44,10 @@ def to_addon_pack_in_score(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
|
progressbar_style: ProgressBarStyle 对象
|
||||||
|
进度条对象
|
||||||
scoreboard_name: str
|
scoreboard_name: str
|
||||||
我的世界的计分板名称
|
我的世界的计分板名称
|
||||||
auto_reset: bool
|
auto_reset: bool
|
||||||
@ -60,12 +63,12 @@ def to_addon_pack_in_score(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 当文件f夹{self.outputPath}/temp/functions存在时清空其下所有项目,然后创建
|
# 当文件f夹{self.outputPath}/temp/functions存在时清空其下所有项目,然后创建
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/temp/functions/"):
|
if os.path.exists(f"{dist_path}/temp/functions/"):
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/functions/")
|
shutil.rmtree(f"{dist_path}/temp/functions/")
|
||||||
os.makedirs(f"{data_cfg.dist_path}/temp/functions/mscplay")
|
os.makedirs(f"{dist_path}/temp/functions/mscplay")
|
||||||
|
|
||||||
# 写入manifest.json
|
# 写入manifest.json
|
||||||
with open(f"{data_cfg.dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
with open(f"{dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
||||||
json.dump(
|
json.dump(
|
||||||
behavior_mcpack_manifest(
|
behavior_mcpack_manifest(
|
||||||
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCFUNCTION(MCPACK) 计分播放器 - 由 音·创 生成",
|
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCFUNCTION(MCPACK) 计分播放器 - 由 音·创 生成",
|
||||||
@ -78,18 +81,18 @@ def to_addon_pack_in_score(
|
|||||||
|
|
||||||
# 写入stop.mcfunction
|
# 写入stop.mcfunction
|
||||||
with open(
|
with open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
||||||
) as f:
|
) as f:
|
||||||
f.write("scoreboard players reset @a {}".format(scoreboard_name))
|
f.write("scoreboard players reset @a {}".format(scoreboard_name))
|
||||||
|
|
||||||
# 将命令列表写入文件
|
# 将命令列表写入文件
|
||||||
index_file = open(
|
index_file = open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||||
)
|
)
|
||||||
for i in range(len(cmdlist)):
|
for i in range(len(cmdlist)):
|
||||||
index_file.write(f"function mscplay/track{i + 1}\n")
|
index_file.write(f"function mscplay/track{i + 1}\n")
|
||||||
with open(
|
with open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/mscplay/track{i + 1}.mcfunction",
|
f"{dist_path}/temp/functions/mscplay/track{i + 1}.mcfunction",
|
||||||
"w",
|
"w",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as f:
|
) as f:
|
||||||
@ -113,13 +116,13 @@ def to_addon_pack_in_score(
|
|||||||
if auto_reset
|
if auto_reset
|
||||||
else ""
|
else ""
|
||||||
),
|
),
|
||||||
f"function mscplay/progressShow\n" if data_cfg.progressbar_style else "",
|
f"function mscplay/progressShow\n" if progressbar_style else "",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if data_cfg.progressbar_style:
|
if progressbar_style:
|
||||||
with open(
|
with open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/mscplay/progressShow.mcfunction",
|
f"{dist_path}/temp/functions/mscplay/progressShow.mcfunction",
|
||||||
"w",
|
"w",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as f:
|
) as f:
|
||||||
@ -128,7 +131,7 @@ def to_addon_pack_in_score(
|
|||||||
[
|
[
|
||||||
single_cmd.cmd
|
single_cmd.cmd
|
||||||
for single_cmd in midi_cvt.form_progress_bar(
|
for single_cmd in midi_cvt.form_progress_bar(
|
||||||
maxscore, scoreboard_name, data_cfg.progressbar_style
|
maxscore, scoreboard_name, progressbar_style
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -136,21 +139,22 @@ def to_addon_pack_in_score(
|
|||||||
|
|
||||||
index_file.close()
|
index_file.close()
|
||||||
|
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack"):
|
if os.path.exists(f"{dist_path}/{midi_cvt.music_name}.mcpack"):
|
||||||
os.remove(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack")
|
os.remove(f"{dist_path}/{midi_cvt.music_name}.mcpack")
|
||||||
compress_zipfile(
|
compress_zipfile(
|
||||||
f"{data_cfg.dist_path}/temp/",
|
f"{dist_path}/temp/",
|
||||||
f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack",
|
f"{dist_path}/{midi_cvt.music_name}.mcpack",
|
||||||
)
|
)
|
||||||
|
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
|
|
||||||
return maxlen, maxscore
|
return maxlen, maxscore
|
||||||
|
|
||||||
|
|
||||||
def to_addon_pack_in_delay(
|
def to_addon_pack_in_delay(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
|
progressbar_style: Optional[ProgressBarStyle],
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
) -> Tuple[int, int]:
|
) -> Tuple[int, int]:
|
||||||
@ -161,8 +165,10 @@ def to_addon_pack_in_delay(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
|
progressbar_style: ProgressBarStyle 对象
|
||||||
|
进度条对象
|
||||||
player: str
|
player: str
|
||||||
玩家选择器,默认为`@a`
|
玩家选择器,默认为`@a`
|
||||||
max_height: int
|
max_height: int
|
||||||
@ -183,17 +189,17 @@ def to_addon_pack_in_delay(
|
|||||||
player_selector=player,
|
player_selector=player,
|
||||||
)[:2]
|
)[:2]
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/temp/"):
|
if os.path.exists(f"{dist_path}/temp/"):
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
os.makedirs(f"{data_cfg.dist_path}/temp/functions/")
|
os.makedirs(f"{dist_path}/temp/functions/")
|
||||||
os.makedirs(f"{data_cfg.dist_path}/temp/structures/")
|
os.makedirs(f"{dist_path}/temp/structures/")
|
||||||
|
|
||||||
# 写入manifest.json
|
# 写入manifest.json
|
||||||
with open(f"{data_cfg.dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
with open(f"{dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
||||||
json.dump(
|
json.dump(
|
||||||
behavior_mcpack_manifest(
|
behavior_mcpack_manifest(
|
||||||
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCSTRUCTURE(MCPACK) 延迟播放器 - 由 音·创 生成",
|
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCSTRUCTURE(MCPACK) 延迟播放器 - 由 音·创 生成",
|
||||||
@ -206,7 +212,7 @@ def to_addon_pack_in_delay(
|
|||||||
|
|
||||||
# 写入stop.mcfunction
|
# 写入stop.mcfunction
|
||||||
with open(
|
with open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
||||||
) as f:
|
) as f:
|
||||||
f.write(
|
f.write(
|
||||||
"gamerule commandblocksenabled false\ngamerule commandblocksenabled true"
|
"gamerule commandblocksenabled false\ngamerule commandblocksenabled true"
|
||||||
@ -214,7 +220,7 @@ def to_addon_pack_in_delay(
|
|||||||
|
|
||||||
# 将命令列表写入文件
|
# 将命令列表写入文件
|
||||||
index_file = open(
|
index_file = open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
struct, size, end_pos = commands_to_structure(
|
struct, size, end_pos = commands_to_structure(
|
||||||
@ -225,7 +231,7 @@ def to_addon_pack_in_delay(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_main.mcstructure",
|
f"{midi_cvt.music_name}_main.mcstructure",
|
||||||
)
|
)
|
||||||
@ -236,7 +242,7 @@ def to_addon_pack_in_delay(
|
|||||||
|
|
||||||
del struct
|
del struct
|
||||||
|
|
||||||
if data_cfg.progressbar_style:
|
if progressbar_style:
|
||||||
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
||||||
index_file.write("scoreboard objectives add {0} dummy {0}计\n".format(scb_name))
|
index_file.write("scoreboard objectives add {0} dummy {0}计\n".format(scb_name))
|
||||||
|
|
||||||
@ -257,7 +263,7 @@ def to_addon_pack_in_delay(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_start.mcstructure",
|
f"{midi_cvt.music_name}_start.mcstructure",
|
||||||
)
|
)
|
||||||
@ -269,7 +275,7 @@ def to_addon_pack_in_delay(
|
|||||||
index_file.write(f"structure load {midi_cvt.music_name}_start ~ ~ ~1\n")
|
index_file.write(f"structure load {midi_cvt.music_name}_start ~ ~ ~1\n")
|
||||||
|
|
||||||
pgb_struct, pgbSize, pgbNowPos = commands_to_structure(
|
pgb_struct, pgbSize, pgbNowPos = commands_to_structure(
|
||||||
midi_cvt.form_progress_bar(max_delay, scb_name, data_cfg.progressbar_style),
|
midi_cvt.form_progress_bar(max_delay, scb_name, progressbar_style),
|
||||||
max_height - 1,
|
max_height - 1,
|
||||||
compability_version_=compability_ver,
|
compability_version_=compability_ver,
|
||||||
)
|
)
|
||||||
@ -277,7 +283,7 @@ def to_addon_pack_in_delay(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_pgb.mcstructure",
|
f"{midi_cvt.music_name}_pgb.mcstructure",
|
||||||
)
|
)
|
||||||
@ -307,7 +313,7 @@ def to_addon_pack_in_delay(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_reset.mcstructure",
|
f"{midi_cvt.music_name}_reset.mcstructure",
|
||||||
)
|
)
|
||||||
@ -331,21 +337,22 @@ def to_addon_pack_in_delay(
|
|||||||
|
|
||||||
index_file.close()
|
index_file.close()
|
||||||
|
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack"):
|
if os.path.exists(f"{dist_path}/{midi_cvt.music_name}.mcpack"):
|
||||||
os.remove(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack")
|
os.remove(f"{dist_path}/{midi_cvt.music_name}.mcpack")
|
||||||
compress_zipfile(
|
compress_zipfile(
|
||||||
f"{data_cfg.dist_path}/temp/",
|
f"{dist_path}/temp/",
|
||||||
f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack",
|
f"{dist_path}/{midi_cvt.music_name}.mcpack",
|
||||||
)
|
)
|
||||||
|
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
|
|
||||||
return len(command_list), max_delay
|
return len(command_list), max_delay
|
||||||
|
|
||||||
|
|
||||||
def to_addon_pack_in_repeater(
|
def to_addon_pack_in_repeater(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
|
progressbar_style: Optional[ProgressBarStyle],
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
max_height: int = 65,
|
max_height: int = 65,
|
||||||
) -> Tuple[int, int]:
|
) -> Tuple[int, int]:
|
||||||
@ -356,8 +363,10 @@ def to_addon_pack_in_repeater(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
|
progressbar_style: ProgressBarStyle 对象
|
||||||
|
进度条对象
|
||||||
player: str
|
player: str
|
||||||
玩家选择器,默认为`@a`
|
玩家选择器,默认为`@a`
|
||||||
max_height: int
|
max_height: int
|
||||||
@ -378,17 +387,17 @@ def to_addon_pack_in_repeater(
|
|||||||
player_selector=player,
|
player_selector=player,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/temp/"):
|
if os.path.exists(f"{dist_path}/temp/"):
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
os.makedirs(f"{data_cfg.dist_path}/temp/functions/")
|
os.makedirs(f"{dist_path}/temp/functions/")
|
||||||
os.makedirs(f"{data_cfg.dist_path}/temp/structures/")
|
os.makedirs(f"{dist_path}/temp/structures/")
|
||||||
|
|
||||||
# 写入manifest.json
|
# 写入manifest.json
|
||||||
with open(f"{data_cfg.dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
with open(f"{dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
||||||
json.dump(
|
json.dump(
|
||||||
behavior_mcpack_manifest(
|
behavior_mcpack_manifest(
|
||||||
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCSTRUCTURE(MCPACK) 中继器播放器 - 由 音·创 生成",
|
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCSTRUCTURE(MCPACK) 中继器播放器 - 由 音·创 生成",
|
||||||
@ -401,7 +410,7 @@ def to_addon_pack_in_repeater(
|
|||||||
|
|
||||||
# 写入stop.mcfunction
|
# 写入stop.mcfunction
|
||||||
with open(
|
with open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
||||||
) as f:
|
) as f:
|
||||||
f.write(
|
f.write(
|
||||||
"gamerule commandblocksenabled false\ngamerule commandblocksenabled true"
|
"gamerule commandblocksenabled false\ngamerule commandblocksenabled true"
|
||||||
@ -409,7 +418,7 @@ def to_addon_pack_in_repeater(
|
|||||||
|
|
||||||
# 将命令列表写入文件
|
# 将命令列表写入文件
|
||||||
index_file = open(
|
index_file = open(
|
||||||
f"{data_cfg.dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
f"{dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||||
)
|
)
|
||||||
|
|
||||||
struct, size, end_pos = commands_to_redstone_delay_structure(
|
struct, size, end_pos = commands_to_redstone_delay_structure(
|
||||||
@ -421,7 +430,7 @@ def to_addon_pack_in_repeater(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_main.mcstructure",
|
f"{midi_cvt.music_name}_main.mcstructure",
|
||||||
)
|
)
|
||||||
@ -432,7 +441,7 @@ def to_addon_pack_in_repeater(
|
|||||||
|
|
||||||
del struct
|
del struct
|
||||||
|
|
||||||
if data_cfg.progressbar_style:
|
if progressbar_style:
|
||||||
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
||||||
index_file.write("scoreboard objectives add {0} dummy {0}计\n".format(scb_name))
|
index_file.write("scoreboard objectives add {0} dummy {0}计\n".format(scb_name))
|
||||||
|
|
||||||
@ -453,7 +462,7 @@ def to_addon_pack_in_repeater(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_start.mcstructure",
|
f"{midi_cvt.music_name}_start.mcstructure",
|
||||||
)
|
)
|
||||||
@ -465,7 +474,7 @@ def to_addon_pack_in_repeater(
|
|||||||
index_file.write(f"structure load {midi_cvt.music_name}_start ~ ~ ~1\n")
|
index_file.write(f"structure load {midi_cvt.music_name}_start ~ ~ ~1\n")
|
||||||
|
|
||||||
pgb_struct, pgbSize, pgbNowPos = commands_to_structure(
|
pgb_struct, pgbSize, pgbNowPos = commands_to_structure(
|
||||||
midi_cvt.form_progress_bar(max_delay, scb_name, data_cfg.progressbar_style),
|
midi_cvt.form_progress_bar(max_delay, scb_name, progressbar_style),
|
||||||
max_height - 1,
|
max_height - 1,
|
||||||
compability_version_=compability_ver,
|
compability_version_=compability_ver,
|
||||||
)
|
)
|
||||||
@ -473,7 +482,7 @@ def to_addon_pack_in_repeater(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_pgb.mcstructure",
|
f"{midi_cvt.music_name}_pgb.mcstructure",
|
||||||
)
|
)
|
||||||
@ -503,7 +512,7 @@ def to_addon_pack_in_repeater(
|
|||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(
|
||||||
os.path.join(
|
os.path.join(
|
||||||
data_cfg.dist_path,
|
dist_path,
|
||||||
"temp/structures/",
|
"temp/structures/",
|
||||||
f"{midi_cvt.music_name}_reset.mcstructure",
|
f"{midi_cvt.music_name}_reset.mcstructure",
|
||||||
)
|
)
|
||||||
@ -527,13 +536,128 @@ def to_addon_pack_in_repeater(
|
|||||||
|
|
||||||
index_file.close()
|
index_file.close()
|
||||||
|
|
||||||
if os.path.exists(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack"):
|
if os.path.exists(f"{dist_path}/{midi_cvt.music_name}.mcpack"):
|
||||||
os.remove(f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack")
|
os.remove(f"{dist_path}/{midi_cvt.music_name}.mcpack")
|
||||||
compress_zipfile(
|
compress_zipfile(
|
||||||
f"{data_cfg.dist_path}/temp/",
|
f"{dist_path}/temp/",
|
||||||
f"{data_cfg.dist_path}/{midi_cvt.music_name}.mcpack",
|
f"{dist_path}/{midi_cvt.music_name}.mcpack",
|
||||||
)
|
)
|
||||||
|
|
||||||
shutil.rmtree(f"{data_cfg.dist_path}/temp/")
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
|
|
||||||
return len(command_list), max_delay
|
return len(command_list), max_delay
|
||||||
|
|
||||||
|
|
||||||
|
def to_addon_pack_in_repeater_divided_by_instrument(
|
||||||
|
midi_cvt: MidiConvert,
|
||||||
|
dist_path: str,
|
||||||
|
player: str = "@a",
|
||||||
|
max_height: int = 65,
|
||||||
|
base_block: str = "concrete",
|
||||||
|
) -> Tuple[int, int]:
|
||||||
|
"""
|
||||||
|
将midi以中继器播放器形式转换为mcstructure结构文件后打包成附加包,并在附加包中生成相应地导入函数
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
midi_cvt: MidiConvert 对象
|
||||||
|
用于转换的MidiConvert对象
|
||||||
|
dist_path: str
|
||||||
|
转换结果输出的目标路径
|
||||||
|
player: str
|
||||||
|
玩家选择器,默认为`@a`
|
||||||
|
max_height: int
|
||||||
|
生成结构最大高度
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
tuple[int指令数量, int音乐总延迟]
|
||||||
|
"""
|
||||||
|
|
||||||
|
compability_ver = (
|
||||||
|
COMPABILITY_VERSION_117
|
||||||
|
if midi_cvt.enable_old_exe_format
|
||||||
|
else COMPABILITY_VERSION_119
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.exists(dist_path):
|
||||||
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
|
# 当文件f夹{self.outputPath}/temp/存在时清空其下所有项目,然后创建
|
||||||
|
if os.path.exists(f"{dist_path}/temp/"):
|
||||||
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
|
os.makedirs(f"{dist_path}/temp/functions/")
|
||||||
|
os.makedirs(f"{dist_path}/temp/structures/")
|
||||||
|
|
||||||
|
# 写入manifest.json
|
||||||
|
with open(f"{dist_path}/temp/manifest.json", "w", encoding="utf-8") as f:
|
||||||
|
json.dump(
|
||||||
|
behavior_mcpack_manifest(
|
||||||
|
pack_description=f"{midi_cvt.music_name} 音乐播放包,MCSTRUCTURE(MCPACK) 中继器播放器 - 由 音·创 生成",
|
||||||
|
pack_name=midi_cvt.music_name + "播放",
|
||||||
|
modules_description=f"无 - 由 音·创 生成",
|
||||||
|
),
|
||||||
|
fp=f,
|
||||||
|
indent=4,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 写入stop.mcfunction
|
||||||
|
with open(
|
||||||
|
f"{dist_path}/temp/functions/stop.mcfunction", "w", encoding="utf-8"
|
||||||
|
) as f:
|
||||||
|
f.write(
|
||||||
|
"gamerule commandblocksenabled false\ngamerule commandblocksenabled true"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 将命令列表写入文件
|
||||||
|
index_file = open(
|
||||||
|
f"{dist_path}/temp/functions/index.mcfunction", "w", encoding="utf-8"
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_dict, max_delay, max_multiple_cmd_count = (
|
||||||
|
midi_cvt.to_command_list_in_delay_devided_by_instrument(
|
||||||
|
player_selector=player,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
base_height = 0
|
||||||
|
|
||||||
|
for inst, cmd_list in cmd_dict.items():
|
||||||
|
struct, size, end_pos = commands_to_redstone_delay_structure(
|
||||||
|
cmd_list,
|
||||||
|
max_delay,
|
||||||
|
max_multiple_cmd_count[inst],
|
||||||
|
base_block,
|
||||||
|
"z+",
|
||||||
|
compability_version_=compability_ver,
|
||||||
|
)
|
||||||
|
|
||||||
|
bkn = "{}_{}".format(midi_cvt.music_name, inst.replace(".", "-"))
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
dist_path,
|
||||||
|
"temp/structures/",
|
||||||
|
"{}_main.mcstructure".format(bkn),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"wb+",
|
||||||
|
) as f:
|
||||||
|
struct.dump(f)
|
||||||
|
|
||||||
|
index_file.write("structure load {}_main ~ ~{} ~3\n".format(bkn, base_height))
|
||||||
|
base_height += 2 + size[1]
|
||||||
|
|
||||||
|
index_file.close()
|
||||||
|
|
||||||
|
if os.path.exists(f"{dist_path}/{midi_cvt.music_name}.mcpack"):
|
||||||
|
os.remove(f"{dist_path}/{midi_cvt.music_name}.mcpack")
|
||||||
|
compress_zipfile(
|
||||||
|
f"{dist_path}/temp/",
|
||||||
|
f"{dist_path}/{midi_cvt.music_name}.mcpack",
|
||||||
|
)
|
||||||
|
|
||||||
|
shutil.rmtree(f"{dist_path}/temp/")
|
||||||
|
|
||||||
|
return midi_cvt.total_note_count, max_delay
|
||||||
|
@ -17,7 +17,8 @@ import os
|
|||||||
import brotli
|
import brotli
|
||||||
|
|
||||||
from ...main import MidiConvert
|
from ...main import MidiConvert
|
||||||
from ...subclass import MineCommand
|
from ...subclass import MineCommand, ProgressBarStyle
|
||||||
|
from ...types import Optional
|
||||||
from ..bdx import (
|
from ..bdx import (
|
||||||
bdx_move,
|
bdx_move,
|
||||||
commands_to_BDX_bytes,
|
commands_to_BDX_bytes,
|
||||||
@ -26,12 +27,12 @@ from ..bdx import (
|
|||||||
y,
|
y,
|
||||||
z,
|
z,
|
||||||
)
|
)
|
||||||
from ..main import ConvertConfig
|
|
||||||
|
|
||||||
|
|
||||||
def to_BDX_file_in_score(
|
def to_BDX_file_in_score(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
|
progressbar_style: Optional[ProgressBarStyle],
|
||||||
scoreboard_name: str = "mscplay",
|
scoreboard_name: str = "mscplay",
|
||||||
auto_reset: bool = False,
|
auto_reset: bool = False,
|
||||||
author: str = "Eilles",
|
author: str = "Eilles",
|
||||||
@ -44,8 +45,10 @@ def to_BDX_file_in_score(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
|
progressbar_style: ProgressBarStyle 对象
|
||||||
|
进度条对象
|
||||||
scoreboard_name: str
|
scoreboard_name: str
|
||||||
我的世界的计分板名称
|
我的世界的计分板名称
|
||||||
auto_reset: bool
|
auto_reset: bool
|
||||||
@ -64,11 +67,11 @@ def to_BDX_file_in_score(
|
|||||||
scoreboard_name=scoreboard_name,
|
scoreboard_name=scoreboard_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.bdx")),
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.bdx")),
|
||||||
"w+",
|
"w+",
|
||||||
) as f:
|
) as f:
|
||||||
f.write("BD@")
|
f.write("BD@")
|
||||||
@ -97,11 +100,9 @@ def to_BDX_file_in_score(
|
|||||||
max_height - 1,
|
max_height - 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
if data_cfg.progressbar_style:
|
if progressbar_style:
|
||||||
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
||||||
midi_cvt.form_progress_bar(
|
midi_cvt.form_progress_bar(max_score, scoreboard_name, progressbar_style),
|
||||||
max_score, scoreboard_name, data_cfg.progressbar_style
|
|
||||||
),
|
|
||||||
max_height - 1,
|
max_height - 1,
|
||||||
)
|
)
|
||||||
_bytes += pgbBytes
|
_bytes += pgbBytes
|
||||||
@ -116,7 +117,7 @@ def to_BDX_file_in_score(
|
|||||||
_bytes += cmdBytes
|
_bytes += cmdBytes
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.bdx")),
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.bdx")),
|
||||||
"ab+",
|
"ab+",
|
||||||
) as f:
|
) as f:
|
||||||
f.write(brotli.compress(_bytes + b"XE"))
|
f.write(brotli.compress(_bytes + b"XE"))
|
||||||
@ -126,7 +127,8 @@ def to_BDX_file_in_score(
|
|||||||
|
|
||||||
def to_BDX_file_in_delay(
|
def to_BDX_file_in_delay(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
|
progressbar_style: Optional[ProgressBarStyle],
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
author: str = "Eilles",
|
author: str = "Eilles",
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
@ -138,8 +140,10 @@ def to_BDX_file_in_delay(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
|
progressbar_style: ProgressBarStyle 对象
|
||||||
|
进度条对象
|
||||||
player: str
|
player: str
|
||||||
玩家选择器,默认为`@a`
|
玩家选择器,默认为`@a`
|
||||||
author: str
|
author: str
|
||||||
@ -156,11 +160,11 @@ def to_BDX_file_in_delay(
|
|||||||
player_selector=player,
|
player_selector=player,
|
||||||
)[:2]
|
)[:2]
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.bdx")),
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.bdx")),
|
||||||
"w+",
|
"w+",
|
||||||
) as f:
|
) as f:
|
||||||
f.write("BD@")
|
f.write("BD@")
|
||||||
@ -171,7 +175,7 @@ def to_BDX_file_in_delay(
|
|||||||
|
|
||||||
cmdBytes, size, finalPos = commands_to_BDX_bytes(cmdlist, max_height - 1)
|
cmdBytes, size, finalPos = commands_to_BDX_bytes(cmdlist, max_height - 1)
|
||||||
|
|
||||||
if data_cfg.progressbar_style:
|
if progressbar_style:
|
||||||
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
scb_name = midi_cvt.music_name[:3] + "Pgb"
|
||||||
_bytes += form_command_block_in_BDX_bytes(
|
_bytes += form_command_block_in_BDX_bytes(
|
||||||
r"scoreboard objectives add {} dummy {}计".replace(r"{}", scb_name),
|
r"scoreboard objectives add {} dummy {}计".replace(r"{}", scb_name),
|
||||||
@ -187,7 +191,7 @@ def to_BDX_file_in_delay(
|
|||||||
)
|
)
|
||||||
_bytes += bdx_move(y, 1)
|
_bytes += bdx_move(y, 1)
|
||||||
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
pgbBytes, pgbSize, pgbNowPos = commands_to_BDX_bytes(
|
||||||
midi_cvt.form_progress_bar(max_delay, scb_name, data_cfg.progressbar_style),
|
midi_cvt.form_progress_bar(max_delay, scb_name, progressbar_style),
|
||||||
max_height - 1,
|
max_height - 1,
|
||||||
)
|
)
|
||||||
_bytes += pgbBytes
|
_bytes += pgbBytes
|
||||||
@ -208,7 +212,7 @@ def to_BDX_file_in_delay(
|
|||||||
_bytes += cmdBytes
|
_bytes += cmdBytes
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.bdx")),
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.bdx")),
|
||||||
"ab+",
|
"ab+",
|
||||||
) as f:
|
) as f:
|
||||||
f.write(brotli.compress(_bytes + b"XE"))
|
f.write(brotli.compress(_bytes + b"XE"))
|
||||||
|
@ -16,77 +16,77 @@ Terms & Conditions: License.md in the root directory
|
|||||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||||
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
# from dataclasses import dataclass
|
||||||
from typing import Literal, Tuple, Union
|
# from typing import Literal, Tuple, Union
|
||||||
|
|
||||||
from ..subclass import DEFAULT_PROGRESSBAR_STYLE, ProgressBarStyle
|
# from ..subclass import DEFAULT_PROGRESSBAR_STYLE, ProgressBarStyle
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
# @dataclass(init=False)
|
||||||
class ConvertConfig: # 必定要改
|
# class ConvertConfig: # 必定要改
|
||||||
"""
|
# """
|
||||||
转换通用设置存储类
|
# 转换通用设置存储类
|
||||||
"""
|
# """
|
||||||
|
|
||||||
progressbar_style: Union[ProgressBarStyle, None]
|
# progressbar_style: Union[ProgressBarStyle, None]
|
||||||
"""进度条样式"""
|
# """进度条样式"""
|
||||||
|
|
||||||
dist_path: str
|
# dist_path: str
|
||||||
"""输出目录"""
|
# """输出目录"""
|
||||||
|
|
||||||
def __init__(
|
# def __init__(
|
||||||
self,
|
# self,
|
||||||
output_path: str,
|
# output_path: str,
|
||||||
progressbar: Union[bool, Tuple[str, Tuple[str, str]], ProgressBarStyle] = True,
|
# progressbar: Union[bool, Tuple[str, Tuple[str, str]], ProgressBarStyle] = True,
|
||||||
ignore_progressbar_param_error: bool = False,
|
# ignore_progressbar_param_error: bool = False,
|
||||||
):
|
# ):
|
||||||
"""
|
# """
|
||||||
将已经转换好的数据内容指令载入MC可读格式
|
# 将已经转换好的数据内容指令载入MC可读格式
|
||||||
|
|
||||||
Parameters
|
# Parameters
|
||||||
----------
|
# ----------
|
||||||
output_path: str
|
# output_path: str
|
||||||
生成内容的输出目录
|
# 生成内容的输出目录
|
||||||
volume: float
|
# volume: float
|
||||||
音量比率,范围为(0,1],其原理为在距离玩家 (1 / volume -1) 的地方播放音频
|
# 音量比率,范围为(0,1],其原理为在距离玩家 (1 / volume -1) 的地方播放音频
|
||||||
speed: float
|
# speed: float
|
||||||
速度倍率,注意:这里的速度指的是播放速度倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
|
# 速度倍率,注意:这里的速度指的是播放速度倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
|
||||||
progressbar: bool|tuple[str, Tuple[str,]]
|
# progressbar: bool|tuple[str, Tuple[str,]]
|
||||||
进度条,当此参数为 `True` 时使用默认进度条,为其他的**值为真**的参数时识别为进度条自定义参数,为其他**值为假**的时候不生成进度条
|
# 进度条,当此参数为 `True` 时使用默认进度条,为其他的**值为真**的参数时识别为进度条自定义参数,为其他**值为假**的时候不生成进度条
|
||||||
|
|
||||||
"""
|
# """
|
||||||
|
|
||||||
self.dist_path = output_path
|
# self.dist_path = output_path
|
||||||
"""输出目录"""
|
# """输出目录"""
|
||||||
|
|
||||||
if progressbar:
|
# if progressbar:
|
||||||
# 此处是对于仅有 True 的参数和自定义参数的判断
|
# # 此处是对于仅有 True 的参数和自定义参数的判断
|
||||||
# 改这一段没🐎
|
# # 改这一段没🐎
|
||||||
if progressbar is True:
|
# if progressbar is True:
|
||||||
self.progressbar_style = DEFAULT_PROGRESSBAR_STYLE
|
# self.progressbar_style = DEFAULT_PROGRESSBAR_STYLE
|
||||||
"""进度条样式"""
|
# """进度条样式"""
|
||||||
return
|
# return
|
||||||
elif isinstance(progressbar, ProgressBarStyle):
|
# elif isinstance(progressbar, ProgressBarStyle):
|
||||||
self.progressbar_style = progressbar
|
# self.progressbar_style = progressbar
|
||||||
"""进度条样式"""
|
# """进度条样式"""
|
||||||
return
|
# return
|
||||||
elif isinstance(progressbar, tuple):
|
# elif isinstance(progressbar, tuple):
|
||||||
if isinstance(progressbar[0], str) and isinstance(
|
# if isinstance(progressbar[0], str) and isinstance(
|
||||||
progressbar[1], tuple
|
# progressbar[1], tuple
|
||||||
):
|
# ):
|
||||||
if isinstance(progressbar[1][0], str) and isinstance(
|
# if isinstance(progressbar[1][0], str) and isinstance(
|
||||||
progressbar[1][1], str
|
# progressbar[1][1], str
|
||||||
):
|
# ):
|
||||||
self.progressbar_style = ProgressBarStyle(
|
# self.progressbar_style = ProgressBarStyle(
|
||||||
progressbar[0], progressbar[1][0], progressbar[1][1]
|
# progressbar[0], progressbar[1][0], progressbar[1][1]
|
||||||
)
|
# )
|
||||||
return
|
# return
|
||||||
if not ignore_progressbar_param_error:
|
# if not ignore_progressbar_param_error:
|
||||||
raise TypeError(
|
# raise TypeError(
|
||||||
"参数 {} 的类型 {} 与所需类型 Union[bool, Tuple[str, Tuple[str, str]], ProgressBarStyle] 不符。".format(
|
# "参数 {} 的类型 {} 与所需类型 Union[bool, Tuple[str, Tuple[str, str]], ProgressBarStyle] 不符。".format(
|
||||||
progressbar, type(progressbar)
|
# progressbar, type(progressbar)
|
||||||
)
|
# )
|
||||||
)
|
# )
|
||||||
|
|
||||||
self.progressbar_style = None
|
# self.progressbar_style = None
|
||||||
"""进度条样式组"""
|
# """进度条样式组"""
|
||||||
|
@ -18,6 +18,7 @@ __all__ = [
|
|||||||
"to_mcstructure_file_in_delay",
|
"to_mcstructure_file_in_delay",
|
||||||
"to_mcstructure_file_in_repeater",
|
"to_mcstructure_file_in_repeater",
|
||||||
"to_mcstructure_file_in_score",
|
"to_mcstructure_file_in_score",
|
||||||
|
"to_mcstructure_files_in_repeater_divided_by_instruments",
|
||||||
]
|
]
|
||||||
__author__ = (("金羿", "Eilles Wan"),)
|
__author__ = (("金羿", "Eilles Wan"),)
|
||||||
|
|
||||||
@ -25,4 +26,5 @@ from .main import (
|
|||||||
to_mcstructure_file_in_delay,
|
to_mcstructure_file_in_delay,
|
||||||
to_mcstructure_file_in_repeater,
|
to_mcstructure_file_in_repeater,
|
||||||
to_mcstructure_file_in_score,
|
to_mcstructure_file_in_score,
|
||||||
|
to_mcstructure_files_in_repeater_divided_by_instruments,
|
||||||
)
|
)
|
||||||
|
@ -14,9 +14,7 @@ Terms & Conditions: License.md in the root directory
|
|||||||
import os
|
import os
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
# from ...exceptions import CommandFormatError
|
|
||||||
from ...main import MidiConvert
|
from ...main import MidiConvert
|
||||||
from ..main import ConvertConfig
|
|
||||||
from ...subclass import MineCommand
|
from ...subclass import MineCommand
|
||||||
from ..mcstructure import (
|
from ..mcstructure import (
|
||||||
COMPABILITY_VERSION_117,
|
COMPABILITY_VERSION_117,
|
||||||
@ -28,7 +26,7 @@ from ..mcstructure import (
|
|||||||
|
|
||||||
def to_mcstructure_file_in_delay(
|
def to_mcstructure_file_in_delay(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
):
|
):
|
||||||
@ -39,8 +37,8 @@ def to_mcstructure_file_in_delay(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
player: str
|
player: str
|
||||||
玩家选择器,默认为`@a`
|
玩家选择器,默认为`@a`
|
||||||
max_height: int
|
max_height: int
|
||||||
@ -61,17 +59,15 @@ def to_mcstructure_file_in_delay(
|
|||||||
player_selector=player,
|
player_selector=player,
|
||||||
)[:2]
|
)[:2]
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
struct, size, end_pos = commands_to_structure(
|
struct, size, end_pos = commands_to_structure(
|
||||||
cmd_list, max_height - 1, compability_version_=compability_ver
|
cmd_list, max_height - 1, compability_version_=compability_ver
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.mcstructure")),
|
||||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.mcstructure")
|
|
||||||
),
|
|
||||||
"wb+",
|
"wb+",
|
||||||
) as f:
|
) as f:
|
||||||
struct.dump(f)
|
struct.dump(f)
|
||||||
@ -81,7 +77,7 @@ def to_mcstructure_file_in_delay(
|
|||||||
|
|
||||||
def to_mcstructure_file_in_score(
|
def to_mcstructure_file_in_score(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
scoreboard_name: str = "mscplay",
|
scoreboard_name: str = "mscplay",
|
||||||
auto_reset: bool = False,
|
auto_reset: bool = False,
|
||||||
max_height: int = 64,
|
max_height: int = 64,
|
||||||
@ -93,8 +89,8 @@ def to_mcstructure_file_in_score(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
scoreboard_name: str
|
scoreboard_name: str
|
||||||
我的世界的计分板名称
|
我的世界的计分板名称
|
||||||
auto_reset: bool
|
auto_reset: bool
|
||||||
@ -117,8 +113,8 @@ def to_mcstructure_file_in_score(
|
|||||||
scoreboard_name=scoreboard_name,
|
scoreboard_name=scoreboard_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
struct, size, end_pos = commands_to_structure(
|
struct, size, end_pos = commands_to_structure(
|
||||||
midi_cvt.music_command_list
|
midi_cvt.music_command_list
|
||||||
@ -142,9 +138,7 @@ def to_mcstructure_file_in_score(
|
|||||||
)
|
)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.mcstructure")),
|
||||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.mcstructure")
|
|
||||||
),
|
|
||||||
"wb+",
|
"wb+",
|
||||||
) as f:
|
) as f:
|
||||||
struct.dump(f)
|
struct.dump(f)
|
||||||
@ -154,7 +148,7 @@ def to_mcstructure_file_in_score(
|
|||||||
|
|
||||||
def to_mcstructure_file_in_repeater(
|
def to_mcstructure_file_in_repeater(
|
||||||
midi_cvt: MidiConvert,
|
midi_cvt: MidiConvert,
|
||||||
data_cfg: ConvertConfig,
|
dist_path: str,
|
||||||
player: str = "@a",
|
player: str = "@a",
|
||||||
axis_side: Literal["z+", "z-", "Z+", "Z-", "x+", "x-", "X+", "X-"] = "z+",
|
axis_side: Literal["z+", "z-", "Z+", "Z-", "x+", "x-", "X+", "X-"] = "z+",
|
||||||
basement_block: str = "concrete",
|
basement_block: str = "concrete",
|
||||||
@ -166,8 +160,8 @@ def to_mcstructure_file_in_repeater(
|
|||||||
----------
|
----------
|
||||||
midi_cvt: MidiConvert 对象
|
midi_cvt: MidiConvert 对象
|
||||||
用于转换的MidiConvert对象
|
用于转换的MidiConvert对象
|
||||||
data_cfg: ConvertConfig 对象
|
dist_path: str
|
||||||
部分转换通用参数
|
转换结果输出的目标路径
|
||||||
player: str
|
player: str
|
||||||
玩家选择器,默认为`@a`
|
玩家选择器,默认为`@a`
|
||||||
axis_side: Literal["z+","z-","Z+","Z-","x+","x-","X+","X-"]
|
axis_side: Literal["z+","z-","Z+","Z-","x+","x-","X+","X-"]
|
||||||
@ -190,8 +184,8 @@ def to_mcstructure_file_in_repeater(
|
|||||||
player_selector=player,
|
player_selector=player,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not os.path.exists(data_cfg.dist_path):
|
if not os.path.exists(dist_path):
|
||||||
os.makedirs(data_cfg.dist_path)
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
struct, size, end_pos = commands_to_redstone_delay_structure(
|
struct, size, end_pos = commands_to_redstone_delay_structure(
|
||||||
cmd_list,
|
cmd_list,
|
||||||
@ -203,11 +197,78 @@ def to_mcstructure_file_in_repeater(
|
|||||||
)
|
)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.abspath(
|
os.path.abspath(os.path.join(dist_path, f"{midi_cvt.music_name}.mcstructure")),
|
||||||
os.path.join(data_cfg.dist_path, f"{midi_cvt.music_name}.mcstructure")
|
|
||||||
),
|
|
||||||
"wb+",
|
"wb+",
|
||||||
) as f:
|
) as f:
|
||||||
struct.dump(f)
|
struct.dump(f)
|
||||||
|
|
||||||
return size, max_delay
|
return size, max_delay
|
||||||
|
|
||||||
|
|
||||||
|
def to_mcstructure_files_in_repeater_divided_by_instruments(
|
||||||
|
midi_cvt: MidiConvert,
|
||||||
|
dist_path: str,
|
||||||
|
player: str = "@a",
|
||||||
|
axis_side: Literal["z+", "z-", "Z+", "Z-", "x+", "x-", "X+", "X-"] = "z+",
|
||||||
|
basement_block: str = "concrete",
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
将midi以延迟播放器形式转换为mcstructure结构文件
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
midi_cvt: MidiConvert 对象
|
||||||
|
用于转换的MidiConvert对象
|
||||||
|
dist_path: str
|
||||||
|
转换结果输出的目标路径
|
||||||
|
player: str
|
||||||
|
玩家选择器,默认为`@a`
|
||||||
|
axis_side: Literal["z+","z-","Z+","Z-","x+","x-","X+","X-"]
|
||||||
|
生成结构的延展方向
|
||||||
|
basement_block: str
|
||||||
|
结构的基底方块
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
int音乐总延迟
|
||||||
|
"""
|
||||||
|
|
||||||
|
compability_ver = (
|
||||||
|
COMPABILITY_VERSION_117
|
||||||
|
if midi_cvt.enable_old_exe_format
|
||||||
|
else COMPABILITY_VERSION_119
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd_dict, max_delay, max_multiple_cmd_count = (
|
||||||
|
midi_cvt.to_command_list_in_delay_devided_by_instrument(
|
||||||
|
player_selector=player,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.exists(dist_path):
|
||||||
|
os.makedirs(dist_path)
|
||||||
|
|
||||||
|
for inst, cmd_list in cmd_dict.items():
|
||||||
|
struct, size, end_pos = commands_to_redstone_delay_structure(
|
||||||
|
cmd_list,
|
||||||
|
max_delay,
|
||||||
|
max_multiple_cmd_count[inst],
|
||||||
|
basement_block,
|
||||||
|
axis_side,
|
||||||
|
compability_version_=compability_ver,
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.abspath(
|
||||||
|
os.path.join(
|
||||||
|
dist_path,
|
||||||
|
"{}_{}.mcstructure".format(
|
||||||
|
midi_cvt.music_name, inst.replace(".", "-")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"wb+",
|
||||||
|
) as f:
|
||||||
|
struct.dump(f)
|
||||||
|
|
||||||
|
return max_delay
|
||||||
|
@ -118,6 +118,7 @@ class MineNote:
|
|||||||
"Percussive" if self.percussive else "",
|
"Percussive" if self.percussive else "",
|
||||||
self.sound_name,
|
self.sound_name,
|
||||||
"" if self.percussive else "NotePitch = {}, ".format(self.note_pitch),
|
"" if self.percussive else "NotePitch = {}, ".format(self.note_pitch),
|
||||||
|
self.velocity,
|
||||||
self.start_tick,
|
self.start_tick,
|
||||||
self.duration,
|
self.duration,
|
||||||
", Track = {}".format(self.track_no) if is_track else "",
|
", Track = {}".format(self.track_no) if is_track else "",
|
||||||
@ -554,6 +555,25 @@ class ProgressBarStyle:
|
|||||||
self.to_play_style = to_play_s
|
self.to_play_style = to_play_s
|
||||||
self.played_style = played_s
|
self.played_style = played_s
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_tuple(cls, tuplized_style: Tuple[str, Tuple[str, str]]):
|
||||||
|
"""自旧版进度条元组表示法读入数据(已不建议使用)"""
|
||||||
|
if isinstance(tuplized_style, tuple):
|
||||||
|
if isinstance(tuplized_style[0], str) and isinstance(
|
||||||
|
tuplized_style[1], tuple
|
||||||
|
):
|
||||||
|
if isinstance(tuplized_style[1][0], str) and isinstance(
|
||||||
|
tuplized_style[1][1], str
|
||||||
|
):
|
||||||
|
return cls(
|
||||||
|
tuplized_style[0], tuplized_style[1][0], tuplized_style[1][1]
|
||||||
|
)
|
||||||
|
raise ValueError(
|
||||||
|
"元组表示的进度条样式组 {} 格式错误,已不建议使用此功能,请尽快更换。".format(
|
||||||
|
tuplized_style
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def set_base_style(self, value: str):
|
def set_base_style(self, value: str):
|
||||||
"""设置基础样式"""
|
"""设置基础样式"""
|
||||||
self.base_style = value
|
self.base_style = value
|
||||||
|
@ -18,7 +18,12 @@ Terms & Conditions: License.md in the root directory
|
|||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from .constants import MC_INSTRUMENT_BLOCKS_TABLE, MM_INSTRUMENT_RANGE_TABLE
|
from .constants import (
|
||||||
|
MC_INSTRUMENT_BLOCKS_TABLE,
|
||||||
|
MM_INSTRUMENT_DEVIATION_TABLE,
|
||||||
|
MC_PITCHED_INSTRUMENT_LIST,
|
||||||
|
MM_INSTRUMENT_RANGE_TABLE,
|
||||||
|
)
|
||||||
from .subclass import SingleNote, MineNote
|
from .subclass import SingleNote, MineNote
|
||||||
|
|
||||||
from .types import (
|
from .types import (
|
||||||
@ -61,7 +66,7 @@ def inst_to_sould_with_deviation(
|
|||||||
) -> Tuple[str, int]:
|
) -> Tuple[str, int]:
|
||||||
"""
|
"""
|
||||||
返回midi的乐器ID对应的我的世界乐器名,对于音域转换算法,如下:
|
返回midi的乐器ID对应的我的世界乐器名,对于音域转换算法,如下:
|
||||||
2**( ( msg.note - 66 ) / 12 ) 即为MC的音高
|
2**( ( msg.note - 60 - X ) / 12 ) 即为MC的音高
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
@ -74,16 +79,17 @@ def inst_to_sould_with_deviation(
|
|||||||
-------
|
-------
|
||||||
tuple(str我的世界乐器名, int转换算法中的X)
|
tuple(str我的世界乐器名, int转换算法中的X)
|
||||||
"""
|
"""
|
||||||
return (
|
sound_id = midi_inst_to_mc_sound(
|
||||||
reference_table.get(
|
instrumentID=instrumentID,
|
||||||
instrumentID,
|
reference_table=reference_table,
|
||||||
default_instrument,
|
default_instrument=default_instrument,
|
||||||
),
|
)
|
||||||
6,
|
return sound_id, MM_INSTRUMENT_DEVIATION_TABLE.get(
|
||||||
|
sound_id,
|
||||||
|
MM_INSTRUMENT_DEVIATION_TABLE.get(
|
||||||
|
default_instrument, 6 if sound_id in MC_PITCHED_INSTRUMENT_LIST else -1
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 明明已经走了
|
|
||||||
# 凭什么还要在我心里留下缠绵缱绻
|
|
||||||
|
|
||||||
|
|
||||||
def midi_inst_to_mc_sound(
|
def midi_inst_to_mc_sound(
|
||||||
@ -179,7 +185,18 @@ def minenote_to_command_paramaters(
|
|||||||
(
|
(
|
||||||
None
|
None
|
||||||
if note_.percussive
|
if note_.percussive
|
||||||
else 2 ** ((note_.note_pitch - 66 + pitch_deviation) / 12)
|
else (
|
||||||
|
2
|
||||||
|
** (
|
||||||
|
(
|
||||||
|
note_.note_pitch
|
||||||
|
- 60
|
||||||
|
- MM_INSTRUMENT_DEVIATION_TABLE.get(note_.sound_name, 6)
|
||||||
|
+ pitch_deviation
|
||||||
|
)
|
||||||
|
/ 12
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -205,7 +222,7 @@ def single_note_to_command_parameters(
|
|||||||
:return str[我的世界音符ID], Tuple[float,float,float]播放视角坐标, float[指令音量参数], float[指令音调参数]
|
:return str[我的世界音符ID], Tuple[float,float,float]播放视角坐标, float[指令音量参数], float[指令音调参数]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mc_sound_ID = midi_inst_to_mc_sound(
|
mc_sound_ID, _X = inst_to_sould_with_deviation(
|
||||||
note_.inst,
|
note_.inst,
|
||||||
reference_table,
|
reference_table,
|
||||||
"note.bd" if note_.percussive else "note.flute",
|
"note.bd" if note_.percussive else "note.flute",
|
||||||
@ -217,7 +234,7 @@ def single_note_to_command_parameters(
|
|||||||
mc_sound_ID,
|
mc_sound_ID,
|
||||||
(0, mc_distance_volume, 0),
|
(0, mc_distance_volume, 0),
|
||||||
note_.velocity / 127,
|
note_.velocity / 127,
|
||||||
None if note_.percussive else 2 ** ((note_.pitch - 66 + deviation) / 12),
|
None if note_.percussive else 2 ** ((note_.pitch - 60 - _X + deviation) / 12),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
49
example.py
49
example.py
@ -19,7 +19,6 @@ Terms & Conditions: ./License.md
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
import Musicreater
|
import Musicreater
|
||||||
from Musicreater.plugin import ConvertConfig
|
|
||||||
from Musicreater.plugin.addonpack import (
|
from Musicreater.plugin.addonpack import (
|
||||||
to_addon_pack_in_delay,
|
to_addon_pack_in_delay,
|
||||||
to_addon_pack_in_repeater,
|
to_addon_pack_in_repeater,
|
||||||
@ -160,7 +159,7 @@ print(f"正在处理 {midi_path} :")
|
|||||||
cvt_mid = Musicreater.MidiConvert.from_midi_file(
|
cvt_mid = Musicreater.MidiConvert.from_midi_file(
|
||||||
midi_path, old_exe_format=False, min_volume=prompts[0], play_speed=prompts[1]
|
midi_path, old_exe_format=False, min_volume=prompts[0], play_speed=prompts[1]
|
||||||
)
|
)
|
||||||
cvt_cfg = ConvertConfig(out_path, prompts[2])
|
|
||||||
|
|
||||||
if fileFormat == 0:
|
if fileFormat == 0:
|
||||||
if playerFormat == 1:
|
if playerFormat == 1:
|
||||||
@ -177,28 +176,62 @@ elif fileFormat == 2:
|
|||||||
elif playerFormat == 2:
|
elif playerFormat == 2:
|
||||||
cvt_method = to_mcstructure_file_in_repeater
|
cvt_method = to_mcstructure_file_in_repeater
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
|
||||||
|
# print(cvt_mid)
|
||||||
|
|
||||||
|
|
||||||
print(
|
print(
|
||||||
" 指令总长:{},最高延迟:{}".format(
|
" 指令总长:{},最高延迟:{}".format(
|
||||||
*(cvt_method(cvt_mid, cvt_cfg, *prompts[3:])) # type: ignore
|
*(
|
||||||
|
cvt_method(
|
||||||
|
cvt_mid,
|
||||||
|
out_path,
|
||||||
|
Musicreater.DEFAULT_PROGRESSBAR_STYLE if prompts[2] else None, # type: ignore
|
||||||
|
*prompts[3:],
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if fileFormat == 0
|
if fileFormat == 0
|
||||||
else (
|
else (
|
||||||
" 指令总长:{},最高延迟:{},结构大小{},终点坐标{}".format(
|
" 指令总长:{},最高延迟:{},结构大小{},终点坐标{}".format(
|
||||||
*(
|
*(
|
||||||
to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:])
|
to_BDX_file_in_score(
|
||||||
|
cvt_mid,
|
||||||
|
out_path,
|
||||||
|
Musicreater.DEFAULT_PROGRESSBAR_STYLE if prompts[2] else None,
|
||||||
|
*prompts[3:],
|
||||||
|
)
|
||||||
if playerFormat == 1
|
if playerFormat == 1
|
||||||
else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:])
|
else to_BDX_file_in_delay(
|
||||||
|
cvt_mid,
|
||||||
|
out_path,
|
||||||
|
Musicreater.DEFAULT_PROGRESSBAR_STYLE if prompts[2] else None,
|
||||||
|
*prompts[3:],
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if fileFormat == 1
|
if fileFormat == 1
|
||||||
else (
|
else (
|
||||||
" 结构大小:{},延迟总数:{},指令数量:{}".format(
|
" 结构大小:{},延迟总数:{},指令数量:{}".format(
|
||||||
*(cvt_method(cvt_mid, cvt_cfg, *prompts[3:])) # type: ignore
|
*(
|
||||||
|
cvt_method(
|
||||||
|
cvt_mid,
|
||||||
|
out_path,
|
||||||
|
*prompts[3:],
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if playerFormat == 2
|
if playerFormat == 1
|
||||||
else " 结构大小:{},延迟总数:{}".format(
|
else " 结构大小:{},延迟总数:{}".format(
|
||||||
*(cvt_method(cvt_mid, cvt_cfg, *prompts[3:])) # type: ignore
|
*(
|
||||||
|
cvt_method(
|
||||||
|
cvt_mid,
|
||||||
|
out_path,
|
||||||
|
# Musicreater.DEFAULT_PROGRESSBAR_STYLE if prompts[2] else None, # type: ignore
|
||||||
|
*prompts[3:],
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,8 @@ print(
|
|||||||
Musicreater.experiment.FutureMidiConvertM4.from_midi_file(
|
Musicreater.experiment.FutureMidiConvertM4.from_midi_file(
|
||||||
input("midi路径:"), old_exe_format=False
|
input("midi路径:"), old_exe_format=False
|
||||||
),
|
),
|
||||||
Musicreater.plugin.ConvertConfig(input("输出路径:"),),
|
input("输出路径:"),
|
||||||
|
# Musicreater.plugin.ConvertConfig(input("输出路径:"),),
|
||||||
max_height=32,
|
max_height=32,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
14
example_singleConvert.py
Normal file
14
example_singleConvert.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import Musicreater
|
||||||
|
import Musicreater.plugin
|
||||||
|
import Musicreater.plugin.addonpack
|
||||||
|
|
||||||
|
print(
|
||||||
|
Musicreater.plugin.addonpack.to_addon_pack_in_repeater_divided_by_instrument(
|
||||||
|
Musicreater.MidiConvert.from_midi_file(
|
||||||
|
input("midi路径:"), old_exe_format=False
|
||||||
|
),
|
||||||
|
input("输出路径:"),
|
||||||
|
# Musicreater.plugin.ConvertConfig(input("输出路径:"),),
|
||||||
|
# max_height=32,
|
||||||
|
)
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user