From 614e646551a54a11fa8234bb36682db67caccc4d Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 20 Sep 2020 20:54:07 -0300 Subject: [PATCH 1/4] bugfix for SSIDs from 10-15 --- afsk/ax25.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/afsk/ax25.py b/afsk/ax25.py index 3c899bb..120c0df 100644 --- a/afsk/ax25.py +++ b/afsk/ax25.py @@ -111,6 +111,9 @@ def callsign_encode(self, callsign): else: ssid = b"0" + if 10 <= int(ssid) <= 15: + ssid = chr(ord(ssid[1])+10) + assert(len(ssid) == 1) assert(len(callsign) <= 6) From 82d68db29c1cb4a070b2dc9a67ae3abe50afb20a Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 20 Sep 2020 23:00:08 -0300 Subject: [PATCH 2/4] Python3 compatibility --- .ipynb_checkpoints/TestAprs-checkpoint.ipynb | 112 +++++++++ .ipynb_checkpoints/TestFcs-checkpoint.ipynb | 123 ++++++++++ .../TestPacket-checkpoint.ipynb | 215 ++++++++++++++++++ TestAprs.ipynb | 112 +++++++++ TestFcs.ipynb | 123 ++++++++++ TestPacket.ipynb | 215 ++++++++++++++++++ afsk/__init__.py | 5 +- afsk/afsk.py | 4 +- afsk/ax25.py | 75 ++---- test.py | 22 +- 10 files changed, 934 insertions(+), 72 deletions(-) create mode 100644 .ipynb_checkpoints/TestAprs-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/TestFcs-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/TestPacket-checkpoint.ipynb create mode 100644 TestAprs.ipynb create mode 100644 TestFcs.ipynb create mode 100644 TestPacket.ipynb diff --git a/.ipynb_checkpoints/TestAprs-checkpoint.ipynb b/.ipynb_checkpoints/TestAprs-checkpoint.ipynb new file mode 100644 index 0000000..d016b84 --- /dev/null +++ b/.ipynb_checkpoints/TestAprs-checkpoint.ipynb @@ -0,0 +1,112 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "logger = logging.getLogger(__name__)\n", + "\n", + "from afsk.ax25 import UI\n", + "from afsk.afsk import encode\n", + "import audiogen\n", + "import sys" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "packet = UI(\n", + "\tdestination='APRS',\n", + "\tsource='LU8AIE', \n", + "\tinfo=':EMAIL :lu8aie@gmail.com Test email'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:__main__:Sending packet: 'LU8AIE>APRS,WIDE1-1,WIDE2-1::EMAIL :lu8aie@gmail.com Test email'\n", + "DEBUG:__main__:Packet bits:bitarray('011111100100000100000101001001010110010100000010000000100000011000011001010101010000111001000001010010010101000100000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110010100010101100101000001010010010001100100000010000000100000001000000010001011100001101101010111000011100100001101001011010100110000000101110011010110110100001101001011000110110011101001100011011110110101101100000010000101010101001101100111000101110000001001010011010110110100001101001011000110110001101101100101101111110')\n" + ] + } + ], + "source": [ + "logger.info(r\"Sending packet: '{0}'\".format(packet))\n", + "logger.debug(r\"Packet bits:{0!r}\".format(packet.unparse()))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "audio = encode(packet.unparse())" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "object of type 'generator' has no len()", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0maudiogen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msampler\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstdout\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0maudio\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwrite_wav\u001b[1;34m(f, channels, sample_width, raw_samples, seekable)\u001b[0m\n\u001b[0;32m 149\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 150\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSAMPLE_WIDTH\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mseekable\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 151\u001b[1;33m \u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwav_samples\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 152\u001b[0m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"next\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 153\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwav_samples\u001b[1;34m(channels, sample_width, raw_samples)\u001b[0m\n\u001b[0;32m 113\u001b[0m \u001b[1;31m# if passed one generator, we have one channel\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 114\u001b[0m \u001b[0mchannels\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 115\u001b[1;33m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 116\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 117\u001b[0m \u001b[1;31m# we have audio waveforms, so sample/pack them first\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mTypeError\u001b[0m: object of type 'generator' has no len()" + ] + } + ], + "source": [ + "audiogen.sampler.write_wav(sys.stdout, audio)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/TestFcs-checkpoint.ipynb b/.ipynb_checkpoints/TestFcs-checkpoint.ipynb new file mode 100644 index 0000000..b6c85aa --- /dev/null +++ b/.ipynb_checkpoints/TestFcs-checkpoint.ipynb @@ -0,0 +1,123 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "\n", + "from afsk.ax25 import FCS\n", + "from bitarray import bitarray\n", + "\n", + "import crc16\n", + "import struct\n", + "\n", + "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", + "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", + "\n", + "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", + "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "fcs = FCS()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "str_bytes = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n", + "bits = bitarray()\n", + "bits.frombytes(str_bytes)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "for bit in bits:\n", + "\tfcs.update_bit(bit)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "assert fcs.digest() == b'[\\x07'" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "calcbytes\n", + "b'[\\x07'\n" + ] + } + ], + "source": [ + "print (\"calcbytes\")\n", + "print (\"%r\" % fcs.digest())" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "digest = bitarray(endian=\"little\")\n", + "digest.frombytes(fcs.digest())\n", + "assert digest == bitarray('1101101011100000')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/TestPacket-checkpoint.ipynb b/.ipynb_checkpoints/TestPacket-checkpoint.ipynb new file mode 100644 index 0000000..34328df --- /dev/null +++ b/.ipynb_checkpoints/TestPacket-checkpoint.ipynb @@ -0,0 +1,215 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "\n", + "from afsk.ax25 import UI\n", + "from bitarray import bitarray\n", + "\n", + "import crc16\n", + "import struct\n", + "\n", + "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", + "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", + "\n", + "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", + "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'\n", + "expected_bytes = b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", + "#expected_bits = bitarray.bitarray('01111110010000010000010100100101011001010000001000000010000001100001000101010101010110010101100101001101000000100000011001110101010010010001000101010001010001100000001001000110011101010100100100010001010100010010011000000010110001101100000000001111010111000010101010100110110011100010111011111001111101001101111110')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "packet = UI(\"APRS\", \"DUMMY\", info=\":Test\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEBUG:afsk.ax25:Stuffing bit\n", + "DEBUG:afsk.ax25:Stuffing bit\n" + ] + } + ], + "source": [ + "generated_bits = packet.unparse()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "generated_bytes = generated_bits.tobytes()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Unstuffed body BA:\n", + "01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011\n" + ] + } + ], + "source": [ + "print (\"Unstuffed body BA:\\n%s\" % unstuffed_body)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "checksummed_content_bits:\n", + "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0' ':Test'\n" + ] + } + ], + "source": [ + "print (\"checksummed_content_bits:\\n%r %r\" % (packet.header(), packet.info))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BS PACKET:\n", + "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð:Testõg'\n" + ] + } + ], + "source": [ + "print (\"BS PACKET:\\n%r\" % (bs_packet))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Packet:\n", + "DUMMY>APRS,WIDE1-1,WIDE2-1::Test\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xdf\\xcf'\n", + "Header:\n", + "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n" + ] + } + ], + "source": [ + "print (\"Packet:\\n%s\\n%r\\nHeader:\\n%r\" % (packet, packet.packet(), packet.header()))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BS HEADER:\n", + "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð'\n" + ] + } + ], + "source": [ + "print (\"BS HEADER:\\n%r\" % (bs_header))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generated:\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", + "Expected:\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n" + ] + } + ], + "source": [ + "print (\"Generated:\\n%r\\nExpected:\\n%r\" % (generated_bytes, expected_bytes))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#assert generated_bits == expected_bits\n", + "assert generated_bytes == expected_bytes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/TestAprs.ipynb b/TestAprs.ipynb new file mode 100644 index 0000000..9d698c6 --- /dev/null +++ b/TestAprs.ipynb @@ -0,0 +1,112 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "logger = logging.getLogger(__name__)\n", + "\n", + "from afsk.ax25 import UI\n", + "from afsk.afsk import encode\n", + "import audiogen\n", + "import sys" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "packet = UI(\n", + "\tdestination='APRS',\n", + "\tsource='LU8AIE', \n", + "\tinfo=':EMAIL :lu8aie@gmail.com Test email'\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:__main__:Sending packet: 'LU8AIE>APRS,WIDE1-1,WIDE2-1::EMAIL :lu8aie@gmail.com Test email'\n", + "DEBUG:__main__:Packet bits:bitarray('011111100100000100000101001001010110010100000010000000100000011000011001010101010000111001000001010010010101000100000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110010100010101100101000001010010010001100100000010000000100000001000000010001011100001101101010111000011100100001101001011010100110000000101110011010110110100001101001011000110110011101001100011011110110101101100000010000101010101001101100111000101110000001001010011010110110100001101001011000110110001101101100101101111110')\n" + ] + } + ], + "source": [ + "logger.info(r\"Sending packet: '{0}'\".format(packet))\n", + "logger.debug(r\"Packet bits:{0!r}\".format(packet.unparse()))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "audio = encode(packet.unparse())" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "object of type 'generator' has no len()", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0maudiogen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msampler\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstdout\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0maudio\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwrite_wav\u001b[1;34m(f, channels, sample_width, raw_samples, seekable)\u001b[0m\n\u001b[0;32m 149\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 150\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSAMPLE_WIDTH\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mseekable\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 151\u001b[1;33m \u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwav_samples\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 152\u001b[0m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"next\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 153\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwav_samples\u001b[1;34m(channels, sample_width, raw_samples)\u001b[0m\n\u001b[0;32m 113\u001b[0m \u001b[1;31m# if passed one generator, we have one channel\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 114\u001b[0m \u001b[0mchannels\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 115\u001b[1;33m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 116\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 117\u001b[0m \u001b[1;31m# we have audio waveforms, so sample/pack them first\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mTypeError\u001b[0m: object of type 'generator' has no len()" + ] + } + ], + "source": [ + "audiogen.sampler.write_wav(sys.stdout, audio)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/TestFcs.ipynb b/TestFcs.ipynb new file mode 100644 index 0000000..b6c85aa --- /dev/null +++ b/TestFcs.ipynb @@ -0,0 +1,123 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "\n", + "from afsk.ax25 import FCS\n", + "from bitarray import bitarray\n", + "\n", + "import crc16\n", + "import struct\n", + "\n", + "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", + "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", + "\n", + "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", + "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "fcs = FCS()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "str_bytes = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n", + "bits = bitarray()\n", + "bits.frombytes(str_bytes)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "for bit in bits:\n", + "\tfcs.update_bit(bit)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "assert fcs.digest() == b'[\\x07'" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "calcbytes\n", + "b'[\\x07'\n" + ] + } + ], + "source": [ + "print (\"calcbytes\")\n", + "print (\"%r\" % fcs.digest())" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "digest = bitarray(endian=\"little\")\n", + "digest.frombytes(fcs.digest())\n", + "assert digest == bitarray('1101101011100000')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/TestPacket.ipynb b/TestPacket.ipynb new file mode 100644 index 0000000..34328df --- /dev/null +++ b/TestPacket.ipynb @@ -0,0 +1,215 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "logging.basicConfig(level=logging.DEBUG)\n", + "\n", + "from afsk.ax25 import UI\n", + "from bitarray import bitarray\n", + "\n", + "import crc16\n", + "import struct\n", + "\n", + "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", + "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", + "\n", + "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", + "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'\n", + "expected_bytes = b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", + "#expected_bits = bitarray.bitarray('01111110010000010000010100100101011001010000001000000010000001100001000101010101010110010101100101001101000000100000011001110101010010010001000101010001010001100000001001000110011101010100100100010001010100010010011000000010110001101100000000001111010111000010101010100110110011100010111011111001111101001101111110')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "packet = UI(\"APRS\", \"DUMMY\", info=\":Test\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "DEBUG:afsk.ax25:Stuffing bit\n", + "DEBUG:afsk.ax25:Stuffing bit\n" + ] + } + ], + "source": [ + "generated_bits = packet.unparse()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "generated_bytes = generated_bits.tobytes()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Unstuffed body BA:\n", + "01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011\n" + ] + } + ], + "source": [ + "print (\"Unstuffed body BA:\\n%s\" % unstuffed_body)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "checksummed_content_bits:\n", + "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0' ':Test'\n" + ] + } + ], + "source": [ + "print (\"checksummed_content_bits:\\n%r %r\" % (packet.header(), packet.info))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BS PACKET:\n", + "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð:Testõg'\n" + ] + } + ], + "source": [ + "print (\"BS PACKET:\\n%r\" % (bs_packet))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Packet:\n", + "DUMMY>APRS,WIDE1-1,WIDE2-1::Test\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xdf\\xcf'\n", + "Header:\n", + "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n" + ] + } + ], + "source": [ + "print (\"Packet:\\n%s\\n%r\\nHeader:\\n%r\" % (packet, packet.packet(), packet.header()))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "BS HEADER:\n", + "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð'\n" + ] + } + ], + "source": [ + "print (\"BS HEADER:\\n%r\" % (bs_header))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Generated:\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", + "Expected:\n", + "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n" + ] + } + ], + "source": [ + "print (\"Generated:\\n%r\\nExpected:\\n%r\" % (generated_bytes, expected_bytes))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "#assert generated_bits == expected_bits\n", + "assert generated_bytes == expected_bytes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/afsk/__init__.py b/afsk/__init__.py index bd02c87..ab8a9f5 100644 --- a/afsk/__init__.py +++ b/afsk/__init__.py @@ -1,4 +1 @@ - -from afsk import encode -import ax25 - +from .ax25 import FCS \ No newline at end of file diff --git a/afsk/afsk.py b/afsk/afsk.py index 3522ac0..dd264bc 100644 --- a/afsk/afsk.py +++ b/afsk/afsk.py @@ -1,5 +1,3 @@ -# coding=utf-8 - # Bell 202 Audio Frequency Shift Keying # http://n1vg.net/packet/ @@ -30,7 +28,7 @@ def encode(binary_data): audiogen module. ''' framed_data = frame(binary_data) - + # set volume to 1/2, preceed packet with 1/20 s silence to allow for startup glitches for sample in itertools.chain( audiogen.silence(1.05), diff --git a/afsk/ax25.py b/afsk/ax25.py index 120c0df..3659ea0 100644 --- a/afsk/ax25.py +++ b/afsk/ax25.py @@ -88,46 +88,31 @@ def fcs_validate(bits): raise Exception("FCS checksum invalid.") class AX25(object): - def __init__( - self, - destination=b"APRS", - source=b"", - digipeaters=(b"RELAY", b"WIDE2-1"), - info=b"\"" - ): + def __init__(self, destination="APRS", source="", digipeaters=("RELAY", "WIDE2-1"), info="\"" ): self.flag = b"\x7e" - self.destination = destination self.source = source self.digipeaters = digipeaters - self.info = info @classmethod def callsign_encode(self, callsign): callsign = callsign.upper() - if callsign.find(b"-") > 0: - callsign, ssid = callsign.split(b"-") + if callsign.find("-") > 0: + callsign, ssid = callsign.split("-") else: - ssid = b"0" - - if 10 <= int(ssid) <= 15: - ssid = chr(ord(ssid[1])+10) + ssid = "0" assert(len(ssid) == 1) assert(len(callsign) <= 6) - callsign = b"{callsign:6s}{ssid}".format(callsign=callsign, ssid=ssid) - + callsign = "{callsign:6s}{ssid}".format(callsign=callsign, ssid=ssid) # now shift left one bit, argh - return b"".join([chr(ord(char) << 1) for char in callsign]) + return b"".join([bytes([char << 1]) for char in callsign.encode('utf-8')]) def encoded_addresses(self): - address_bytes = bytearray(b"{destination}{source}{digis}".format( - destination = AX25.callsign_encode(self.destination), - source = AX25.callsign_encode(self.source), - digis = b"".join([AX25.callsign_encode(digi) for digi in self.digipeaters]) - )) + address = b"".join([AX25.callsign_encode(self.destination),AX25.callsign_encode(self.source), b"".join([AX25.callsign_encode(digi) for digi in self.digipeaters])]) + address_bytes = bytearray(address) # set the low order (first, with eventual little bit endian encoding) bit # in order to flag the end of the address string @@ -136,36 +121,30 @@ def encoded_addresses(self): return address_bytes def header(self): - return b"{addresses}{control}{protocol}".format( - addresses = self.encoded_addresses(), - control = self.control_field, # * 8, - protocol = self.protocol_id, - ) + return b"".join([self.encoded_addresses(), self.control_field, self.protocol_id]) + def packet(self): - return b"{header}{info}{fcs}".format( - flag = self.flag, - header = self.header(), - info = self.info, - fcs = self.fcs() - ) + return b"".join([self.flag,self.header(),self.info.encode('utf-8'),self.fcs()]) + def unparse(self): flag = bitarray(endian="little") flag.frombytes(self.flag) bits = bitarray(endian="little") - bits.frombytes("".join([self.header(), self.info, self.fcs()])) - + bits.frombytes(b"".join([self.header(), self.info.encode('utf-8'), self.fcs()])) return flag + bit_stuff(bits) + flag def __repr__(self): return self.__str__() + def __str__(self): - return b"{source}>{destination},{digis}:{info}".format( + __str__ = "{source}>{destination},{digis}:{info}".format( destination = self.destination, source = self.source, - digis = b",".join(self.digipeaters), + digis = ",".join(self.digipeaters), info = self.info ) + return __str__ @classmethod def parse(cls, bits): @@ -180,7 +159,7 @@ def parse(cls, bits): def fcs(self): content = bitarray(endian="little") - content.frombytes("".join([self.header(), self.info])) + content.frombytes(b"".join([self.header(), self.info.encode('utf-8')])) fcs = FCS() for bit in content: @@ -190,20 +169,8 @@ def fcs(self): return fcs.digest() class UI(AX25): - def __init__( - self, - destination=b"APRS", - source=b"", - digipeaters=(b"WIDE1-1", b"WIDE2-1"), - info=b"" - ): - AX25.__init__( - self, - destination, - source, - digipeaters, - info - ) + def __init__(self, destination="APRS", source="", digipeaters=("WIDE1-1", "WIDE2-1"), info=""): + AX25.__init__(self, destination, source, digipeaters, info) self.control_field = b"\x03" self.protocol_id = b"\xf0" @@ -222,7 +189,7 @@ def main(arguments=None): ) parser.add_argument( '--destination', - default=b'APRS', + default='APRS', help='AX.25 destination address. See http://www.aprs.org/aprs11/tocalls.txt' ) parser.add_argument( diff --git a/test.py b/test.py index 3b632cf..4076637 100644 --- a/test.py +++ b/test.py @@ -1,7 +1,7 @@ import logging logging.basicConfig(level=logging.DEBUG) -import afsk +from afsk.ax25 import FCS from bitarray import bitarray import crc16 @@ -15,29 +15,29 @@ def test_packet(): - packet = afsk.ax25.UI("APRS", "DUMMY", info=":Test") + packet = ax25.UI("APRS", "DUMMY", info=":Test") generated_bits = packet.unparse() generated_bytes = generated_bits.tobytes() expected_bytes = '~\x82\xa0\xa4\xa6@@`\x88\xaa\x9a\x9a\xb2@`\xae\x92\x88\x8ab@b\xae\x92\x88\x8ad@c\x03\xf0:Test\x9f/\xfb\x01' #expected_bits = bitarray.bitarray('01111110010000010000010100100101011001010000001000000010000001100001000101010101010110010101100101001101000000100000011001110101010010010001000101010001010001100000001001000110011101010100100100010001010100010010011000000010110001101100000000001111010111000010101010100110110011100010111011111001111101001101111110') - print "Unstuffed body BA:\n%s" % unstuffed_body + print ("Unstuffed body BA:\n%s" % unstuffed_body) - print "checksummed_content_bits:\n%r" % "".join([packet.header(), packet.info]) + print ("checksummed_content_bits:\n%r %r" % (packet.header(), packet.info)) - print "BS PACKET:\n%r" % (bs_packet) - print "Packet:\n%s\n%r\nHeader:\n%r" % (packet, packet.packet(), packet.header()) - print "BS HEADER:\n%r" % (bs_header) - print "Generated:\n%r\nExpected:\n%r" % (generated_bytes, expected_bytes) + print ("BS PACKET:\n%r" % (bs_packet)) + print ("Packet:\n%s\n%r\nHeader:\n%r" % (packet, packet.packet(), packet.header())) + print ("BS HEADER:\n%r" % (bs_header)) + print ("Generated:\n%r\nExpected:\n%r" % (generated_bytes, expected_bytes)) #assert generated_bits == expected_bits assert generated_bytes == expected_bytes def test_fcs(): - fcs = afsk.ax25.FCS() - bytes = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + fcs = FCS() + str_bytes = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' bits = bitarray() - bits.frombytes(bytes) + bits.frombytes(str_bytes) for bit in bits: fcs.update_bit(bit) From 501dcae03846d085ad26a449b68411fe9e029d49 Mon Sep 17 00:00:00 2001 From: Simonas Kareiva Date: Wed, 15 Jun 2022 18:34:19 +0300 Subject: [PATCH 3/4] v0.0.4: Python3 compatibility by ignaciop000 * Fix module imports * Fix print() function * Use str instead of bytes for text data * Fix dependency on audiogen (switch to audiogen_p3) --- .ipynb_checkpoints/TestAprs-checkpoint.ipynb | 112 --------- .ipynb_checkpoints/TestFcs-checkpoint.ipynb | 123 ---------- .../TestPacket-checkpoint.ipynb | 215 ------------------ TestAprs.ipynb | 112 --------- TestFcs.ipynb | 123 ---------- TestPacket.ipynb | 215 ------------------ afsk/afsk.py | 6 +- afsk/ax25.py | 10 +- setup.py | 8 +- 9 files changed, 12 insertions(+), 912 deletions(-) delete mode 100644 .ipynb_checkpoints/TestAprs-checkpoint.ipynb delete mode 100644 .ipynb_checkpoints/TestFcs-checkpoint.ipynb delete mode 100644 .ipynb_checkpoints/TestPacket-checkpoint.ipynb delete mode 100644 TestAprs.ipynb delete mode 100644 TestFcs.ipynb delete mode 100644 TestPacket.ipynb diff --git a/.ipynb_checkpoints/TestAprs-checkpoint.ipynb b/.ipynb_checkpoints/TestAprs-checkpoint.ipynb deleted file mode 100644 index d016b84..0000000 --- a/.ipynb_checkpoints/TestAprs-checkpoint.ipynb +++ /dev/null @@ -1,112 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "logger = logging.getLogger(__name__)\n", - "\n", - "from afsk.ax25 import UI\n", - "from afsk.afsk import encode\n", - "import audiogen\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "packet = UI(\n", - "\tdestination='APRS',\n", - "\tsource='LU8AIE', \n", - "\tinfo=':EMAIL :lu8aie@gmail.com Test email'\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:__main__:Sending packet: 'LU8AIE>APRS,WIDE1-1,WIDE2-1::EMAIL :lu8aie@gmail.com Test email'\n", - "DEBUG:__main__:Packet bits:bitarray('011111100100000100000101001001010110010100000010000000100000011000011001010101010000111001000001010010010101000100000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110010100010101100101000001010010010001100100000010000000100000001000000010001011100001101101010111000011100100001101001011010100110000000101110011010110110100001101001011000110110011101001100011011110110101101100000010000101010101001101100111000101110000001001010011010110110100001101001011000110110001101101100101101111110')\n" - ] - } - ], - "source": [ - "logger.info(r\"Sending packet: '{0}'\".format(packet))\n", - "logger.debug(r\"Packet bits:{0!r}\".format(packet.unparse()))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "audio = encode(packet.unparse())" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "object of type 'generator' has no len()", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0maudiogen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msampler\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstdout\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0maudio\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwrite_wav\u001b[1;34m(f, channels, sample_width, raw_samples, seekable)\u001b[0m\n\u001b[0;32m 149\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 150\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSAMPLE_WIDTH\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mseekable\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 151\u001b[1;33m \u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwav_samples\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 152\u001b[0m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"next\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 153\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwav_samples\u001b[1;34m(channels, sample_width, raw_samples)\u001b[0m\n\u001b[0;32m 113\u001b[0m \u001b[1;31m# if passed one generator, we have one channel\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 114\u001b[0m \u001b[0mchannels\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 115\u001b[1;33m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 116\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 117\u001b[0m \u001b[1;31m# we have audio waveforms, so sample/pack them first\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mTypeError\u001b[0m: object of type 'generator' has no len()" - ] - } - ], - "source": [ - "audiogen.sampler.write_wav(sys.stdout, audio)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/.ipynb_checkpoints/TestFcs-checkpoint.ipynb b/.ipynb_checkpoints/TestFcs-checkpoint.ipynb deleted file mode 100644 index b6c85aa..0000000 --- a/.ipynb_checkpoints/TestFcs-checkpoint.ipynb +++ /dev/null @@ -1,123 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "\n", - "from afsk.ax25 import FCS\n", - "from bitarray import bitarray\n", - "\n", - "import crc16\n", - "import struct\n", - "\n", - "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", - "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", - "\n", - "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", - "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "fcs = FCS()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "str_bytes = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n", - "bits = bitarray()\n", - "bits.frombytes(str_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "for bit in bits:\n", - "\tfcs.update_bit(bit)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "assert fcs.digest() == b'[\\x07'" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "calcbytes\n", - "b'[\\x07'\n" - ] - } - ], - "source": [ - "print (\"calcbytes\")\n", - "print (\"%r\" % fcs.digest())" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "digest = bitarray(endian=\"little\")\n", - "digest.frombytes(fcs.digest())\n", - "assert digest == bitarray('1101101011100000')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/.ipynb_checkpoints/TestPacket-checkpoint.ipynb b/.ipynb_checkpoints/TestPacket-checkpoint.ipynb deleted file mode 100644 index 34328df..0000000 --- a/.ipynb_checkpoints/TestPacket-checkpoint.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "\n", - "from afsk.ax25 import UI\n", - "from bitarray import bitarray\n", - "\n", - "import crc16\n", - "import struct\n", - "\n", - "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", - "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", - "\n", - "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", - "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'\n", - "expected_bytes = b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", - "#expected_bits = bitarray.bitarray('01111110010000010000010100100101011001010000001000000010000001100001000101010101010110010101100101001101000000100000011001110101010010010001000101010001010001100000001001000110011101010100100100010001010100010010011000000010110001101100000000001111010111000010101010100110110011100010111011111001111101001101111110')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "packet = UI(\"APRS\", \"DUMMY\", info=\":Test\")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEBUG:afsk.ax25:Stuffing bit\n", - "DEBUG:afsk.ax25:Stuffing bit\n" - ] - } - ], - "source": [ - "generated_bits = packet.unparse()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "generated_bytes = generated_bits.tobytes()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Unstuffed body BA:\n", - "01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011\n" - ] - } - ], - "source": [ - "print (\"Unstuffed body BA:\\n%s\" % unstuffed_body)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "checksummed_content_bits:\n", - "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0' ':Test'\n" - ] - } - ], - "source": [ - "print (\"checksummed_content_bits:\\n%r %r\" % (packet.header(), packet.info))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BS PACKET:\n", - "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð:Testõg'\n" - ] - } - ], - "source": [ - "print (\"BS PACKET:\\n%r\" % (bs_packet))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Packet:\n", - "DUMMY>APRS,WIDE1-1,WIDE2-1::Test\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xdf\\xcf'\n", - "Header:\n", - "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n" - ] - } - ], - "source": [ - "print (\"Packet:\\n%s\\n%r\\nHeader:\\n%r\" % (packet, packet.packet(), packet.header()))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BS HEADER:\n", - "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð'\n" - ] - } - ], - "source": [ - "print (\"BS HEADER:\\n%r\" % (bs_header))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generated:\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", - "Expected:\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n" - ] - } - ], - "source": [ - "print (\"Generated:\\n%r\\nExpected:\\n%r\" % (generated_bytes, expected_bytes))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "#assert generated_bits == expected_bits\n", - "assert generated_bytes == expected_bytes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/TestAprs.ipynb b/TestAprs.ipynb deleted file mode 100644 index 9d698c6..0000000 --- a/TestAprs.ipynb +++ /dev/null @@ -1,112 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "logger = logging.getLogger(__name__)\n", - "\n", - "from afsk.ax25 import UI\n", - "from afsk.afsk import encode\n", - "import audiogen\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "packet = UI(\n", - "\tdestination='APRS',\n", - "\tsource='LU8AIE', \n", - "\tinfo=':EMAIL :lu8aie@gmail.com Test email'\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:__main__:Sending packet: 'LU8AIE>APRS,WIDE1-1,WIDE2-1::EMAIL :lu8aie@gmail.com Test email'\n", - "DEBUG:__main__:Packet bits:bitarray('011111100100000100000101001001010110010100000010000000100000011000011001010101010000111001000001010010010101000100000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110010100010101100101000001010010010001100100000010000000100000001000000010001011100001101101010111000011100100001101001011010100110000000101110011010110110100001101001011000110110011101001100011011110110101101100000010000101010101001101100111000101110000001001010011010110110100001101001011000110110001101101100101101111110')\n" - ] - } - ], - "source": [ - "logger.info(r\"Sending packet: '{0}'\".format(packet))\n", - "logger.debug(r\"Packet bits:{0!r}\".format(packet.unparse()))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "audio = encode(packet.unparse())" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "object of type 'generator' has no len()", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0maudiogen\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msampler\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msys\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstdout\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0maudio\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwrite_wav\u001b[1;34m(f, channels, sample_width, raw_samples, seekable)\u001b[0m\n\u001b[0;32m 149\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 150\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrite_wav\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSAMPLE_WIDTH\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mFalse\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mseekable\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 151\u001b[1;33m \u001b[0mstream\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwav_samples\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msample_width\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 152\u001b[0m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"next\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 153\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mc:\\users\\ignac\\documents\\github\\audiogen\\audiogen\\sampler.py\u001b[0m in \u001b[0;36mwav_samples\u001b[1;34m(channels, sample_width, raw_samples)\u001b[0m\n\u001b[0;32m 113\u001b[0m \u001b[1;31m# if passed one generator, we have one channel\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 114\u001b[0m \u001b[0mchannels\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 115\u001b[1;33m \u001b[0mchannel_count\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchannels\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 116\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mraw_samples\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 117\u001b[0m \u001b[1;31m# we have audio waveforms, so sample/pack them first\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mTypeError\u001b[0m: object of type 'generator' has no len()" - ] - } - ], - "source": [ - "audiogen.sampler.write_wav(sys.stdout, audio)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/TestFcs.ipynb b/TestFcs.ipynb deleted file mode 100644 index b6c85aa..0000000 --- a/TestFcs.ipynb +++ /dev/null @@ -1,123 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "\n", - "from afsk.ax25 import FCS\n", - "from bitarray import bitarray\n", - "\n", - "import crc16\n", - "import struct\n", - "\n", - "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", - "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", - "\n", - "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", - "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "fcs = FCS()" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "str_bytes = b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'\n", - "bits = bitarray()\n", - "bits.frombytes(str_bytes)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "for bit in bits:\n", - "\tfcs.update_bit(bit)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "assert fcs.digest() == b'[\\x07'" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "calcbytes\n", - "b'[\\x07'\n" - ] - } - ], - "source": [ - "print (\"calcbytes\")\n", - "print (\"%r\" % fcs.digest())" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "digest = bitarray(endian=\"little\")\n", - "digest.frombytes(fcs.digest())\n", - "assert digest == bitarray('1101101011100000')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/TestPacket.ipynb b/TestPacket.ipynb deleted file mode 100644 index 34328df..0000000 --- a/TestPacket.ipynb +++ /dev/null @@ -1,215 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import logging\n", - "logging.basicConfig(level=logging.DEBUG)\n", - "\n", - "from afsk.ax25 import UI\n", - "from bitarray import bitarray\n", - "\n", - "import crc16\n", - "import struct\n", - "\n", - "bs_header = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n", - "bs_packet = '\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xf5g'\n", - "\n", - "unstuffed_body = '01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011'\n", - "stuffed_body = '0100000100000101001001010110010100000010000000100000011000010001010101010101100101011001010011010000001000000110011101010100100100010001010100010100011000000010010001100111010101001001000100010101000100100110000000101100011011000000000011110101110000101010101001101100111000101110111110011111010011'\n", - "expected_bytes = b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", - "#expected_bits = bitarray.bitarray('01111110010000010000010100100101011001010000001000000010000001100001000101010101010110010101100101001101000000100000011001110101010010010001000101010001010001100000001001000110011101010100100100010001010100010010011000000010110001101100000000001111010111000010101010100110110011100010111011111001111101001101111110')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "packet = UI(\"APRS\", \"DUMMY\", info=\":Test\")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "DEBUG:afsk.ax25:Stuffing bit\n", - "DEBUG:afsk.ax25:Stuffing bit\n" - ] - } - ], - "source": [ - "generated_bits = packet.unparse()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "generated_bytes = generated_bits.tobytes()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Unstuffed body BA:\n", - "01000001000001010010010101100101000000100000001000000110000100010101010101011001010110010100110100000010000001100111010101001001000100010101000101000110000000100100011001110101010010010001000101010001001001100000001011000110110000000000111101011100001010101010011011001110001011101111101111110011\n" - ] - } - ], - "source": [ - "print (\"Unstuffed body BA:\\n%s\" % unstuffed_body)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "checksummed_content_bits:\n", - "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0' ':Test'\n" - ] - } - ], - "source": [ - "print (\"checksummed_content_bits:\\n%r %r\" % (packet.header(), packet.info))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BS PACKET:\n", - "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð:Testõg'\n" - ] - } - ], - "source": [ - "print (\"BS PACKET:\\n%r\" % (bs_packet))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Packet:\n", - "DUMMY>APRS,WIDE1-1,WIDE2-1::Test\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\xdf\\xcf'\n", - "Header:\n", - "b'\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0'\n" - ] - } - ], - "source": [ - "print (\"Packet:\\n%s\\n%r\\nHeader:\\n%r\" % (packet, packet.packet(), packet.header()))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "BS HEADER:\n", - "'\\x82\\xa0¤¦@@`\\x88ª\\x9a\\x9a²@`®\\x92\\x88\\x8ab@b®\\x92\\x88\\x8ad@c\\x03ð'\n" - ] - } - ], - "source": [ - "print (\"BS HEADER:\\n%r\" % (bs_header))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Generated:\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n", - "Expected:\n", - "b'~\\x82\\xa0\\xa4\\xa6@@`\\x88\\xaa\\x9a\\x9a\\xb2@`\\xae\\x92\\x88\\x8ab@b\\xae\\x92\\x88\\x8ad@c\\x03\\xf0:Test\\x9f/\\xfb\\x01'\n" - ] - } - ], - "source": [ - "print (\"Generated:\\n%r\\nExpected:\\n%r\" % (generated_bytes, expected_bytes))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "#assert generated_bits == expected_bits\n", - "assert generated_bytes == expected_bytes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/afsk/afsk.py b/afsk/afsk.py index dd264bc..48a48f0 100644 --- a/afsk/afsk.py +++ b/afsk/afsk.py @@ -9,9 +9,9 @@ from bitarray import bitarray -import audiogen -from audiogen.util import multiply -from audiogen.util import constant +import audiogen_p3 as audiogen +from audiogen_p3.util import multiply +from audiogen_p3.util import constant MARK_HZ = 1200.0 SPACE_HZ = 2200.0 diff --git a/afsk/ax25.py b/afsk/ax25.py index 3659ea0..281d4d8 100644 --- a/afsk/ax25.py +++ b/afsk/ax25.py @@ -8,9 +8,9 @@ import argparse from bitarray import bitarray -import audiogen +import audiogen_p3 as audiogen -import afsk +from . import afsk def bit_stuff(data): count = 0 @@ -196,7 +196,7 @@ def main(arguments=None): '-d', '--digipeaters', '--path', - default=b'WIDE1-1,WIDE2-1', + default='WIDE1-1,WIDE2-1', help='Digipeater path to use. "New Paradigm" recommendations are "WIDE1-1,WIDE2-1" for mobile and "WIDE2-1" for fixed stations. Defaults to "WIDE1-1,WIDE2-1."' ) parser.add_argument( @@ -215,14 +215,14 @@ def main(arguments=None): if args.verbose == 0: logging.basicConfig(level=logging.INFO) - elif args.verbose >=1: + else: logging.basicConfig(level=logging.DEBUG) packet = UI( destination=args.destination, source=args.callsign, info=args.info, - digipeaters=args.digipeaters.split(b','), + digipeaters=args.digipeaters.split(','), ) logger.info(r"Sending packet: '{0}'".format(packet)) diff --git a/setup.py b/setup.py index c9d6019..f454838 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ required_modules = [ 'argparse', - 'audiogen', + 'audiogen_p3', 'bitarray', ] extras_require = { @@ -17,7 +17,7 @@ setup( name="afsk", - version="0.0.3", + version="0.0.4", description=u"Bell 202 Audio Frequency Shift Keying encoder and APRS packet audio tools", author="Christopher H. Casebeer", author_email="", @@ -40,8 +40,8 @@ classifiers=[ "Environment :: Console", "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 2.6", - "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.8", "Intended Audience :: Developers", "Intended Audience :: End Users/Desktop", "Topic :: Multimedia :: Sound/Audio", From 1ff43a557bcbb4b4815656491e41d77aff305f2d Mon Sep 17 00:00:00 2001 From: Simonas Kareiva Date: Wed, 15 Jun 2022 18:43:10 +0300 Subject: [PATCH 4/4] Replace itertools.izip() with a builtin --- afsk/afsk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/afsk/afsk.py b/afsk/afsk.py index 48a48f0..81ec5da 100644 --- a/afsk/afsk.py +++ b/afsk/afsk.py @@ -51,7 +51,7 @@ def modulate(data): clock = (x / BAUD_RATE for x in itertools.count(1)) tones = (MARK_HZ if bit else SPACE_HZ for bit in data) - for boundary, frequency in itertools.izip(clock, tones): + for boundary, frequency in izip(clock, tones): # frequency of current symbol is determined by how much # we advance the signal's phase in each audio frame phase_change_per_sample = TWO_PI / (audiogen.sampler.FRAME_RATE / frequency)