#!/bin/env python3

import sys
import argparse
import socket
import time


BUFFER_LEN = 320
SAMPLE_RATE = 8000
DELAY = BUFFER_LEN / 2 / SAMPLE_RATE


HEADER_PTT_PRESSED = b"USRP" + b"\x00" * 11 + b"\x01" + b"\x00" * 16
HEADER_PTT_RELEASED = b"USRP" + b"\x00" * 28


def fm_feed(local_addr, local_port, remote_addr, remote_port, input_file):
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.bind((local_addr, local_port))
    udp_socket.connect((remote_addr, remote_port))

    try:
        audio_data = input_file.read(BUFFER_LEN)
        while audio_data != b"":
            frame = HEADER_PTT_PRESSED + audio_data
            udp_socket.sendall(frame)
            time.sleep(DELAY)

            audio_data = input_file.read(BUFFER_LEN)
    finally:
        frame = HEADER_PTT_RELEASED + b"0x00" * BUFFER_LEN
        udp_socket.sendall(frame)


def main():
    parser = argparse.ArgumentParser(
        prog="fm_feed",
        description="Send audio data to mmdvm host as USRP frames",
        epilog="Audio format: Signed 16bit integers, little endian, 8000 samples per second",
    )

    parser.add_argument(
        "--local-addr", help="sender address to use in the UDP frames", required=True
    )
    parser.add_argument(
        "--local-port", help="sender port to use in the UDP frames", default=4810
    )
    parser.add_argument(
        "--remote-addr", help="remote address to use in the UDP frames", required=True
    )
    parser.add_argument(
        "--remote-port", help="remote port to use in the UDP frames", default=3810
    )

    parser.add_argument(
        "--audio",
        help="file with raw audio data to send. Default is to read from stdin.",
    )

    args = parser.parse_args()

    input_file = sys.stdin.buffer
    if args.audio is not None:
        input_file = open(args.audio, "rb")

    fm_feed(
        args.local_addr, args.local_port, args.remote_addr, args.remote_port, input_file
    )


if __name__ == "__main__":
    main()
