""" MOD reader by Yui Kinomoto @arlez80 """ """ ファイルから読み込み @param path File path @return smf """ func read_file( path ): var f = File.new( ) if not f.file_exists( path ): print( "file %s is not found" % path ) breakpoint f.open( path, f.READ ) var stream = StreamPeerBuffer.new( ) stream.set_data_array( f.get_buffer( f.get_len( ) ) ) stream.big_endian = true f.close( ) return self._read( stream ) """ 配列から読み込み @param data PoolByteArray @return smf """ func read_data( data ): var stream = StreamPeerBuffer.new( ) stream.set_data_array( data ) stream.big_endian = true return self._read( stream ) """ 読み込み @param stream @return smf """ func _read( stream ): var name = self._read_string( stream, 20 ) var samples = self._read_sample_informations( stream ) var song_length = stream.get_u8( ) var unknown_number = stream.get_u8( ) var song_positions = stream.get_partial_data( 128 )[1] var max_song_position = 0 for sp in song_positions: if max_song_position < sp: max_song_position = sp var magic = self._read_string( stream, 4 ) var channel_count = 4 match magic: "6CHN": channel_count = 6 "FLT8", "8CHN", "CD81", "OKTA": channel_count = 8 "16CN": channel_count = 16 "32CN": channel_count = 32 _: # print( "Unknown magic" ) # breakpoint pass var patterns = self._read_patterns( stream, max_song_position, channel_count ) self._read_sample_data( stream, samples ) return { "name": name, "song_length": song_length, "unknown_number": unknown_number, "song_positions": song_positions, "magic": magic, "patterns": patterns, "samples": samples, } """ サンプルのデータを読み込む """ func _read_sample_informations( stream ): var samples = [] for i in range( 0, 31 ): var sample = {} sample.name = self._read_string( stream, 22 ) sample.length = stream.get_u16( ) * 2 sample.fine_tune = stream.get_u8( ) & 0x0F if 0x08 < sample.fine_tune: sample.fine_tune = 0x10 - sample.fine_tune sample.volume = stream.get_u8( ) sample.loop_start = stream.get_u16( ) * 2 sample.loop_length = stream.get_u16( ) * 2 samples.append( sample ) return samples """ パターンを読み込む """ func _read_patterns( stream, max_position, channels ): var patterns = [] for position in range( 0, max_position ): var pattern = [] for i in range( 0, 64 ): var line = [] for ch in range( 0, channels ): var v1 = stream.get_u16( ) var v2 = stream.get_u16( ) var sample_number = ( ( v1 >> 8 ) & 0xF0 ) | ( ( v2 >> 12 ) & 0x0F ) var key_number = v1 & 0x0FFF var effect_command = v2 & 0x0FFF line.append({ "sample_number": sample_number, "key_number": key_number, "effect_command": effect_command, }) pattern.append( line ) patterns.append( pattern ) """ 波形データ読み込む """ func _read_sample_data( stream, samples ): for sample in samples: sample.data = stream.get_partial_data( sample.length )[1] """ 文字列の読み込み @param stream Stream @param size string size @return string """ func _read_string( stream, size ): return stream.get_partial_data( size )[1].get_string_from_ascii( )