准备移植 v2 功能到插件来

This commit is contained in:
2026-02-08 06:14:20 +08:00
parent d4901cf3dc
commit 2a5ccb8eeb
17 changed files with 1095 additions and 956 deletions

View File

@@ -33,7 +33,6 @@ __author__ = (
("金羿", "Eilles"),
("玉衡Alioth", "YuhengAlioth"),
("鱼旧梦", "ElapsingDreams"),
("偷吃不是Touch", "Touch"),
)
from .paramcurve import ParamCurve, InterpolationMethod, BoundaryBehaviour

View File

@@ -41,6 +41,7 @@ from typing import (
Generator,
Iterator,
Set,
Type,
)
if sys.version_info >= (3, 11):
@@ -97,6 +98,7 @@ from .data import SingleMusic, SingleTrack
# 枚举类
# ========================
class PluginTypes(str, Enum):
"""插件类型枚举"""
@@ -110,7 +112,6 @@ class PluginTypes(str, Enum):
LIBRARY = "library"
# ========================
# 数据类
# ========================
@@ -174,7 +175,7 @@ class PluginConfig(ABC):
with file_path.open("wb") as f:
tomli_w.dump(self.to_dict(), f, multiline_strings=False, indent=4)
except Exception as e:
raise PluginConfigDumpError(e)
raise PluginConfigDumpError("插件配置文件无法保存。") from e
@classmethod
def load_from_file(cls, file_path: Path) -> "PluginConfig":
@@ -199,7 +200,7 @@ class PluginConfig(ABC):
with file_path.open("rb") as f:
return cls.from_dict(tomllib.load(f))
except Exception as e:
raise PluginConfigLoadError(e)
raise PluginConfigLoadError("插件配置文件无法加载。") from e
@dataclass

View File

@@ -1,59 +0,0 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 Midi 读取插件
"""
"""
版权所有 © 2026 金羿、玉衡Alioth
Copyright © 2026 Eilles, YuhengAlioth
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
import mido
from pathlib import Path
from typing import BinaryIO, Optional
from Musicreater import SingleMusic
from Musicreater.plugins import (
music_input_plugin,
PluginConfig,
PluginMetaInformation,
PluginTypes,
MusicInputPluginBase,
)
@music_input_plugin("midi_2_music_plugin")
class MidiImport2MusicPlugin(MusicInputPluginBase):
"""Midi 音乐数据导入插件"""
metainfo = PluginMetaInformation(
name="Midi 导入插件",
author="金羿、玉衡Alioth",
description="从 Midi 文件导入音乐数据",
version=(0, 0, 1),
type=PluginTypes.FUNCTION_MUSIC_IMPORT,
license="Same as Musicreater",
)
supported_formats = ("MID", "MIDI")
def loadbytes(
self, bytes_buffer_in: BinaryIO, config: PluginConfig | None
) -> SingleMusic:
midi_file = mido.MidiFile(file=bytes_buffer_in)
return SingleMusic() # =========================== TODO: 等待制作
def load(self, file_path: Path, config: Optional[PluginConfig]) -> "SingleMusic":
"""从 Midi 文件导入音乐数据"""
midi_file = mido.MidiFile(filename=file_path)
return SingleMusic() # =========================== TODO: 等待制作

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 Midi 读取插件
"""
"""
版权所有 © 2026 金羿、玉衡Alioth、偷吃不是Touch
Copyright © 2026 Eilles, YuhengAlioth, Touch
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from .main import MidiImportConfig, MidiImport2MusicPlugin

View File

