mirror of
https://github.com/romanz/amodem.git
synced 2026-03-23 10:41:01 +08:00
move and rename CLI script
This commit is contained in:
171
scripts/amodem
171
scripts/amodem
@@ -1,171 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# PYTHON_ARGCOMPLETE_OK
|
||||
|
||||
import sys
|
||||
if sys.version_info.major == 2:
|
||||
_stdin = sys.stdin
|
||||
_stdout = sys.stdout
|
||||
else:
|
||||
_stdin = sys.stdin.buffer
|
||||
_stdout = sys.stdout.buffer
|
||||
|
||||
import argparse
|
||||
import argcomplete
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger('__name__')
|
||||
|
||||
from amodem import config
|
||||
from amodem import recv
|
||||
from amodem import send
|
||||
from amodem import wave
|
||||
from amodem import calib
|
||||
|
||||
null = open('/dev/null', 'wb')
|
||||
|
||||
|
||||
def FileType(mode, process=None):
|
||||
def opener(fname):
|
||||
assert 'r' in mode or 'w' in mode
|
||||
if process is None and fname is None:
|
||||
fname = '-'
|
||||
|
||||
if fname is None:
|
||||
if 'r' in mode:
|
||||
return process(stdout=wave.sp.PIPE, stderr=null).stdout
|
||||
if 'w' in mode:
|
||||
return process(stdin=wave.sp.PIPE, stderr=null).stdin
|
||||
|
||||
if fname == '-':
|
||||
if 'r' in mode:
|
||||
return _stdin
|
||||
if 'w' in mode:
|
||||
return _stdout
|
||||
|
||||
return open(fname, mode)
|
||||
|
||||
return opener
|
||||
|
||||
|
||||
def main():
|
||||
fmt = ('Audio OFDM MODEM: {:.1f} kb/s ({:d}-QAM x {:d} carriers) '
|
||||
'Fs={:.1f} kHz')
|
||||
description = fmt.format(config.modem_bps / 1e3, len(config.symbols),
|
||||
config.Nfreq, config.Fs / 1e3)
|
||||
p = argparse.ArgumentParser(description=description)
|
||||
g = p.add_mutually_exclusive_group()
|
||||
g.add_argument('-v', '--verbose', default=0, action='count')
|
||||
g.add_argument('-q', '--quiet', default=False, action='store_true')
|
||||
subparsers = p.add_subparsers()
|
||||
|
||||
# Modulator
|
||||
sender = subparsers.add_parser(
|
||||
'send', help='modulate binary data into audio signal.')
|
||||
sender.add_argument(
|
||||
'-i', '--input', help='input file (use "-" for stdin).')
|
||||
sender.add_argument(
|
||||
'-o', '--output', help='output file (use "-" for stdout).'
|
||||
' if not specified, `aplay` tool will be used.')
|
||||
sender.add_argument(
|
||||
'-c', '--calibrate', default=False, action='store_true')
|
||||
sender.add_argument(
|
||||
'-w', '--wave', default=False, action='store_true')
|
||||
sender.add_argument(
|
||||
'--silence-start', type=float, default=1.0,
|
||||
help='seconds of silence before transmission starts')
|
||||
sender.add_argument(
|
||||
'--silence-stop', type=float, default=1.0,
|
||||
help='seconds of silence after transmission stops')
|
||||
|
||||
sender.set_defaults(
|
||||
main=run_send,
|
||||
input_type=FileType('rb'),
|
||||
output_type=FileType('wb', wave.play)
|
||||
)
|
||||
|
||||
# Demodulator
|
||||
receiver = subparsers.add_parser(
|
||||
'recv', help='demodulate audio signal into binary data.')
|
||||
receiver.add_argument(
|
||||
'-i', '--input', help='input file (use "-" for stdin).'
|
||||
' if not specified, `arecord` tool will be used.')
|
||||
receiver.add_argument(
|
||||
'-o', '--output', help='output file (use "-" for stdout).')
|
||||
receiver.add_argument(
|
||||
'-c', '--calibrate', default=False, action='store_true')
|
||||
receiver.add_argument(
|
||||
'-w', '--wave', default=False, action='store_true')
|
||||
receiver.add_argument(
|
||||
'--skip', type=int, default=128,
|
||||
help='skip initial N samples, due to spurious spikes')
|
||||
receiver.add_argument(
|
||||
'--plot', action='store_true', default=False,
|
||||
help='plot results using pylab module')
|
||||
receiver.set_defaults(
|
||||
main=run_recv,
|
||||
input_type=FileType('rb', wave.record),
|
||||
output_type=FileType('wb')
|
||||
)
|
||||
|
||||
# Configuration
|
||||
subparsers.add_parser('config').set_defaults(main=config.dump)
|
||||
|
||||
argcomplete.autocomplete(p)
|
||||
args = p.parse_args()
|
||||
if args.verbose == 0:
|
||||
level, format = 'INFO', '%(message)s'
|
||||
elif args.verbose == 1:
|
||||
level, format = 'DEBUG', '%(message)s'
|
||||
elif args.verbose >= 2:
|
||||
level, format = ('DEBUG', '%(asctime)s %(levelname)-10s '
|
||||
'%(message)-100s '
|
||||
'%(filename)s:%(lineno)d')
|
||||
if args.quiet:
|
||||
level, format = 'WARNING', '%(message)s'
|
||||
logging.basicConfig(level=level, format=format)
|
||||
|
||||
# Parsing and execution
|
||||
log.debug('MODEM settings: %r', config.settings)
|
||||
if getattr(args, 'plot', False):
|
||||
import pylab
|
||||
args.plot = pylab
|
||||
args.main(args)
|
||||
|
||||
|
||||
def join_process(process):
|
||||
exitcode = 0
|
||||
try:
|
||||
exitcode = process.wait()
|
||||
except KeyboardInterrupt:
|
||||
process.kill()
|
||||
exitcode = process.wait()
|
||||
sys.exit(exitcode)
|
||||
|
||||
|
||||
def run_modem(args, func):
|
||||
args.input = args.input_type(args.input)
|
||||
args.output = args.output_type(args.output)
|
||||
func(args)
|
||||
|
||||
|
||||
def run_send(args):
|
||||
if args.calibrate:
|
||||
calib.send(verbose=args.verbose)
|
||||
elif args.wave:
|
||||
join_process(wave.play(fname=args.input))
|
||||
else:
|
||||
run_modem(args, send.main)
|
||||
|
||||
|
||||
def run_recv(args):
|
||||
if args.calibrate:
|
||||
calib.recv(verbose=args.verbose)
|
||||
elif args.wave:
|
||||
join_process(wave.record(fname=args.output))
|
||||
else:
|
||||
run_modem(args, recv.main)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user