Skip to content

Instantly share code, notes, and snippets.

@kallsyms
Created June 2, 2022 04:28
Show Gist options
  • Save kallsyms/c6e29bb72c190cd4b0edc5c1511bd3f9 to your computer and use it in GitHub Desktop.
Save kallsyms/c6e29bb72c190cd4b0edc5c1511bd3f9 to your computer and use it in GitHub Desktop.
Strip headers from VITA-49 packets and dump the raw I/Q data contained within
import sys
import struct
import requests
# some details from https://github.com/RedhawkSDR/VITA49/blob/master/cpp/include/BasicVRTPacket.h
def parse_vita_float(radix, bits):
# https://github.com/RedhawkSDR/VITA49/blob/a7230bcbd3547733be669b7c745eb7d9b0e17d25/cpp/include/VRTMath.h#L471
div = float(1 << radix)
return float(bits) / div
def parse_vita_double(bits):
return parse_vita_float(20, bits)
def parse_vita_f16(bits):
return parse_vita_float(7, bits)
if __name__ == "__main__":
# Usage: python3 vita_extract.py {vita49_input_filename} {raw_output_filename}
infn = sys.argv[1]
if infn.startswith('http'):
req = requests.get(infn, stream=True)
if not req.ok:
raise Exception(str(req))
inf = req.raw
else:
inf = open(infn, 'rb')
with open(sys.argv[2], 'wb') as outf:
while True:
hdrb = inf.read(4)
if not hdrb:
break
assert len(hdrb) == 4
h = int.from_bytes(hdrb, 'big')
typ = h >> 28
sz = h & 0xffff
sz *= 4
# size includes the 4 bytes we already read
everything = hdrb + inf.read(sz - 4)
assert len(everything) == sz
if typ == 1:
#hdr = everything[:7*4]
data = everything[7*4:]
outf.write(data)
elif typ == 4:
ctx = everything[7*4:]
# context
# https://github.com/microsoft/azure-software-radio/blob/main/gr-azure-software-radio/lib/difi_source_cpp_impl.cc#L314
unpacked = list(struct.unpack('!LLQQQQLLQQLLQ', ctx))
names = ['cif', 'rp', 'bw', 'ifref', 'rfref', 'ifoff', 'refl', 'gain', 'rate', 'tsadj', 'tscal', 'indic', 'payloadfmt']
unpacked = dict(zip(names, unpacked))
unpacked['cif'] = hex(unpacked['cif'])
unpacked['rp'] = hex(unpacked['rp'])
unpacked['bw'] = parse_vita_double(unpacked['bw'])
unpacked['ifref'] = parse_vita_double(unpacked['ifref'])
unpacked['rfref'] = parse_vita_double(unpacked['rfref'])
unpacked['ifoff'] = parse_vita_double(unpacked['ifoff'])
unpacked['refl'] = parse_vita_f16(unpacked['refl'])
# unsure of this
unpacked['gain'] = {1: parse_vita_f16(unpacked['gain'] & 0xffff), 2: parse_vita_f16(unpacked['gain'] >> 16)}
unpacked['rate'] = parse_vita_double(unpacked['rate'])
unpacked['indic'] = {'reflock': bool(unpacked['indic'] & (1 << 17))}
unpacked['payloadfmt'] = {'bitdepth': (unpacked['payloadfmt'] >> 32 & 0x1f) + 1}
print(unpacked)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment