Compare commits

...

26 Commits

Author SHA1 Message Date
Sebastien Van Cauwenberghe 9a1e8769ab Add EOT message
When program keeps running, the ### EOT message allows the user
to know that the stdin has been fully transmitted.
2017-02-16 14:05:31 -08:00
Kamal Mostafa d4ce82136d tests: use cmp not md5sum for tx-consistency tests
OS X doesn't provide md5sum.
https://github.com/kamalmostafa/minimodem/issues/24#issuecomment-213816836
2016-04-24 09:40:29 -07:00
Kamal Mostafa 17e17b784e minimodem-0.24-1 2016-04-23 11:22:32 -07:00
Kamal Mostafa fc03264643 debian: bump standards-version=3.9.7 and debhelper-compat-version=9 2016-04-23 11:22:00 -07:00
Kamal Mostafa ea3f837c90 Fix --tx float consistency: disable .wav "PEAK chunk" header
Fixes: tests/17-verify-tx-consistent-float.test

This might also relate to:
https://github.com/kamalmostafa/minimodem/issues/24
2016-04-23 10:34:35 -07:00
Kamal Mostafa 78cff1778b tests: verify --tx consistency
PASS: 16-verify-tx-consistent.test
FAIL: 17-verify-tx-consistent-float.test

The FAIL is due inconsistency in the .wav header (only for floats)
constructed by libsndfile -- its different every wall-clock second.
Even just a bare header (no audio samples) shows the effect:

  minimodem --float-samples --tx 1000 -f /tmp/xx.wav </dev/null
  sum -r /tmp/xx.wav
  sleep 1
  minimodem --float-samples --tx 1000 -f /tmp/xx.wav </dev/null
  sum -r /tmp/xx.wav

This might also relate to:
https://github.com/kamalmostafa/minimodem/issues/24
2016-04-23 10:24:13 -07:00
Kamal Mostafa c2e4d9e1c4 Do not emit 0.5 sec flush for audio file output 2016-04-17 09:49:27 -07:00
Chris Osborn 513a11d454 Limit carrier/idle generation for input with delays
For non-interactive output (writing to an audio file), generate the
idle output carrier for same duration that the input is idle.  Makes
this case generate an output .wav file of just over 1 second duration:

  { echo hello; sleep 1; echo world; } | minimodem --tx -f /tmp/xx.wav 300
2016-04-17 08:49:36 -07:00
Kamal Mostafa 84b2406b97 Rename tv_idletimeout (no functional change) 2016-04-17 08:43:32 -07:00
Kamal Mostafa ad83ef5df3 Refactor emit idle tone (no functional change)
Clean up the "emit idle tone" code, which should never have involved
tx_leader_bits_len (that was a copy-paste laziness).

"Emit idle tone" simply generates the idle tone for a hardcoded period
of time now codified as 'idle_tone_usec' and set to 1/25 of a second
(to match the existing behavior).
2016-04-13 09:41:20 -07:00
Colin Ian King 96a60f51b0 initialize ampl_out to avoid it containing garbage
static analysis from clang scan-build detected some paths
in the call to fsk_frame_analyze where ampl_out is not being
set:

fsk.c:493:13: warning: Assigned value is garbage or undefined
            best_a = ampl_out;

..probably the sanest approach here is to initialize it to 0.0
just to avoid it being garbage rather than setting it to zero in
the failed error paths in fsk_frame_analyze.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
2016-03-21 12:42:30 -07:00
Colin Ian King 2d3bd487ca Fix the final few printf format specifiers in fsk.c
Signed-off-by: Colin Ian King <colin.king@canonical.com>
2016-03-21 12:42:30 -07:00
Colin Ian King 7397c3cd9b Fix build warnings about ternary operator precedence
Be more explicit with parenthesis to avoid any possibly confusion
about operator precendence.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
2016-03-21 12:42:29 -07:00
Colin Ian King d6a616fff8 Use %td for ptrdiff_t printf format specifier
Signed-off-by: Colin Ian King <colin.king@canonical.com>
2016-03-21 12:42:29 -07:00
Colin Ian King 632e92f1ae Use %u printf format specifier for unsigned int
Signed-off-by: Colin Ian King <colin.king@canonical.com>
2016-03-21 12:42:29 -07:00
Kamal Mostafa 93b35cbd9d baudot_charset: fix compile warning
Thanks to Colin Ian King <colin.king@canonical.com>.
2016-03-21 12:42:29 -07:00
Kamal Mostafa 3a8d490074 fix harmless strncasecmp off-by-one 2016-02-20 07:02:09 -08:00
Kamal Mostafa bc794806db minimodem-0.23-1 2016-02-19 13:14:29 -08:00
Kamal Mostafa 37bf388038 fix configure.ac version macro glitch 2016-02-19 13:04:28 -08:00
Kamal Mostafa f801ae3f28 update copyright dates 2016 2016-02-19 12:29:58 -08:00
Kamal Mostafa 842c1923e2 trim tests/testdata-ascii.txt
Remove confusing old copy of README.
2016-02-19 12:29:21 -08:00
Kamal Mostafa 6e22843115 add TTY/TDD to README 2016-02-19 12:28:11 -08:00
Kamal Mostafa 4b3301a7ef TTY/TDD self-test and man page entry 2016-01-21 13:20:48 -08:00
Rodrigo Menezes f48257ac59 TTY/TDD support 2016-01-20 10:07:21 -08:00
Kevin Zheng a23c5c73be Clean up configure script 2015-12-22 12:09:51 -06:00
Kevin Zheng 40c1f4c35c Fix bash-isms in configure script 2015-12-22 12:07:51 -06:00
18 changed files with 215 additions and 166 deletions

