Compare commits

...

17 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
11 changed files with 123 additions and 24 deletions

View File

@ -1,5 +1,5 @@
AC_PREREQ([2.64])
AC_INIT([minimodem], [0.23], [kamal@whence.com])
AC_INIT([minimodem], [0.24], [kamal@whence.com])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/Makefile.in])
AM_INIT_AUTOMAKE

18
debian/changelog vendored
View File

@ -1,3 +1,21 @@
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 ]

2
debian/compat vendored
View File

@ -1 +1 @@
7
9

4
debian/control vendored
View File

@ -2,8 +2,8 @@ Source: minimodem
Section: comm
Priority: optional
Maintainer: Kamal Mostafa <kamal@whence.com>
Build-Depends: debhelper (>= 7.0.50~), libfftw3-dev, libpulse-dev, libasound2-dev [linux-any], libsndfile1-dev
Standards-Version: 3.9.6
Build-Depends: debhelper (>= 9), libfftw3-dev, libpulse-dev, libasound2-dev [linux-any], libsndfile1-dev
Standards-Version: 3.9.7
Homepage: http://www.whence.com/minimodem
Vcs-Git: https://github.com/kamalmostafa/minimodem.git
Vcs-Browser: https://github.com/kamalmostafa/minimodem

View File

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

View File

@ -62,7 +62,7 @@ fsk_plan_new(
errno = EINVAL;
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);
@ -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' );
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,
&bit_values[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' )
continue;
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,
&bit_values[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++ )
*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);
return confidence;
}
@ -474,14 +474,14 @@ fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples,
int 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;
if ( t >= (int)try_max_nsamples )
break;
if ( t < 0 )
continue;
float c, ampl_out;
float c, ampl_out = 0.0;
unsigned long long bits_out = 0;
debug_log("try fsk_frame_analyze at t=%d\n", t);
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='");
for ( j=0; j<expect_n_bits; j++ )
debug_log("%c", ( *bits_outp >> j ) & 1 ? '1' : '0' );
debug_log("' datum='%c' (0x%02x) c=%f a=%f t=%d\n",
debug_log("%c", ( ( *bits_outp >> j ) & 1 ) ? '1' : '0' );
debug_log("' datum='%c' (0x%02x) c=%f a=%f t=%u\n",
isprint(bitchar)||isspace(bitchar) ? bitchar : '.',
bitchar,
confidence, best_a, best_t);

View File

@ -190,6 +190,9 @@ Filter the received text output, replacing any "non-printable" bytes
with a '.' character.
(This option applies to \-\-rx mode only).
.TP
.B \-\-print-eot
Print "### EOT" to stderr after each transmit completes.
.TP
.B \-\-tx-carrier
When transmitting from a blocking source, keep a carrier going while waiting
for more data.

View File

@ -46,12 +46,14 @@
char *program_name = "";
int tx_transmitting = 0;
int tx_print_eot = 0;
int tx_leader_bits_len = 2;
int tx_trailer_bits_len = 2;
simpleaudio *tx_sa_out;
float tx_bfsk_mark_f;
unsigned int tx_bit_nsamples;
unsigned int tx_flush_nsamples;
void
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++ )
simpleaudio_tone(tx_sa_out, tx_bfsk_mark_f, tx_bit_nsamples);
// 0.5 sec of zero samples to flush - FIXME lame
size_t sample_rate = simpleaudio_get_rate(tx_sa_out);
simpleaudio_tone(tx_sa_out, 0, sample_rate/2);
if ( tx_flush_nsamples )
simpleaudio_tone(tx_sa_out, 0, tx_flush_nsamples);
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_bfsk_mark_f = bfsk_mark_f;
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
struct itimerval itv = {
@ -142,6 +149,9 @@ static void fsk_transmit_stdin(
{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;
if ( block_input )
signal(SIGALRM, tx_stop_transmit_sighandler);
@ -159,8 +169,16 @@ static void fsk_transmit_stdin(
{
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
struct timeval tv_zero = { 0, 0 };
if( block_input || select(fd+1, &fdset, NULL, NULL, &tv_zero) )
struct timeval tv_idletimeout = { 0, 0 };
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));
if( n_read <= 0 ) //Includes EOF (0) and errors (-1)
@ -211,10 +229,10 @@ static void fsk_transmit_stdin(
else
{
tx_transmitting = 1;
unsigned int j;
/* emit idle tone (mark) */
for ( j=0; j<tx_leader_bits_len; j++ )
simpleaudio_tone(sa_out, invert_start_stop ? bfsk_space_f : bfsk_mark_f, sample_rate/50);
simpleaudio_tone(sa_out,
invert_start_stop ? bfsk_space_f : bfsk_mark_f,
idle_carrier_usec * sample_rate / 1000000);
}
if ( block_input )
@ -403,6 +421,7 @@ usage()
" --binary-output\n"
" --binary-raw {nbits}\n"
" --print-filter\n"
" --print-eot\n"
" --tx-carrier\n"
" {baudmode}\n"
" any_number_N Bell-like N bps --ascii\n"
@ -562,6 +581,7 @@ main( int argc, char*argv[] )
MINIMODEM_OPT_BINARY_RAW,
MINIMODEM_OPT_PRINT_FILTER,
MINIMODEM_OPT_XRXNOISE,
MINIMODEM_OPT_PRINT_EOT,
MINIMODEM_OPT_TXCARRIER
};
@ -601,6 +621,7 @@ main( int argc, char*argv[] )
{ "binary-output", 0, 0, MINIMODEM_OPT_BINARY_OUTPUT },
{ "binary-raw", 1, 0, MINIMODEM_OPT_BINARY_RAW },
{ "print-filter", 0, 0, MINIMODEM_OPT_PRINT_FILTER },
{ "print-eot", 0, 0, MINIMODEM_OPT_PRINT_EOT },
{ "Xrxnoise", 1, 0, MINIMODEM_OPT_XRXNOISE },
{ "tx-carrier", 0, 0, MINIMODEM_OPT_TXCARRIER },
{ 0 }
@ -734,6 +755,9 @@ main( int argc, char*argv[] )
case MINIMODEM_OPT_TXCARRIER:
txcarrier = 1;
break;
case MINIMODEM_OPT_PRINT_EOT:
tx_print_eot = 1;
break;
default:
usage();
}
@ -782,7 +806,7 @@ main( int argc, char*argv[] )
bfsk_n_data_bits = 5;
if ( bfsk_nstopbits < 0 )
bfsk_nstopbits = 1.5;
} else if ( strncasecmp(modem_mode, "tdd",3)==0 ) {
} 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;
@ -1111,7 +1135,7 @@ main( int argc, char*argv[] )
assert ( samples_nvalid + read_nsamples <= samplebuf_size );
ssize_t r;
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);
if ( r < 0 ) {
fprintf(stderr, "simpleaudio_read: error\n");
@ -1374,7 +1398,7 @@ main( int argc, char*argv[] )
if (bfsk_msb_first) {
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;
char dataoutbuf[4096];

View File

@ -200,6 +200,15 @@ sa_sndfile_open_stream(
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? */
sa->rate = sfinfo.samplerate;
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