@@ -0,0 +1,795 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 Midi 读取插件的数值常量
"""
"""
版权所有 © 2026 金羿、玉衡Alioth、偷吃不是Touch
Copyright © 2026 Eilles, YuhengAlioth, Touch
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
from typing import Dict, List, Tuple
# Midi用对照表
MIDI_DEFAULT_VOLUME_VALUE: int = (
64 # Midi默认音量当用户未指定时默认使用折中默认音量
)
MIDI_DEFAULT_PROGRAM_VALUE: int = (
74 # 当 Midi 本身与用户皆未指定音色时,默认 Flute 长笛
)
# Midi乐器对MC乐器对照表
# “经典”对照表,由 Chalie Ping “查理平” 和 金羿ELS 提供
MM_CLASSIC_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.pling",
5: "note.pling",
6: "note.harp",
7: "note.harp",
8: "note.snare",
9: "note.harp",
10: "note.didgeridoo",
11: "note.harp",
12: "note.xylophone",
13: "note.chime",
14: "note.harp",
15: "note.harp",
16: "note.bass",
17: "note.harp",
18: "note.harp",
19: "note.harp",
20: "note.harp",
21: "note.harp",
22: "note.harp",
23: "note.guitar",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.bass",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.harp",
41: "note.harp",
42: "note.harp",
43: "note.harp",
44: "note.iron_xylophone",
45: "note.guitar",
46: "note.harp",
47: "note.harp",
48: "note.guitar",
49: "note.guitar",
50: "note.bit",
51: "note.bit",
52: "note.harp",
53: "note.harp",
54: "note.bit",
55: "note.flute",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.flute",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.bit",
65: "note.bit",
66: "note.bit",
67: "note.bit",
68: "note.flute",
69: "note.harp",
70: "note.harp",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.harp",
75: "note.flute",
76: "note.harp",
77: "note.harp",
78: "note.harp",
79: "note.harp",
80: "note.bit",
81: "note.bit",
82: "note.bit",
83: "note.bit",
84: "note.bit",
85: "note.bit",
86: "note.bit",
87: "note.bit",
88: "note.bit",
89: "note.bit",
90: "note.bit",
91: "note.bit",
92: "note.bit",
93: "note.bit",
94: "note.bit",
95: "note.bit",
96: "note.bit",
97: "note.bit",
98: "note.bit",
99: "note.bit",
100: "note.bit",
101: "note.bit",
102: "note.bit",
103: "note.bit",
104: "note.harp",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.harp",
109: "note.harp",
110: "note.harp",
111: "note.guitar",
112: "note.harp",
113: "note.bell",
114: "note.harp",
115: "note.cow_bell",
116: "note.bd",
117: "note.bass",
118: "note.bit",
119: "note.bd",
120: "note.guitar",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.harp",
125: "note.hat",
126: "note.bd",
127: "note.snare",
}
"""“经典”乐音乐器对照表"""
MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.bd",
35: "note.bd",
36: "note.hat",
37: "note.snare",
38: "note.snare",
39: "note.snare",
40: "note.hat",
41: "note.snare",
42: "note.hat",
43: "note.snare",
44: "note.snare",
45: "note.bell",
46: "note.snare",
47: "note.snare",
48: "note.bell",
49: "note.hat",
50: "note.bell",
51: "note.bell",
52: "note.bell",
53: "note.bell",
54: "note.bell",
55: "note.bell",
56: "note.snare",
57: "note.hat",
58: "note.chime",
59: "note.iron_xylophone",
60: "note.bd",
61: "note.bd",
62: "note.xylophone",
63: "note.xylophone",
64: "note.xylophone",
65: "note.hat",
66: "note.bell",
67: "note.bell",
68: "note.hat",
69: "note.hat",
70: "note.snare",
71: "note.flute",
72: "note.hat",
73: "note.hat",
74: "note.xylophone",
75: "note.hat",
76: "note.hat",
77: "note.xylophone",
78: "note.xylophone",
79: "note.bell",
80: "note.bell",
}
"""“经典”打击乐器对照表"""
# Touch “偷吃” 高准确率音色对照表
MM_TOUCH_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.pling",
5: "note.pling",
6: "note.guitar",
7: "note.guitar",
8: "note.iron_xylophone",
9: "note.bell",
10: "note.iron_xylophone",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.xylophone",
14: "note.chime",
15: "note.banjo",
16: "note.xylophone",
17: "note.iron_xylophone",
18: "note.flute",
19: "note.flute",
20: "note.flute",
21: "note.flute",
22: "note.flute",
23: "note.flute",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.bass",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.flute",
41: "note.flute",
42: "note.flute",
43: "note.bass",
44: "note.flute",
45: "note.iron_xylophone",
46: "note.harp",
47: "note.snare",
48: "note.flute",
49: "note.flute",
50: "note.flute",
51: "note.flute",
52: "note.didgeridoo",
53: "note.flute",
54: "note.flute",
55: "mob.zombie.wood",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.flute",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.bit",
65: "note.bit",
66: "note.bit",
67: "note.bit",
68: "note.flute",
69: "note.bit",
70: "note.banjo",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.flute",
75: "note.flute",
76: "note.iron_xylophone",
77: "note.iron_xylophone",
78: "note.flute",
79: "note.flute",
80: "note.bit",
81: "note.bit",
82: "note.flute",
83: "note.flute",
84: "note.guitar",
85: "note.flute",
86: "note.bass",
87: "note.bass",
88: "note.bit",
89: "note.flute",
90: "note.bit",
91: "note.flute",
92: "note.bell",
93: "note.guitar",
94: "note.flute",
95: "note.bit",
96: "note.bit",
97: "note.flute",
98: "note.bell",
99: "note.bit",
100: "note.bit",
101: "note.bit",
102: "note.bit",
103: "note.bit",
104: "note.iron_xylophone",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.bell",
109: "note.flute",
110: "note.flute",
111: "note.flute",
112: "note.bell",
113: "note.xylophone",
114: "note.flute",
115: "note.hat",
116: "note.snare",
117: "note.snare",
118: "note.bd",
119: "firework.blast",
120: "note.guitar",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.bit",
125: "note.hat",
126: "firework.twinkle",
127: "mob.zombie.wood",
}
"""“偷吃”乐音乐器对照表"""
MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.hat",
35: "note.bd",
36: "note.bd",
37: "note.snare",
38: "note.snare",
39: "fire.ignite",
40: "note.snare",
41: "note.hat",
42: "note.hat",
43: "firework.blast",
44: "note.hat",
45: "note.snare",
46: "note.snare",
47: "note.snare",
48: "note.bell",
49: "note.hat",
50: "note.bell",
51: "note.bell",
52: "note.bell",
53: "note.bell",
54: "note.bell",
55: "note.bell",
56: "note.snare",
57: "note.hat",
58: "note.chime",
59: "note.iron_xylophone",
60: "note.bd",
61: "note.bd",
62: "note.xylophone",
63: "note.xylophone",
64: "note.xylophone",
65: "note.hat",
66: "note.bell",
67: "note.bell",
68: "note.hat",
69: "note.hat",
70: "note.snare",
71: "note.flute",
72: "note.hat",
73: "note.hat",
74: "note.xylophone",
75: "note.hat",
76: "note.hat",
77: "note.xylophone",
78: "note.xylophone",
79: "note.bell",
80: "note.bell",
}
"""“偷吃”打击乐器对照表"""
# Dislink “断联” 音色对照表
# https://github.com/Dislink/midi2bdx/blob/main/index.html
MM_DISLINK_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.harp",
5: "note.harp",
6: "note.harp",
7: "note.harp",
8: "note.iron_xylophone",
9: "note.bell",
10: "note.iron_xylophone",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.iron_xylophone",
14: "note.chime",
15: "note.iron_xylophone",
16: "note.harp",
17: "note.harp",
18: "note.harp",
19: "note.harp",
20: "note.harp",
21: "note.harp",
22: "note.harp",
23: "note.harp",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.guitar",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.harp",
41: "note.flute",
42: "note.flute",
43: "note.flute",
44: "note.flute",
45: "note.harp",
46: "note.harp",
47: "note.harp",
48: "note.harp",
49: "note.harp",
50: "note.harp",
51: "note.harp",
52: "note.harp",
53: "note.harp",
54: "note.harp",
55: "note.harp",
56: "note.harp",
57: "note.harp",
58: "note.harp",
59: "note.harp",
60: "note.harp",
61: "note.harp",
62: "note.harp",
63: "note.harp",
64: "note.harp",
65: "note.harp",
66: "note.harp",
67: "note.harp",
68: "note.harp",
69: "note.harp",
70: "note.harp",
71: "note.harp",
72: "note.flute",
73: "note.flute",
74: "note.flute",
75: "note.flute",
76: "note.flute",
77: "note.flute",
78: "note.flute",
79: "note.flute",
80: "note.bit",
81: "note.bit",
82: "note.harp",
83: "note.harp",
84: "note.harp",
85: "note.harp",
86: "note.harp",
87: "note.harp",
88: "note.harp",
89: "note.harp",
90: "note.harp",
91: "note.harp",
92: "note.harp",
93: "note.harp",
94: "note.harp",
95: "note.harp",
96: "note.harp",
97: "note.harp",
98: "note.harp",
99: "note.harp",
100: "note.harp",
101: "note.harp",
102: "note.harp",
103: "note.harp",
104: "note.harp",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.harp",
109: "note.harp",
110: "note.harp",
111: "note.harp",
112: "note.cow_bell",
113: "note.harp",
114: "note.harp",
115: "note.bd",
116: "note.bd",
117: "note.bd",
118: "note.bd",
119: "note.harp",
120: "note.harp",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.harp",
125: "note.harp",
126: "note.harp",
127: "note.harp",
}
"""“断联”乐音乐器对照表"""
MM_DISLINK_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.bd",
35: "note.bd",
36: "note.snare",
37: "note.snare",
38: "note.bd",
39: "note.snare",
40: "note.bd",
41: "note.hat",
42: "note.bd",
43: "note.hat",
44: "note.bd",
45: "note.hat",
46: "note.bd",
47: "note.bd",
48: "note.bd",
49: "note.bd",
50: "note.bd",
51: "note.bd",
52: "note.bd",
53: "note.bd",
54: "note.bd",
55: "note.cow_bell",
56: "note.bd",
57: "note.bd",
58: "note.bd",
59: "note.bd",
60: "note.bd",
61: "note.bd",
62: "note.bd",
63: "note.bd",
64: "note.bd",
65: "note.bd",
66: "note.bd",
67: "note.bd",
68: "note.bd",
69: "note.bd",
70: "note.bd",
71: "note.bd",
72: "note.bd",
73: "note.bd",
74: "note.bd",
75: "note.bd",
76: "note.bd",
77: "note.bd",
78: "note.bd",
79: "note.bd",
80: "note.bd",
}
"""“断联”打击乐器对照表"""
# NoteBlockStudio “NBS”音色对照表
# https://github.com/OpenNBS/NoteBlockStudio/blob/main/scripts/midi_instruments/midi_instruments.gml
MM_NBS_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.pling",
2: "note.harp",
3: "note.pling",
4: "note.harp",
5: "note.harp",
6: "note.guitar",
7: "note.banjo",
8: "note.bell",
9: "note.bell",
10: "note.bell",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.xylophone",
14: "note.bell",
15: "note.iron_xylophone",
16: "note.flute",
17: "note.flute",
18: "note.flute",
19: "note.flute",
20: "note.flute",
21: "note.flute",
22: "note.flute",
23: "note.flute",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.bass",
28: "note.guitar",
29: "note.guitar",
30: "note.bass",
31: "note.bass",
32: "note.bass",
33: "note.guitar",
34: "note.guitar",
35: "note.bass",
36: "note.pling",
37: "note.flute",
38: "note.flute",
39: "note.flute",
40: "note.flute",
41: "note.flute",
42: "note.didgeridoo",
43: "note.flute",
44: "note.didgeridoo",
45: "note.flute",
46: "note.flute",
47: "note.flute",
48: "note.flute",
49: "note.flute",
50: "note.flute",
51: "note.flute",
52: "note.flute",
53: "note.flute",
54: "note.flute",
55: "note.flute",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.bit",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.flute",
65: "note.guitar",
66: "note.flute",
67: "note.flute",
68: "note.flute",
69: "note.bell",
70: "note.flute",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.chime",
75: "note.flute",
76: "note.flute",
77: "note.guitar",
78: "note.pling",
79: "note.flute",
80: "note.guitar",
81: "note.banjo",
82: "note.banjo",
83: "note.banjo",
84: "note.guitar",
85: "note.iron_xylophone",
86: "note.flute",
87: "note.flute",
88: "note.chime",
89: "note.cow_bell",
90: "note.iron_xylophone",
91: "note.xylophone",
92: "note.basedrum",
93: "note.snare",
94: "note.snare",
95: "note.basedrum",
96: "note.snare",
97: "note.hat",
98: "note.snare",
99: "note.hat",
100: "note.basedrum",
101: "note.hat",
102: "note.basedrum",
103: "note.hat",
104: "note.basedrum",
105: "note.snare",
106: "note.snare",
107: "note.snare",
108: "note.cow_bell",
109: "note.snare",
110: "note.hat",
111: "note.snare",
112: "note.hat",
113: "note.hat",
114: "note.hat",
115: "note.hat",
116: "note.hat",
117: "note.chime",
118: "note.hat",
119: "note.snare",
120: "note.hat",
121: "note.hat",
122: "note.hat",
123: "note.hat",
124: "note.hat",
125: "note.snare",
126: "note.basedrum",
127: "note.basedrum",
}
"""“NBS”乐音乐器对照表"""
MM_NBS_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
24: "note.bit",
25: "note.snare",
26: "note.hat",
27: "note.snare",
28: "note.snare",
29: "note.hat",
30: "note.hat",
31: "note.hat",
32: "note.hat",
33: "note.hat",
34: "note.chime",
35: "note.basedrum",
36: "note.basedrum",
37: "note.hat",
38: "note.snare",
39: "note.hat",
40: "note.snare",
41: "note.basedrum",
42: "note.snare",
43: "note.basedrum",
44: "note.snare",
45: "note.basedrum",
46: "note.basedrum",
47: "note.snare",
48: "note.snare",
49: "note.snare",
50: "note.snare",
51: "note.snare",
52: "note.snare",
53: "note.hat",
54: "note.snare",
55: "note.snare",
56: "note.cow_bell",
57: "note.snare",
58: "note.hat",
59: "note.snare",
60: "note.hat",
61: "note.hat",
62: "note.hat",
63: "note.basedrum",
64: "note.basedrum",
65: "note.snare",
66: "note.snare",
67: "note.xylophone",
68: "note.xylophone",
69: "note.hat",
70: "note.hat",
71: "note.flute",
72: "note.flute",
73: "note.hat",
74: "note.hat",
75: "note.hat",
76: "note.hat",
77: "note.hat",
78: "note.didgeridoo",
79: "note.didgeridoo",
80: "note.hat",
81: "note.chime",
82: "note.hat",
83: "note.chime",
84: "note.chime",
85: "note.hat",
86: "note.basedrum",
87: "note.basedrum",
}
"""“NBS”打击乐器对照表"""