View File

@ -1,5 +1,5 @@
minimodem - software audio Bell-type or RTTY FSK modem minimodem - software audio Bell-type or RTTY FSK modem
Copyright (C) 2011-2014 Kamal Mostafa <kamal@whence.com> Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

6
README
View File

@ -1,11 +1,11 @@
minimodem - general-purpose software audio FSK modem minimodem - general-purpose software audio FSK modem
Copyright (C) 2011-2014 Kamal Mostafa <kamal@whence.com> Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
Minimodem is a command-line program which decodes (or generates) audio Minimodem is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols. modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, NOAA SAME, various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
and Caller-ID. NOAA SAME, and Caller-ID.
Minimodem can play and capture audio modem tones in real-time via the Minimodem can play and capture audio modem tones in real-time via the
system audio device, or in batched mode via audio files. system audio device, or in batched mode via audio files.

View File

@ -1,121 +1,79 @@
dnl
dnl configure.ac Generated by project-setup
dnl
AC_DEFUN([PKG_NAME], [minimodem])
AC_DEFUN([PKG_VERSION], [0.22.1])
AC_DEFUN([PKG_AUTHOR], [Kamal Mostafa <kamal@whence.com>])
AC_DEFUN([PKG_BUGS_TO], [kamal@whence.com])
AC_PREREQ([2.64]) AC_PREREQ([2.64])
AC_INIT([minimodem], [0.24], [kamal@whence.com])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/Makefile.in])
AM_INIT_AUTOMAKE
AC_INIT(PKG_NAME, PKG_VERSION, PKG_BUGS_TO) VERSION=AC_PACKAGE_VERSION
dnl Release versioning info
VERSION=PKG_VERSION
AC_SUBST(VERSION) AC_SUBST(VERSION)
AM_INIT_AUTOMAKE # Program Checks
AC_CONFIG_SRCDIR([src/Makefile.in])
AC_CONFIG_HEADERS([config.h])
# AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_CC AC_PROG_CC
# AC_PROG_RANLIB
# Library Checks
AC_SEARCH_LIBS([lroundf], [m])
# Configure dependency libs deps_packages="fftw3f"
AC_CHECK_LIB([m],[lroundf])
# fftw3f
deps_packages+=" fftw3f"
# ALSA # ALSA
AC_ARG_WITH([alsa], AC_ARG_WITH([alsa], [AS_HELP_STRING([--without-alsa],
AS_HELP_STRING([--without-alsa], [build without ALSA support])) [build without ALSA support])])
AS_IF([test "x$with_alsa" == "xno"], AS_IF([test "x$with_alsa" == "xno"], [
# then use_alsa=0
use_alsa=0, ], [
# else use_alsa=1
use_alsa=1 deps_packages="$deps_packages alsa"
deps_packages+=" alsa") ])
AC_DEFINE_UNQUOTED(USE_ALSA, $use_alsa, AC_DEFINE_UNQUOTED([USE_ALSA], [$use_alsa],
[Define to 1 to enable ALSA support]) [Define to 1 to enable ALSA support])
# pulseaudio # pulseaudio
AC_ARG_WITH([pulseaudio], AC_ARG_WITH([pulseaudio], AS_HELP_STRING([--without-pulseaudio],
AS_HELP_STRING([--without-pulseaudio], [build without pulseaudio support])) [build without pulseaudio support]))
AS_IF([test "x$with_pulseaudio" == "xno"], AS_IF([test "x$with_pulseaudio" == "xno"], [
# then use_pulseaudio=0
use_pulseaudio=0, ], [
# else use_pulseaudio=1
use_pulseaudio=1 deps_packages="$deps_packages libpulse-simple"
deps_packages+=" libpulse-simple") ])
AC_DEFINE_UNQUOTED(USE_PULSEAUDIO, $use_pulseaudio, AC_DEFINE_UNQUOTED([USE_PULSEAUDIO], [$use_pulseaudio],
[Define to 1 to enable pulseaudio support]) [Define to 1 to enable pulseaudio support])
# sndfile # sndfile
AC_ARG_WITH([sndfile], AC_ARG_WITH([sndfile], AS_HELP_STRING([--without-sndfile],
AS_HELP_STRING([--without-sndfile], [build without sndfile support])) [build without sndfile support]))
AS_IF([test "x$with_sndfile" == "xno"], AS_IF([test "x$with_sndfile" == "xno"], [
# then use_sndfile=0
use_sndfile=0, ], [
# else use_sndfile=1
use_sndfile=1 deps_packages="$deps_packages sndfile"
deps_packages+=" sndfile") ])
AC_DEFINE_UNQUOTED(USE_SNDFILE, $use_sndfile, AC_DEFINE_UNQUOTED([USE_SNDFILE], [$use_sndfile],
[Define to 1 to enable sndfile support]) [Define to 1 to enable sndfile support])
# benchmarks # benchmarks
AC_ARG_WITH([benchmarks], AC_ARG_WITH([benchmarks], AS_HELP_STRING([--disable-benchmarks],
AS_HELP_STRING([--disable-benchmarks], [build without internal benchmarks])) [build without internal benchmarks]))
AS_IF([test "x$with_benchmarks" == "xno"], AS_IF([test "x$with_benchmarks" == "xno"], [
# then use_benchmarks=0
use_benchmarks=0, ], [
# else use_benchmarks=1
use_benchmarks=1) ])
AC_DEFINE_UNQUOTED(USE_BENCHMARKS, $use_benchmarks, AC_DEFINE_UNQUOTED([USE_BENCHMARKS], [$use_benchmarks],
[Define to 1 to enable internal benchmarks]) [Define to 1 to enable internal benchmarks])
AC_MSG_RESULT([ AC_MSG_RESULT([
PKG_NAME PKG_VERSION configuration summary: option summary:
--with-pulseaudio $with_pulseaudio ($use_pulseaudio) alsa $with_alsa ($use_alsa)
--with-alsa $with_alsa ($use_alsa) benchmarks $with_benchmarks ($use_benchmarks)
--with-sndfile $with_sndfile ($use_sndfile) pulseaudio $with_pulseaudio ($use_pulseaudio)
--with-benchmarks $with_benchmarks ($use_benchmarks) sndfile $with_sndfile ($use_sndfile)
deps_packages: $deps_packages
]) ])
# Checks for libraries. # Checks for libraries.
PKG_CHECK_MODULES(DEPS, [ $deps_packages ]) PKG_CHECK_MODULES(DEPS, [$deps_packages])
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
AC_SUBST([auto_find_tests], ['$(sort $(wildcard *.test))']) AC_SUBST([auto_find_tests], ['$(sort $(wildcard *.test))'])
# Checks for header files. AC_CONFIG_FILES([Makefile src/Makefile src/minimodem.1 tests/Makefile])
# AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
# AC_HEADER_STDBOOL
# AC_TYPE_PID_T
# Checks for library functions.
# AC_FUNC_FORK
AC_CONFIG_FILES([
Makefile
src/Makefile
src/minimodem.1
tests/Makefile
])
# testdata/Makefile
AC_OUTPUT AC_OUTPUT

