def unparse(self): """ノーマルトラックをアンパースする Returns: ノーマルトラックバイナリ """ # 変数宣言 data = self.data track_header = '' binary = '' # トラック名の変換 binary += struct.pack('4B', 0x00, 0xff, 0x03, len(data['name'])) + data['name'] # テキストデータの変換 text = self.__unparse_text() #step = 119 step = 127 - len("DM:....:") for i in range(0, len(text) - 1, step): frame = min(step, len(text) - i) binary += struct.pack("4B", 0x00, 0xff, 0x01, frame + 8) binary += "DM:%04d:" % (i / step) + text[i:i + frame] # コントロールチェンジイベントの変換 for b in data['cc_data']: binary += tools.dtime2binary(b['dtime']) binary += struct.pack('3B', *b['cc']) # End of Track binary += data['eot'] # MTrk と トラックサイズの再計算 track_header = struct.pack( '>4sI', data['MTrk'], len(binary) ) return track_header + binary
def unparse(self): """マスタートラックをアンパースする Returns: マスタートラックバイナリ """ data = self.data binary = 'MTrk' + pack('>I', data['size']) for event in data['metaevents']: binary += tools.dtime2binary(event['dtime']) binary += pack('cBB', '\xff', event['type'], event['len']) t = event['type'] if t == 0x2f: # End of Track pass elif t == 0x51: # Tempo binary += pack('>I', self.tempo)[1:] elif t == 0x03: # Track Name binary += self.name elif t == 0x58: # Beat binary += pack('4b', *self.beat) return binary
def unparse(self): """マスタートラックをアンパースする Returns: マスタートラックバイナリ """ data = self.data binary = "MTrk" + struct.pack(">I", data["size"]) for event in data["metaevents"]: binary += tools.dtime2binary(event["dtime"]) binary += struct.pack("cBB", "\xff", event["type"], event["len"]) t = event["type"] if t == 0x2F: # End of Track pass elif t == 0x51: # Tempo binary += struct.pack(">I", self.tempo)[1:] elif t == 0x03: # Track Name binary += self.name elif t == 0x58: # Beat binary += struct.pack("4b", *self.beat) return binary
def parse(self, fp): """vsqファイルのノーマルトラック部分をパースする Args: fp: vsqファイルポインタ or FakeFileインスタンス fpはノーマルトラックのところまでシークしておく必要がある """ #トラックチャンクヘッダの解析 data = { "MTrk": unpack(">4s", fp.read(4))[0], "size": unpack('>i', fp.read(4))[0], "text": '', "cc_data": []} #MIDIイベントの解析 while True: dtime = tools.get_dtime(fp) mevent = unpack('3B', fp.read(3)) if mevent[1] == 0x2f: data['eot'] = tools.dtime2binary(dtime) + '\xff\x2f\x00' break #Control Changeイベント if mevent[0] == 0xb0: data['cc_data'].append({'dtime': dtime, 'cc': mevent}) else: #TrackNameイベント if mevent[1] == 0x03: data['name'] = fp.read(mevent[2]) #Textイベント elif mevent[1] == 0x01: fp.read(8) # skip "DM:xxxx:" data['text'] += fp.read(mevent[2] - 8) data.update(self.__parse_text(data['text'])) anotes, singers = self.__pack_events(data['Events'], data['Details']) self.data = data self.anotes = anotes self.singers = singers