mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2025-09-03 19:06:23 +00:00
更丰富的音符附加信息支持
This commit is contained in:
@ -22,8 +22,8 @@ The Licensor of Musicreater("this project") is Eilles, bgArray.
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||
|
||||
|
||||
__version__ = "2.4.1"
|
||||
__vername__ = "Midi 歌词支持,文档格式更新"
|
||||
__version__ = "2.4.2"
|
||||
__vername__ = "音符附加信息升级"
|
||||
__author__ = (
|
||||
("金羿", "Eilles"),
|
||||
("诸葛亮与八卦阵", "bgArray"),
|
||||
|
@ -79,7 +79,7 @@ class FutureMidiConvertLyricSupport(MidiConvert):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -367,7 +367,7 @@ class FutureMidiConvertKamiRES(MidiConvert):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -446,7 +446,7 @@ class FutureMidiConvertKamiRES(MidiConvert):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -783,7 +783,7 @@ class FutureMidiConvertJavaE(MidiConvert):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -874,8 +874,14 @@ class FutureMidiConvertM4(MidiConvert):
|
||||
|
||||
totalCount = int(_note.duration / _apply_time_division)
|
||||
|
||||
if totalCount == 0:
|
||||
print(_note.extra_info)
|
||||
if (
|
||||
totalCount == 0
|
||||
or (_note.get_info("PITCH") > 2 and _note.sound_name != "note.bass")
|
||||
):
|
||||
from rich import print as prt
|
||||
|
||||
prt("[INFO] 音符太短或音调太高,无法生成插值")
|
||||
prt(_note)
|
||||
return [
|
||||
_note,
|
||||
]
|
||||
@ -883,18 +889,24 @@ class FutureMidiConvertM4(MidiConvert):
|
||||
|
||||
result: List[MineNote] = []
|
||||
|
||||
_slide = _note.duration / totalCount
|
||||
_distance_slide = 20 / totalCount
|
||||
|
||||
for _i in range(totalCount):
|
||||
result.append(
|
||||
MineNote(
|
||||
mc_sound_name=_note.sound_name,
|
||||
midi_pitch=_note.note_pitch,
|
||||
midi_velocity=_note.velocity,
|
||||
start_time=int(
|
||||
_note.start_tick + _i * (_note.duration / totalCount)
|
||||
),
|
||||
last_time=int(_note.duration / totalCount),
|
||||
start_time=int(_note.start_tick + _i * _slide),
|
||||
last_time=int(_slide),
|
||||
# track_number=_note.track_no,
|
||||
is_percussion=_note.percussive,
|
||||
distance=_note.sound_distance + _i * _distance_slide,
|
||||
azimuth=(
|
||||
_note.sound_azimuth[0],
|
||||
_note.sound_azimuth[1] + 5 * random.random(),
|
||||
),
|
||||
extra_information=_note.extra_info,
|
||||
)
|
||||
# (
|
||||
@ -931,14 +943,17 @@ class FutureMidiConvertM4(MidiConvert):
|
||||
for channel in self.channels.values():
|
||||
for note in channel:
|
||||
note.set_info(
|
||||
minenote_to_command_paramaters(
|
||||
["NOTE_ID", "COODINATES", "VOLUME", "PITCH"],
|
||||
minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
if not note.percussive:
|
||||
notes_list.extend(self._linear_note(note, 1 * note.extra_info[3]))
|
||||
notes_list.extend(
|
||||
self._linear_note(note, 2 * note.get_info("PITCH"))
|
||||
)
|
||||
else:
|
||||
notes_list.append(note)
|
||||
|
||||
@ -954,12 +969,17 @@ class FutureMidiConvertM4(MidiConvert):
|
||||
else:
|
||||
max_multi = max(max_multi, multi)
|
||||
multi = 0
|
||||
|
||||
(
|
||||
mc_sound_ID,
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = note.extra_info
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
|
||||
self.music_command_list.append(
|
||||
MineCommand(
|
||||
command=(
|
||||
|
@ -112,7 +112,7 @@ class MusicSequence:
|
||||
"""
|
||||
音符序列类
|
||||
|
||||
Paramaters
|
||||
Parameters
|
||||
==========
|
||||
name_of_music: str
|
||||
乐曲名称
|
||||
@ -175,7 +175,7 @@ class MusicSequence:
|
||||
"""
|
||||
自mido对象导入一个音符序列类
|
||||
|
||||
Paramaters
|
||||
Parameters
|
||||
==========
|
||||
mido_file: mido.MidiFile
|
||||
需要处理的midi对象
|
||||
@ -247,7 +247,7 @@ class MusicSequence:
|
||||
"""
|
||||
从字节码导入音乐序列,目前支持 MSQ 第二、三、四版和 FSQ 第一、二版。
|
||||
|
||||
Paramaters
|
||||
Parameters
|
||||
==========
|
||||
bytes_buffer_in: bytes
|
||||
字节码
|
||||
@ -1588,7 +1588,7 @@ class MidiConvert(MusicSequence):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -1672,7 +1672,7 @@ class MidiConvert(MusicSequence):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
@ -1758,7 +1758,7 @@ class MidiConvert(MusicSequence):
|
||||
relative_coordinates,
|
||||
volume_percentage,
|
||||
mc_pitch,
|
||||
) = minenote_to_command_paramaters(
|
||||
) = minenote_to_command_parameters(
|
||||
note,
|
||||
pitch_deviation=self.music_deviation,
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ Terms & Conditions: License.md in the root directory
|
||||
|
||||
from math import sin, cos, asin, radians, degrees, sqrt, atan
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Any, List, Tuple, Union, Dict
|
||||
from typing import Optional, Any, List, Tuple, Union, Dict, Sequence
|
||||
|
||||
from .constants import MC_PITCHED_INSTRUMENT_LIST
|
||||
|
||||
@ -54,7 +54,7 @@ class MineNote:
|
||||
sound_azimuth: Tuple[float, float]
|
||||
"""声源方位 角度"""
|
||||
|
||||
extra_info: Any
|
||||
extra_info: Dict[str, Any]
|
||||
"""你觉得放什么好?"""
|
||||
|
||||
def __init__(
|
||||
@ -68,7 +68,7 @@ class MineNote:
|
||||
is_percussion: Optional[bool] = None,
|
||||
distance: Optional[float] = None,
|
||||
azimuth: Optional[Tuple[float, float]] = None,
|
||||
extra_information: Optional[Dict[str, Any]] = None,
|
||||
extra_information: Dict[str, Any] = {},
|
||||
):
|
||||
"""
|
||||
用于存储单个音符的类
|
||||
@ -98,7 +98,7 @@ class MineNote:
|
||||
注:此参数为tuple,包含两个元素,分别表示:
|
||||
`rV` 发声源在竖直(上下)轴上,从玩家视角正前方开始,向顺时针旋转的角度
|
||||
`rH` 发声源在水平(左右)轴上,从玩家视角正前方开始,向上(到达玩家正上方顶点后变为向下,以此类推的旋转)旋转的角度
|
||||
extra_information: Any
|
||||
extra_information: Dict[str, Any]
|
||||
附加信息,尽量存储为字典
|
||||
|
||||
Returns
|
||||
@ -136,7 +136,7 @@ class MineNote:
|
||||
)
|
||||
"""声源距离"""
|
||||
|
||||
self.extra_info = extra_information
|
||||
self.extra_info = extra_information if extra_information else {}
|
||||
|
||||
@classmethod
|
||||
def from_traditional(
|
||||
@ -210,7 +210,15 @@ class MineNote:
|
||||
is_percussion=is_percussion,
|
||||
distance=r,
|
||||
azimuth=(alpha_v, beta_h),
|
||||
extra_information=extra_information,
|
||||
extra_information=(
|
||||
(
|
||||
extra_information
|
||||
if isinstance(extra_information, dict)
|
||||
else {"EXTRA_INFO": extra_information}
|
||||
)
|
||||
if extra_information
|
||||
else {}
|
||||
),
|
||||
)
|
||||
|
||||
@property
|
||||
@ -225,7 +233,7 @@ class MineNote:
|
||||
|
||||
@classmethod
|
||||
def decode(cls, code_buffer: bytes, is_high_time_precision: bool = True):
|
||||
"""自字节码析出MineNote类"""
|
||||
"""自字节码析出 MineNote 类"""
|
||||
group_1 = int.from_bytes(code_buffer[:6], "big")
|
||||
percussive_ = bool(group_1 & 0b1)
|
||||
duration_ = (group_1 := group_1 >> 1) & 0b11111111111111111
|
||||
@ -375,9 +383,34 @@ class MineNote:
|
||||
)
|
||||
)
|
||||
|
||||
def set_info(self, sth: Any):
|
||||
def set_info(self, key: Union[str, Sequence[str]], value: Any):
|
||||
"""设置附加信息"""
|
||||
self.extra_info = sth
|
||||
if isinstance(key, str):
|
||||
self.extra_info[key] = value
|
||||
elif (
|
||||
isinstance(key, Sequence)
|
||||
and isinstance(value, Sequence)
|
||||
and (k := len(key)) == len(value)
|
||||
):
|
||||
for i in range(k):
|
||||
self.extra_info[key[i]] = value[i]
|
||||
else:
|
||||
raise TypeError("参数类型错误")
|
||||
|
||||
def get_info(self, key: str) -> Any:
|
||||
"""获取附加信息"""
|
||||
if key in self.extra_info:
|
||||
return self.extra_info[key]
|
||||
elif "EXTRA_INFO" in self.extra_info:
|
||||
if (
|
||||
isinstance(self.extra_info["EXTRA_INFO"], dict)
|
||||
and key in self.extra_info["EXTRA_INFO"]
|
||||
):
|
||||
return self.extra_info["EXTRA_INFO"].get(key)
|
||||
else:
|
||||
return self.extra_info["EXTRA_INFO"]
|
||||
else:
|
||||
return None
|
||||
|
||||
def stringize(
|
||||
self, include_displacement: bool = False, include_extra_data: bool = False
|
||||
|
@ -49,7 +49,7 @@ ChannelType = Dict[
|
||||
],
|
||||
]
|
||||
"""
|
||||
以字典所标记的频道信息类型(已弃用)
|
||||
以字典所标记的通道信息类型(已弃用)
|
||||
|
||||
Dict[int,Dict[int,List[Union[Tuple[Literal["PgmC"], int, int],Tuple[Literal["NoteS"], int, int, int],Tuple[Literal["NoteE"], int, int],]],],]
|
||||
"""
|
||||
@ -60,7 +60,14 @@ MineNoteChannelType = Mapping[
|
||||
List[MineNote,],
|
||||
]
|
||||
"""
|
||||
我的世界频道信息类型
|
||||
我的世界通道信息类型
|
||||
|
||||
Dict[int,Dict[int,List[MineNote,],],]
|
||||
"""
|
||||
|
||||
MineNoteTrackType = Mapping[
|
||||
int,
|
||||
List[MineNote,],
|
||||
]
|
||||
|
||||
|
||||
|
@ -212,8 +212,8 @@ def panning_2_rotation_trigonometric(pan_: float) -> float:
|
||||
return math.degrees(math.acos((64 - pan_) / 63)) - 90
|
||||
|
||||
|
||||
def minenote_to_command_paramaters(
|
||||
note_: MineNote,
|
||||
def minenote_to_command_parameters(
|
||||
mine_note: MineNote,
|
||||
pitch_deviation: float = 0,
|
||||
) -> Tuple[
|
||||
str,
|
||||
@ -226,7 +226,7 @@ def minenote_to_command_paramaters(
|
||||
|
||||
Parameters
|
||||
------------
|
||||
note_: MineNote
|
||||
mine_note: MineNote
|
||||
音符对象
|
||||
deviation: float
|
||||
音调偏移量
|
||||
@ -238,19 +238,19 @@ def minenote_to_command_paramaters(
|
||||
"""
|
||||
|
||||
return (
|
||||
note_.sound_name,
|
||||
note_.position_displacement,
|
||||
note_.velocity / 127,
|
||||
mine_note.sound_name,
|
||||
mine_note.position_displacement,
|
||||
mine_note.velocity / 127,
|
||||
(
|
||||
None
|
||||
if note_.percussive
|
||||
if mine_note.percussive
|
||||
else (
|
||||
2
|
||||
** (
|
||||
(
|
||||
note_.note_pitch
|
||||
mine_note.note_pitch
|
||||
- 60
|
||||
- MM_INSTRUMENT_DEVIATION_TABLE.get(note_.sound_name, 6)
|
||||
- MM_INSTRUMENT_DEVIATION_TABLE.get(mine_note.sound_name, 6)
|
||||
+ pitch_deviation
|
||||
)
|
||||
/ 12
|
||||
|
Reference in New Issue
Block a user