View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 Midi 读取插件
"""
"""
版权所有 © 2026 金羿、玉衡Alioth、偷吃不是Touch
Copyright © 2026 Eilles, YuhengAlioth, Touch
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
import mido
from dataclasses import dataclass
from pathlib import Path
from typing import BinaryIO, Optional, Dict, List
from Musicreater import SingleMusic
from Musicreater.plugins import (
music_input_plugin,
PluginConfig,
PluginMetaInformation,
PluginTypes,
MusicInputPluginBase,
)
from Musicreater.types import (
FittingFunctionType,
)
from .constants import (
MIDI_DEFAULT_PROGRAM_VALUE,
MIDI_DEFAULT_VOLUME_VALUE,
MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
)
from .utils import velocity_2_distance_natural, panning_2_rotation_trigonometric
@dataclass
class MidiImportConfig(PluginConfig):
"""Midi 音乐数据导入插件配置"""
ignore_mismatch_error: bool = True
speed: float = 1.0
default_program_value: int = MIDI_DEFAULT_PROGRAM_VALUE
default_volume_value: int = MIDI_DEFAULT_VOLUME_VALUE
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO
pitched_note_rtable: Dict[int, str] = MM_TOUCH_PITCHED_INSTRUMENT_TABLE
percussion_note_rtable: Dict[int, str] = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE
vol_processing_function: FittingFunctionType = velocity_2_distance_natural
pan_processing_function: FittingFunctionType = panning_2_rotation_trigonometric
note_rtable_replacement: Dict[str, str] = {}
@music_input_plugin("midi_2_music_by_tracks")
class MidiImport2MusicPlugin(MusicInputPluginBase):
"""Midi 音乐数据导入插件"""
metainfo = PluginMetaInformation(
name="Midi 导入插件",
author="金羿、玉衡Alioth",
description="从 Midi 文件导入音乐数据",
version=(0, 0, 1),
type=PluginTypes.FUNCTION_MUSIC_IMPORT,
license="Same as Musicreater",
)
supported_formats = ("MID", "MIDI")
def loadbytes(
self, bytes_buffer_in: BinaryIO, config: MidiImportConfig = MidiImportConfig()
) -> SingleMusic:
midi_file = mido.MidiFile(file=bytes_buffer_in)
return SingleMusic() # =========================== TODO: 等待制作
def load(
self, file_path: Path, config: MidiImportConfig = MidiImportConfig()
) -> "SingleMusic":
"""从 Midi 文件导入音乐数据"""
midi_file = mido.MidiFile(filename=file_path)
return SingleMusic() # =========================== TODO: 等待制作

