mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
133 lines
4.3 KiB
Python
133 lines
4.3 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
Created on Fri Dec 11 23:10:21 2020
|
||
|
|
||
|
@author: DJ2LS
|
||
|
"""
|
||
|
|
||
|
import freedv
|
||
|
import logging
|
||
|
import sound
|
||
|
|
||
|
import pyaudio
|
||
|
|
||
|
class Helpers():
|
||
|
|
||
|
def crc16(data: bytes):
|
||
|
|
||
|
#https://stackoverflow.com/a/60604183
|
||
|
|
||
|
|
||
|
xor_in = 0x0000 # initial value
|
||
|
xor_out = 0x0000 # final XOR value
|
||
|
poly = 0x8005 # generator polinom (normal form)
|
||
|
|
||
|
reg = xor_in
|
||
|
for octet in data:
|
||
|
# reflect in
|
||
|
for i in range(8):
|
||
|
topbit = reg & 0x8000
|
||
|
if octet & (0x80 >> i):
|
||
|
topbit ^= 0x8000
|
||
|
reg <<= 1
|
||
|
if topbit:
|
||
|
reg ^= poly
|
||
|
reg &= 0xFFFF
|
||
|
# reflect out
|
||
|
return reg ^ xor_out
|
||
|
|
||
|
def getAudioDevices():
|
||
|
p = pyaudio.PyAudio()
|
||
|
info = p.get_host_api_info_by_index(0)
|
||
|
numdevices = info.get('deviceCount')
|
||
|
for i in range(0, numdevices):
|
||
|
if (p.get_device_info_by_host_api_device_index(0,i).get('maxInputChannels')) > 0:
|
||
|
print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))
|
||
|
if (p.get_device_info_by_host_api_device_index(0,i).get('maxOutputChannels')) > 0:
|
||
|
print("Output Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))
|
||
|
|
||
|
|
||
|
class TX():
|
||
|
|
||
|
|
||
|
def Broadcast(self, bcdata):
|
||
|
|
||
|
modem = freedv.FreeDV()
|
||
|
audio = sound.Audio()
|
||
|
|
||
|
|
||
|
#preamble = b'\x00' * modem.bytes_per_frame * 2 #SET PREAMPLE
|
||
|
preamble = b'\x00\x00\x00'
|
||
|
header = b'' # SET HEADER
|
||
|
#postamble = b'\xFF' * modem.bytes_per_frame# * 2 # SET POSTAMPLE
|
||
|
frame = preamble + header + bcdata# + postamble # COMBINE PREAMPLE, HEADER, DATA AND POSTAMPLE
|
||
|
|
||
|
logging.info(hex(Helpers.crc16(bcdata)))
|
||
|
logging.info(len(hex(Helpers.crc16(bcdata))))
|
||
|
#testcrc = modem.c_lib.freedv_gen_crc16(frame,modem.payload_per_frame)
|
||
|
|
||
|
|
||
|
logging.info("BYTES PER FRAME: " + str(modem.bytes_per_frame))
|
||
|
logging.info("PAYLOAD PER FRAME: " + str(modem.payload_per_frame))
|
||
|
logging.info("FRAME LENGTH: " + str(len(frame)))
|
||
|
#logging.info(str(len(frame)/modem.bytes_per_frame))
|
||
|
#logging.info(str(len(frame) % modem.bytes_per_frame))
|
||
|
|
||
|
|
||
|
# Check if data is divisable by bytes per frame. If yes (0) skip, If no (>0) fill up with frames
|
||
|
checkframe = len(frame) % modem.bytes_per_frame
|
||
|
|
||
|
# filecrc = binascii.crc16(frame).to_bytes(2, byteorder='big', signed=False)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#if checkframe != 0:
|
||
|
# filler = bytes(modem.bytes_per_frame - (len(frame) % modem.bytes_per_frame))
|
||
|
# logging.info("FILLER: " + str(len(filler)))
|
||
|
#
|
||
|
# frame = frame + filler
|
||
|
# if len(filler) == 6:
|
||
|
# filler * 2
|
||
|
#frame = frame + filler
|
||
|
#checkframe = len(frame) % modem.bytes_per_frame * 2
|
||
|
#logging.info("CHECKFRAME: " + str(checkframe))
|
||
|
#logging.info("FRAME LENGTH: " + str(len(frame)))
|
||
|
|
||
|
# Pull frame into a datalist to work as a simple buffer
|
||
|
data_list = [frame[i:i+modem.bytes_per_frame*2] for i in range(0, len(frame), modem.bytes_per_frame*2)] # PACK DATAFRAME TO A LIST WHICH IS AS BIG AS THE FRAME SIZE OF FREEDV MODE
|
||
|
|
||
|
#data_list.append(b'0x00')
|
||
|
|
||
|
|
||
|
length = len(data_list) # GET LENGTH OF DATA LIST
|
||
|
|
||
|
# Loop through data list for every item and modulate it
|
||
|
for i in range(length): # LOOP THROUGH DATA LIST
|
||
|
#crc = Helpers.crc16(data_list[i])
|
||
|
#logging.info(hex(crc))
|
||
|
logging.info(data_list[i])
|
||
|
modulated_data = modem.Modulate(data_list[i])
|
||
|
#logging.info(bytes(modulated_data))
|
||
|
audio.Play(modulated_data)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
class RX():
|
||
|
|
||
|
def ReceiveAudio():
|
||
|
|
||
|
audio = sound.Audio.Record()
|
||
|
frame = freedv.FreeDV.Demodulate(audio)
|
||
|
logging.info(frame)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|