mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-07-24 01:02:32 +00:00
需要和重新设计音量的配置方式。开始做实验
This commit is contained in:
@@ -66,10 +66,10 @@ class MidiImportConfig(PluginConfig):
|
||||
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
|
||||
default_midi_charset: str = "latin1"
|
||||
default_lyric_encoding: str = "utf-8" # 默认歌词编码
|
||||
midi_charset: str = "latin1"
|
||||
string_encoding: str = "utf-8" # 默认歌词编码
|
||||
"""
|
||||
默认歌词编码,设定为空时不进行二次编码处理
|
||||
默认字串编码,设定为空时不对原 Midi 中的字符串二次编码
|
||||
"""
|
||||
|
||||
# 对照表,此处 None 值在下边 post init 函数中有处理
|
||||
@@ -200,9 +200,7 @@ class MidiImport2MusicPlugin(MusicInputPluginBase):
|
||||
if config is None:
|
||||
config = MidiImportConfig()
|
||||
return self.midifile_2_singlemusic(
|
||||
mido.MidiFile(
|
||||
file=bytes_buffer_in, clip=True, charset=config.default_midi_charset
|
||||
),
|
||||
mido.MidiFile(file=bytes_buffer_in, clip=True, charset=config.midi_charset),
|
||||
config,
|
||||
)
|
||||
|
||||
@@ -213,9 +211,7 @@ class MidiImport2MusicPlugin(MusicInputPluginBase):
|
||||
if config is None:
|
||||
config = MidiImportConfig()
|
||||
return self.midifile_2_singlemusic(
|
||||
mido.MidiFile(
|
||||
filename=file_path, clip=True, charset=config.default_midi_charset
|
||||
),
|
||||
mido.MidiFile(filename=file_path, clip=True, charset=config.midi_charset),
|
||||
config,
|
||||
)
|
||||
|
||||
@@ -344,7 +340,9 @@ class MidiImport2MusicPlugin(MusicInputPluginBase):
|
||||
midi_copyright_list.append(msg.text)
|
||||
elif msg.type == "track_name":
|
||||
# 检测轨道名称事件
|
||||
midi_track_name_dict[track_no] = msg.name
|
||||
midi_track_name_dict[track_no] = msg.name.encode("latin1").decode(
|
||||
config.string_encoding
|
||||
)
|
||||
elif msg.type == "note_on" and msg.velocity != 0:
|
||||
# 一个音符开始弹奏
|
||||
|
||||
@@ -428,9 +426,9 @@ class MidiImport2MusicPlugin(MusicInputPluginBase):
|
||||
note_table_replacement=config.note_replacement_table,
|
||||
lyric_line=(
|
||||
_lyric.encode("latin1").decode(
|
||||
config.default_lyric_encoding
|
||||
config.string_encoding
|
||||
)
|
||||
if config.default_lyric_encoding
|
||||
if config.string_encoding
|
||||
else _lyric
|
||||
),
|
||||
)
|
||||
@@ -498,7 +496,7 @@ class MidiImport2MusicPlugin(MusicInputPluginBase):
|
||||
for track_properties, every_single_track in divided_tracks.items():
|
||||
# [音轨编号, 通道编号, 乐器名称, 音量, 声相]
|
||||
if track_properties[0] and (
|
||||
track_name := midi_track_name_dict.get(track_properties[0])
|
||||
track_name := midi_track_name_dict.get(track_properties[0], "无名音轨")
|
||||
): # 音轨编号
|
||||
every_single_track.name = track_name
|
||||
if track_properties[2]: # 乐器名称
|
||||
|
||||
@@ -204,7 +204,7 @@ def midi_msgs_to_noteinfo(
|
||||
return (
|
||||
SingleNote(
|
||||
note_pitch=note,
|
||||
note_volume=velocity,
|
||||
note_volume=velocity, # 需要重新设计
|
||||
start_tick=(tk := int(start_time / float(play_speed) / 50000)),
|
||||
keep_tick=round(duration / float(play_speed) / 50000),
|
||||
mass_precision_time=round(
|
||||
|
||||
@@ -113,6 +113,16 @@ class MusicPreview:
|
||||
if file.is_file():
|
||||
self.res_raw_data[file.stem] = librosa.load(file, sr=None)
|
||||
|
||||
# print(
|
||||
# file.stem,": { 'AVG':",
|
||||
# np.average(np.absolute(self.res_raw_data[file.stem][0])),", 'MID' :",
|
||||
# np.median(np.absolute(self.res_raw_data[file.stem][0])),", 'MAX' :",
|
||||
# np.max(np.absolute(self.res_raw_data[file.stem][0])),", 'MIN' :",
|
||||
# np.min(np.absolute(self.res_raw_data[file.stem][0])),", 'VAR' :",
|
||||
# np.var(np.absolute(self.res_raw_data[file.stem][0])),"}",
|
||||
# flush=True,
|
||||
# )
|
||||
|
||||
def res_shift(
|
||||
self,
|
||||
sound_name: str,
|
||||
@@ -121,24 +131,28 @@ class MusicPreview:
|
||||
duration: int,
|
||||
# rate: int
|
||||
):
|
||||
y_orig, sr_orig = self.res_raw_data[sound_name]
|
||||
original_y, original_sample_rate = self.res_raw_data[sound_name]
|
||||
if not percussive:
|
||||
if self.mode == 1:
|
||||
# 变调, 时域压扩, 重采样 mc方法
|
||||
self.res_data[sound_name][pitch] = librosa.resample(
|
||||
librosa.effects.time_stretch(
|
||||
librosa.effects.pitch_shift(y_orig, sr=sr_orig, n_steps=pitch),
|
||||
librosa.effects.pitch_shift(
|
||||
original_y, sr=original_sample_rate, n_steps=pitch
|
||||
),
|
||||
rate=2 ** (pitch / 12),
|
||||
),
|
||||
orig_sr=sr_orig,
|
||||
orig_sr=original_sample_rate,
|
||||
target_sr=self.output_sample_rate,
|
||||
fix=False,
|
||||
)
|
||||
elif self.mode == 0:
|
||||
# 重采样, 变调
|
||||
self.res_data[sound_name][pitch] = librosa.resample(
|
||||
librosa.effects.pitch_shift(y_orig, sr=sr_orig, n_steps=pitch),
|
||||
orig_sr=sr_orig,
|
||||
librosa.effects.pitch_shift(
|
||||
original_y, sr=original_sample_rate, n_steps=pitch
|
||||
),
|
||||
orig_sr=original_sample_rate,
|
||||
target_sr=self.output_sample_rate,
|
||||
fix=False,
|
||||
)
|
||||
@@ -146,16 +160,18 @@ class MusicPreview:
|
||||
|
||||
# 变调, 时域压扩, 重采样 MIDI-FFT
|
||||
if self.overlay_mode_c == 2:
|
||||
rate = duration / 20 / (len(y_orig[0]) / sr_orig)
|
||||
rate = duration / 20 / (len(original_y[0]) / original_sample_rate)
|
||||
else:
|
||||
rate = duration / 20 / (len(y_orig) / sr_orig)
|
||||
rate = duration / 20 / (len(original_y) / original_sample_rate)
|
||||
rate = rate if rate != 0 else 1
|
||||
self.res_data[sound_name][pitch] = librosa.resample(
|
||||
librosa.effects.time_stretch(
|
||||
librosa.effects.pitch_shift(y_orig, sr=sr_orig, n_steps=pitch),
|
||||
librosa.effects.pitch_shift(
|
||||
original_y, sr=original_sample_rate, n_steps=pitch
|
||||
),
|
||||
rate=rate,
|
||||
),
|
||||
orig_sr=sr_orig,
|
||||
orig_sr=original_sample_rate,
|
||||
target_sr=self.output_sample_rate,
|
||||
fix=False,
|
||||
)
|
||||
@@ -163,38 +179,41 @@ class MusicPreview:
|
||||
# 变调, 时域压扩, 重采样 MIDI-cut
|
||||
if self.overlay_mode_c == 2:
|
||||
deal = librosa.effects.pitch_shift(
|
||||
y_orig, sr=sr_orig, n_steps=pitch
|
||||
original_y, sr=original_sample_rate, n_steps=pitch
|
||||
)[
|
||||
...,
|
||||
: (
|
||||
int(duration / 20 * sr_orig)
|
||||
if duration / 20 * sr_orig > len(y_orig[0])
|
||||
else len(y_orig[0])
|
||||
int(duration / 20 * original_sample_rate)
|
||||
if duration / 20 * original_sample_rate > len(original_y[0])
|
||||
else len(original_y[0])
|
||||
),
|
||||
]
|
||||
else:
|
||||
deal = librosa.effects.pitch_shift(
|
||||
y_orig, sr=sr_orig, n_steps=pitch
|
||||
original_y, sr=original_sample_rate, n_steps=pitch
|
||||
)[
|
||||
: (
|
||||
int(duration / 20 * sr_orig)
|
||||
if duration / 20 * sr_orig > len(y_orig)
|
||||
else len(y_orig)
|
||||
int(duration / 20 * original_sample_rate)
|
||||
if duration / 20 * original_sample_rate > len(original_y)
|
||||
else len(original_y)
|
||||
)
|
||||
]
|
||||
self.res_data[sound_name][pitch] = librosa.resample(
|
||||
deal, orig_sr=sr_orig, target_sr=self.output_sample_rate, fix=False
|
||||
deal,
|
||||
orig_sr=original_sample_rate,
|
||||
target_sr=self.output_sample_rate,
|
||||
fix=False,
|
||||
)
|
||||
else:
|
||||
# if self.mode == 1:
|
||||
# 重采样, 不变调
|
||||
# print(">>", sound_name, pitch)
|
||||
self.res_data[sound_name][pitch] = librosa.resample(
|
||||
y_orig,
|
||||
orig_sr=sr_orig,
|
||||
original_y,
|
||||
orig_sr=original_sample_rate,
|
||||
target_sr=self.output_sample_rate,
|
||||
fix=False, # 尽管这样不变调,但是也不应将 pitch 与打击乐器联系在一起
|
||||
) # 已经在下面重新用 0 取代了打击乐器的 pitch
|
||||
) # 已经在下面重新用 0 取代了打击乐器的 pitch
|
||||
"""elif self.mode == 0:
|
||||
# 重采样, 不变调, 衰弱
|
||||
self.cache_dict[raw_name] = librosa_resample(
|
||||
@@ -354,20 +373,18 @@ class MusicPreview:
|
||||
if not note.percussive:
|
||||
overlay(
|
||||
self.res_data[note.instrument][accurate_pitch]
|
||||
* note.volume
|
||||
/ (note.position.sound_distance + 0.5)
|
||||
/ 127,
|
||||
* (1 - (note.position.sound_distance / 48)),
|
||||
note.start_tick,
|
||||
)
|
||||
# 上述参数的原顺序应为
|
||||
# x * (音量 / 127) * (1 / (距离 + 0.5))
|
||||
# 乘法优先是为了提高计算精度,小的数的除法优先同理
|
||||
# 下面是后来的注释
|
||||
# 这种方式是错误的 —— 金羿 20260720
|
||||
else:
|
||||
overlay(
|
||||
self.res_data[note.instrument][accurate_pitch]
|
||||
* note.volume
|
||||
/ (note.position.sound_distance + 0.5)
|
||||
/ 127,
|
||||
* (1 - (note.position.sound_distance / 48)),
|
||||
note.start_tick,
|
||||
)
|
||||
|
||||
|
||||
@@ -409,6 +409,7 @@ MC_PITCHED_INSTRUMENT_LIST: List[str] = [
|
||||
|
||||
MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
||||
"note.bass": ("planks",),
|
||||
"note.bassattack": ("planks",), # 无法找到此音效
|
||||
"note.snare": ("sand",),
|
||||
"note.hat": ("glass",),
|
||||
"note.bd": ("stone",),
|
||||
@@ -424,12 +425,11 @@ MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
||||
"note.bit": ("emerald_block",),
|
||||
"note.banjo": ("hay_block",),
|
||||
"note.pling": ("glowstone",),
|
||||
"note.bassattack": ("stone",), # 无法找到此音效
|
||||
"note.harp": ("dirt",),
|
||||
"note.trumpet": ("waxed_copper",),
|
||||
"note.trumpet_exposed": ("waxed_exposed_copper",),
|
||||
"note.trumpet_weathered": ("waxed_weathered_copper",),
|
||||
"note.trumpet_oxidized": ("waxed_oxidized_copper",),
|
||||
"note.harp": ("dirt",),
|
||||
# 呃……
|
||||
"firework.blast": ("sandstone",),
|
||||
"firework.twinkle": ("red_sandstone",),
|
||||
@@ -438,6 +438,38 @@ MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
||||
}
|
||||
"""MC乐器对音符盒下垫方块对照表"""
|
||||
|
||||
MC_INSTRUMENT_VOLUME_BALANCE_TABLE: Dict[str, float] = {
|
||||
"note.bass": 0.18975738,
|
||||
"note.bassattack": 0.19250469,
|
||||
"note.snare": 0.09636449,
|
||||
"note.hat": 0.041303635,
|
||||
"note.bd": 0.25398168,
|
||||
"note.bell": 0.03190162,
|
||||
"note.flute": 0.050610494,
|
||||
"note.chime": 0.011847978,
|
||||
"note.guitar": 0.03356794,
|
||||
"note.xylophone": 0.025973769,
|
||||
"note.iron_xylophone": 0.044438824,
|
||||
"note.cow_bell": 0.09123069,
|
||||
"note.didgeridoo": 0.06332747,
|
||||
"note.bit": 0.028824601,
|
||||
"note.banjo": 0.02944984,
|
||||
"note.pling": 0.11315284,
|
||||
"note.trumpet": 0.069420114,
|
||||
"note.trumpet_exposed": 0.083734825,
|
||||
"note.trumpet_oxidized": 0.047252066,
|
||||
"note.trumpet_weathered": 0.06659823,
|
||||
"note.harp": 0.12101666,
|
||||
# 嗯……
|
||||
"fire.ignite": 0.004931174,
|
||||
"firework.blast": 0.015445901,
|
||||
"firework.twinkle": 0.032410737,
|
||||
"mob.cat.meow-2": 0.0675417,
|
||||
"mob.cat.meow-4": 0.05923138,
|
||||
"mob.zombie.wood": 0.14135803,
|
||||
}
|
||||
|
||||
|
||||
MC_EILLES_RT261_INSTRUMENT_REPLACE_TABLE: Dict[str, str] = {
|
||||
"note.trumpet": "note.flute",
|
||||
"note.trumpet_exposed": "note.flute",
|
||||
@@ -505,7 +537,7 @@ MM_INSTRUMENT_RANGE_TABLE: Dict[str, Tuple[Tuple[int, int], int]] = {
|
||||
}
|
||||
"""
|
||||
不同乐器的音域偏离对照表
|
||||
元组里的是范围,后面的整数是中央 C 所在
|
||||
元组里的是范围,后面的整数是游戏里的默认采样音高
|
||||
"""
|
||||
|
||||
MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
||||
|
||||
Reference in New Issue
Block a user