View File

@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
"""
音·创 v3 内置的 Midi 读取插件的功能方法
"""
"""
版权所有 © 2026 金羿、玉衡Alioth
Copyright © 2026 Eilles, YuhengAlioth
开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""
# 睿乐组织 开发交流群 861684859
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
import math
def velocity_2_distance_natural(
vol: float,
) -> float:
"""
midi力度值拟合成的距离函数
Parameters
----------
vol: int
midi 音符力度值
Returns
-------
float播放中心到玩家的距离
"""
return (
-8.081720684086314
* math.log(
vol + 14.579508825070013,
)
+ 37.65806375944386
if vol < 60.64
else 0.2721359356095803 * ((vol + 2592.272889454798) ** 1.358571233418649)
+ -6.313841334963396 * (vol + 2592.272889454798)
+ 4558.496367823575
)
def velocity_2_distance_straight(vol: float) -> float:
"""
midi力度值拟合成的距离函数
Parameters
----------
vol: int
midi 音符力度值
Returns
-------
float播放中心到玩家的距离
"""
return vol / -8 + 16
def panning_2_rotation_linear(pan_: float) -> float:
"""
Midi 左右平衡偏移值线性转为声源旋转角度
Parameters
----------
pan_: int
Midi 左右平衡偏移值
此参数为int范围从 0 到 127当为 64 时,声源居中
Returns
-------
float
声源旋转角度
"""
return (pan_ - 64) * 90 / 63
def panning_2_rotation_trigonometric(pan_: float) -> float:
"""
Midi 左右平衡偏移值,依照圆的声场定位,转为声源旋转角度
Parameters
----------
pan_: int
Midi 左右平衡偏移值
此参数为int范围从 0 到 127当为 64 时,声源居中
Returns
-------
float
声源旋转角度
"""
if pan_ <= 0:
return -90
elif pan_ >= 127:
return 90
else:
return math.degrees(math.acos((64 - pan_) / 63)) - 90

View File

@@ -46,13 +46,6 @@ MIDI_PAN = "pan"
# Midi用对照表
MIDI_DEFAULT_VOLUME_VALUE: int = (
64 # Midi默认音量当用户未指定时默认使用折中默认音量
)
MIDI_DEFAULT_PROGRAM_VALUE: int = (
74 # 当 Midi 本身与用户皆未指定音色时,默认 Flute 长笛
)
MIDI_PITCH_NAME_TABLE: Dict[int, str] = {
0: "C",
@@ -528,770 +521,10 @@ MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
*注意* 该表中的单位是对于 Midi Pitch 音调(整数)的低音偏移。
也就是说,该数值越高,则在 Midi Pitch 中的值域越低
默认的偏移量为 6 ,因为在计算音高时候少减去了 6 个 Pitch 单位
(在表里的数据是用作被减数的,实际计算时默认有 +6所以在表中默认的 6 最后就会被抵消)
"""
# Midi乐器对MC乐器对照表
# “经典”对照表,由 Chalie Ping “查理平” 和 金羿ELS 提供
MM_CLASSIC_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.pling",
5: "note.pling",
6: "note.harp",
7: "note.harp",
8: "note.snare",
9: "note.harp",
10: "note.didgeridoo",
11: "note.harp",
12: "note.xylophone",
13: "note.chime",
14: "note.harp",
15: "note.harp",
16: "note.bass",
17: "note.harp",
18: "note.harp",
19: "note.harp",
20: "note.harp",
21: "note.harp",
22: "note.harp",
23: "note.guitar",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.bass",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.harp",
41: "note.harp",
42: "note.harp",
43: "note.harp",
44: "note.iron_xylophone",
45: "note.guitar",
46: "note.harp",
47: "note.harp",
48: "note.guitar",
49: "note.guitar",
50: "note.bit",
51: "note.bit",
52: "note.harp",
53: "note.harp",
54: "note.bit",
55: "note.flute",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.flute",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.bit",
65: "note.bit",
66: "note.bit",
67: "note.bit",
68: "note.flute",
69: "note.harp",
70: "note.harp",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.harp",
75: "note.flute",
76: "note.harp",
77: "note.harp",
78: "note.harp",
79: "note.harp",
80: "note.bit",
81: "note.bit",
82: "note.bit",
83: "note.bit",
84: "note.bit",
85: "note.bit",
86: "note.bit",
87: "note.bit",
88: "note.bit",
89: "note.bit",
90: "note.bit",
91: "note.bit",
92: "note.bit",
93: "note.bit",
94: "note.bit",
95: "note.bit",
96: "note.bit",
97: "note.bit",
98: "note.bit",
99: "note.bit",
100: "note.bit",
101: "note.bit",
102: "note.bit",
103: "note.bit",
104: "note.harp",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.harp",
109: "note.harp",
110: "note.harp",
111: "note.guitar",
112: "note.harp",
113: "note.bell",
114: "note.harp",
115: "note.cow_bell",
116: "note.bd",
117: "note.bass",
118: "note.bit",
119: "note.bd",
120: "note.guitar",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.harp",
125: "note.hat",
126: "note.bd",
127: "note.snare",
}
"""“经典”乐音乐器对照表"""
MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.bd",
35: "note.bd",
36: "note.hat",
37: "note.snare",
38: "note.snare",
39: "note.snare",
40: "note.hat",
41: "note.snare",
42: "note.hat",
43: "note.snare",
44: "note.snare",
45: "note.bell",
46: "note.snare",
47: "note.snare",
48: "note.bell",
49: "note.hat",
50: "note.bell",
51: "note.bell",
52: "note.bell",
53: "note.bell",
54: "note.bell",
55: "note.bell",
56: "note.snare",
57: "note.hat",
58: "note.chime",
59: "note.iron_xylophone",
60: "note.bd",
61: "note.bd",
62: "note.xylophone",
63: "note.xylophone",
64: "note.xylophone",
65: "note.hat",
66: "note.bell",
67: "note.bell",
68: "note.hat",
69: "note.hat",
70: "note.snare",
71: "note.flute",
72: "note.hat",
73: "note.hat",
74: "note.xylophone",
75: "note.hat",
76: "note.hat",
77: "note.xylophone",
78: "note.xylophone",
79: "note.bell",
80: "note.bell",
}
"""“经典”打击乐器对照表"""
# Touch “偷吃” 高准确率音色对照表
MM_TOUCH_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.pling",
5: "note.pling",
6: "note.guitar",
7: "note.guitar",
8: "note.iron_xylophone",
9: "note.bell",
10: "note.iron_xylophone",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.xylophone",
14: "note.chime",
15: "note.banjo",
16: "note.xylophone",
17: "note.iron_xylophone",
18: "note.flute",
19: "note.flute",
20: "note.flute",
21: "note.flute",
22: "note.flute",
23: "note.flute",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.bass",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.flute",
41: "note.flute",
42: "note.flute",
43: "note.bass",
44: "note.flute",
45: "note.iron_xylophone",
46: "note.harp",
47: "note.snare",
48: "note.flute",
49: "note.flute",
50: "note.flute",
51: "note.flute",
52: "note.didgeridoo",
53: "note.flute",
54: "note.flute",
55: "mob.zombie.wood",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.flute",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.bit",
65: "note.bit",
66: "note.bit",
67: "note.bit",
68: "note.flute",
69: "note.bit",
70: "note.banjo",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.flute",
75: "note.flute",
76: "note.iron_xylophone",
77: "note.iron_xylophone",
78: "note.flute",
79: "note.flute",
80: "note.bit",
81: "note.bit",
82: "note.flute",
83: "note.flute",
84: "note.guitar",
85: "note.flute",
86: "note.bass",
87: "note.bass",
88: "note.bit",
89: "note.flute",
90: "note.bit",
91: "note.flute",
92: "note.bell",
93: "note.guitar",
94: "note.flute",
95: "note.bit",
96: "note.bit",
97: "note.flute",
98: "note.bell",
99: "note.bit",
100: "note.bit",
101: "note.bit",
102: "note.bit",
103: "note.bit",
104: "note.iron_xylophone",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.bell",
109: "note.flute",
110: "note.flute",
111: "note.flute",
112: "note.bell",
113: "note.xylophone",
114: "note.flute",
115: "note.hat",
116: "note.snare",
117: "note.snare",
118: "note.bd",
119: "firework.blast",
120: "note.guitar",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.bit",
125: "note.hat",
126: "firework.twinkle",
127: "mob.zombie.wood",
}
"""“偷吃”乐音乐器对照表"""
MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.hat",
35: "note.bd",
36: "note.bd",
37: "note.snare",
38: "note.snare",
39: "fire.ignite",
40: "note.snare",
41: "note.hat",
42: "note.hat",
43: "firework.blast",
44: "note.hat",
45: "note.snare",
46: "note.snare",
47: "note.snare",
48: "note.bell",
49: "note.hat",
50: "note.bell",
51: "note.bell",
52: "note.bell",
53: "note.bell",
54: "note.bell",
55: "note.bell",
56: "note.snare",
57: "note.hat",
58: "note.chime",
59: "note.iron_xylophone",
60: "note.bd",
61: "note.bd",
62: "note.xylophone",
63: "note.xylophone",
64: "note.xylophone",
65: "note.hat",
66: "note.bell",
67: "note.bell",
68: "note.hat",
69: "note.hat",
70: "note.snare",
71: "note.flute",
72: "note.hat",
73: "note.hat",
74: "note.xylophone",
75: "note.hat",
76: "note.hat",
77: "note.xylophone",
78: "note.xylophone",
79: "note.bell",
80: "note.bell",
}
"""“偷吃”打击乐器对照表"""
# Dislink “断联” 音色对照表
# https://github.com/Dislink/midi2bdx/blob/main/index.html
MM_DISLINK_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.harp",
2: "note.pling",
3: "note.harp",
4: "note.harp",
5: "note.harp",
6: "note.harp",
7: "note.harp",
8: "note.iron_xylophone",
9: "note.bell",
10: "note.iron_xylophone",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.iron_xylophone",
14: "note.chime",
15: "note.iron_xylophone",
16: "note.harp",
17: "note.harp",
18: "note.harp",
19: "note.harp",
20: "note.harp",
21: "note.harp",
22: "note.harp",
23: "note.harp",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.guitar",
28: "note.guitar",
29: "note.guitar",
30: "note.guitar",
31: "note.guitar",
32: "note.bass",
33: "note.bass",
34: "note.bass",
35: "note.bass",
36: "note.bass",
37: "note.bass",
38: "note.bass",
39: "note.bass",
40: "note.harp",
41: "note.flute",
42: "note.flute",
43: "note.flute",
44: "note.flute",
45: "note.harp",
46: "note.harp",
47: "note.harp",
48: "note.harp",
49: "note.harp",
50: "note.harp",
51: "note.harp",
52: "note.harp",
53: "note.harp",
54: "note.harp",
55: "note.harp",
56: "note.harp",
57: "note.harp",
58: "note.harp",
59: "note.harp",
60: "note.harp",
61: "note.harp",
62: "note.harp",
63: "note.harp",
64: "note.harp",
65: "note.harp",
66: "note.harp",
67: "note.harp",
68: "note.harp",
69: "note.harp",
70: "note.harp",
71: "note.harp",
72: "note.flute",
73: "note.flute",
74: "note.flute",
75: "note.flute",
76: "note.flute",
77: "note.flute",
78: "note.flute",
79: "note.flute",
80: "note.bit",
81: "note.bit",
82: "note.harp",
83: "note.harp",
84: "note.harp",
85: "note.harp",
86: "note.harp",
87: "note.harp",
88: "note.harp",
89: "note.harp",
90: "note.harp",
91: "note.harp",
92: "note.harp",
93: "note.harp",
94: "note.harp",
95: "note.harp",
96: "note.harp",
97: "note.harp",
98: "note.harp",
99: "note.harp",
100: "note.harp",
101: "note.harp",
102: "note.harp",
103: "note.harp",
104: "note.harp",
105: "note.banjo",
106: "note.harp",
107: "note.harp",
108: "note.harp",
109: "note.harp",
110: "note.harp",
111: "note.harp",
112: "note.cow_bell",
113: "note.harp",
114: "note.harp",
115: "note.bd",
116: "note.bd",
117: "note.bd",
118: "note.bd",
119: "note.harp",
120: "note.harp",
121: "note.harp",
122: "note.harp",
123: "note.harp",
124: "note.harp",
125: "note.harp",
126: "note.harp",
127: "note.harp",
}
"""“断联”乐音乐器对照表"""
MM_DISLINK_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
34: "note.bd",
35: "note.bd",
36: "note.snare",
37: "note.snare",
38: "note.bd",
39: "note.snare",
40: "note.bd",
41: "note.hat",
42: "note.bd",
43: "note.hat",
44: "note.bd",
45: "note.hat",
46: "note.bd",
47: "note.bd",
48: "note.bd",
49: "note.bd",
50: "note.bd",
51: "note.bd",
52: "note.bd",
53: "note.bd",
54: "note.bd",
55: "note.cow_bell",
56: "note.bd",
57: "note.bd",
58: "note.bd",
59: "note.bd",
60: "note.bd",
61: "note.bd",
62: "note.bd",
63: "note.bd",
64: "note.bd",
65: "note.bd",
66: "note.bd",
67: "note.bd",
68: "note.bd",
69: "note.bd",
70: "note.bd",
71: "note.bd",
72: "note.bd",
73: "note.bd",
74: "note.bd",
75: "note.bd",
76: "note.bd",
77: "note.bd",
78: "note.bd",
79: "note.bd",
80: "note.bd",
}
"""“断联”打击乐器对照表"""
# NoteBlockStudio “NBS”音色对照表
# https://github.com/OpenNBS/NoteBlockStudio/blob/main/scripts/midi_instruments/midi_instruments.gml
MM_NBS_PITCHED_INSTRUMENT_TABLE: Dict[int, str] = {
0: "note.harp",
1: "note.pling",
2: "note.harp",
3: "note.pling",
4: "note.harp",
5: "note.harp",
6: "note.guitar",
7: "note.banjo",
8: "note.bell",
9: "note.bell",
10: "note.bell",
11: "note.iron_xylophone",
12: "note.iron_xylophone",
13: "note.xylophone",
14: "note.bell",
15: "note.iron_xylophone",
16: "note.flute",
17: "note.flute",
18: "note.flute",
19: "note.flute",
20: "note.flute",
21: "note.flute",
22: "note.flute",
23: "note.flute",
24: "note.guitar",
25: "note.guitar",
26: "note.guitar",
27: "note.bass",
28: "note.guitar",
29: "note.guitar",
30: "note.bass",
31: "note.bass",
32: "note.bass",
33: "note.guitar",
34: "note.guitar",
35: "note.bass",
36: "note.pling",
37: "note.flute",
38: "note.flute",
39: "note.flute",
40: "note.flute",
41: "note.flute",
42: "note.didgeridoo",
43: "note.flute",
44: "note.didgeridoo",
45: "note.flute",
46: "note.flute",
47: "note.flute",
48: "note.flute",
49: "note.flute",
50: "note.flute",
51: "note.flute",
52: "note.flute",
53: "note.flute",
54: "note.flute",
55: "note.flute",
56: "note.flute",
57: "note.flute",
58: "note.flute",
59: "note.flute",
60: "note.bit",
61: "note.flute",
62: "note.flute",
63: "note.flute",
64: "note.flute",
65: "note.guitar",
66: "note.flute",
67: "note.flute",
68: "note.flute",
69: "note.bell",
70: "note.flute",
71: "note.flute",
72: "note.flute",
73: "note.flute",
74: "note.chime",
75: "note.flute",
76: "note.flute",
77: "note.guitar",
78: "note.pling",
79: "note.flute",
80: "note.guitar",
81: "note.banjo",
82: "note.banjo",
83: "note.banjo",
84: "note.guitar",
85: "note.iron_xylophone",
86: "note.flute",
87: "note.flute",
88: "note.chime",
89: "note.cow_bell",
90: "note.iron_xylophone",
91: "note.xylophone",
92: "note.basedrum",
93: "note.snare",
94: "note.snare",
95: "note.basedrum",
96: "note.snare",
97: "note.hat",
98: "note.snare",
99: "note.hat",
100: "note.basedrum",
101: "note.hat",
102: "note.basedrum",
103: "note.hat",
104: "note.basedrum",
105: "note.snare",
106: "note.snare",
107: "note.snare",
108: "note.cow_bell",
109: "note.snare",
110: "note.hat",
111: "note.snare",
112: "note.hat",
113: "note.hat",
114: "note.hat",
115: "note.hat",
116: "note.hat",
117: "note.chime",
118: "note.hat",
119: "note.snare",
120: "note.hat",
121: "note.hat",
122: "note.hat",
123: "note.hat",
124: "note.hat",
125: "note.snare",
126: "note.basedrum",
127: "note.basedrum",
}
"""“NBS”乐音乐器对照表"""
MM_NBS_PERCUSSION_INSTRUMENT_TABLE: Dict[int, str] = {
24: "note.bit",
25: "note.snare",
26: "note.hat",
27: "note.snare",
28: "note.snare",
29: "note.hat",
30: "note.hat",
31: "note.hat",
32: "note.hat",
33: "note.hat",
34: "note.chime",
35: "note.basedrum",
36: "note.basedrum",
37: "note.hat",
38: "note.snare",
39: "note.hat",
40: "note.snare",
41: "note.basedrum",
42: "note.snare",
43: "note.basedrum",
44: "note.snare",
45: "note.basedrum",
46: "note.basedrum",
47: "note.snare",
48: "note.snare",
49: "note.snare",
50: "note.snare",
51: "note.snare",
52: "note.snare",
53: "note.hat",
54: "note.snare",
55: "note.snare",
56: "note.cow_bell",
57: "note.snare",
58: "note.hat",
59: "note.snare",
60: "note.hat",
61: "note.hat",
62: "note.hat",
63: "note.basedrum",
64: "note.basedrum",
65: "note.snare",
66: "note.snare",
67: "note.xylophone",
68: "note.xylophone",
69: "note.hat",
70: "note.hat",
71: "note.flute",
72: "note.flute",
73: "note.hat",
74: "note.hat",
75: "note.hat",
76: "note.hat",
77: "note.hat",
78: "note.didgeridoo",
79: "note.didgeridoo",
80: "note.hat",
81: "note.chime",
82: "note.hat",
83: "note.chime",
84: "note.chime",
85: "note.hat",
86: "note.basedrum",
87: "note.basedrum",
}
"""“NBS”打击乐器对照表"""
# Midi音高对MC方块对照表

