diff --git a/.gitignore b/.gitignore index f6eff6c..e819f29 100644 --- a/.gitignore +++ b/.gitignore @@ -5,12 +5,13 @@ # mystuff /.vscode -*.mid -*.midi -*.mcpack -*.bdx -*.json -*.mcstructure +/*.mid +/*.midi +/*.mcpack +/*.bdx +/*.json +/*.mcstructure +.mscbackup /logs /languages /llc_cli.py diff --git a/Musicreater/__init__.py b/Musicreater/__init__.py index b35b252..f7b9666 100644 --- a/Musicreater/__init__.py +++ b/Musicreater/__init__.py @@ -17,8 +17,8 @@ Terms & Conditions: License.md in the root directory # 若需转载或借鉴 许可声明请查看仓库目录下的 License.md -__version__ = "1.4.1" -__vername__ = "提高mcstructure结构的兼容性" +__version__ = "1.4.2" +__vername__ = "优质的红石音乐生成&更好的线性插值算法" __author__ = ( ("金羿", "Eilles Wan"), ("诸葛亮与八卦阵", "bgArray"), diff --git a/Musicreater/experiment.py b/Musicreater/experiment.py index fa4ab6b..88522ee 100644 --- a/Musicreater/experiment.py +++ b/Musicreater/experiment.py @@ -171,6 +171,7 @@ class FutureMidiConvertM4(MidiConvert): :return list[tuple(int开始时间(毫秒), int乐器, int音符, int力度(内置), float音量(播放)),]""" totalCount = int(_note.duration / _apply_time_division) + if totalCount == 0: return [ (_note.start_time, _note.inst, _note.pitch, _note.velocity, 1), @@ -277,7 +278,7 @@ class FutureMidiConvertM4(MidiConvert): for note in track: for every_note in self._linear_note( - note, 50 if note.track_no == 0 else 500 + note, 100 if note.track_no == 0 else 500 ): soundID, _X = ( self.perc_inst_to_soundID_withX(note.pitch) @@ -334,7 +335,7 @@ class FutureMidiConvertM4(MidiConvert): max_volume: float = 1.0, speed: float = 1.0, player_selector: str = "@a", - ) -> Tuple[List[SingleCommand], int]: + ) -> Tuple[List[SingleCommand], int, int]: """ 使用金羿的转换思路,使用完全填充算法优化音感后,将midi转换为我的世界命令列表,并输出每个音符之后的延迟 @@ -349,7 +350,7 @@ class FutureMidiConvertM4(MidiConvert): Returns ------- - tuple( list[SingleCommand,...], int音乐时长游戏刻 ) + tuple( list[SingleCommand,...], int音乐时长游戏刻, int最大同时播放的指令数量 ) """ if speed == 0: @@ -410,9 +411,10 @@ class FutureMidiConvertM4(MidiConvert): SpecialBits = True if no == 9 else False for note in track: - for every_note in self._linear_note( - note, 50 if note.track_no == 0 else 500 - ): + liner_list = self._linear_note( + note, 100 if note.track_no == 0 else 500 + ) + for every_note in liner_list: soundID, _X = ( self.perc_inst_to_soundID_withX(note.pitch) if SpecialBits @@ -444,10 +446,14 @@ class FutureMidiConvertM4(MidiConvert): all_ticks = list(tracks.keys()) all_ticks.sort() - results = [] + results:List[SingleCommand] = [] + max_multi = 0 + now_multi_delay = 0 + now_multi = 0 for i in range(len(all_ticks)): - for j in range(len(tracks[all_ticks[i]])): + l = len(tracks[all_ticks[i]]) + for j in range(l): results.append( SingleCommand( tracks[all_ticks[i]][j], @@ -460,15 +466,20 @@ class FutureMidiConvertM4(MidiConvert): else all_ticks[i] ) ), - annotation="在{}播放{}%的{}音".format( - mctick2timestr(i), max_volume * 100, "" - ), + annotation="由 音·创 生成", ) ) + if results[-1].delay + now_multi_delay <= 1: + now_multi += 1 + now_multi_delay += results[-1].delay + else: + max_multi = max(max_multi, now_multi) + now_multi = 0 + now_multi_delay = 0 self.music_command_list = results self.music_tick_num = max(all_ticks) - return results, self.music_tick_num + return results, self.music_tick_num, max_multi class FutureMidiConvertM5(MidiConvert): diff --git a/Musicreater/plugin/mcstructure.py b/Musicreater/plugin/mcstructure.py index 4169f0e..f0dd9e3 100644 --- a/Musicreater/plugin/mcstructure.py +++ b/Musicreater/plugin/mcstructure.py @@ -349,93 +349,137 @@ def commands_to_redstone_delay_structure( goahead = forward_IER(forward) + command_actually_length = sum([int(bool(cmd.delay))for cmd in commands]) + + a = 1 + for cmd in commands: + # print("\r 正在进行处理:",end="") + if cmd.delay > 2: + a = 1 + else: + a += 1 + + struct = Structure( size=( - round(delay_length / 2 + 0.5 + len(commands)) + round(delay_length / 2 + command_actually_length) if extensioon_direction == x - else max_multicmd_length, + else a, 3, - round(delay_length / 2 + 0.5 + len(commands)) + round(delay_length / 2 + command_actually_length) if extensioon_direction == z - else max_multicmd_length, + else a, ), + fill=Block('minecraft','air',compability_version=compability_version_), compability_version=compability_version_, ) pos_now = { - x: (0 if forward else struct.size[0]), + x: ((1 if extensioon_direction == x else 0) if forward else struct.size[0]), y: 0, - z: (0 if forward else struct.size[2]), + z: ((1 if extensioon_direction == z else 0) if forward else struct.size[2]), } - first_impluse = True + chain_list = 0 + # print("结构元信息设定完毕") for cmd in commands: - single_repeater_value = round(cmd.delay / 2) % 4 - 1 - additional_repeater = round(cmd.delay / 2) // 4 - for i in range(additional_repeater): - struct.set_block( - tuple(pos_now.values()), - Block( - "minecraft", - base_block, - compability_version=compability_version_, - ), - ) + # print("\r 正在进行处理:",end="") + if cmd.delay > 1: + # print("\rdelay > 0",end='') + single_repeater_value = int(cmd.delay / 2) % 4 - 1 + additional_repeater = int(cmd.delay / 2 // 4) + for i in range(additional_repeater): + struct.set_block( + tuple(pos_now.values()),# type: ignore + Block( + "minecraft", + base_block, + compability_version=compability_version_, + ), + ) + struct.set_block( + (pos_now[x], 1, pos_now[z]), + form_repeater_in_NBT_struct( + delay=3, + facing=repeater_facing, + compability_version_number=compability_version_, + ), + ) + pos_now[extensioon_direction] += goahead + if single_repeater_value >= 0: + struct.set_block( + tuple(pos_now.values()),# type: ignore + Block( + "minecraft", + base_block, + compability_version=compability_version_, + ), + ) + struct.set_block( + (pos_now[x], 1, pos_now[z]), + form_repeater_in_NBT_struct( + delay=single_repeater_value, + facing=repeater_facing, + compability_version_number=compability_version_, + ), + ) + pos_now[extensioon_direction] += goahead struct.set_block( (pos_now[x], 1, pos_now[z]), - form_repeater_in_NBT_struct( - delay=3, - facing=repeater_facing, + form_command_block_in_NBT_struct( + command=cmd.command_text, + coordinate=(pos_now[x], 1, pos_now[z]), + particularValue=command_statevalue(extensioon_direction, forward), + # impluse= (0 if first_impluse else 2), + impluse=0, + condition=False, + alwaysRun=False, + tickDelay=cmd.delay % 2, + customName=cmd.annotation_text, compability_version_number=compability_version_, ), ) - pos_now[extensioon_direction] += goahead - first_impluse = True - if single_repeater_value >= 0: struct.set_block( - tuple(pos_now.values()), + (pos_now[x], 2, pos_now[z]), Block( "minecraft", - base_block, + "redstone_wire", compability_version=compability_version_, ), ) + pos_now[extensioon_direction] += goahead + chain_list = 1 + + else: + # print(pos_now) + now_pos_copy = pos_now.copy() + now_pos_copy[extensioon_direction] -= goahead + now_pos_copy[aside_direction] += chain_list + # print(pos_now,"\n=========") struct.set_block( - (pos_now[x], 1, pos_now[z]), - form_repeater_in_NBT_struct( - delay=single_repeater_value, - facing=repeater_facing, + (now_pos_copy[x], 1, now_pos_copy[z]), + form_command_block_in_NBT_struct( + command=cmd.command_text, + coordinate=(now_pos_copy[x], 1, now_pos_copy[z]), + particularValue=command_statevalue(extensioon_direction, forward), + # impluse= (0 if first_impluse else 2), + impluse=0, + condition=False, + alwaysRun=False, + tickDelay=cmd.delay % 2, + customName=cmd.annotation_text, compability_version_number=compability_version_, ), ) - pos_now[extensioon_direction] += goahead - first_impluse = True - struct.set_block( - (pos_now[x], 1, pos_now[z]), - form_command_block_in_NBT_struct( - command=cmd.command_text, - coordinate=(pos_now[x], 1, pos_now[z]), - particularValue=command_statevalue(extensioon_direction, forward), - # impluse= (0 if first_impluse else 2), - impluse=0, - condition=False, - alwaysRun=False, - tickDelay=0, - customName=cmd.annotation_text, - compability_version_number=compability_version_, - ), - ) - struct.set_block( - (pos_now[x], 2, pos_now[z]), - Block( - "minecraft", - "redstone_wire", - compability_version=compability_version_, - ), - ) - pos_now[extensioon_direction] += goahead + struct.set_block( + (now_pos_copy[x], 2, now_pos_copy[z]), + Block( + "minecraft", + "redstone_wire", + compability_version=compability_version_, + ), + ) + chain_list += 1 - first_impluse = False - - return struct, struct.size, tuple(pos_now.values()) + return struct, struct.size, tuple(pos_now.values())# type: ignore diff --git a/example.py b/example.py index 8bb99da..3274662 100644 --- a/example.py +++ b/example.py @@ -103,7 +103,7 @@ else: print(f"正在处理 {midi_path} :") -cvt_mid = Musicreater.MidiConvert.from_midi_file(midi_path, old_exe_format=False) +cvt_mid = Musicreater.MidiConvert.from_midi_file(midi_path, old_exe_format=True) cvt_cfg = ConvertConfig(out_path, *prompts[:3]) print( diff --git a/example_mcstructure_rcd_future.py b/example_mcstructure_rcd_future.py new file mode 100644 index 0000000..7c0bc49 --- /dev/null +++ b/example_mcstructure_rcd_future.py @@ -0,0 +1,13 @@ +import Musicreater.experiment +import Musicreater.plugin +import Musicreater.plugin.mcstructfile + +print( + Musicreater.plugin.mcstructfile.to_mcstructure_file_in_redstone_CD( + Musicreater.experiment.FutureMidiConvertM4.from_midi_file(input("midi路径:"), old_exe_format=False), + Musicreater.plugin.ConvertConfig( + input("输出路径:"), + volume=1 + ), + ) +) diff --git a/resources/测试片段.mid b/resources/测试片段.mid new file mode 100644 index 0000000..0e4513a Binary files /dev/null and b/resources/测试片段.mid differ diff --git a/resources/测试片段.mscz b/resources/测试片段.mscz new file mode 100644 index 0000000..be9c5d9 Binary files /dev/null and b/resources/测试片段.mscz differ