26
debian/changelog vendored
View File

@ -1,3 +1,29 @@
minimodem (0.24-1) unstable; urgency=medium
[ Chris Osborn ]
* Limit carrier/idle generation for input with delays
[ Kamal Mostafa ]
* Fix --tx float consistency: disable .wav "PEAK chunk" header
* Do not emit 0.5 sec flush for audio file output
* debian: bump standards-version=3.9.7 and debhelper-compat-version=9
[ Colin Ian King ]
* multiple static analysis and warnings fixes
-- Kamal Mostafa <kamal@whence.com> Sat, 23 Apr 2016 10:35:44 -0700
minimodem (0.23-1) unstable; urgency=medium
[ Rodrigo Menezes ]
* TTY/TDD support
-- Kamal Mostafa <kamal@whence.com> Fri, 19 Feb 2016 13:05:07 -0800
minimodem (0.22.1-1) unstable; urgency=medium minimodem (0.22.1-1) unstable; urgency=medium
* Do not enable tx-carrier for non-interactive --file sessions * Do not enable tx-carrier for non-interactive --file sessions

2
debian/compat vendored
View File

@ -1 +1 @@
7 9

8
debian/control vendored
View File

@ -2,8 +2,8 @@ Source: minimodem
Section: comm Section: comm
Priority: optional Priority: optional
Maintainer: Kamal Mostafa <kamal@whence.com> Maintainer: Kamal Mostafa <kamal@whence.com>
Build-Depends: debhelper (>= 7.0.50~), libfftw3-dev, libpulse-dev, libasound2-dev [linux-any], libsndfile1-dev Build-Depends: debhelper (>= 9), libfftw3-dev, libpulse-dev, libasound2-dev [linux-any], libsndfile1-dev
Standards-Version: 3.9.6 Standards-Version: 3.9.7
Homepage: http://www.whence.com/minimodem Homepage: http://www.whence.com/minimodem
Vcs-Git: https://github.com/kamalmostafa/minimodem.git Vcs-Git: https://github.com/kamalmostafa/minimodem.git
Vcs-Browser: https://github.com/kamalmostafa/minimodem Vcs-Browser: https://github.com/kamalmostafa/minimodem
@ -16,8 +16,8 @@ Description: general-purpose software audio FSK modem
Minimodem is a command-line program which decodes (or generates) audio Minimodem is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols. modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, NOAA SAME, various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
and Caller-ID. NOAA SAME, and Caller-ID.
. .
Minimodem can play and capture audio modem tones in real-time via the Minimodem can play and capture audio modem tones in real-time via the
system audio device, or in batched mode via audio files. system audio device, or in batched mode via audio files.

