diff --git a/Musicreater/builtin_plugins/midi_read/main.py b/Musicreater/builtin_plugins/midi_read/main.py index c2083c0..72e1ecb 100644 --- a/Musicreater/builtin_plugins/midi_read/main.py +++ b/Musicreater/builtin_plugins/midi_read/main.py @@ -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]: # 乐器名称 diff --git a/Musicreater/builtin_plugins/midi_read/utils.py b/Musicreater/builtin_plugins/midi_read/utils.py index c7d0587..6ba03fd 100644 --- a/Musicreater/builtin_plugins/midi_read/utils.py +++ b/Musicreater/builtin_plugins/midi_read/utils.py @@ -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( diff --git a/Musicreater/builtin_plugins/music_preview/main.py b/Musicreater/builtin_plugins/music_preview/main.py index 4167a77..5808735 100644 --- a/Musicreater/builtin_plugins/music_preview/main.py +++ b/Musicreater/builtin_plugins/music_preview/main.py @@ -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, ) diff --git a/Musicreater/constants.py b/Musicreater/constants.py index e83fb08..37d6bd3 100644 --- a/Musicreater/constants.py +++ b/Musicreater/constants.py @@ -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] = { diff --git a/resources/test/enfasted_list_merging_test.py b/resources/experiments/enfasted_list_merging_test.py similarity index 100% rename from resources/test/enfasted_list_merging_test.py rename to resources/experiments/enfasted_list_merging_test.py diff --git a/resources/test/genexpr_vs_yieldfrom.py b/resources/experiments/genexpr_vs_yieldfrom.py similarity index 100% rename from resources/test/genexpr_vs_yieldfrom.py rename to resources/experiments/genexpr_vs_yieldfrom.py diff --git a/resources/test/list_merging_text.py b/resources/experiments/list_merging_text.py similarity index 100% rename from resources/test/list_merging_text.py rename to resources/experiments/list_merging_text.py diff --git a/resources/test/pgb-animate.json b/resources/experiments/pgb-animate.json similarity index 100% rename from resources/test/pgb-animate.json rename to resources/experiments/pgb-animate.json diff --git a/resources/test/volumn_function_fit.py b/resources/experiments/volumn_function_fit.py similarity index 100% rename from resources/test/volumn_function_fit.py rename to resources/experiments/volumn_function_fit.py diff --git a/resources/test/volumn_function_test.py b/resources/experiments/volumn_function_test.py similarity index 100% rename from resources/test/volumn_function_test.py rename to resources/experiments/volumn_function_test.py