mirror of
https://github.com/romanz/amodem.git
synced 2026-05-03 08:27:26 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
451551d37e | ||
|
|
1d5fb11481 | ||
|
|
a8e8bbbf02 | ||
|
|
d015118d76 | ||
|
|
9410a988b1 | ||
|
|
2a03d9f72c | ||
|
|
2925becfac | ||
|
|
30d6af680a | ||
|
|
3284447d1c | ||
|
|
8557faba6e | ||
|
|
d8059b5ff0 |
@@ -1,6 +1,6 @@
|
||||
[bumpversion]
|
||||
commit = True
|
||||
tag = True
|
||||
current_version = 1.15.4
|
||||
current_version = 1.15.6
|
||||
|
||||
[bumpversion:file:setup.py]
|
||||
|
||||
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -12,17 +12,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install --upgrade pip setuptools
|
||||
pip install pytest pytest-cov mock pycodestyle coverage pylint
|
||||
pip install -e .
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[MESSAGES CONTROL]
|
||||
disable=invalid-name, missing-docstring, too-many-instance-attributes, too-few-public-methods, logging-format-interpolation, consider-using-with
|
||||
disable=invalid-name, missing-docstring, too-many-instance-attributes, too-few-public-methods, logging-format-interpolation, consider-using-with, redefined-outer-name
|
||||
|
||||
@@ -88,11 +88,11 @@ def FileType(mode, interface_factory=None):
|
||||
|
||||
|
||||
def get_volume_cmd(args):
|
||||
volume_controllers = [
|
||||
dict(test='pactl --version',
|
||||
send='pactl set-sink-volume @DEFAULT_SINK@',
|
||||
recv='pactl set-source-volume @DEFAULT_SOURCE@')
|
||||
]
|
||||
volume_controllers = [{
|
||||
'test': 'pactl --version',
|
||||
'send': 'pactl set-sink-volume @DEFAULT_SINK@',
|
||||
'recv': 'pactl set-source-volume @DEFAULT_SOURCE@'
|
||||
}]
|
||||
if args.calibrate == 'auto':
|
||||
for c in volume_controllers:
|
||||
if os.system(c['test']) == 0:
|
||||
@@ -106,7 +106,7 @@ def wrap(cls, stream, enable):
|
||||
|
||||
def create_parser(description, interface_factory):
|
||||
p = argparse.ArgumentParser(description=description)
|
||||
subparsers = p.add_subparsers()
|
||||
subparsers = p.add_subparsers(required=True)
|
||||
|
||||
# Modulator
|
||||
sender = subparsers.add_parser(
|
||||
@@ -196,6 +196,8 @@ def _version():
|
||||
|
||||
|
||||
def _config_log(args):
|
||||
level = fmt = None
|
||||
|
||||
if args.verbose == 0:
|
||||
level, fmt = 'INFO', '%(message)s'
|
||||
elif args.verbose == 1:
|
||||
|
||||
@@ -7,6 +7,10 @@ import time
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AudioError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Interface:
|
||||
def __init__(self, config, debug=False):
|
||||
self.debug = bool(debug)
|
||||
@@ -35,7 +39,7 @@ class Interface:
|
||||
|
||||
def _error_check(self, res):
|
||||
if res != 0:
|
||||
raise Exception(res, self._error_string(res))
|
||||
raise AudioError(res, self._error_string(res))
|
||||
|
||||
def __enter__(self):
|
||||
self.call('Initialize')
|
||||
|
||||
@@ -66,7 +66,7 @@ def detector(config, src, frame_length=200):
|
||||
max_index = np.argmax(coeffs)
|
||||
freq = config.frequencies[max_index]
|
||||
rms = abs(coeffs[max_index])
|
||||
coherency = rms / total
|
||||
coherency = rms / total if total > 0 else 0.0
|
||||
flags = [total > 0.1, peak < 1.0, coherency > 0.99]
|
||||
|
||||
success = all(flags)
|
||||
@@ -75,10 +75,10 @@ def detector(config, src, frame_length=200):
|
||||
else:
|
||||
msg = f'too {errors[flags.index(False)]} signal'
|
||||
|
||||
yield dict(
|
||||
freq=freq, rms=rms, peak=peak, coherency=coherency,
|
||||
total=total, success=success, msg=msg
|
||||
)
|
||||
yield {
|
||||
'freq': freq, 'rms': rms, 'peak': peak, 'coherency': coherency,
|
||||
'total': total, 'success': success, 'msg': msg
|
||||
}
|
||||
|
||||
|
||||
def volume_calibration(result_iterator, volume_ctl):
|
||||
|
||||
@@ -79,7 +79,7 @@ class MODEM:
|
||||
symbols = np.array(list(symbols))
|
||||
bits_per_symbol = np.log2(len(symbols))
|
||||
bits_per_symbol = np.round(bits_per_symbol)
|
||||
N = (2 ** bits_per_symbol)
|
||||
N = 2 ** bits_per_symbol
|
||||
assert N == len(symbols)
|
||||
bits_per_symbol = int(bits_per_symbol)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class Receiver:
|
||||
self.plt.subplot(1, 2, 2)
|
||||
self.plt.plot(np.abs(S))
|
||||
self.plt.plot(equalizer.prefix)
|
||||
errors = (bits != equalizer.prefix)
|
||||
errors = bits != equalizer.prefix
|
||||
if any(errors):
|
||||
msg = f'Incorrect prefix: {sum(errors)} errors'
|
||||
raise ValueError(msg)
|
||||
|
||||
@@ -5,7 +5,7 @@ class Reader:
|
||||
|
||||
wait = 0.2
|
||||
timeout = 2.0
|
||||
bufsize = (8 << 10)
|
||||
bufsize = 8 << 10
|
||||
|
||||
def __init__(self, fd, data_type=None, eof=False):
|
||||
self.fd = fd
|
||||
|
||||
0
amodem/tests/__init__.py
Normal file
0
amodem/tests/__init__.py
Normal file
@@ -1,7 +1,7 @@
|
||||
from amodem import alsa, config
|
||||
|
||||
import mock
|
||||
|
||||
from .. import alsa, config
|
||||
|
||||
|
||||
def test_alsa():
|
||||
interface = alsa.Interface(config=config.fastest())
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import mock
|
||||
import time
|
||||
import pytest
|
||||
from amodem import async_reader
|
||||
import logging
|
||||
import time
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from .. import async_reader
|
||||
|
||||
|
||||
logging.basicConfig(format='%(message)s')
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from amodem import audio, config
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from .. import audio, config
|
||||
|
||||
|
||||
def test():
|
||||
length = 1024
|
||||
@@ -31,4 +31,4 @@ def test():
|
||||
s.close()
|
||||
|
||||
with pytest.raises(Exception):
|
||||
interface._error_check(1)
|
||||
interface._error_check(1) # pylint: disable=protected-access
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
from amodem import calib
|
||||
from amodem import common
|
||||
from amodem import config
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
import numpy as np
|
||||
import random
|
||||
import pytest
|
||||
|
||||
import mock
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from .. import calib, common, config
|
||||
|
||||
|
||||
config = config.fastest()
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from amodem import common
|
||||
from amodem import config
|
||||
import numpy as np
|
||||
|
||||
from .. import common, config
|
||||
|
||||
|
||||
def iterlist(x, *args, **kwargs):
|
||||
x = np.array(x)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from amodem import config
|
||||
from .. import config
|
||||
|
||||
|
||||
def test_bitrates():
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from amodem import dsp
|
||||
from amodem import recv
|
||||
from amodem import detect
|
||||
from amodem import equalizer
|
||||
from amodem import sampling
|
||||
from amodem import config
|
||||
from amodem import common
|
||||
from .. import common, config, detect, dsp, equalizer, recv, sampling
|
||||
|
||||
config = config.fastest()
|
||||
|
||||
|
||||
@@ -17,7 +12,7 @@ def test_detect():
|
||||
x = np.cos(2 * np.pi * config.Fc * t)
|
||||
|
||||
detector = detect.Detector(config, pylab=common.Dummy())
|
||||
samples, amp, freq_err = detector.run(x)
|
||||
_samples, amp, freq_err = detector.run(x)
|
||||
assert abs(1 - amp) < 1e-12
|
||||
assert abs(freq_err) < 1e-12
|
||||
|
||||
@@ -39,11 +34,11 @@ def test_prefix():
|
||||
sampler = sampling.Sampler(signal)
|
||||
return dsp.Demux(sampler=sampler, omegas=[omega], Nsym=config.Nsym)
|
||||
r = recv.Receiver(config, pylab=common.Dummy())
|
||||
r._prefix(symbols_stream(signal))
|
||||
r._prefix(symbols_stream(signal)) # pylint: disable=protected-access
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
silence = 0 * signal
|
||||
r._prefix(symbols_stream(silence))
|
||||
r._prefix(symbols_stream(silence)) # pylint: disable=protected-access
|
||||
|
||||
|
||||
def test_find_start():
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
from amodem import dsp
|
||||
from amodem import sampling
|
||||
from amodem import config
|
||||
import utils
|
||||
|
||||
import numpy as np
|
||||
import random
|
||||
import itertools
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .. import dsp, sampling, config
|
||||
from . import utils
|
||||
|
||||
config = config.fastest()
|
||||
|
||||
|
||||
@@ -69,7 +68,7 @@ def quantize(q, s):
|
||||
def test_overflow():
|
||||
q = dsp.MODEM(config.symbols)
|
||||
r = np.random.RandomState(seed=0)
|
||||
for i in range(10000):
|
||||
for _ in range(10000):
|
||||
s = 10*(r.normal() + 1j * r.normal())
|
||||
quantize(q, s)
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from numpy.random import RandomState
|
||||
import numpy as np
|
||||
|
||||
import utils
|
||||
from amodem import equalizer
|
||||
from amodem import dsp
|
||||
from amodem import config
|
||||
from . import utils
|
||||
from .. import config, dsp, equalizer
|
||||
|
||||
config = config.fastest()
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from amodem import framing
|
||||
import random
|
||||
import itertools
|
||||
import random
|
||||
|
||||
import pytest
|
||||
|
||||
from .. import framing
|
||||
|
||||
|
||||
def concat(iterable):
|
||||
return bytearray(itertools.chain.from_iterable(iterable))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from amodem import sampling
|
||||
from amodem import common
|
||||
from io import BytesIO
|
||||
|
||||
import numpy as np
|
||||
from io import BytesIO
|
||||
|
||||
from .. import common, sampling
|
||||
|
||||
|
||||
def test_resample():
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from amodem import stream
|
||||
import subprocess as sp
|
||||
import sys
|
||||
|
||||
from .. import stream
|
||||
|
||||
script = br"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
from amodem import main
|
||||
from amodem import common
|
||||
from amodem import sampling
|
||||
from amodem import config
|
||||
import utils
|
||||
from io import BytesIO
|
||||
import logging
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
import logging
|
||||
|
||||
from .. import common, config, main, sampling
|
||||
from . import utils
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG, # useful for debugging
|
||||
format='%(asctime)s %(levelname)-12s %(message)s')
|
||||
|
||||
|
||||
8
setup.py
8
setup.py
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
from setuptools import setup
|
||||
from setuptools import setup, find_packages
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
class PyTest(TestCommand):
|
||||
@@ -15,13 +15,13 @@ class PyTest(TestCommand):
|
||||
|
||||
setup(
|
||||
name='amodem',
|
||||
version='1.15.4',
|
||||
version='1.15.6',
|
||||
description='Audio Modem Communication Library',
|
||||
author='Roman Zeyde',
|
||||
author_email='dev@romanzey.de',
|
||||
license='MIT',
|
||||
url='http://github.com/romanz/amodem',
|
||||
packages=['amodem'],
|
||||
packages=find_packages(),
|
||||
tests_require=['pytest'],
|
||||
cmdclass={'test': PyTest},
|
||||
install_requires=['numpy'],
|
||||
@@ -37,6 +37,8 @@ setup(
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
'Programming Language :: Python :: 3.11',
|
||||
'Programming Language :: Python :: 3.12',
|
||||
'Programming Language :: Python :: 3.13',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
'Topic :: System :: Networking',
|
||||
'Topic :: Communications',
|
||||
|
||||
Reference in New Issue
Block a user