4
debian/copyright vendored
View File

@ -4,7 +4,7 @@ Upstream-Contact: Kamal Mostafa <kamal@whence.com>
Source: http://www.whence.com/minimodem Source: http://www.whence.com/minimodem
Files: * Files: *
Copyright: 2011-2014 Kamal Mostafa <kamal@whence.com> Copyright: 2011-2016 Kamal Mostafa <kamal@whence.com>
License: GPL-3.0+ License: GPL-3.0+
Files: src/*uic* Files: src/*uic*
@ -12,7 +12,7 @@ Copyright: 2014 Marcos Vives Del Sol <socram8888@gmail.com>
License: GPL-3.0+ License: GPL-3.0+
Files: debian/* Files: debian/*
Copyright: 2011-2014 Kamal Mostafa <kamal@whence.com> Copyright: 2011-2016 Kamal Mostafa <kamal@whence.com>
License: GPL-3.0+ License: GPL-3.0+
License: GPL-3.0+ License: GPL-3.0+

View File

@ -1,7 +1,7 @@
# #
# Makefile.am # Makefile.am
# #
# Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com> # Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -194,7 +194,7 @@ baudot_encode_table[0x60][2] = {
* 1 LTRS state * 1 LTRS state
* 2 FIGS state * 2 FIGS state
*/ */
static int baudot_charset = 0; // FIXME static unsigned int baudot_charset = 0; // FIXME
void void

View File

