mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-07-31 15:34:57 +00:00
新增新文件路径小参数,新增音乐预览插件测试样例。修复小问题
This commit is contained in:
@@ -17,10 +17,12 @@ Terms & Conditions: License.md in the root directory
|
|||||||
|
|
||||||
|
|
||||||
from copy import deepcopy, copy
|
from copy import deepcopy, copy
|
||||||
|
from pathlib import Path
|
||||||
from typing import Any, Dict, Generator, List, Optional, Tuple, Union, TypeVar
|
from typing import Any, Dict, Generator, List, Optional, Tuple, Union, TypeVar
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
def enumerated_stuffcopy_dictionary(
|
def enumerated_stuffcopy_dictionary(
|
||||||
enumeration_times: int = 17, staff: T = {}
|
enumeration_times: int = 17, staff: T = {}
|
||||||
) -> Dict[int, T]:
|
) -> Dict[int, T]:
|
||||||
@@ -30,3 +32,16 @@ def enumerated_stuffcopy_dictionary(
|
|||||||
# 这告诉我们,你不能忽略任何一个复制的序列,因为它真的,我哭死,折磨我一整天,全在这个bug上了
|
# 这告诉我们,你不能忽略任何一个复制的序列,因为它真的,我哭死,折磨我一整天,全在这个bug上了
|
||||||
# 上面的这指的是 copy.deepcopy —— 金羿 来自 20260210
|
# 上面的这指的是 copy.deepcopy —— 金羿 来自 20260210
|
||||||
return {i: deepcopy(staff) for i in range(enumeration_times)}
|
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",
|
license="Apache 2.0",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
supported_formats = ("WAV", "WAVE", "PCM")
|
||||||
|
|
||||||
def dump(self, data: SingleMusic, file_path: Path, config: PcmConversionConfig):
|
def dump(self, data: SingleMusic, file_path: Path, config: PcmConversionConfig):
|
||||||
|
|
||||||
pr = perf_counter_ns()
|
pr = perf_counter_ns()
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ class MusicPreview:
|
|||||||
# 此处 TODO,需待旧梦来完善
|
# 此处 TODO,需待旧梦来完善
|
||||||
self.pitch_precision_decimals = 0
|
self.pitch_precision_decimals = 0
|
||||||
|
|
||||||
|
|
||||||
self.pitch_deviation = music_deviation
|
self.pitch_deviation = music_deviation
|
||||||
|
|
||||||
for file in self.resources_path.iterdir():
|
for file in self.resources_path.iterdir():
|
||||||
@@ -189,13 +188,13 @@ class MusicPreview:
|
|||||||
else:
|
else:
|
||||||
# if self.mode == 1:
|
# if self.mode == 1:
|
||||||
# 重采样, 不变调
|
# 重采样, 不变调
|
||||||
print(">>", sound_name, pitch)
|
# print(">>", sound_name, pitch)
|
||||||
self.res_data[sound_name][pitch] = librosa.resample(
|
self.res_data[sound_name][pitch] = librosa.resample(
|
||||||
y_orig,
|
y_orig,
|
||||||
orig_sr=sr_orig,
|
orig_sr=sr_orig,
|
||||||
target_sr=self.output_sample_rate,
|
target_sr=self.output_sample_rate,
|
||||||
fix=False, # 尽管这样不变调,但是也不应将 pitch 与打击乐器联系在一起
|
fix=False, # 尽管这样不变调,但是也不应将 pitch 与打击乐器联系在一起
|
||||||
)
|
) # 已经在下面重新用 0 取代了打击乐器的 pitch
|
||||||
"""elif self.mode == 0:
|
"""elif self.mode == 0:
|
||||||
# 重采样, 不变调, 衰弱
|
# 重采样, 不变调, 衰弱
|
||||||
self.cache_dict[raw_name] = librosa_resample(
|
self.cache_dict[raw_name] = librosa_resample(
|
||||||
@@ -221,14 +220,15 @@ class MusicPreview:
|
|||||||
duration: int,
|
duration: int,
|
||||||
):
|
):
|
||||||
|
|
||||||
print(
|
# print(
|
||||||
sound_name,
|
# sound_name,
|
||||||
pitch,
|
# pitch,
|
||||||
">>",
|
# ">>",
|
||||||
(pitch := self.make_pitch_accurate(pitch)),
|
# (pitch := self.make_pitch_accurate(pitch)),
|
||||||
percussive,
|
# percussive,
|
||||||
duration,
|
# duration,
|
||||||
)
|
# )
|
||||||
|
pitch = 0 if percussive else self.make_pitch_accurate(pitch)
|
||||||
|
|
||||||
if sound_name in self.res_data:
|
if sound_name in self.res_data:
|
||||||
if pitch in self.res_data[sound_name]:
|
if pitch in self.res_data[sound_name]:
|
||||||
@@ -333,24 +333,24 @@ class MusicPreview:
|
|||||||
out_sr = self.output_sample_rate
|
out_sr = self.output_sample_rate
|
||||||
|
|
||||||
for note in music.get_minenotes(start_time=start_tick, end_time=end_tick):
|
for note in music.get_minenotes(start_time=start_tick, end_time=end_tick):
|
||||||
accurate_pitch = self.make_pitch_accurate(
|
accurate_pitch = (
|
||||||
note.pitch
|
0
|
||||||
- 60
|
if note.percussive
|
||||||
- (
|
else self.make_pitch_accurate(
|
||||||
0
|
note.pitch
|
||||||
if note.percussive
|
- 60
|
||||||
else MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6)
|
- MM_INSTRUMENT_DEVIATION_TABLE.get(note.instrument, 6)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
print(
|
# print(
|
||||||
":",
|
# ":",
|
||||||
note.instrument,
|
# note.instrument,
|
||||||
note.pitch,
|
# note.pitch,
|
||||||
">>",
|
# ">>",
|
||||||
accurate_pitch,
|
# accurate_pitch,
|
||||||
note.percussive,
|
# note.percussive,
|
||||||
note.duration_tick,
|
# note.duration_tick,
|
||||||
)
|
# )
|
||||||
if not note.percussive:
|
if not note.percussive:
|
||||||
overlay(
|
overlay(
|
||||||
self.res_data[note.instrument][accurate_pitch]
|
self.res_data[note.instrument][accurate_pitch]
|
||||||
|
|||||||
+1
-1
@@ -509,7 +509,7 @@ class SingleTrack(List[SingleNote]):
|
|||||||
|
|
||||||
self.argument_curves = {item: None for item in CurvableParam}
|
self.argument_curves = {item: None for item in CurvableParam}
|
||||||
|
|
||||||
super().__init__(*args)
|
super().__init__(args)
|
||||||
super().sort()
|
super().sort()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -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,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user