View File

@@ -222,11 +222,10 @@ class SingleNote:
)
)
raise SingleNoteDecodeError(
e,
"技术信息:\nGROUP1\t`{}`\nCODE_BUFFER\t`{}`".format(
group_1, code_buffer
),
)
) from e
def encode(self, is_high_time_precision: bool = True) -> bytes:
"""
@@ -621,7 +620,7 @@ class SingleMusic(List[SingleTrack]):
music_credits: str
"""曲目的版权信息"""
# 感叹一下什么冗余设计啊!(叉腰)
# 感叹一下什么冗余设计啊!(叉腰)
extra_info: Dict[str, Any]
"""这还得放东西?"""

View File

@@ -241,7 +241,6 @@ class PluginRegisteredError(PluginLoadError):
super().__init__("插件重复注册:", *args)
class PluginConfigRelatedError(MusicreaterOuterlyError):
"""插件配置相关错误"""

View File

@@ -257,13 +257,11 @@ class MusiCreater:
self._plugin_cache[plg_id] = self._plugin_cache[plugin_name]
return self._plugin_cache[plg_id]
closest = self._get_closest_plugin_id(plg_id)
raise AttributeError(
"插件`{}`不存在,请检查插件的惟一识别码是否正确".format(plg_id)
+ (
";或者阁下可能想要使用的是`{}`插件?".format(closest)
if closest
if (closest := self._get_closest_plugin_id(plg_id))
else ""
)
)

View File

@@ -60,6 +60,7 @@ from .exceptions import (
ParameterTypeError,
PluginInstanceNotFoundError,
PluginRegisteredError,
PluginNotFoundError,
)
@@ -119,16 +120,19 @@ def load_plugin_module(package: Union[Path, str]):
插件包路径或名称,当为 Path 类时为路径,为 str 时为包名,切勿混淆。
"""
if isinstance(package, Path):
relative_path = package.resolve().relative_to(Path.cwd().resolve())
if relative_path.stem == "__init__":
return importlib.import_module(".".join(relative_path.parts[:-1]))
try:
if isinstance(package, Path):
relative_path = package.resolve().relative_to(Path.cwd().resolve())
if relative_path.stem == "__init__":
return importlib.import_module(".".join(relative_path.parts[:-1]))
else:
return importlib.import_module(
".".join(relative_path.parts[:-1] + (relative_path.stem,))
)
else:
return importlib.import_module(
".".join(relative_path.parts[:-1] + (relative_path.stem,))
)
else:
return importlib.import_module(package)
return importlib.import_module(package)
except ModuleNotFoundError as e:
raise PluginNotFoundError("无法找到名为`{}`的插件包".format(package))
class PluginRegistry:
@@ -278,10 +282,10 @@ class PluginRegistry:
],
key=lambda plugin: plugin.metainfo.version,
)
except ValueError:
except ValueError as e:
raise PluginInstanceNotFoundError(
"未找到“用于{}、名为`{}`”的插件".format(plugin_usage, plugin_name)
)
) from e
def get_music_input_plugin(self, plugin_name: str) -> MusicInputPluginBase:
"""获取指定名称的全曲导入用插件,当名称重叠时,取版本号最大的"""
@@ -389,6 +393,7 @@ def music_operate_plugin(plugin_id: str):
plugin_id, _global_plugin_registry.register_music_operate_plugin
)
def track_operate_plugin(plugin_id: str):
"""音轨处理插件装饰器"""
return __plugin_regist_decorator(
@@ -416,6 +421,7 @@ def service_plugin(plugin_id: str):
plugin_id, _global_plugin_registry.register_service_plugin
)
def library_plugin(plugin_id: str):
"""支持库插件装饰器"""

