完成对 MineNote 音调偏移的重构

This commit is contained in:
Eilles
2026-08-07 02:56:10 +08:00
parent 9a3fe99519
commit d525eed6e1
6 changed files with 39 additions and 97 deletions
+1
View File
@@ -32,6 +32,7 @@ TEST-*.*
vanilla_assets/
/*.mid
/*.midi
/*.wav
# Fack Apple
.DS_Store
@@ -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)
)
+13 -22
View File
@@ -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,
)
),
@@ -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)
+3 -1
View File
@@ -625,7 +625,9 @@ MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
}
"""
不同乐器的音调偏离对照表
*注意* 该表中的单位是对于 Midi Pitch 音调(整数)的低音偏移。
*注意*
该表中的单位是 Midi Pitch(整数)
表示的值是该乐器的采样音调需要减去 60 后再减去多少才会为 0
也就是说,该数值越高,则在 Midi Pitch 中的值域越低
默认的偏移量为 6 ,因为在计算音高时候少减去了 6 个 Pitch 单位
(在表里的数据是用作被减数的,实际计算时默认有 +6,所以在表中默认的 6 最后就会被抵消)
+11 -5
View File
@@ -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