@ -1,7 +1,7 @@
/* /*
* fsk.c * fsk.c
* *
* Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com> * Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -62,7 +62,7 @@ fsk_plan_new(
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
debug_log("### b_mark=%u b_space=%u fftsize=%u\n", debug_log("### b_mark=%u b_space=%u fftsize=%d\n",
fskp->b_mark, fskp->b_space, fskp->fftsize); fskp->b_mark, fskp->b_space, fskp->fftsize);
@ -202,7 +202,7 @@ fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit,
assert( expect_bits[bitnum] == '1' || expect_bits[bitnum] == '0' ); assert( expect_bits[bitnum] == '1' || expect_bits[bitnum] == '0' );
bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f); bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f);
debug_log( " bit# %2u @ %7u: ", bitnum, bit_begin_sample); debug_log( " bit# %2d @ %7u: ", bitnum, bit_begin_sample);
fsk_bit_analyze(fskp, samples+bit_begin_sample, bit_nsamples, fsk_bit_analyze(fskp, samples+bit_begin_sample, bit_nsamples,
&bit_values[bitnum], &bit_values[bitnum],
&bit_sig_mags[bitnum], &bit_sig_mags[bitnum],
@ -247,7 +247,7 @@ fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit,
if ( expect_bits[bitnum] != 'd' ) if ( expect_bits[bitnum] != 'd' )
continue; continue;
bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f); bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f);
debug_log( " bit# %2u @ %7u: ", bitnum, bit_begin_sample); debug_log( " bit# %2d @ %7u: ", bitnum, bit_begin_sample);
fsk_bit_analyze(fskp, samples+bit_begin_sample, bit_nsamples, fsk_bit_analyze(fskp, samples+bit_begin_sample, bit_nsamples,
&bit_values[bitnum], &bit_values[bitnum],
&bit_sig_mags[bitnum], &bit_sig_mags[bitnum],
@ -440,7 +440,7 @@ fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit,
for ( bitnum=0; bitnum<n_bits; bitnum++ ) for ( bitnum=0; bitnum<n_bits; bitnum++ )
*bits_outp |= (unsigned long long) bit_values[bitnum] << bitnum; *bits_outp |= (unsigned long long) bit_values[bitnum] << bitnum;
debug_log(" frame algo=%u confidence=%f ampl=%f\n", debug_log(" frame algo=%d confidence=%f ampl=%f\n",
CONFIDENCE_ALGO, confidence, *ampl_outp); CONFIDENCE_ALGO, confidence, *ampl_outp);
return confidence; return confidence;
} }
@ -474,14 +474,14 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples,
int j; int j;
for ( j=0; ; j++ ) for ( j=0; ; j++ )
{ {
int up = j%2 ? 1 : -1; int up = ( j % 2 ) ? 1 : -1;
int t = try_first_sample + up*((j+1)/2)*try_step_nsamples; int t = try_first_sample + up*((j+1)/2)*try_step_nsamples;
if ( t >= (int)try_max_nsamples ) if ( t >= (int)try_max_nsamples )
break; break;
if ( t < 0 ) if ( t < 0 )
continue; continue;
float c, ampl_out; float c, ampl_out = 0.0;
unsigned long long bits_out = 0; unsigned long long bits_out = 0;
debug_log("try fsk_frame_analyze at t=%d\n", t); debug_log("try fsk_frame_analyze at t=%d\n", t);
c = fsk_frame_analyze(fskp, samples+t, samples_per_bit, c = fsk_frame_analyze(fskp, samples+t, samples_per_bit,
@ -525,8 +525,8 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples,
debug_log("FSK_FRAME bits='"); debug_log("FSK_FRAME bits='");
for ( j=0; j<expect_n_bits; j++ ) for ( j=0; j<expect_n_bits; j++ )
debug_log("%c", ( *bits_outp >> j ) & 1 ? '1' : '0' ); debug_log("%c", ( ( *bits_outp >> j ) & 1 ) ? '1' : '0' );
debug_log("' datum='%c' (0x%02x) c=%f a=%f t=%d\n", debug_log("' datum='%c' (0x%02x) c=%f a=%f t=%u\n",
isprint(bitchar)||isspace(bitchar) ? bitchar : '.', isprint(bitchar)||isspace(bitchar) ? bitchar : '.',
bitchar, bitchar,
confidence, best_a, best_t); confidence, best_a, best_t);

View File

@ -30,8 +30,8 @@ minimodem \- general-purpose software audio FSK modem
is a command-line program which decodes (or generates) audio is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols. modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, NOAA SAME, various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
and Caller-ID. NOAA SAME, and Caller-ID.
.PP .PP
.B Minimodem .B Minimodem
can play and capture audio modem tones in real-time via the system can play and capture audio modem tones in real-time via the system
@ -67,6 +67,9 @@ default mark and space tone frequencies.
.B rtty .B rtty
: RTTY 45.45 bps \-\-baudot \-\-stopbits 1.5 : RTTY 45.45 bps \-\-baudot \-\-stopbits 1.5
.TP .TP
.B tdd
: TTY/TDD 45.45 bps \-\-baudot \-\-stopbits 2.0
.TP
.B same .B same
: SAME 520.83 bps \-\-startbits 0 \-\-stopbits 0 \-\-sync-byte 0xAB : SAME 520.83 bps \-\-startbits 0 \-\-stopbits 0 \-\-sync-byte 0xAB
.br .br
@ -187,6 +190,9 @@ Filter the received text output, replacing any "non-printable" bytes
with a '.' character. with a '.' character.
(This option applies to \-\-rx mode only). (This option applies to \-\-rx mode only).
.TP .TP
.B \-\-print-eot
Print "### EOT" to stderr after each transmit completes.
.TP
.B \-\-tx-carrier .B \-\-tx-carrier
When transmitting from a blocking source, keep a carrier going while waiting When transmitting from a blocking source, keep a carrier going while waiting
for more data. for more data.
@ -233,7 +239,7 @@ The latest version is available at <http://www.whence.com/minimodem>.
.B minimodem .B minimodem
was written by Kamal Mostafa <kamal@whence.com>. was written by Kamal Mostafa <kamal@whence.com>.
.SH COPYRIGHT .SH COPYRIGHT
Copyright \(co 2011-2014 by Kamal Mostafa <kamal@whence.com>. Copyright \(co 2011-2016 by Kamal Mostafa <kamal@whence.com>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
.br .br
This is free software: you are free to change and redistribute it. This is free software: you are free to change and redistribute it.

View File

@ -3,7 +3,7 @@
* *
* minimodem - software audio Bell-type or RTTY FSK modem * minimodem - software audio Bell-type or RTTY FSK modem
* *
* Copyright (C) 2011-2014 Kamal Mostafa <kamal@whence.com> * Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -46,12 +46,14 @@
char *program_name = ""; char *program_name = "";
int tx_transmitting = 0; int tx_transmitting = 0;
int tx_print_eot = 0;
int tx_leader_bits_len = 2; int tx_leader_bits_len = 2;
int tx_trailer_bits_len = 2; int tx_trailer_bits_len = 2;
simpleaudio *tx_sa_out; simpleaudio *tx_sa_out;
float tx_bfsk_mark_f; float tx_bfsk_mark_f;
unsigned int tx_bit_nsamples; unsigned int tx_bit_nsamples;
unsigned int tx_flush_nsamples;
void void
tx_stop_transmit_sighandler( int sig ) tx_stop_transmit_sighandler( int sig )
@ -62,11 +64,12 @@ tx_stop_transmit_sighandler( int sig )
for ( j=0; j<tx_trailer_bits_len; j++ ) for ( j=0; j<tx_trailer_bits_len; j++ )
simpleaudio_tone(tx_sa_out, tx_bfsk_mark_f, tx_bit_nsamples); simpleaudio_tone(tx_sa_out, tx_bfsk_mark_f, tx_bit_nsamples);
// 0.5 sec of zero samples to flush - FIXME lame if ( tx_flush_nsamples )
size_t sample_rate = simpleaudio_get_rate(tx_sa_out); simpleaudio_tone(tx_sa_out, 0, tx_flush_nsamples);
simpleaudio_tone(tx_sa_out, 0, sample_rate/2);
tx_transmitting = 0; tx_transmitting = 0;
if ( tx_print_eot )
fprintf(stderr, "### EOT\n");
} }
@ -130,6 +133,10 @@ static void fsk_transmit_stdin(
tx_sa_out = sa_out; tx_sa_out = sa_out;
tx_bfsk_mark_f = bfsk_mark_f; tx_bfsk_mark_f = bfsk_mark_f;
tx_bit_nsamples = bit_nsamples; tx_bit_nsamples = bit_nsamples;
if ( tx_interactive )
tx_flush_nsamples = sample_rate/2; // 0.5 sec of zero samples to flush
else
tx_flush_nsamples = 0;
// one-shot // one-shot
struct itimerval itv = { struct itimerval itv = {
@ -142,6 +149,9 @@ static void fsk_transmit_stdin(
{0, 0} // it_value {0, 0} // it_value
}; };
// arbitrary chosen timeout value: 1/25 of a second
unsigned int idle_carrier_usec = (1000000/25);
int block_input = tx_interactive && !txcarrier; int block_input = tx_interactive && !txcarrier;
if ( block_input ) if ( block_input )
signal(SIGALRM, tx_stop_transmit_sighandler); signal(SIGALRM, tx_stop_transmit_sighandler);
@ -159,8 +169,16 @@ static void fsk_transmit_stdin(
{ {
FD_ZERO(&fdset); FD_ZERO(&fdset);
FD_SET(fd, &fdset); FD_SET(fd, &fdset);
struct timeval tv_zero = { 0, 0 }; struct timeval tv_idletimeout = { 0, 0 };
if( block_input || select(fd+1, &fdset, NULL, NULL, &tv_zero) )
if ( !tx_interactive ) {
// When stdin blocks we "emit idle tone", for a duration of
// idle_carrier_usec. If !tx_interactive (i.e. writing to an
// audio file) make the select timeout the same duration.
tv_idletimeout.tv_usec = idle_carrier_usec;
}
if( block_input || select(fd+1, &fdset, NULL, NULL, &tv_idletimeout) )
{ {
n_read = read(fd, &buf, sizeof(buf)); n_read = read(fd, &buf, sizeof(buf));
if( n_read <= 0 ) //Includes EOF (0) and errors (-1) if( n_read <= 0 ) //Includes EOF (0) and errors (-1)
@ -211,10 +229,10 @@ static void fsk_transmit_stdin(
else else
{ {
tx_transmitting = 1; tx_transmitting = 1;
unsigned int j;
/* emit idle tone (mark) */ /* emit idle tone (mark) */
for ( j=0; j<tx_leader_bits_len; j++ ) simpleaudio_tone(sa_out,
simpleaudio_tone(sa_out, invert_start_stop ? bfsk_space_f : bfsk_mark_f, sample_rate/50); invert_start_stop ? bfsk_space_f : bfsk_mark_f,
idle_carrier_usec * sample_rate / 1000000);
} }
if ( block_input ) if ( block_input )
@ -360,7 +378,7 @@ version()
{ {
printf( printf(
"minimodem %s\n" "minimodem %s\n"
"Copyright (C) 2011-2014 Kamal Mostafa <kamal@whence.com>\n" "Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>\n"
"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n" "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n"
"This is free software: you are free to change and redistribute it.\n" "This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n\n" "There is NO WARRANTY, to the extent permitted by law.\n\n"
@ -403,12 +421,14 @@ usage()
" --binary-output\n" " --binary-output\n"
" --binary-raw {nbits}\n" " --binary-raw {nbits}\n"
" --print-filter\n" " --print-filter\n"
" --print-eot\n"
" --tx-carrier\n" " --tx-carrier\n"
" {baudmode}\n" " {baudmode}\n"
" any_number_N Bell-like N bps --ascii\n" " any_number_N Bell-like N bps --ascii\n"
" 1200 Bell202 1200 bps --ascii\n" " 1200 Bell202 1200 bps --ascii\n"
" 300 Bell103 300 bps --ascii\n" " 300 Bell103 300 bps --ascii\n"
" rtty RTTY 45.45 bps --baudot --stopbits=1.5\n" " rtty RTTY 45.45 bps --baudot --stopbits=1.5\n"
" tdd TTY/TDD 45.45 bps --baudot --stopbits=2.0\n"
" same NOAA SAME 520.83 bps --sync-byte=0xAB ...\n" " same NOAA SAME 520.83 bps --sync-byte=0xAB ...\n"
" callerid Bell202 CID 1200 bps\n" " callerid Bell202 CID 1200 bps\n"
" uic{-train,-ground} UIC-751-3 Train/Ground 600 bps\n" " uic{-train,-ground} UIC-751-3 Train/Ground 600 bps\n"
@ -561,6 +581,7 @@ main( int argc, char*argv[] )
MINIMODEM_OPT_BINARY_RAW, MINIMODEM_OPT_BINARY_RAW,
MINIMODEM_OPT_PRINT_FILTER, MINIMODEM_OPT_PRINT_FILTER,
MINIMODEM_OPT_XRXNOISE, MINIMODEM_OPT_XRXNOISE,
MINIMODEM_OPT_PRINT_EOT,
MINIMODEM_OPT_TXCARRIER MINIMODEM_OPT_TXCARRIER
}; };
@ -600,6 +621,7 @@ main( int argc, char*argv[] )
{ "binary-output", 0, 0, MINIMODEM_OPT_BINARY_OUTPUT }, { "binary-output", 0, 0, MINIMODEM_OPT_BINARY_OUTPUT },
{ "binary-raw", 1, 0, MINIMODEM_OPT_BINARY_RAW }, { "binary-raw", 1, 0, MINIMODEM_OPT_BINARY_RAW },
{ "print-filter", 0, 0, MINIMODEM_OPT_PRINT_FILTER }, { "print-filter", 0, 0, MINIMODEM_OPT_PRINT_FILTER },
{ "print-eot", 0, 0, MINIMODEM_OPT_PRINT_EOT },
{ "Xrxnoise", 1, 0, MINIMODEM_OPT_XRXNOISE }, { "Xrxnoise", 1, 0, MINIMODEM_OPT_XRXNOISE },
{ "tx-carrier", 0, 0, MINIMODEM_OPT_TXCARRIER }, { "tx-carrier", 0, 0, MINIMODEM_OPT_TXCARRIER },
{ 0 } { 0 }
@ -733,6 +755,9 @@ main( int argc, char*argv[] )
case MINIMODEM_OPT_TXCARRIER: case MINIMODEM_OPT_TXCARRIER:
txcarrier = 1; txcarrier = 1;
break; break;
case MINIMODEM_OPT_PRINT_EOT:
tx_print_eot = 1;
break;
default: default:
usage(); usage();
} }
@ -781,6 +806,16 @@ main( int argc, char*argv[] )
bfsk_n_data_bits = 5; bfsk_n_data_bits = 5;
if ( bfsk_nstopbits < 0 ) if ( bfsk_nstopbits < 0 )
bfsk_nstopbits = 1.5; bfsk_nstopbits = 1.5;
} else if ( strncasecmp(modem_mode, "tdd",4)==0 ) {
bfsk_databits_decode = databits_decode_baudot;
bfsk_databits_encode = databits_encode_baudot;
bfsk_data_rate = 45.45;
if ( bfsk_n_data_bits == 0 )
bfsk_n_data_bits = 5;
if ( bfsk_nstopbits < 0 )
bfsk_nstopbits = 2.0;
bfsk_mark_f = 1400;
bfsk_space_f = 1800;
} else if ( strncasecmp(modem_mode, "same",5)==0 ) { } else if ( strncasecmp(modem_mode, "same",5)==0 ) {
// http://www.nws.noaa.gov/nwr/nwrsame.htm // http://www.nws.noaa.gov/nwr/nwrsame.htm
bfsk_data_rate = 520.0 + 5/6.0; bfsk_data_rate = 520.0 + 5/6.0;
@ -1100,7 +1135,7 @@ main( int argc, char*argv[] )
assert ( samples_nvalid + read_nsamples <= samplebuf_size ); assert ( samples_nvalid + read_nsamples <= samplebuf_size );
ssize_t r; ssize_t r;
r = simpleaudio_read(sa, samples_readptr, read_nsamples); r = simpleaudio_read(sa, samples_readptr, read_nsamples);
debug_log("simpleaudio_read(samplebuf+%zd, n=%zu) returns %zd\n", debug_log("simpleaudio_read(samplebuf+%td, n=%zu) returns %zd\n",
samples_readptr - samplebuf, read_nsamples, r); samples_readptr - samplebuf, read_nsamples, r);
if ( r < 0 ) { if ( r < 0 ) {
fprintf(stderr, "simpleaudio_read: error\n"); fprintf(stderr, "simpleaudio_read: error\n");
@ -1363,7 +1398,7 @@ main( int argc, char*argv[] )
if (bfsk_msb_first) { if (bfsk_msb_first) {
bits = bit_reverse(bits, bfsk_n_data_bits); bits = bit_reverse(bits, bfsk_n_data_bits);
} }
debug_log("Input: %08x%08x - Databits: %i - Shift: %i\n", (unsigned int)(bits >> 32), (unsigned int)bits, bfsk_n_data_bits, bfsk_nstartbits); debug_log("Input: %08x%08x - Databits: %u - Shift: %i\n", (unsigned int)(bits >> 32), (unsigned int)bits, bfsk_n_data_bits, bfsk_nstartbits);
unsigned int dataout_size = 4096; unsigned int dataout_size = 4096;
char dataoutbuf[4096]; char dataoutbuf[4096];

View File

@ -1,7 +1,7 @@
/* /*
* simple-tone-generator.c * simple-tone-generator.c
* *
* Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com> * Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by

View File

@ -200,6 +200,15 @@ sa_sndfile_open_stream(
return 0; return 0;
} }
// Disable the insertion of this questionable "PEAK chunk" header thing.
// Relates only to writing SF_FORMAT_FLOAT .wav and .aiff files
// (minimodem --tx --float-samples). When left enabled, this adds some
// wonky bytes to the header which change from run to run (different every
// wall-clock second. WTF?
// http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_ADD_PEAK_CHUNK
/* Turn off the PEAK chunk. */
sf_command(s, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE);
/* good or bad to override these? */ /* good or bad to override these? */
sa->rate = sfinfo.samplerate; sa->rate = sfinfo.samplerate;
sa->channels = sfinfo.channels; sa->channels = sfinfo.channels;

View File

@ -0,0 +1,44 @@
#!/bin/bash
MINIMODEM="${MINIMODEM-./minimodem}"
[ -f "$MINIMODEM" ] || {
MINIMODEM="../src/minimodem"
[ -f "$MINIMODEM" ] || {
echo "E: cannot find minimodem in ./ or ../src/" 1>&2
exit 1
}
}
minimodem_tx_args="1200 $1"
textfile="testdata-ascii.txt"
TMPF="/tmp/minimodem-test-$$"
trap "rm -f $TMPF.*" 0
set -e
$MINIMODEM --tx --file $TMPF.1.wav $minimodem_tx_args < "$textfile"
sleep 1
$MINIMODEM --tx --file $TMPF.2.wav $minimodem_tx_args < "$textfile"
sleep 1
$MINIMODEM --tx --file $TMPF.3.wav $minimodem_tx_args < "$textfile"
cmp -s $TMPF.1.wav $TMPF.2.wav || {
echo -e "TX-NOT-CONSISTENT"
exit 1
}
cmp -s $TMPF.1.wav $TMPF.3.wav || {
echo -e "TX-NOT-CONSISTENT"
exit 1
}
stats="three runs of '--tx $minimodem_tx_args' created identical output"
result="OK "
exitcode=0
echo -e "$result $stats"
exit $exitcode

View File

@ -0,0 +1 @@
exec ./16-verify-tx-consistent.test --float-samples

1
tests/81-tdd.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-baudot.txt tdd

View File

@ -15,34 +15,3 @@ the quick brown fox jumps over the lazy dog
Earning our SkyMiles Earning our SkyMiles
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
minimodem - software audio Bell-type or RTTY FSK modem
Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com>
Minimodem is a command-line program which generates (or decodes) audio
modem tones at any specified baud rate, emulating an old Bell-type or
radio-teletype FSK modem. The tones can be played to (or recorded from)
the system audio (PulseAudio or ALSA) or to an audio file.
Minimodem can be used to transfer data between nearby computers using an
audio cable (or just via sound waves), or between remote computers using
radio, telephone, or another audio communications medium.
----------------------------------------------------------------------------
minimodem - software audio Bell-type or RTTY FSK modem
Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.