diff --git a/.gitignore b/.gitignore index bc8c252..d49abd9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ TEST-*.* vanilla_assets/ /*.mid /*.midi +/*.wav # Fack Apple .DS_Store diff --git a/Musicreater/builtin_plugins/music_preview/main.py b/Musicreater/builtin_plugins/music_preview/main.py index 7ca6a06..a3b0722 100644 --- a/Musicreater/builtin_plugins/music_preview/main.py +++ b/Musicreater/builtin_plugins/music_preview/main.py @@ -292,7 +292,7 @@ class MusicPreview: + len( self.get_res( sound_name=i.instrument, - pitch=i.pitch + pitch=i.midi_pitch - 60 - MM_INSTRUMENT_DEVIATION_TABLE.get( i.instrument, 6 @@ -328,7 +328,7 @@ class MusicPreview: + len( self.get_res( sound_name=i.instrument, - pitch=i.pitch + pitch=i.midi_pitch - 60 - MM_INSTRUMENT_DEVIATION_TABLE.get( i.instrument, 6 @@ -358,7 +358,7 @@ class MusicPreview: 0 if note.percussive else self.make_pitch_accurate( - note.pitch + note.midi_pitch - 60 - MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6) ) diff --git a/Musicreater/builtin_plugins/to_commands/main.py b/Musicreater/builtin_plugins/to_commands/main.py index 8b67da1..530262b 100644 --- a/Musicreater/builtin_plugins/to_commands/main.py +++ b/Musicreater/builtin_plugins/to_commands/main.py @@ -35,7 +35,7 @@ from Musicreater.exceptions import ZeroSpeedError, IllegalMinimumVolumeError from Musicreater._utils import enumerated_stuffcopy_dictionary from .progressbar import ProgressBarStyle, DEFAULT_PROGRESSBAR_STYLE, mctick2timestr -from .utils import minenote_to_command_parameters +from .utils import get_accurate_deviation # @dataclass # class CommandConvertionConfig(PluginConfig): @@ -505,17 +505,14 @@ class NoteDataConvert2CommandPlugin(LibraryPluginBase): this_channel = [] + __deviation = get_accurate_deviation( + track.instrument.name, + pitch_deviation=music_deviation, + ) + for note in track.minenotes: max_score = max(max_score, note.start_tick) - ( - relative_coordinates, - mc_pitch, - ) = minenote_to_command_parameters( - note, - pitch_deviation=music_deviation, - ) - this_channel.append( MineCommand( ( @@ -527,9 +524,9 @@ class NoteDataConvert2CommandPlugin(LibraryPluginBase): .replace(")", r"}") ) + "playsound {} @s ^{:.4f} ^{:.4f} ^{:.4f} 3.0 {:.6f} {}".format( - track.instrument, - *relative_coordinates, - 1.0 if note.percussive else mc_pitch, + note.instrument, + *note.position.position_displacement, + mc_pitch := note.minecraft_pitch(__deviation), minimum_volume, ) ), @@ -591,22 +588,16 @@ class NoteDataConvert2CommandPlugin(LibraryPluginBase): max_multi = max(max_multi, multi) multi = 0 - ( - relative_coordinates, - mc_pitch, - ) = minenote_to_command_parameters( - note, - pitch_deviation=music_deviation, - ) - music_command_list.append( MineCommand( command=( execute_command_head.format(player_selector) + "playsound {} @s ^{:.4f} ^{:.4f} ^{:.4f} 3.0 {:.6f} {}".format( note.instrument, - *relative_coordinates, - 1.0 if note.percussive else mc_pitch, + *note.position.position_displacement, + mc_pitch := note.minecraft_pitch( + get_accurate_deviation(note.instrument, music_deviation) + ), minimum_volume, ) ), diff --git a/Musicreater/builtin_plugins/to_commands/utils.py b/Musicreater/builtin_plugins/to_commands/utils.py index cf80bfc..0b416de 100644 --- a/Musicreater/builtin_plugins/to_commands/utils.py +++ b/Musicreater/builtin_plugins/to_commands/utils.py @@ -32,23 +32,19 @@ from Musicreater import MineNote, SingleNote from Musicreater.constants import MM_INSTRUMENT_DEVIATION_TABLE -# 这个函数可以直接被优化成一个只处理音调参数的,没必要完整留着 -def minenote_to_command_parameters( - mine_note: MineNote, +def get_accurate_deviation( + instrument: str, pitch_deviation: float = 0, -) -> Tuple[ - Tuple[float, float, float], - Union[float, Literal[None]], -]: +) -> float: """ - 将 MineNote 对象转为《我的世界》音符播放所需之参数 + 获取乐器所对应的音调偏移量 参数 ---- - mine_note: MineNote - 我的世界音符对象 + instrument: str + 我的世界乐器 pitch_deviation: float - 音调偏移量 + 人工干预的音调偏移量 返回 ---- @@ -56,58 +52,4 @@ def minenote_to_command_parameters( 播放视角坐标, 指令音调参数 """ - return ( - mine_note.position.position_displacement, - ( - None - if mine_note.percussive - else ( - 2 - ** ( - ( - mine_note.pitch - - 60 - - MM_INSTRUMENT_DEVIATION_TABLE.get(mine_note.instrument, 6) - + pitch_deviation - ) - / 12 - ) - ) - ), - ) - - -def calculate_minecraft_pitch( - note: MineNote, pitch_deviation: float = 0 -) -> Optional[float]: - """ - 计算音符的音调参数 - - 参数 - ---- - note: MineNote - 我的世界音符对象 - deviation: float - 音调偏移量 - - 返回 - ---- - Optional[float] - 音调参数, 当为打击乐器时为 None - """ - return ( - None - if note.percussive - else ( - 2 - ** ( - ( - note.pitch - - 60 - - MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6) - + pitch_deviation - ) - / 12 - ) - ) - ) + return pitch_deviation - MM_INSTRUMENT_DEVIATION_TABLE.get(instrument, 6) diff --git a/Musicreater/constants.py b/Musicreater/constants.py index c1c44a2..25493a5 100644 --- a/Musicreater/constants.py +++ b/Musicreater/constants.py @@ -625,7 +625,9 @@ MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = { } """ 不同乐器的音调偏离对照表 -*注意* 该表中的单位是对于 Midi Pitch 音调(整数)的低音偏移。 +*注意* + 该表中的单位是 Midi Pitch(整数) + 表示的值是该乐器的采样音调需要减去 60 后再减去多少才会为 0 也就是说,该数值越高,则在 Midi Pitch 中的值域越低 默认的偏移量为 6 ,因为在计算音高时候少减去了 6 个 Pitch 单位 (在表里的数据是用作被减数的,实际计算时默认有 +6,所以在表中默认的 6 最后就会被抵消) diff --git a/Musicreater/data.py b/Musicreater/data.py index 133adb2..49af845 100644 --- a/Musicreater/data.py +++ b/Musicreater/data.py @@ -426,7 +426,7 @@ class SingleNote: class MineNote: """我的世界音符对象(仅提供我的世界相关接口)""" - pitch: float + midi_pitch: float """Midi 音高""" instrument: str """乐器标识""" @@ -463,7 +463,7 @@ class MineNote: ) -> "MineNote": """从SingleNote对象创建MineNote对象""" return cls( - pitch=note.midi_pitch + adjust_note_pitch, + midi_pitch=note.midi_pitch + adjust_note_pitch, instrument=note_instrument, start_tick=note.start_time, duration_tick=note.duration, @@ -508,15 +508,21 @@ class MineNote: ), ) - def minecraft_pitch(self, pitch_deviation: float): + + def minecraft_pitch(self, pitch_deviation: float) -> float: + """ + 获取该音符在 Minecraft Playsound 指令中对应的音调参数 + """ + + # TODO 当前的设计方法并未考虑到自定义乐器的音调偏移 return ( - None + 1.0 if self.percussive else ( 2 ** ( ( - self.pitch + self.midi_pitch - 60 # - MM_INSTRUMENT_DEVIATION_TABLE.get(self.instrument, 6) + pitch_deviation