mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2025-09-04 03:16:23 +00:00
更丰富的音符附加信息支持
This commit is contained in:
@ -22,8 +22,8 @@ The Licensor of Musicreater("this project") is Eilles, bgArray.
|
|||||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||||
|
|
||||||
|
|
||||||
__version__ = "2.4.1"
|
__version__ = "2.4.2"
|
||||||
__vername__ = "Midi 歌词支持,文档格式更新"
|
__vername__ = "音符附加信息升级"
|
||||||
__author__ = (
|
__author__ = (
|
||||||
("金羿", "Eilles"),
|
("金羿", "Eilles"),
|
||||||
("诸葛亮与八卦阵", "bgArray"),
|
("诸葛亮与八卦阵", "bgArray"),
|
||||||
|
@ -79,7 +79,7 @@ class FutureMidiConvertLyricSupport(MidiConvert):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -367,7 +367,7 @@ class FutureMidiConvertKamiRES(MidiConvert):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -446,7 +446,7 @@ class FutureMidiConvertKamiRES(MidiConvert):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -783,7 +783,7 @@ class FutureMidiConvertJavaE(MidiConvert):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -874,8 +874,14 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
|
|
||||||
totalCount = int(_note.duration / _apply_time_division)
|
totalCount = int(_note.duration / _apply_time_division)
|
||||||
|
|
||||||
if totalCount == 0:
|
if (
|
||||||
print(_note.extra_info)
|
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 [
|
return [
|
||||||
_note,
|
_note,
|
||||||
]
|
]
|
||||||
@ -883,18 +889,24 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
|
|
||||||
result: List[MineNote] = []
|
result: List[MineNote] = []
|
||||||
|
|
||||||
|
_slide = _note.duration / totalCount
|
||||||
|
_distance_slide = 20 / totalCount
|
||||||
|
|
||||||
for _i in range(totalCount):
|
for _i in range(totalCount):
|
||||||
result.append(
|
result.append(
|
||||||
MineNote(
|
MineNote(
|
||||||
mc_sound_name=_note.sound_name,
|
mc_sound_name=_note.sound_name,
|
||||||
midi_pitch=_note.note_pitch,
|
midi_pitch=_note.note_pitch,
|
||||||
midi_velocity=_note.velocity,
|
midi_velocity=_note.velocity,
|
||||||
start_time=int(
|
start_time=int(_note.start_tick + _i * _slide),
|
||||||
_note.start_tick + _i * (_note.duration / totalCount)
|
last_time=int(_slide),
|
||||||
),
|
|
||||||
last_time=int(_note.duration / totalCount),
|
|
||||||
# track_number=_note.track_no,
|
# track_number=_note.track_no,
|
||||||
is_percussion=_note.percussive,
|
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,
|
extra_information=_note.extra_info,
|
||||||
)
|
)
|
||||||
# (
|
# (
|
||||||
@ -931,14 +943,17 @@ 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(
|
||||||
minenote_to_command_paramaters(
|
["NOTE_ID", "COODINATES", "VOLUME", "PITCH"],
|
||||||
|
minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
if not note.percussive:
|
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:
|
else:
|
||||||
notes_list.append(note)
|
notes_list.append(note)
|
||||||
|
|
||||||
@ -954,12 +969,17 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
else:
|
else:
|
||||||
max_multi = max(max_multi, multi)
|
max_multi = max(max_multi, multi)
|
||||||
multi = 0
|
multi = 0
|
||||||
|
|
||||||
(
|
(
|
||||||
mc_sound_ID,
|
mc_sound_ID,
|
||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = note.extra_info
|
) = minenote_to_command_parameters(
|
||||||
|
note,
|
||||||
|
pitch_deviation=self.music_deviation,
|
||||||
|
)
|
||||||
|
|
||||||
self.music_command_list.append(
|
self.music_command_list.append(
|
||||||
MineCommand(
|
MineCommand(
|
||||||
command=(
|
command=(
|
||||||
|
@ -112,7 +112,7 @@ class MusicSequence:
|
|||||||
"""
|
"""
|
||||||
音符序列类
|
音符序列类
|
||||||
|
|
||||||
Paramaters
|
Parameters
|
||||||
==========
|
==========
|
||||||
name_of_music: str
|
name_of_music: str
|
||||||
乐曲名称
|
乐曲名称
|
||||||
@ -175,7 +175,7 @@ class MusicSequence:
|
|||||||
"""
|
"""
|
||||||
自mido对象导入一个音符序列类
|
自mido对象导入一个音符序列类
|
||||||
|
|
||||||
Paramaters
|
Parameters
|
||||||
==========
|
==========
|
||||||
mido_file: mido.MidiFile
|
mido_file: mido.MidiFile
|
||||||
需要处理的midi对象
|
需要处理的midi对象
|
||||||
@ -247,7 +247,7 @@ class MusicSequence:
|
|||||||
"""
|
"""
|
||||||
从字节码导入音乐序列,目前支持 MSQ 第二、三、四版和 FSQ 第一、二版。
|
从字节码导入音乐序列,目前支持 MSQ 第二、三、四版和 FSQ 第一、二版。
|
||||||
|
|
||||||
Paramaters
|
Parameters
|
||||||
==========
|
==========
|
||||||
bytes_buffer_in: bytes
|
bytes_buffer_in: bytes
|
||||||
字节码
|
字节码
|
||||||
@ -1588,7 +1588,7 @@ class MidiConvert(MusicSequence):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -1672,7 +1672,7 @@ class MidiConvert(MusicSequence):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
pitch_deviation=self.music_deviation,
|
||||||
)
|
)
|
||||||
@ -1758,7 +1758,7 @@ class MidiConvert(MusicSequence):
|
|||||||
relative_coordinates,
|
relative_coordinates,
|
||||||
volume_percentage,
|
volume_percentage,
|
||||||
mc_pitch,
|
mc_pitch,
|
||||||
) = minenote_to_command_paramaters(
|
) = minenote_to_command_parameters(
|
||||||
note,
|
note,
|
||||||
pitch_deviation=self.music_deviation,
|
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 math import sin, cos, asin, radians, degrees, sqrt, atan
|
||||||
from dataclasses import dataclass
|
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
|
from .constants import MC_PITCHED_INSTRUMENT_LIST
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ class MineNote:
|
|||||||
sound_azimuth: Tuple[float, float]
|
sound_azimuth: Tuple[float, float]
|
||||||
"""声源方位 角度"""
|
"""声源方位 角度"""
|
||||||
|
|
||||||
extra_info: Any
|
extra_info: Dict[str, Any]
|
||||||
"""你觉得放什么好?"""
|
"""你觉得放什么好?"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -68,7 +68,7 @@ class MineNote:
|
|||||||
is_percussion: Optional[bool] = None,
|
is_percussion: Optional[bool] = None,
|
||||||
distance: Optional[float] = None,
|
distance: Optional[float] = None,
|
||||||
azimuth: Optional[Tuple[float, 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,包含两个元素,分别表示:
|
注:此参数为tuple,包含两个元素,分别表示:
|
||||||
`rV` 发声源在竖直(上下)轴上,从玩家视角正前方开始,向顺时针旋转的角度
|
`rV` 发声源在竖直(上下)轴上,从玩家视角正前方开始,向顺时针旋转的角度
|
||||||
`rH` 发声源在水平(左右)轴上,从玩家视角正前方开始,向上(到达玩家正上方顶点后变为向下,以此类推的旋转)旋转的角度
|
`rH` 发声源在水平(左右)轴上,从玩家视角正前方开始,向上(到达玩家正上方顶点后变为向下,以此类推的旋转)旋转的角度
|
||||||
extra_information: Any
|
extra_information: Dict[str, Any]
|
||||||
附加信息,尽量存储为字典
|
附加信息,尽量存储为字典
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -136,7 +136,7 @@ class MineNote:
|
|||||||
)
|
)
|
||||||
"""声源距离"""
|
"""声源距离"""
|
||||||
|
|
||||||
self.extra_info = extra_information
|
self.extra_info = extra_information if extra_information else {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_traditional(
|
def from_traditional(
|
||||||
@ -210,7 +210,15 @@ class MineNote:
|
|||||||
is_percussion=is_percussion,
|
is_percussion=is_percussion,
|
||||||
distance=r,
|
distance=r,
|
||||||
azimuth=(alpha_v, beta_h),
|
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
|
@property
|
||||||
@ -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(
|
def stringize(
|
||||||
self, include_displacement: bool = False, include_extra_data: bool = False
|
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],]],],]
|
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,],
|
List[MineNote,],
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
我的世界频道信息类型
|
我的世界通道信息类型
|
||||||
|
|
||||||
Dict[int,Dict[int,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
|
return math.degrees(math.acos((64 - pan_) / 63)) - 90
|
||||||
|
|
||||||
|
|
||||||
def minenote_to_command_paramaters(
|
def minenote_to_command_parameters(
|
||||||
note_: MineNote,
|
mine_note: MineNote,
|
||||||
pitch_deviation: float = 0,
|
pitch_deviation: float = 0,
|
||||||
) -> Tuple[
|
) -> Tuple[
|
||||||
str,
|
str,
|
||||||
@ -226,7 +226,7 @@ def minenote_to_command_paramaters(
|
|||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
------------
|
------------
|
||||||
note_: MineNote
|
mine_note: MineNote
|
||||||
音符对象
|
音符对象
|
||||||
deviation: float
|
deviation: float
|
||||||
音调偏移量
|
音调偏移量
|
||||||
@ -238,19 +238,19 @@ def minenote_to_command_paramaters(
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
return (
|
return (
|
||||||
note_.sound_name,
|
mine_note.sound_name,
|
||||||
note_.position_displacement,
|
mine_note.position_displacement,
|
||||||
note_.velocity / 127,
|
mine_note.velocity / 127,
|
||||||
(
|
(
|
||||||
None
|
None
|
||||||
if note_.percussive
|
if mine_note.percussive
|
||||||
else (
|
else (
|
||||||
2
|
2
|
||||||
** (
|
** (
|
||||||
(
|
(
|
||||||
note_.note_pitch
|
mine_note.note_pitch
|
||||||
- 60
|
- 60
|
||||||
- MM_INSTRUMENT_DEVIATION_TABLE.get(note_.sound_name, 6)
|
- MM_INSTRUMENT_DEVIATION_TABLE.get(mine_note.sound_name, 6)
|
||||||
+ pitch_deviation
|
+ pitch_deviation
|
||||||
)
|
)
|
||||||
/ 12
|
/ 12
|
||||||
|
Reference in New Issue
Block a user