1*a58d3d2aSXin Li""" 2*a58d3d2aSXin Li/* Copyright (c) 2022 Amazon 3*a58d3d2aSXin Li Written by Jan Buethe */ 4*a58d3d2aSXin Li/* 5*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without 6*a58d3d2aSXin Li modification, are permitted provided that the following conditions 7*a58d3d2aSXin Li are met: 8*a58d3d2aSXin Li 9*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright 10*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer. 11*a58d3d2aSXin Li 12*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright 13*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the 14*a58d3d2aSXin Li documentation and/or other materials provided with the distribution. 15*a58d3d2aSXin Li 16*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 20*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*a58d3d2aSXin Li*/ 28*a58d3d2aSXin Li""" 29*a58d3d2aSXin Li 30*a58d3d2aSXin Liimport numpy as np 31*a58d3d2aSXin Li 32*a58d3d2aSXin Li 33*a58d3d2aSXin Li 34*a58d3d2aSXin Lidef write_fec_packets(filename, packets, rates=None): 35*a58d3d2aSXin Li """ writes packets in binary format """ 36*a58d3d2aSXin Li 37*a58d3d2aSXin Li assert np.dtype(np.float32).itemsize == 4 38*a58d3d2aSXin Li assert np.dtype(np.int16).itemsize == 2 39*a58d3d2aSXin Li 40*a58d3d2aSXin Li # derive some sizes 41*a58d3d2aSXin Li num_packets = len(packets) 42*a58d3d2aSXin Li subframes_per_packet = packets[0].shape[-2] 43*a58d3d2aSXin Li num_features = packets[0].shape[-1] 44*a58d3d2aSXin Li 45*a58d3d2aSXin Li # size of float is 4 46*a58d3d2aSXin Li subframe_size = num_features * 4 47*a58d3d2aSXin Li packet_size = subframe_size * subframes_per_packet + 2 # two bytes for rate 48*a58d3d2aSXin Li 49*a58d3d2aSXin Li version = 1 50*a58d3d2aSXin Li # header size (version, header_size, num_packets, packet_size, subframe_size, subrames_per_packet, num_features) 51*a58d3d2aSXin Li header_size = 14 52*a58d3d2aSXin Li 53*a58d3d2aSXin Li with open(filename, 'wb') as f: 54*a58d3d2aSXin Li 55*a58d3d2aSXin Li # header 56*a58d3d2aSXin Li f.write(np.int16(version).tobytes()) 57*a58d3d2aSXin Li f.write(np.int16(header_size).tobytes()) 58*a58d3d2aSXin Li f.write(np.int16(num_packets).tobytes()) 59*a58d3d2aSXin Li f.write(np.int16(packet_size).tobytes()) 60*a58d3d2aSXin Li f.write(np.int16(subframe_size).tobytes()) 61*a58d3d2aSXin Li f.write(np.int16(subframes_per_packet).tobytes()) 62*a58d3d2aSXin Li f.write(np.int16(num_features).tobytes()) 63*a58d3d2aSXin Li 64*a58d3d2aSXin Li # packets 65*a58d3d2aSXin Li for i, packet in enumerate(packets): 66*a58d3d2aSXin Li if type(rates) == type(None): 67*a58d3d2aSXin Li rate = 0 68*a58d3d2aSXin Li else: 69*a58d3d2aSXin Li rate = rates[i] 70*a58d3d2aSXin Li 71*a58d3d2aSXin Li f.write(np.int16(rate).tobytes()) 72*a58d3d2aSXin Li 73*a58d3d2aSXin Li features = np.flip(packet, axis=-2) 74*a58d3d2aSXin Li f.write(features.astype(np.float32).tobytes()) 75*a58d3d2aSXin Li 76*a58d3d2aSXin Li 77*a58d3d2aSXin Lidef read_fec_packets(filename): 78*a58d3d2aSXin Li """ reads packets from binary format """ 79*a58d3d2aSXin Li 80*a58d3d2aSXin Li assert np.dtype(np.float32).itemsize == 4 81*a58d3d2aSXin Li assert np.dtype(np.int16).itemsize == 2 82*a58d3d2aSXin Li 83*a58d3d2aSXin Li with open(filename, 'rb') as f: 84*a58d3d2aSXin Li 85*a58d3d2aSXin Li # header 86*a58d3d2aSXin Li version = np.frombuffer(f.read(2), dtype=np.int16).item() 87*a58d3d2aSXin Li header_size = np.frombuffer(f.read(2), dtype=np.int16).item() 88*a58d3d2aSXin Li num_packets = np.frombuffer(f.read(2), dtype=np.int16).item() 89*a58d3d2aSXin Li packet_size = np.frombuffer(f.read(2), dtype=np.int16).item() 90*a58d3d2aSXin Li subframe_size = np.frombuffer(f.read(2), dtype=np.int16).item() 91*a58d3d2aSXin Li subframes_per_packet = np.frombuffer(f.read(2), dtype=np.int16).item() 92*a58d3d2aSXin Li num_features = np.frombuffer(f.read(2), dtype=np.int16).item() 93*a58d3d2aSXin Li 94*a58d3d2aSXin Li dummy_features = np.zeros((1, subframes_per_packet, num_features), dtype=np.float32) 95*a58d3d2aSXin Li 96*a58d3d2aSXin Li # packets 97*a58d3d2aSXin Li rates = [] 98*a58d3d2aSXin Li packets = [] 99*a58d3d2aSXin Li for i in range(num_packets): 100*a58d3d2aSXin Li 101*a58d3d2aSXin Li rate = np.frombuffer(f.read(2), dtype=np.int16).item 102*a58d3d2aSXin Li rates.append(rate) 103*a58d3d2aSXin Li 104*a58d3d2aSXin Li features = np.reshape(np.frombuffer(f.read(subframe_size * subframes_per_packet), dtype=np.float32), dummy_features.shape) 105*a58d3d2aSXin Li packet = np.flip(features, axis=-2) 106*a58d3d2aSXin Li packets.append(packet) 107*a58d3d2aSXin Li 108*a58d3d2aSXin Li return packets