예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
    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
예제 #4
0
    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