aboutsummaryrefslogtreecommitdiffstats
path: root/eti-udp/etireader.py
blob: 9b91ca79931d636eca0f892ce1908677c4163adf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python

import struct
import os

ETI_FORMAT_RAW = "RAW"
ETI_FORMAT_STREAMED = "STREAMED"
ETI_FORMAT_FRAMED = "FRAMED"

class EtiReaderException(Exception):
    pass

class EtiReader(object):
    def __init__(self, filename):
        self.filename = filename
        self.fd = open(filename, "rb")
        self.fmt = self.discover_filetype()
        print("EtiReader reading {0}, discovered type {1}".format(filename, self.fmt))

    def discover_filetype(self):
        self.fd.seek(0)
        sync = False
        i = 0
        while True:
            sync = self.check_sync()
            if not sync:
                i = i + 1
                self.fd.seek(i)
            else:
                break

        if i == 0:
            self.fd.seek(0)
            return ETI_FORMAT_RAW
        elif i == 2:
            self.fd.seek(0)
            return ETI_FORMAT_STREAMED
        elif i == 6:
            self.fd.seek(4)
            return ETI_FORMAT_FRAMED
        else:
            print("ETI File not aligned, supposing RAW!")
            return ETI_FORMAT_RAW
                

    def __iter__(self):
        while True:
            n = self.next()
            if n == "":
                break
            else:
                yield n

    def next(self):
        if self.fmt == ETI_FORMAT_RAW:
            etiframe = self.fd.read(6144)
            if etiframe == "":
                raise EtiReaderException("Unable to read frame")
            return etiframe


        elif self.fmt == ETI_FORMAT_FRAMED or self.fmt == ETI_FORMAT_STREAMED:
            
            framesize_pack = self.fd.read(2)
            if len(framesize_pack) < 2:
                raise EtiReaderException("Unable to read frame size")
            framesize = struct.unpack("H", framesize_pack)[0]
            if framesize == 0 or framesize > 6144:
                raise EtiReaderException("Framesize: {0}".format(framesize))

            if not self.check_sync():
                raise EtiReaderException("Unable to read sync")

            self.fd.seek(-2, os.SEEK_CUR)
            frame = self.fd.read(framesize+2)
            if len(frame) < framesize:
                raise EtiReaderException("Unable to read frame")
            return frame

    def check_sync(self):
        here = self.fd.tell()
        sync_pack = self.fd.read(4)
        self.fd.seek(here)

        sync = struct.unpack("I", sync_pack)[0]

        return sync == 0x49c5f8ff or sync == 0xb63a07ff


if __name__ == "__main__":
    def etireadertest(reader):
        i = 0
        for frame in reader:
            allframes.append(frame)
            print("Frame {0}, length {1}".format(
                i, len(frame)))
            i += 1
            if i > 10:
                break

    allframes = []
    etireadertest(EtiReader("buddard.eti"))

    allframes = []
    etireadertest(EtiReader("streamed.eti"))

    allframes = []
    etireadertest(EtiReader("funk.eti"))

    allframes = []
    etireadertest(EtiReader("funk.raw.eti"))