#!/usr/bin/env python

"""
Convert a binary data file (generated by rx_samples_to_file) to a memroy text
file that can be read by Verilog's $readmemh.
"""

import argparse
import os
import time
import sys


CHUNK_SIZE = 2**20


def le_bin_str_to_signed_short(b):
    v = ord(b[1])*(1<<8) + ord(b[0])
    if v > (1<<15):
        v = v - (1<<16)
    return v


def signed_short_to_hex_str(n):
    return format(n%(1<<16), '04x')


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('file', help="Binary file.")
    parser.add_argument('--out', help="Output file.")
    parser.add_argument('--scale', type=int, default=1)

    args = parser.parse_args()

    if args.out is None:
        args.out = '%s.txt' % (os.path.splitext(args.file)[0])

    begin = time.clock()
    byte_count = 0
    total_bytes = os.path.getsize(args.file)
    with open(args.file, 'rb') as input:
        with open(args.out, 'wb', buffering=2**26) as output:
            while True:
                bytes = input.read(CHUNK_SIZE)
                if len(bytes) == 0:
                    break
                for i in range(0, len(bytes), 4):
                    I = le_bin_str_to_signed_short(bytes[i:i+2])/args.scale
                    Q = le_bin_str_to_signed_short(bytes[i+2:i+4])/args.scale
                    output.write('%s%s\n' % (signed_short_to_hex_str(I),
                                             signed_short_to_hex_str(Q)))
                byte_count += len(bytes)
                elapsed = time.clock() - begin
                speed = byte_count / elapsed
                eta = (total_bytes - byte_count)/speed
                progress = '%d / %d B\tSpeed: %.1f B/s\t Elapsed: %d s\tETA: %d s' %\
                    (byte_count>>20, total_bytes, speed, int(elapsed), int(eta))
                sys.stdout.write('\r%s' % (progress))
                sys.stdout.flush()
    sys.stdout.write('\n')


if __name__ == '__main__':
    main()