View File

@@ -36,12 +36,15 @@ from itertools import chain
import mido
from .constants import *
from Musicreater.constants import *
from .old_exceptions import *
from .subclass import *
from .old_types import *
from .utils import *
from Musicreater.builtin_plugins.midi_read.constants import *
from Musicreater.builtin_plugins.midi_read.utils import *
"""
学习笔记:
tempo: microseconds per quarter note 毫秒每四分音符,换句话说就是一拍占多少微秒
@@ -796,7 +799,7 @@ class MusicSequence:
def add_note(self, channel_no: int, note: MineNote, is_sort: bool = True):
"""
在指定通道添加一个音符
值得注意:在版本 2.2.3 及之前 is_sort 参数默认为 False ;在此之后为 True
值得注意:在版本 2.2.3 及之前 is_sort 参数默认为 False在此之后为 True
"""
self.channels[channel_no].append(note)
self.total_note_count += 1

View File

@@ -15,7 +15,6 @@ Terms & Conditions: License.md in the root directory
# Email TriM-Organization@hotmail.com
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
import math
import random
# from io import BytesIO
@@ -34,7 +33,7 @@ from typing import (
from xxhash import xxh3_64, xxh3_128, xxh32
from .constants import (
from Musicreater.constants import (
MC_INSTRUMENT_BLOCKS_TABLE,
MC_PITCHED_INSTRUMENT_LIST,
MM_INSTRUMENT_DEVIATION_TABLE,
@@ -127,90 +126,6 @@ def midi_inst_to_mc_sound(
)
def velocity_2_distance_natural(
vol: float,
) -> float:
"""
midi力度值拟合成的距离函数
Parameters
----------
vol: int
midi 音符力度值
Returns
-------
float播放中心到玩家的距离
"""
return (
-8.081720684086314
* math.log(
vol + 14.579508825070013,
)
+ 37.65806375944386
if vol < 60.64
else 0.2721359356095803 * ((vol + 2592.272889454798) ** 1.358571233418649)
+ -6.313841334963396 * (vol + 2592.272889454798)
+ 4558.496367823575
)
def velocity_2_distance_straight(vol: float) -> float:
"""
midi力度值拟合成的距离函数
Parameters
----------
vol: int
midi 音符力度值
Returns
-------
float播放中心到玩家的距离
"""
return vol / -8 + 16
def panning_2_rotation_linear(pan_: float) -> float:
"""
Midi 左右平衡偏移值线性转为声源旋转角度
Parameters
----------
pan_: int
Midi 左右平衡偏移值
此参数为int范围从 0 到 127当为 64 时,声源居中
Returns
-------
float
声源旋转角度
"""
return (pan_ - 64) * 90 / 63
def panning_2_rotation_trigonometric(pan_: float) -> float:
"""
Midi 左右平衡偏移值,依照圆的声场定位,转为声源旋转角度
Parameters
----------
pan_: int
Midi 左右平衡偏移值
此参数为int范围从 0 到 127当为 64 时,声源居中
Returns
-------
float
声源旋转角度
"""
if pan_ <= 0:
return -90
elif pan_ >= 127:
return 90
else:
return math.degrees(math.acos((64 - pan_) / 63)) - 90
def minenote_to_command_parameters(
mine_note: MineNote,

View File

@@ -3,10 +3,9 @@
dynamic = ["version"]
requires-python = ">= 3.8, < 4.0"
dependencies = [
"mido >= 1.3",
"tomli >= 2.4.0; python_version < '3.11'",
"tomli-w >= 1.0.0",
"xxhash >= 3",
"tomli >= 2.4.0, < 3.0 ; python_version < '3.11'",
"tomli-w >= 1.0.0, < 2.0",
"xxhash >= 3, < 4.0",
]
authors = [
@@ -46,14 +45,23 @@
[project.optional-dependencies]
full = [
"TrimMCStruct <= 0.0.5.9",
"brotli >= 1.0.0",
midi = [
"mido >= 1.3, < 2.0",
]
structure = [
"numpy",
"TrimMCStruct <= 0.0.5.9",
"brotli >= 1.0.0, < 2.0",
]
full = [
"mido >= 1.3",
"numpy",
"TrimMCStruct <= 0.0.5.9",
"brotli >= 1.0.0, < 2.0",
]
dev = [
"TrimMCStruct <= 0.0.5.9",
"brotli >= 1.0.0",
"brotli >= 1.0.0, < 2.0",
"dill",
"rich",
"pyinstaller",

View File

@@ -1,4 +1,3 @@
# 一个简单的项目实践测试
from pathlib import Path
from Musicreater import load_plugin_module, MusiCreater
@@ -6,19 +5,31 @@ from Musicreater.plugins import _global_plugin_registry
load_plugin_module("Musicreater.builtin_plugins.midi_read")
from Musicreater.builtin_plugins.midi_read import MidiImportConfig
print("当前支持的导入格式:", _global_plugin_registry.supported_input_formats())
print("当前支持的导出格式:", _global_plugin_registry.supported_output_formats())
print(msct:=MusiCreater.import_music(Path("./resources/测试片段.mid")))
print(msct := MusiCreater.import_music(Path("./resources/测试片段.mid")))
print(msct.music)
# 为了让类型检查器满意,以下方法不建议使用,因为这本质上是越过了 MusiCreater 类而直接执行插件的函数
# 为了确保类型安全,以下方法不建议使用,因为这本质上是越过了 MusiCreater 类而直接执行插件的函数
print(t := msct.midi_2_music_plugin.load(Path("./resources/测试片段.mid"), None))
# 我们建议用这种方式来代替
t = _global_plugin_registry._music_input_plugins["midi_2_music_plugin"].load(Path("./resources/测试片段.mid"), None)
t = _global_plugin_registry._music_input_plugins["midi_2_music_plugin"].load(
Path("./resources/测试片段.mid"),
MidiImportConfig(
speed=1.0,
),
)
# 或者
from Musicreater.plugins import MusicInputPluginBase
if isinstance((p := msct.midi_2_music_plugin), MusicInputPluginBase):
# 但是,我们不建议用这样的方式读取操作配置类,尽管这也是可以的
t = p.load(Path("./resources/测试片段.mid"), None)
print(_global_plugin_registry)
print(msct._plugin_cache)

26
uv.lock generated
View File

@@ -577,8 +577,7 @@ wheels = [
name = "musicreater"
source = { editable = "." }
dependencies = [
{ name = "mido" },
{ name = "tomli" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
{ name = "tomli-w", version = "1.0.0", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version < '3.9'" },
{ name = "tomli-w", version = "1.2.0", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version >= '3.9'" },
{ name = "xxhash" },
@@ -594,6 +593,17 @@ dev = [
{ name = "twine" },
]
full = [
{ name = "brotli" },
{ name = "mido" },
{ name = "numpy", version = "1.24.4", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version < '3.9'" },
{ name = "numpy", version = "2.0.2", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version == '3.9.*'" },
{ name = "numpy", version = "2.2.6", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version >= '3.10'" },
{ name = "trimmcstruct" },
]
midi = [
{ name = "mido" },
]
structure = [
{ name = "brotli" },
{ name = "numpy", version = "1.24.4", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version < '3.9'" },
{ name = "numpy", version = "2.0.2", source = { registry = "https://mirror.nju.edu.cn/pypi/web/simple" }, marker = "python_full_version == '3.9.*'" },
@@ -605,19 +615,23 @@ full = [
requires-dist = [
{ name = "brotli", marker = "extra == 'dev'", specifier = ">=1.0.0" },
{ name = "brotli", marker = "extra == 'full'", specifier = ">=1.0.0" },
{ name = "brotli", marker = "extra == 'structure'", specifier = ">=1.0.0" },
{ name = "dill", marker = "extra == 'dev'" },
{ name = "mido", specifier = ">=1.3" },
{ name = "mido", marker = "extra == 'full'", specifier = ">=1.3" },
{ name = "mido", marker = "extra == 'midi'", specifier = ">=1.3" },
{ name = "numpy", marker = "extra == 'full'" },
{ name = "numpy", marker = "extra == 'structure'" },
{ name = "pyinstaller", marker = "extra == 'dev'" },
{ name = "rich", marker = "extra == 'dev'" },
{ name = "tomli" },
{ name = "tomli-w" },
{ name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.4.0,<3.0" },
{ name = "tomli-w", specifier = ">=1.0.0,<2.0" },
{ name = "trimmcstruct", marker = "extra == 'dev'", specifier = "<=0.0.5.9" },
{ name = "trimmcstruct", marker = "extra == 'full'", specifier = "<=0.0.5.9" },
{ name = "trimmcstruct", marker = "extra == 'structure'", specifier = "<=0.0.5.9" },
{ name = "twine", marker = "extra == 'dev'" },
{ name = "xxhash", specifier = ">=3" },
]
provides-extras = ["full", "dev"]
provides-extras = ["midi", "structure", "full", "dev"]
[[package]]
name = "mutf8"