新增新文件路径小参数,新增音乐预览插件测试样例。修复小问题

This commit is contained in:
Eilles
2026-07-09 02:06:14 +08:00
parent 2c6e831533
commit fc9ec86adb
5 changed files with 88 additions and 30 deletions
+15
View File
@@ -17,10 +17,12 @@ Terms & Conditions: License.md in the root directory
from copy import deepcopy, copy
from pathlib import Path
from typing import Any, Dict, Generator, List, Optional, Tuple, Union, TypeVar
T = TypeVar("T")
def enumerated_stuffcopy_dictionary(
enumeration_times: int = 17, staff: T = {}
) -> Dict[int, T]:
@@ -30,3 +32,16 @@ def enumerated_stuffcopy_dictionary(
# 这告诉我们,你不能忽略任何一个复制的序列,因为它真的,我哭死,折磨我一整天,全在这个bug上了
# 上面的这指的是 copy.deepcopy —— 金羿 来自 20260210
return {i: deepcopy(staff) for i in range(enumeration_times)}
def incremental_save_path(
file_name: str, suffix: str = ".file", appendix_connector: str = "-"
) -> Path:
ss_path = Path(file_name).with_suffix(suffix)
if ss_path.exists():
now_appendix = 2
while (
ss_path := Path(file_name + appendix_connector + str(now_appendix) + suffix)
).exists():
now_appendix += 1
return ss_path
@@ -107,6 +107,9 @@ class NoteDataConvert2PcmPlugin(MusicOutputPluginBase):
license="Apache 2.0",
)
supported_formats = ("WAV", "WAVE", "PCM")
def dump(self, data: SingleMusic, file_path: Path, config: PcmConversionConfig):
pr = perf_counter_ns()
@@ -48,7 +48,7 @@ from Musicreater.constants import MM_INSTRUMENT_DEVIATION_TABLE
class MusicPreview:
# 当前的资源存储方法过于鸡肋
# 应当依托于 SingleMusic 和 SingleTrack 提供的 extra_info 参数,得到更优的解法
# 或者更理想的情况是把当前插件作为一个 Service 插件,然后通过 serve API 进行调用
@@ -102,12 +102,11 @@ class MusicPreview:
self.output_sample_rate = sample_rate
self.get_value_method = value_get_method
self.resources_path = resource_folder
# 在当前算法下,小数点精度必须为 0
# 此处 TODO,需待旧梦来完善
self.pitch_precision_decimals = 0
self.pitch_deviation = music_deviation
for file in self.resources_path.iterdir():
@@ -189,13 +188,13 @@ class MusicPreview:
else:
# if self.mode == 1:
# 重采样, 不变调
print(">>", sound_name, pitch)
# print(">>", sound_name, pitch)
self.res_data[sound_name][pitch] = librosa.resample(
y_orig,
orig_sr=sr_orig,
target_sr=self.output_sample_rate,
fix=False, # 尽管这样不变调,但是也不应将 pitch 与打击乐器联系在一起
)
) # 已经在下面重新用 0 取代了打击乐器的 pitch
"""elif self.mode == 0:
# 重采样, 不变调, 衰弱
self.cache_dict[raw_name] = librosa_resample(
@@ -221,14 +220,15 @@ class MusicPreview:
duration: int,
):
print(
sound_name,
pitch,
">>",
(pitch := self.make_pitch_accurate(pitch)),
percussive,
duration,
)
# print(
# sound_name,
# pitch,
# ">>",
# (pitch := self.make_pitch_accurate(pitch)),
# percussive,
# duration,
# )
pitch = 0 if percussive else self.make_pitch_accurate(pitch)
if sound_name in self.res_data:
if pitch in self.res_data[sound_name]:
@@ -333,24 +333,24 @@ class MusicPreview:
out_sr = self.output_sample_rate
for note in music.get_minenotes(start_time=start_tick, end_time=end_tick):
accurate_pitch = self.make_pitch_accurate(
note.pitch
- 60
- (
0
if note.percussive
else MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6)
accurate_pitch = (
0
if note.percussive
else self.make_pitch_accurate(
note.pitch
- 60
- MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6)
)
)
print(
":",
note.instrument,
note.pitch,
">>",
accurate_pitch,
note.percussive,
note.duration_tick,
)
# print(
# ":",
# note.instrument,
# note.pitch,
# ">>",
# accurate_pitch,
# note.percussive,
# note.duration_tick,
# )
if not note.percussive:
overlay(
self.res_data[note.instrument][accurate_pitch]
+1 -1
View File
@@ -509,7 +509,7 @@ class SingleTrack(List[SingleNote]):
self.argument_curves = {item: None for item in CurvableParam}
super().__init__(*args)
super().__init__(args)
super().sort()
@classmethod
+40
View File
@@ -0,0 +1,40 @@
# 一个简单的项目实践测试
from pathlib import Path
from rich import print
from Musicreater import load_plugin_from_module, MusiCreater
from Musicreater.plugins import _global_plugin_registry
from Musicreater._utils import incremental_save_path
load_plugin_from_module("Musicreater.builtin_plugins.midi_read")
load_plugin_from_module("Musicreater.builtin_plugins.music_preview")
from Musicreater.builtin_plugins.midi_read import MidiImportConfig
from Musicreater.builtin_plugins.music_preview import PcmConversionConfig
print("当前支持的导入格式:", _global_plugin_registry.supported_input_formats())
print("当前支持的导出格式:", _global_plugin_registry.supported_output_formats())
msct = MusiCreater.import_music(
Path(input("文件路径:")).resolve(),
plugin_config=MidiImportConfig(),
)
print("全局插件注册表:", _global_plugin_registry)
print("插件缓存字典:", msct._plugin_cache)
print(
msct.export_music(
(fn := incremental_save_path("output", suffix=".wav")),
plugin_id="music_to_pcm_plugin",
plugin_config=PcmConversionConfig(
assets_path=Path("./vanilla_assets/wav/").resolve(),
synthesis_mode=2,
pitch_accuracy_decimals=0,
),
),
"\n文件路径:",
fn,
)