Compare commits

...

231 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
Kamal Mostafa 0555866e57 minimodem-0.22.1-1 2015-08-24 13:55:27 -07:00
Kamal Mostafa 2b5e2c6a40 Do not enable tx-carrier for non-interactive --file sessions
The logic that determined whether to 'block_input' was backwards with
respect to non-interactive --file sessions, such that using --file
*enabled* the tx-carrier behavior when it should have disabled it.
This went unnoticed because on reasonably fast systems, reading the
input data from the file never induce the timeout anyway -- only very
slow machines reveal the problem: long gaps of 'mark' between each
frame, as if each input character was slowly typed interactively.

Fixes: ecebf01 Add ability to output a carrier while waiting for data
2015-08-24 13:54:34 -07:00
Kamal Mostafa 6d9b4d2e0c minimodem-0.22-1 2015-08-23 10:42:47 -07:00
Kamal Mostafa 639b695f31 eliminate all instances of implicit double-promotion 2015-08-23 10:16:15 -07:00
Kamal Mostafa d002c60a92 appease clang self-assignment warning 2015-08-23 09:12:34 -07:00
Kamal Mostafa ed8e633af0 fix non-integer mark/space frequency handling 2015-08-23 09:00:40 -07:00
Kamal Mostafa 17adb2158f clean up autoconf config files 2015-08-23 08:29:12 -07:00
Kevin Zheng 2020b4c2bf Untrack automatically generated files 2015-08-23 08:19:41 -07:00
Kamal Mostafa 2953cdcd8a add Nick Moriarty to AUTHORS 2015-04-22 16:58:44 -07:00
Nick Moriarty 8915ce1525 Fix ALSA latency (causing ALSA not to block).
With arbitrarily large latency setting (unsigned int)-1, ALSA will happily
accept all the samples we want to throw at it.

Reducing to a reasonably long (but still sub-second) value of 100ms, we
cause ALSA writes to block and work properly with --tx-carrier.
2015-04-22 17:48:28 +01:00
Nick Moriarty ecebf013f0 Add ability to output a carrier while waiting for data
Added --tx-carrier, which continues to output a tone while a blocking source
waits for more data on stdin.
2015-04-22 17:48:28 +01:00
Kamal Mostafa 49bfa06f8e minimodem: --binary-raw {nbits} output mode 2015-04-21 14:01:03 -07:00
Kamal Mostafa 1439efa68d minimodem-0.21-1 2014-11-24 08:37:09 -08:00
Kamal Mostafa 2ae79d8a5b man: add uic-train and uic-ground modes 2014-11-16 13:02:59 -08:00
Kamal Mostafa 3b54fa7768 add Marcos Vives Del Sol to AUTHORS and debian/copyright 2014-11-16 12:46:14 -08:00
Kamal Mostafa ff47edfb68 minimodem: accept "uic*" for uic-ground 2014-11-16 12:46:14 -08:00
Marcos Vives Del Sol 532bcfb84c Honor --invert-start-stop in TX 2014-11-16 12:46:14 -08:00
Marcos Vives Del Sol 25d01f73d8 Add UIC-751-3 decoding and optional MSB-first TX/RX
[ kamal: cleanup ]
2014-11-16 12:46:14 -08:00
Marcos Vives Del Sol ff0346f5a8 Really use 64 data types for demodulation
[ kamal: cleanup ]
2014-11-16 12:46:14 -08:00
Kamal Mostafa 2cdf2d29e4 build_expect_bits_string cleanup 2014-11-16 12:46:14 -08:00
Marcos Vives Del Sol bbf121a63f Compute expected bit strings outside of main loop 2014-11-16 12:46:14 -08:00
Marcos Vives Del Sol 163af2539c Add Windows executable to gitignore 2014-11-16 12:46:13 -08:00
Marcos Vives Del Sol cc6b5c9123 Change code to use 64-bit variables for decoding 2014-11-16 12:46:13 -08:00
Marcos Vives Del Sol 909adf0d59 Add option to change start-stop polarity 2014-11-16 12:46:13 -08:00
Kamal Mostafa 40f1d50cbd fsk: calc separate divergences for mark and space bits
Calculate and consider separate signal-strength divergence values for
mark and space bits, so that imbalanced (but consistent) mark/space
strengths do not drive down confidence.

Note: This change makes all existing test cases yield very slightly
higher confidence values.
2014-11-16 11:00:36 -08:00
Kamal Mostafa 746f0f6c7a minimodem: free samplebuf to appease valgrind 2014-11-14 09:12:27 -08:00
Kamal Mostafa eaf229ea5e minimodem-0.20-1 2014-11-13 11:08:29 -08:00
Kamal Mostafa d3a6fd1f26 debian/control: move Vcs- fields to github; bump S-V to 3.9.6 2014-11-13 11:08:29 -08:00
Kamal Mostafa ba5ecec2f7 update copyright dates 2014 2014-11-13 10:56:31 -08:00
Kamal Mostafa 84cfb3ad67 autoreconf (automake 1.14.1) 2014-11-13 10:56:31 -08:00
Kamal Mostafa 8401f038e6 fix tests/ harness for automake 1.13
See http://osdir.com/ml/bug-automake-gnu/2013-06/msg00010.html
2014-11-09 10:34:00 -08:00
Kamal Mostafa 8c9484a738 callerid: handle name and phone '[N/A]' or '[blocked]' 2014-11-08 10:30:07 -08:00
Kamal Mostafa a6a7e0da35 callerid: warn when used with --auto-carrier 2014-11-08 09:27:31 -08:00
Billseph Gamesh 2a37e24964 callerid: fix MDMF decode when 0x08 (Name N/A) field is encountered
Off-by-one comparison caused any MDMF packet with an 0x08 field to
get junked.
2014-11-08 08:51:12 -08:00
David A Aitcheson a126663220 man: fix url to wikipedia SAME page
Prevent groff from botching this embedded URL when it generates
minimodem.1.html.
2014-11-04 07:46:14 -08:00
Kamal Mostafa 3c5ac8819d simpleaudio: do not crash on stereo input file
Complain about non-mono input audio files instead of crashing.
Thanks goblin@github for the report.

GitHub: fixes kamalmostafa/minimodem#1
2014-03-18 15:01:05 -07:00
Kamal Mostafa 3c227b516a minimodem-0.19-1 2013-09-18 09:11:36 -07:00
Kamal Mostafa 151e360720 minimodem: -7 implements 7-bit ASCII 2013-09-17 07:56:20 -07:00
Kamal Mostafa a524e38222 minimodem: fix --baudot cmdline switch
The --baudot (a.k.a. -5) command line switch didn't actually engage
the Baudot encoder/decoder, just set 5 bits per frame.
2013-09-05 15:36:49 -07:00
Kamal Mostafa d51803bc69 minimodem-0.18-1 2013-06-10 09:29:26 -07:00
Kamal Mostafa f9bdf43423 update copyright dates 2013-06-10 09:28:02 -07:00
Kamal Mostafa 31f8af5056 debian/control: enable Vcs- fields 2013-06-10 09:05:29 -07:00
Kamal Mostafa 0140e0df12 minimodem: --tx SAME emits 16 sync-byte preamble
Emit a preamble of 16 (hardcoded) sync-bytes if --sync-byte is
specified with --tx mode.  This makes --tx SAME emit the required
preamble of 16 0xAB's automatically.  So --rx SAME now directly
decodes the output of --tx SAME without needing to manually inject
the preamble byte(s), simplifying the test case.

Thanks to Harold Giddings, for reporting the issue.
2013-06-08 10:16:56 -07:00
Kamal Mostafa 24f1acff4f minimodem: fsk_transmit_frame factored out 2013-06-08 10:04:06 -07:00
Kamal Mostafa 8876f6674a minimodem: rename bfsk_sync_on_data to bfsk_do_rx_sync 2013-06-08 09:27:01 -07:00
Kamal Mostafa 9e741dd474 minimodem-0.17.1-1 2013-03-21 13:08:35 -07:00
Kamal Mostafa d98d0d6387 (portability) link with -lm explicitly
We need to explicitly link with -lm since we actually call lroundf() and sin().
2013-03-21 13:04:35 -07:00
Kamal Mostafa c25545951f minimodem-0.17-1 2013-03-20 12:10:37 -07:00
Kamal Mostafa d774ad74dd minimodem: handle arbitrary --startbits N
minimodem --startbits N works for rx and tx, where (0 <= N <= 20).

Thanks Martyn (kronalias), for reporting.
2013-03-20 12:08:52 -07:00
Kamal Mostafa b76b5a3fa3 minimodem-0.16.1-1 2013-01-25 15:09:47 -08:00
Kamal Mostafa 7ab18a268f minimodem: do not call setitimer(new_value=NULL)
Linux kernel warns:

    minimodem calls setitimer() with new_value NULL pointer. Misfeature support
    will be removed

Thanks Robert Hooker, for reporting.
2013-01-25 15:03:54 -08:00
Kamal Mostafa 1f74732147 minimodem-0.16-1 2012-11-03 14:32:40 -07:00
Kamal Mostafa 9d3200ca60 autoreconf 2012-11-03 14:28:47 -07:00
Kamal Mostafa 032d0bb79c minimodem: refine frame position if confidence falls
Allows for more accurate tracking, esp. for no-frame-bits protocols.
Fixes tests/test-80-SAME-datastream.
2012-11-03 14:20:33 -07:00
Kamal Mostafa 4709b5d146 tests: 80-SAME-datastream 2012-11-03 14:15:53 -07:00
Kamal Mostafa 1446844d32 minimodem: do not transmit leader tone if no start bits 2012-11-03 14:10:44 -07:00
Kamal Mostafa c2fa2dae93 fsk: fix FSK_DEBUG character decode 2012-11-03 13:26:10 -07:00
Kamal Mostafa 6ad778ce03 minimodem: fix --tx startbits/stopbits handling
Make --tx support specified --startbits and --stopbits; also enables --tx SAME.

Thanks to Jamie Batmanglidj for reporting the issue.
2012-11-01 12:48:40 -07:00
Kamal Mostafa 83f8c7cbdd minimodem-0.15.1-1 2012-10-16 18:11:21 -07:00
Kamal Mostafa 7fed380d0a callerid: do not use recursive call to reset
Testing by Mike Tedesco shows the recursive databits_decode_callerid()
seems to break on OS X (only); I don't see why it should.  Avoid the
issue by not making a recursive call.
2012-10-16 18:02:21 -07:00
Kamal Mostafa 93bf08f750 callerid: fix parser - do not store noise bytes 2012-10-10 10:05:51 -07:00
Kamal Mostafa 5e28a8026f minimodem-0.15-1 2012-10-05 20:16:44 -07:00
Kamal Mostafa 1a60f1c12d update README text 2012-10-05 20:07:23 -07:00
Kamal Mostafa 65493fa12a minimodem: --rx callerid
New "callerid" baudmode supports Bell202 Caller-ID (MDMF or SDMF) prototol.
2012-10-05 19:40:17 -07:00
Kamal Mostafa 49ccd10e1f minimodem: --rx prints all bytes unmolested, unless --print-filter
Now, minimodem prints all received bytes without isprint() filtering,
unless --print-filter is specified.  Allows for binary file transfers
and multibyte characters.
2012-10-05 13:29:30 -07:00
Kamal Mostafa ead6952a58 (portability) simple-tone-generator.c needs stdio.h 2012-10-04 18:13:23 -07:00
Mike Tedesco 577b84d7f2 (portability) use stdlib.h not malloc.h 2012-10-04 18:10:33 -07:00
Mike Tedesco d8f7601b4f (portability) simpleaudio.c needs stdio.h 2012-10-04 18:08:31 -07:00
Kamal Mostafa 761cf00b16 minimodem: handle SIGINT on --rx: close the sa backend and print stats 2012-10-02 14:22:38 -07:00
Kamal Mostafa 9627669b24 minimodem-0.14-1 2012-10-01 21:16:17 -07:00
Kamal Mostafa 2373364d9a minimodem: performance: read samples in larger blocks
For performance, read samples from the simpleaudio backend in larger
blocks when the number of bits per frame ends up being small.
2012-10-01 21:00:28 -07:00
Kamal Mostafa 2af26a4d06 simpleaudio-alsa: allow max latency
Request "maximum possible allowed latency", to help avoid underruns.
2012-10-01 19:06:27 -07:00
Kamal Mostafa 151ee0e004 simpleaudio-alsa: handle underruns better; print '#' 2012-10-01 19:02:39 -07:00
Kamal Mostafa b97aeb0778 simpleaudio-pulse: fix intermittent --tx noise
For some unknown reason setting attr.prebuf=1 causes horrible noise
for some playback sessions, so don't do that.
2012-10-01 14:30:00 -07:00
Kamal Mostafa 99c4b526af minimodem-0.13.1-1 2012-09-10 20:48:11 -07:00
Kamal Mostafa 6340365e2f simpleaudio-sndfile: fix minimodem tx_interactive
Un-break tx_interactive: minimodem enables tx_interactive whenever the
stream_name is NULL, so go back to using the stream_name as the sndfile
filename.
2012-09-10 20:02:53 -07:00
Kamal Mostafa 093d9aa18a minimodem-0.13-1 2012-09-09 18:40:41 -07:00
Kamal Mostafa 9f1695a3b6 minimodem: fix --auto-carrier crash on positive-shift modes 2012-09-09 17:42:53 -07:00
Kamal Mostafa d603fc444d minimodem: --alsa[=plughw:X,Y] 2012-09-09 15:24:35 -07:00
Kamal Mostafa 5ee6a23c42 simpleaudio: backend_device support 2012-09-09 15:24:01 -07:00
Kamal Mostafa c2bb5c6205 simpleaudio-alsa: fix bogus latency, set 200 ms 2012-09-09 15:03:40 -07:00
Kamal Mostafa 7df0366e60 minimodem-0.12.1-1 2012-09-06 16:47:27 -07:00
Kamal Mostafa fabd47ba99 minimodem: less aggressive refine on acquisition 2012-09-05 23:22:27 -07:00
Kamal Mostafa 2612aba0e2 minimodem-0.12-1 2012-09-05 09:45:34 -07:00
Kamal Mostafa c8dd7ac06b minimodem: fix --rx-one 2012-09-05 09:37:06 -07:00
Kamal Mostafa 3a1469b85e minimodem: fix usage message 2012-09-05 09:36:12 -07:00
Kamal Mostafa 8931ae1311 baudot: use non-Baudot chars for debug output 2012-09-04 15:37:19 -07:00
Kamal Mostafa 30de59026b minimodem: --inverted switches the mark/space freqs 2012-09-04 16:26:10 -07:00
Kamal Mostafa 8731b54bc2 minimodem: refine fsk frame position on carrier acquisition
FSK_ANALYZE_NSTEPS was previously 10.

Now FSK_ANALYZE_NSTEPS_CARRIER_LOCK is 100, and FSK_ANALYZE_NSTEPS is
reduced to 4.

(Also, try_confidence_search_limit = INFINITY on carrier acquisition frame).

Effects: Better initial phase lock on signal in the first
place; sloppier tracking of fast/slow signals; reduced longterm CPU load.
2012-09-03 23:31:16 -07:00
Kamal Mostafa aa1124d6e7 minimodem: fix incorrect try_max_nsamples calculation 2012-09-02 14:25:43 -07:00
Kamal Mostafa fd45b5571c minimodem: restrict try_max_nsamples to 75% of a bit-width
... actually 125% of a bit width before acquiring carrier.
2012-09-02 14:27:04 -07:00
Kamal Mostafa 7b0e47ac4e minimodem: --binary-output 2012-09-01 00:09:32 -07:00
Kamal Mostafa a172268117 minimodem: auto get samplerate from audio files 2012-09-02 18:10:59 -07:00
Kamal Mostafa 0f3338a91b minimodem: match sync_byte in the fsk layer 2012-09-02 12:02:06 -07:00
Kamal Mostafa 9187dd60a7 minimodem: --rx same (NOAA SAME protocol) 2012-09-01 13:34:50 -07:00
Kamal Mostafa 04cc215640 minimodem: --sync-byte {0xXX} 2012-09-01 14:54:32 -07:00
Kamal Mostafa 82c72352ab minimodem: --startbits; deprecate -T 2012-09-01 13:33:49 -07:00
Kamal Mostafa e2a51f093a databits: split out the databits implementations
rename framebits to databits
added databits_binary decoder
2012-08-31 21:39:08 -07:00
Kamal Mostafa a7d1602c9d minimodem: calculate frame_bits_{mask,shift} 2012-08-31 20:42:05 -07:00
Kamal Mostafa f16e318ae4 minimodem-0.11-1 2012-08-30 16:51:05 -07:00
Kamal Mostafa cbd048aac6 minimodem: bfsk_nstartsbits variable
- FIXME: doesn't actually implement the proper expect_bits string
 - only useful for testing SAME decoder's hardcoded "dddddddd" expect_bits
2012-08-30 16:02:53 -07:00
Kamal Mostafa 7b34e89433 minimodem: --stopbits replaces --txstopbits; better bps metric
RX metrics account for fractional number of stop bits (e.g 1.5);
RX bps metric slightly more accurate (?).
2012-08-30 15:05:33 -07:00
Kamal Mostafa becf16761e minimodem: fsk confidence thresholds: thresh=1.5, limit=2.3
Note: fsk_confidence_thresh can now be reduced to 1.5 due to track_amplitude.
2012-08-26 15:16:49 -07:00
Kamal Mostafa 3447a994b7 minimodem: track_amplitude signal amplitude drop 2012-08-30 00:07:15 -07:00
Kamal Mostafa 1ed3b8465a fsk: confidence algo #6: "SNR * (1-divergence)"
Disabled all the hardcoded noise limiters.
2012-08-24 22:38:41 -07:00
Kamal Mostafa 23a44ce374 tests: noise testcases 2012-08-30 00:25:15 -07:00
Kamal Mostafa 0c022aca03 minimodem: --rx-one quits after first no-carrier 2012-08-30 10:17:55 -07:00
Kamal Mostafa b480b841da minimodem: --Xrxnoise=factor adds test noise
Injects random noise to input signal (in memory) before analysis.
2012-08-30 00:00:19 -07:00
Kamal Mostafa 664f345636 tests: run fewer rate-slop cases 2012-08-30 09:00:02 -07:00
Kamal Mostafa 6d749c7771 simpleaudio-alsa: enable ALSA soft-resample 2012-08-29 21:26:47 -07:00
Kamal Mostafa e59931beba tests: amplitude 2012-08-25 10:07:26 -07:00
Kamal Mostafa dd6040336d minimodem: stats report ampl={amplitude} 2012-08-25 09:17:05 -07:00
Kamal Mostafa f8434f3c94 simple-tone: fix sin() rounding for S16 shorts
- fix sine wave rounding for shorts
 - short epsilon == 1
 - clamp shorts to mag <= 1.0
2012-08-26 12:34:38 -07:00
Kamal Mostafa 762a3ea788 minimodem: --volume sets tx amplitude 2012-08-25 00:32:11 -07:00
Kamal Mostafa 501ee25c7d fsk: expect_bits_string param, no start/stop bits required
fsk_find_frame() takes expect_bits_string  (e.g. "10dddddddd1"), as a
parameter supplied by the caller allowing for encodings which don't use
any start/stop bits (e.g. just "dddddddd").
2012-08-24 13:20:20 -07:00
Kamal Mostafa 6bb683a90b minimodem: fix broken -l switch 2012-08-23 19:23:33 -07:00
Kamal Mostafa 9c6b06f8b0 minimodem-0.10.1-2 2012-08-21 18:43:29 -07:00
Kamal Mostafa 3a26594c4b debian: enable build hardening flags 2012-08-20 14:09:33 -07:00
Kamal Mostafa 8c23532836 minimodem-0.10.1-1 2012-08-19 16:10:38 -07:00
Kamal Mostafa 3999041f07 tests: run fewer rate-slop tests 2012-08-19 16:02:21 -07:00
Kamal Mostafa e9263c9c9d fsk: fix noise <= EPSILON handling
Handle noise <= EPSILON better; fixes (im)perfect test cases on i386.
2012-08-19 15:58:08 -07:00
Kamal Mostafa 96ec6450bb minimodem: fix size_t %zu warnings on 32-bit platforms 2012-08-19 14:39:14 -07:00
Kamal Mostafa c9efe7f5e8 debian: disable ALSA on non-Linux platforms
kfreebsd in Debian supplies alsa via the alsa-oss wrapper package, but that
is missing snd_pcm_recover() at least, so build --without-alsa on the
non-Linux platforms.
2012-08-19 13:52:35 -07:00
Kamal Mostafa 059719fe02 configure: move summary message 2012-08-19 13:16:13 -07:00
Kamal Mostafa 814a86eaf3 minimodem-0.10-1 2012-08-19 09:11:49 -07:00
Kamal Mostafa e27dec4be8 add dspguide.com to THANKS 2012-08-19 07:54:42 -07:00
Kamal Mostafa f81f069d95 minimodem: --limit (2.3) sets fsk_confidence_search_limit
Significant performance enhancements from fsk_confidence_search_limit:
runs far fewer FFT's when --limit (default 2.3) is less than INFINITY.
2012-08-18 21:24:01 -07:00
Kamal Mostafa e1b055cf4f fsk: AVOID_TRANSIENTS noise limiter re-enabled
Algo #5 needs this, just as #3 did.
2012-08-18 19:15:33 -07:00
Kamal Mostafa 076343a9c3 fsk: MIN_MAGNITUDE noise limiter 2012-08-18 19:15:07 -07:00
Kamal Mostafa 725355aa43 fsk: performance: do not bzero fftin 2012-08-18 16:52:07 -07:00
Kamal Mostafa bc30de33a4 minimodem: fix carrier_nsamples
All test cases (except 45.45 RTTY) get rate perfect!
2012-08-18 13:43:45 -07:00
Kamal Mostafa 97e8f4f715 tests: 21-rate-slop 2012-08-17 21:54:29 -07:00
Kamal Mostafa 83bb72b474 tests: self-test tx -- rx args 2012-08-17 21:46:54 -07:00
Kamal Mostafa 24eaf984b5 tests: self-test handles perfect tests 2012-08-17 21:22:02 -07:00
Kamal Mostafa 18b1eb7457 minimodem: default confidence = 2.0 for SNR algo #5 2012-08-18 19:19:22 -07:00
Kamal Mostafa cf9ba20ee0 fsk: confidence algo #5 (SNR)
Computes SNR confidence value, where "signal" is the magnitude of the FSK
driven frequency, and "noise" is the magnitude of the non-driven frequency.

(Also includes unused algo #4 code, which may not compile anymore.)
2012-08-14 22:31:30 -07:00
Kamal Mostafa df80c98e22 minimodem: fsk_frame_overscan replaces FSK_SCAN_LAG 2012-08-16 01:03:54 -07:00
Kamal Mostafa 6ee10626c9 simple-tone: use integer mod not fmod 2012-08-15 16:57:39 -07:00
Kamal Mostafa c039dad33a THANKS file 2012-08-15 14:07:46 -07:00
Kamal Mostafa fbc99e54fb simpleaudio: benchmarks cpu id 2012-08-15 12:00:17 -07:00
Kamal Mostafa 1dff8e726f move src/testcases to ./tests 2012-08-15 11:44:26 -07:00
Kamal Mostafa f6c4697cf9 .gitignore files 2012-08-14 13:29:00 -07:00
Kamal Mostafa 8533fd1550 simpleaudio: fix --benchmarks for sizeof(long)==4 platforms 2012-08-14 08:28:36 -07:00
Kamal Mostafa b02e248beb minimodem-0.9-1 2012-08-13 21:53:10 -07:00
Kamal Mostafa 67eb9821be update copyright dates 2012-08-13 21:51:53 -07:00
Kamal Mostafa 5fb00dd283 self-test: more test cases 2012-08-13 21:19:08 -07:00
Kamal Mostafa d8ed9bef82 self-test: print the test args 2012-08-13 21:17:38 -07:00
Kamal Mostafa a9c2258706 minimodem: use sine lookup table of 1024, or --lut={tx_sin_table_len} 2012-08-13 21:17:03 -07:00
Kamal Mostafa e2225d6098 simple-tone: sin() lookup tables 2012-08-13 21:09:24 -07:00
Kamal Mostafa d273828f80 minimodem: --float-samples: short arg -F deprecated 2012-08-13 15:55:57 -07:00
Kamal Mostafa bd08b9002c minimodem: --benchmarks: runs internal performance tests 2012-08-13 15:51:04 -07:00
Kamal Mostafa 23ecd6f5a7 simpleaudio: benchmark backend 2012-08-13 15:50:04 -07:00
Kamal Mostafa 9948e7c7dd minimodem: --tx uses S16 samples by default, --float-samples overrides 2012-08-12 15:47:59 -07:00
Kamal Mostafa 6671138471 simpleaudio: S16 format handling for backends 2012-08-12 15:39:04 -07:00
Kamal Mostafa a65a20d274 simpleaudio: generalize r/w buf pointer types 2012-08-12 14:39:23 -07:00
Kamal Mostafa 4d326a8c82 simpleaudio: generalized simpleaudio_open_stream 2012-08-12 14:24:55 -07:00
Kamal Mostafa 5dddc1445a simple-tone: generate S16 format samples 2012-08-11 21:19:30 -07:00
Kamal Mostafa 3053ea78bc simpleaudio: SA_SAMPLE_FORMAT framework 2012-08-11 21:00:37 -07:00
Kamal Mostafa 39bee9adf1 simpleaudio: get_framesize 2012-08-11 20:40:20 -07:00
Kamal Mostafa 07a8ca158b testcases: test-10-verify-perfect 2012-08-11 18:22:43 -07:00
Kamal Mostafa ae6d387d2d self-test: rename testcases 2012-08-11 16:31:05 -07:00
Kamal Mostafa f3a9337f8d self-test: change arg order 2012-08-11 16:25:51 -07:00
Kamal Mostafa 8d90e839d7 minimodem: --samplerate sets the audio sample rate 2012-08-11 10:24:28 -07:00
Kamal Mostafa 22317f54fc simpleaudio: handle any audio sample rate 2012-08-11 10:07:12 -07:00
Kamal Mostafa 500208ba81 simpleaudio-alsa: do not allow soft_resample 2012-08-11 10:28:20 -07:00
Kamal Mostafa d96edbcb4f debian: build-dep libasound2-dev
And demote pulseaudio from Recommends: to Suggests:.
2012-08-08 20:29:08 -07:00
Kamal Mostafa b78828ea11 minimodem: usage message fix 2012-08-08 20:18:52 -07:00
Kamal Mostafa 4b926d58bb minimodem: --alsa selects ALSA at runtime
./configure now enables --with-pulseaudio and --with-alsa by default;
either can be disabled.

minimodem --alsa: uses ALSA at runtime instead of the default PulseAudio.
2012-08-08 20:10:55 -07:00
Kamal Mostafa 445156dfa0 minimodem: man page cleanup 2012-08-08 19:58:05 -07:00
Kamal Mostafa d1f8966ff1 simpleaudio-alsa: correct comments 2012-08-08 18:56:01 -07:00
Kamal Mostafa 7cb56487f8 simpleaudio-alsa: do not fiddle with sw params at all 2012-08-08 18:53:24 -07:00
Kamal Mostafa 2baf78cba6 simpleaudio-alsa: use default latency, not minimum 2012-08-08 18:35:11 -07:00
Kamal Mostafa deed39904d simpleaudio-alsa: loop in the sa_ routine; fix xruns 2012-08-08 16:24:44 -07:00
Kamal Mostafa 95d7a87ce1 minimodem: configure --with-alsa for ALSA instead of Pulseaudio 2012-08-08 14:26:39 -07:00
Kamal Mostafa e01ccb1d71 simpleaudio: alsa back-end 2012-08-08 14:25:53 -07:00
Kamal Mostafa f4aa9dd64a minimodem-0.8.2-1 2012-08-06 14:55:36 -07:00
Kamal Mostafa b68a0c0d43 debian: update copyright format and bump standards version 2012-08-06 14:54:25 -07:00
Kamal Mostafa 7d8c62cf5e configure: new opts --without-{pulseaudio,sndfile}
./configure --without-pulseaudio or --without-sndfile (but not both)
to preclude those dependencies.

Sources use config.h defines USE_PULSEAUDIO and USE_SNDFILE.
2012-08-06 13:14:26 -07:00
Kamal Mostafa 03396e7027 configure: autoreconf update to autoconf 2.6.8
aclocal 1.11.3
autoconf 2.68
automake 1.11.3
2012-08-06 14:11:50 -07:00
Kamal Mostafa 4f3e04b45d minimodem-0.8.1-1 2011-07-15 20:40:54 -07:00
Kamal Mostafa 777b57dd3a minimodem: do not do interactive signal handling with --tx --file 2011-07-15 20:37:13 -07:00
Kamal Mostafa e5e620ed95 minimodem-0.8-1 2011-07-15 19:33:50 -07:00
Kamal Mostafa 5c849bfca3 minimodem: man page enhancements 2011-07-15 19:17:31 -07:00
Kamal Mostafa 93405a3751 minimodem: default 1.5 stop bits for rtty only 2011-07-15 19:00:20 -07:00
Kamal Mostafa 2efe4bac19 minimodem: set reasonable default mark/space for high baud rates 2011-07-15 17:56:02 -07:00
Kamal Mostafa 7686acc38e minimodem: transmit interactive zero latency; fix leader/trailer 2011-07-13 20:37:17 -07:00
Kamal Mostafa 836475faa3 simpleaudio: zero pulseaudio playback latency 2011-07-13 20:35:45 -07:00
Kamal Mostafa 79344a03dd simpleaudio: zero pulseaudio capture latency 2011-07-10 12:34:44 -07:00
Kamal Mostafa 7b10750d3c start new release 2011-07-15 19:01:46 -07:00
Kamal Mostafa 164e133900 minimodem-0.7-1 2011-07-08 18:51:47 -07:00
Kamal Mostafa ccf9459ac2 man: recommend --auto-carrier with rtty 2011-07-08 18:13:24 -07:00
Kamal Mostafa 9a85232c96 minimodem: --quiet 2011-07-08 18:08:52 -07:00
Kamal Mostafa 695c628427 minimodem: --auto-carrier off by default
No longer on by default for <= 300 baud.
2011-07-08 17:42:19 -07:00
Kamal Mostafa 633153916b minimodem: --confidence param 2011-07-08 13:16:06 -07:00
Kamal Mostafa 7a5aea88df minimodem: rate analysis fixes ("rate perfect")
adjust MIN_CONFIDENCE
2011-07-08 13:03:00 -07:00
Kamal Mostafa bca34371e1 fsk: do not consider the stop bit twice 2011-07-08 13:00:50 -07:00
Kamal Mostafa 9efb04cb8c tests: use -T 1 to check for rate perfect 2011-07-08 11:53:50 -07:00
Kamal Mostafa 47ced96ccf minimodem: version message to stdout 2011-07-08 09:48:52 -07:00
Kamal Mostafa da141a008e tests: make case 02 shorter 2011-07-08 09:26:52 -07:00
Kamal Mostafa 726b284afc minimodem: CARRIER_AUTODETECT_THRESHOLD reduced to 0.001 2011-07-08 09:26:25 -07:00
Kamal Mostafa 25e6e41939 fsk: no FSK_MIN_STRENGTH limitation 2011-07-08 09:26:02 -07:00
Kamal Mostafa 1aafe0022b self-test: MINIMODEM env var 2011-07-08 08:53:06 -07:00
Kamal Mostafa 845c3e1be6 fsk: CONFIDENCE_ALGO 3 (worst divergence)
CONFIDENCE_ALGO 3 (worst divergence):
 - single worst diverging bit in the frame
 - amplitude normalized
 - drop AVOID_TRANSIENT
2011-07-08 08:03:31 -07:00
Kamal Mostafa cb3e81e576 fsk debug 2011-07-08 07:31:54 -07:00
Kamal Mostafa fd0546d80d fsk expect_bits 2011-07-07 13:31:10 -07:00
88 changed files with 3898 additions and 9709 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
*.o
.deps
Makefile
Makefile.in
/aclocal.m4
/autom4te.cache/
/compile
/config.h.in
/config.h
/config.log
/config.status
/configure
/depcomp
/install-sh
/missing
/stamp-h1
/test-driver

View File

@ -1 +1,3 @@
Kamal Mostafa <kamal@whence.com>
Marcos Vives Del Sol <socram8888@gmail.com> [ UIC-751-3 mode ]
Nick Moriarty <njmoriarty@gmail.com> [ --tx-carrier feature ]

View File

@ -1,5 +1,5 @@
minimodem - software audio Bell-type or RTTY FSK modem
Copyright (C) 2011 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
it under the terms of the GNU General Public License as published by

View File

@ -1 +1 @@
SUBDIRS = src
SUBDIRS = src tests

View File

@ -1,677 +0,0 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d "$(distdir)" \
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DEPS_CFLAGS = @DEPS_CFLAGS@
DEPS_LIBS = @DEPS_LIBS@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = src
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@$(am__cd) '$(distuninstallcheck_dir)' \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
ctags-recursive install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
distclean distclean-generic distclean-hdr distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

16
README
View File

@ -1,10 +1,14 @@
minimodem - software audio Bell-type or RTTY FSK modem
Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
minimodem - general-purpose software audio FSK modem
Copyright (C) 2011-2016 Kamal Mostafa <kamal@whence.com>
Minimodem is a command-line program which generates (or decodes) audio
modem tones, emulating an old Bell-type or radio-teletype FSK modem.
The tones can be played to (or recorded from) the PulseAudio system
or to an audio file.
Minimodem is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
NOAA SAME, and Caller-ID.
Minimodem can play and capture audio modem tones in real-time via the
system audio device, or in batched mode via audio files.
Minimodem can be used to transfer data between nearby computers using an
audio cable (or just via sound waves), or between remote computers using

42
THANKS Normal file
View File

@ -0,0 +1,42 @@
My thanks to the following, who assisted with the development and testing
of minimodem.
- Kamal Mostafa <kamal@whence.com>
Colin Ian King <colin.king@canonical.com> was one of the first users of
minimodem and was instrumental in the testing of the initial versions.
He has used minimodem to debug suspend/resume issues, representing its
first practical application:
http://smackerelofopinion.blogspot.com/2011/08/debugging-s3-suspendresume-using.html
Thanks, Colin!
Elektra <onelektra@gmx.net> provided encouragement and extensive help with
making minimodem work on an OpenWRT router, including testing the ALSA
back-end and runtime performance improvements for non-FPU systems. Elektra
demonstrates and discusses minimodem on the German Freifunk radio show:
http://wiki.freifunk.net/Freifunk.radio_20120814
Thanks, Elektra!
Chris Van Hoof <vanhoof@ouwish.com> provided encouragement, testing help,
and hardware relating to the S.A.M.E. protocol.
Thanks Chris!
Mike Tedesco <mike.tedesco@venturesoft.com> provided encouragement and
testing for the Caller-ID protocol handling, and portability fixes for OS X.
Thanks Mike!
My employer Canonical, Ltd. for encouraging me to spend time developing
and maintaining this and other open-source projects. Thanks, Canonical!
Dr. Steven W. Smith, for providing his incredible book "The Scientist and
Engineer's Guide to Digital Signal Processing" free of charge online at
http://www.dspguide.com/
Thanks, Dr. Smith!

1109
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Version number of package */
#undef VERSION

4974
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +1,79 @@
dnl
dnl configure.ac Generated by project-setup
dnl
AC_DEFUN([PKG_NAME], [minimodem])
AC_DEFUN([PKG_VERSION], [0.6.1])
AC_DEFUN([PKG_AUTHOR], [Kamal Mostafa <kamal@whence.com>])
AC_DEFUN([PKG_BUGS_TO], [kamal@whence.com])
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)
dnl Release versioning info
VERSION=PKG_VERSION
VERSION=AC_PACKAGE_VERSION
AC_SUBST(VERSION)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/Makefile.in])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
# Program Checks
AC_PROG_CC
# AC_PROG_RANLIB
# Library Checks
AC_SEARCH_LIBS([lroundf], [m])
deps_packages="fftw3f"
# ALSA
AC_ARG_WITH([alsa], [AS_HELP_STRING([--without-alsa],
[build without ALSA support])])
AS_IF([test "x$with_alsa" == "xno"], [
use_alsa=0
], [
use_alsa=1
deps_packages="$deps_packages alsa"
])
AC_DEFINE_UNQUOTED([USE_ALSA], [$use_alsa],
[Define to 1 to enable ALSA support])
# pulseaudio
AC_ARG_WITH([pulseaudio], AS_HELP_STRING([--without-pulseaudio],
[build without pulseaudio support]))
AS_IF([test "x$with_pulseaudio" == "xno"], [
use_pulseaudio=0
], [
use_pulseaudio=1
deps_packages="$deps_packages libpulse-simple"
])
AC_DEFINE_UNQUOTED([USE_PULSEAUDIO], [$use_pulseaudio],
[Define to 1 to enable pulseaudio support])
# sndfile
AC_ARG_WITH([sndfile], AS_HELP_STRING([--without-sndfile],
[build without sndfile support]))
AS_IF([test "x$with_sndfile" == "xno"], [
use_sndfile=0
], [
use_sndfile=1
deps_packages="$deps_packages sndfile"
])
AC_DEFINE_UNQUOTED([USE_SNDFILE], [$use_sndfile],
[Define to 1 to enable sndfile support])
# benchmarks
AC_ARG_WITH([benchmarks], AS_HELP_STRING([--disable-benchmarks],
[build without internal benchmarks]))
AS_IF([test "x$with_benchmarks" == "xno"], [
use_benchmarks=0
], [
use_benchmarks=1
])
AC_DEFINE_UNQUOTED([USE_BENCHMARKS], [$use_benchmarks],
[Define to 1 to enable internal benchmarks])
AC_MSG_RESULT([
option summary:
alsa $with_alsa ($use_alsa)
benchmarks $with_benchmarks ($use_benchmarks)
pulseaudio $with_pulseaudio ($use_pulseaudio)
sndfile $with_sndfile ($use_sndfile)
])
# Checks for libraries.
PKG_CHECK_MODULES(DEPS, [
libpulse-simple
sndfile
fftw3f
])
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
PKG_CHECK_MODULES(DEPS, [$deps_packages])
# Checks for header files.
# AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
AC_SUBST([auto_find_tests], ['$(sort $(wildcard *.test))'])
# 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
])
# testdata/Makefile
AC_CONFIG_FILES([Makefile src/Makefile src/minimodem.1 tests/Makefile])
AC_OUTPUT

280
debian/changelog vendored
View File

@ -1,3 +1,283 @@
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
* Do not enable tx-carrier for non-interactive --file sessions
-- Kamal Mostafa <kamal@whence.com> Mon, 24 Aug 2015 13:51:57 -0700
minimodem (0.22-1) unstable; urgency=medium
[ Kamal Mostafa ]
* minimodem --binary-raw {nbits}: raw binary bits output mode
* fix non-integer mark/space frequency handling
* eliminate all instances of implicit double-promotion
[Nick Moriarty ]
* minimodem --tx-carrier: output a carrier while waiting for data
* Fix ALSA latency (causing ALSA not to block).
[ Kevin Zheng ]
* Untrack automatically generated files
-- Kamal Mostafa <kamal@whence.com> Sun, 23 Aug 2015 10:34:55 -0700
minimodem (0.21-1) unstable; urgency=medium
[ Marcos Vives Del Sol ]
* UIC-751-3 600 bps train message modes (uic-train, uic-ground)
* minimodem --invert-start-stop option inverts polarity of framing bits
[ Kamal Mostafa ]
* fsk confidence algo: calc separate divergences for mark and space bits
(improves signal demodulation)
-- Kamal Mostafa <kamal@whence.com> Mon, 24 Nov 2014 08:28:06 -0800
minimodem (0.20-1) unstable; urgency=medium
* fix stereo input file crash (thanks goblin@github)
* fix man page URL (thanks David Aitcheson)
* fix caller-id for blocked info (thanks Billseph Gamesh)
* test harness update for automake >= 1.13
* debian/control housekeeping
-- Kamal Mostafa <kamal@whence.com> Thu, 13 Nov 2014 10:31:57 -0800
minimodem (0.19-1) unstable; urgency=low
* minimodem new command line switch: -7 implements 7-bit ASCII
* fixed --baudot command line switch
-- Kamal Mostafa <kamal@whence.com> Wed, 18 Sep 2013 09:08:47 -0700
minimodem (0.18-1) unstable; urgency=low
* minimodem --tx SAME emits 16 sync-byte preamble
-- Kamal Mostafa <kamal@whence.com> Mon, 10 Jun 2013 09:28:20 -0700
minimodem (0.17.1-1) unstable; urgency=low
* (portability) link with -lm explicitly
- unbreaks Ubuntu 13.04 build.
-- Kamal Mostafa <kamal@whence.com> Thu, 21 Mar 2013 13:06:42 -0700
minimodem (0.17-1) unstable; urgency=low
* handle arbitrary --startbits N
-- Kamal Mostafa <kamal@whence.com> Wed, 20 Mar 2013 12:07:13 -0700
minimodem (0.16.1-1) unstable; urgency=low
* do not induce 'setitimer new_value NULL' kernel warning
-- Kamal Mostafa <kamal@whence.com> Fri, 25 Jan 2013 15:06:54 -0800
minimodem (0.16-1) unstable; urgency=low
* refine frame position if confidence falls
* fix --tx mode startbits/stopbits handling
* do not transmit leader tone if no startbit
-- Kamal Mostafa <kamal@whence.com> Sat, 03 Nov 2012 14:29:11 -0700
minimodem (0.15.1-1) unstable; urgency=low
* caller-ID parser fixes
-- Kamal Mostafa <kamal@whence.com> Tue, 16 Oct 2012 18:09:49 -0700
minimodem (0.15-1) unstable; urgency=low
* caller-ID support
* fixed multibyte character and binary data transfer
* stats are printed after ^C interrupt
* portability fixes (thanks, Mike Tedesco)
* minimodem new runtime command line switches:
--rx callerid Bell202 CID 1200 bps
--print-filter inhibit printing non-printable bytes
-- Kamal Mostafa <kamal@whence.com> Fri, 05 Oct 2012 20:08:24 -0700
minimodem (0.14-1) unstable; urgency=low
* general --rx performance enhancements
* fix PulseAudio --tx latency (and intermittent white noise)
* fix ALSA --rx latency some more; print '#' on underruns
-- Kamal Mostafa <kamal@whence.com> Mon, 01 Oct 2012 21:12:47 -0700
minimodem (0.13.1-1) unstable; urgency=low
* fix --tx non-interactive behavior (no timeout for --file)... again.
-- Kamal Mostafa <kamal@whence.com> Mon, 10 Sep 2012 20:45:36 -0700
minimodem (0.13-1) unstable; urgency=low
* added ALSA device selection via minimodem --alsa[=plughw:X,Y]
* fixed ALSA latency
* fixed --auto-carrier crash on positive-shift modes
-- Kamal Mostafa <kamal@whence.com> Sun, 09 Sep 2012 18:35:42 -0700
minimodem (0.12.1-1) unstable; urgency=low
* runtime performance fixes
-- Kamal Mostafa <kamal@whence.com> Thu, 06 Sep 2012 16:45:14 -0700
minimodem (0.12-1) unstable; urgency=low
* FSK signal acquisition precision enhancements
* runtime performance enhancements
* fixed automatic setting of samplerate from audio file
* fixed defective --rx-one switch behavior
* minimodem new and changed runtime command line switches:
--rx same NOAA S.A.M.E. protocol
-i, --inverted swaps the mark/space frequencies
--startbits {n}
--stopbits {n.n} *Note the -T synonym has been deprecated
--sync-byte {0xXX}
--binary-output
-- Kamal Mostafa <kamal@whence.com> Wed, 05 Sep 2012 09:44:03 -0700
minimodem (0.11-1) unstable; urgency=low
* new confidence algo: "SNR * (1-divergence)"
- improved sensitivity: handles signal amplitudes down to FLT_EPSILON
- improved noise rejection
- tightened --rx signal analysis metrics
* enabled ALSA soft-resampling
* more 'make check' test cases
* minimodem changed runtime command line switches:
-c, --confidence new default reduced to 1.5
-T, --stopbits {m.n} was --txstopbits, now also evaluated for rx metrics
* minimodem new runtime command line switches:
-v, --volume {amplitude or 'E'} sets --tx output volume
--rx-one quits after first carrier/no-carrier
-- Kamal Mostafa <kamal@whence.com> Thu, 30 Aug 2012 16:30:41 -0700
minimodem (0.10.1-2) unstable; urgency=low
* debian: enable build hardening flags
-- Kamal Mostafa <kamal@whence.com> Tue, 21 Aug 2012 18:41:44 -0700
minimodem (0.10.1-1) unstable; urgency=low
* better floating-point epsilon handling to fix (im)perfect test case
failures on i386
* debian: build --without-alsa on non-Linux platforms like kfreebsd-*
as their alsa-oss wrapper is insufficient
-- Kamal Mostafa <kamal@whence.com> Sun, 19 Aug 2012 16:05:38 -0700
minimodem (0.10-1) unstable; urgency=low
* new confidence algo ("SNR")
* new performance vs. quality controls
* significant --rx fsk analyzer performance improvements
* minor --tx fsk generator performance improvements
* more 'make check' test cases
* minimodem new runtime command line switches:
-c, --confidence {min-snr-threshold} default 2.0
-l, --limit {max-snr-search-limit} default 2.3
-- Kamal Mostafa <kamal@whence.com> Sun, 19 Aug 2012 08:58:07 -0700
minimodem (0.9-1) unstable; urgency=low
* runtime configurable audio sample rate and system audio backend
(PulseAudio or ALSA)
* use 1024-element sine wave lookup table by default (for --tx only)
* output 16-bit integer audio samples by default (for --tx only)
* configure --with/out switches for {pulseaudio,alsa,sndfile,benchmarks}
* internal sine wave benchmarks
* more 'make check' test cases
* minimodem new runtime command line switches:
-R, --samplerate {rate} specify audio sample rate (default 48000)
-A, --alsa use ALSA backend (default PulseAudio)
--lut={tx_sin_table_len} use lookup table of len, 0 to disable LUT
--float-samples use 32-bit float audio samples for --tx
--benchmarks run and report internal performance tests
-- Kamal Mostafa <kamal@whence.com> Mon, 13 Aug 2012 21:52:32 -0700
minimodem (0.8.2-1) unstable; urgency=low
* configure: new opts --without-{pulseaudio,sndfile}
* debian/copyright: update copyright format
-- Kamal Mostafa <kamal@whence.com> Mon, 06 Aug 2012 14:47:05 -0700
minimodem (0.8.1-1) unstable; urgency=low
* fix --tx stdin non-interactive behavior (no timeout for --file)
-- Kamal Mostafa <kamal@whence.com> Fri, 15 Jul 2011 20:37:38 -0700
minimodem (0.8-1) unstable; urgency=low
* auto select reasonable default mark/space for high baud rates
* low-latency PulseAudio capture (for that old-timey modem feel)
* fix --tx stdin interactive behavior
* default 1.5 stop bits for rtty only
-- Kamal Mostafa <kamal@whence.com> Fri, 15 Jul 2011 19:25:05 -0700
minimodem (0.7-1) unstable; urgency=low
* new amplitude-independent confidence algo ("worst divergence")
* fsk decode squelch reduced to 0.0
* rx rate analysis refinement
* new command-line parameters:
--auto-carrier (no longer default)
--confidence {value}
--quiet
-- Kamal Mostafa <kamal@whence.com> Fri, 08 Jul 2011 18:34:58 -0700
minimodem (0.6.1-1) unstable; urgency=low
* debian Recommends: pulseaudio

2
debian/compat vendored
View File

@ -1 +1 @@
7
9

24
debian/control vendored
View File

@ -2,21 +2,25 @@ Source: minimodem
Section: comm
Priority: optional
Maintainer: Kamal Mostafa <kamal@whence.com>
Build-Depends: debhelper (>= 7.0.50~), autotools-dev, libfftw3-dev, libpulse-dev, libsndfile1-dev
Standards-Version: 3.9.2
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: git://git.debian.org/collab-maint/minimodem.git
#Vcs-Browser: http://git.debian.org/?p=collab-maint/minimodem.git;a=summary
Vcs-Git: https://github.com/kamalmostafa/minimodem.git
Vcs-Browser: https://github.com/kamalmostafa/minimodem
Package: minimodem
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Recommends: pulseaudio
Description: software audio Bell-type or RTTY FSK modem
Minimodem is a command-line program which generates (or decodes) audio
modem tones, emulating an old Bell-type or radio-teletype FSK modem.
The tones can be played to (or recorded from) the PulseAudio system
or to an audio file.
Suggests: pulseaudio
Description: general-purpose software audio FSK modem
Minimodem is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
NOAA SAME, and Caller-ID.
.
Minimodem can play and capture audio modem tones in real-time via the
system audio device, or in batched mode via audio files.
.
Minimodem can be used to transfer data between nearby computers using an
audio cable (or just via sound waves), or between remote computers using

48
debian/copyright vendored
View File

@ -1,31 +1,35 @@
Format: http://dep.debian.net/deps/dep5
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: minimodem
Upstream-Contact: Kamal Mostafa <kamal@whence.com>
Source: http://www.whence.com/minimodem
minimodem - software audio Bell-type or RTTY FSK modem
minimodem is Copyright (C) 2011 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 package 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/>.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
Files: *
Copyright: 2011-2016 Kamal Mostafa <kamal@whence.com>
License: GPL-3.0+
Files: src/*uic*
Copyright: 2014 Marcos Vives Del Sol <socram8888@gmail.com>
License: GPL-3.0+
Files: debian/*
Copyright: 2011 Kamal Mostafa <kamal@whence.com>
Copyright: 2011-2016 Kamal Mostafa <kamal@whence.com>
License: GPL-3.0+
License: GPL-3.0+
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/>.
.
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
"/usr/share/common-licenses/GPL-3".

15
debian/rules vendored
View File

@ -9,5 +9,20 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# kfreebsd in Debian supplies alsa via the alsa-oss wrapper package, but that
# is missing snd_pcm_recover() at least, so build --without-alsa on the
# non-Linux platforms:
DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
ifneq (linux,$(DEB_HOST_ARCH_OS))
configure_flags += --without-alsa
endif
# enable hardening flags (for debian/compat<9):
configure_flags += $(shell f=`dpkg-buildflags --export=configure` && echo $$f)
override_dh_auto_configure:
dh_auto_configure -- $(configure_flags)
%:
dh $@

3
debian/watch vendored
View File

@ -1,6 +1,3 @@
# Example watch control file for uscan
# Rename this file to "watch" and then you can run the "uscan" command
# to check for upstream updates and more.
# See uscan(1) for format
# Compulsory line, this is a version 3 file

630
depcomp
View File

@ -1,630 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
# Software Foundation, Inc.
# 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 2, 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/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u="sed s,\\\\\\\\,/,g"
depmode=msvisualcpp
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,520 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2009-04-28.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

376
missing
View File

@ -1,376 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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 2, 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/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar*)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

4
src/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/minimodem
/minimodem.1
/minimodem.1.html
/minimodem.exe

View File

@ -1,7 +1,7 @@
#
# Makefile.am
#
# Copyright (C) 2011 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
# it under the terms of the GNU General Public License as published by
@ -17,18 +17,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
AM_CFLAGS = -Wall # -Werror
AM_CFLAGS = -Wall # -Werror -Wdouble-promotion
INCLUDES = $(DEPS_CFLAGS)
AM_CPPFLAGS = $(DEPS_CFLAGS)
bin_PROGRAMS = minimodem
dist_man_MANS = minimodem.1
EXTRA_DIST = self-test testcases/* # run-test
TESTS = testcases/test.*
EXTRA_DIST = minimodem.1.html
SIMPLEAUDIO_SRC = \
simpleaudio.h \
@ -36,12 +34,29 @@ SIMPLEAUDIO_SRC = \
simpleaudio.c \
simple-tone-generator.c \
simpleaudio-pulse.c \
simpleaudio-alsa.c \
simpleaudio-benchmark.c \
simpleaudio-sndfile.c
FSK_SRC = fsk.h fsk.c
BAUDOT_SRC = baudot.h baudot.c
minimodem_LDADD = $(DEPS_LIBS)
minimodem_SOURCES = minimodem.c $(BAUDOT_SRC) $(FSK_SRC) $(SIMPLEAUDIO_SRC)
UIC_SRC = uic_codes.h uic_codes.c
DATABITS_SRC = \
databits.h \
databits_ascii.c \
databits_binary.c \
databits_callerid.c \
databits_baudot.c $(BAUDOT_SRC) \
databits_uic.c $(UIC_SRC)
minimodem_LDADD = $(DEPS_LIBS)
minimodem_SOURCES = minimodem.c $(DATABITS_SRC) $(FSK_SRC) $(SIMPLEAUDIO_SRC)
minimodem.1.html: minimodem.1 Makefile
man --html=cat ./minimodem.1 | sed '5,$$ s:\(http\:[^ &]*\):<A HREF="\1">\1</A>:g' > $@
[ -s $@ ] || { rm $@; exit 1; }

View File

@ -1,672 +0,0 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#
# Makefile.am
#
# Copyright (C) 2011 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/>.
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
bin_PROGRAMS = minimodem$(EXEEXT)
subdir = src
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
PROGRAMS = $(bin_PROGRAMS)
am__objects_1 = baudot.$(OBJEXT)
am__objects_2 = fsk.$(OBJEXT)
am__objects_3 = simpleaudio.$(OBJEXT) simple-tone-generator.$(OBJEXT) \
simpleaudio-pulse.$(OBJEXT) simpleaudio-sndfile.$(OBJEXT)
am_minimodem_OBJECTS = minimodem.$(OBJEXT) $(am__objects_1) \
$(am__objects_2) $(am__objects_3)
minimodem_OBJECTS = $(am_minimodem_OBJECTS)
am__DEPENDENCIES_1 =
minimodem_DEPENDENCIES = $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(minimodem_SOURCES)
DIST_SOURCES = $(minimodem_SOURCES)
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
man1dir = $(mandir)/man1
NROFF = nroff
MANS = $(dist_man_MANS)
ETAGS = etags
CTAGS = ctags
am__tty_colors = \
red=; grn=; lgn=; blu=; std=
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DEPS_CFLAGS = @DEPS_CFLAGS@
DEPS_LIBS = @DEPS_LIBS@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EXEEXT = @EXEEXT@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CFLAGS = -Wall # -Werror
INCLUDES = $(DEPS_CFLAGS)
dist_man_MANS = minimodem.1
EXTRA_DIST = self-test testcases/* # run-test
TESTS = testcases/test.*
SIMPLEAUDIO_SRC = \
simpleaudio.h \
simpleaudio_internal.h \
simpleaudio.c \
simple-tone-generator.c \
simpleaudio-pulse.c \
simpleaudio-sndfile.c
FSK_SRC = fsk.h fsk.c
BAUDOT_SRC = baudot.h baudot.c
minimodem_LDADD = $(DEPS_LIBS)
minimodem_SOURCES = minimodem.c $(BAUDOT_SRC) $(FSK_SRC) $(SIMPLEAUDIO_SRC)
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p; \
then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
minimodem$(EXEEXT): $(minimodem_OBJECTS) $(minimodem_DEPENDENCIES)
@rm -f minimodem$(EXEEXT)
$(LINK) $(minimodem_OBJECTS) $(minimodem_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/baudot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minimodem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-tone-generator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-pulse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-sndfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
install-man1: $(dist_man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
@list=''; test -n "$(man1dir)" || exit 0; \
{ for i in $$list; do echo "$$i"; done; \
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
test -z "$$files" || { \
echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; skip=0; \
srcdir=$(srcdir); export srcdir; \
list=' $(TESTS) '; \
$(am__tty_colors); \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*[\ \ ]$$tst[\ \ ]*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
col=$$red; res=XPASS; \
;; \
*) \
col=$$grn; res=PASS; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*[\ \ ]$$tst[\ \ ]*) \
xfail=`expr $$xfail + 1`; \
col=$$lgn; res=XFAIL; \
;; \
*) \
failed=`expr $$failed + 1`; \
col=$$red; res=FAIL; \
;; \
esac; \
else \
skip=`expr $$skip + 1`; \
col=$$blu; res=SKIP; \
fi; \
echo "$${col}$$res$${std}: $$tst"; \
done; \
if test "$$all" -eq 1; then \
tests="test"; \
All=""; \
else \
tests="tests"; \
All="All "; \
fi; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="$$All$$all $$tests passed"; \
else \
if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all $$tests failed"; \
else \
if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
fi; \
fi; \
dashes="$$banner"; \
skipped=""; \
if test "$$skip" -ne 0; then \
if test "$$skip" -eq 1; then \
skipped="($$skip test was not run)"; \
else \
skipped="($$skip tests were not run)"; \
fi; \
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$skipped"; \
fi; \
report=""; \
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
report="Please report to $(PACKAGE_BUGREPORT)"; \
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$report"; \
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
if test "$$failed" -eq 0; then \
echo "$$grn$$dashes"; \
else \
echo "$$red$$dashes"; \
fi; \
echo "$$banner"; \
test -z "$$skipped" || echo "$$skipped"; \
test -z "$$report" || echo "$$report"; \
echo "$$dashes$$std"; \
test "$$failed" -eq 0; \
else :; fi
distdir: $(DISTFILES)
@list='$(MANS)'; if test -n "$$list"; then \
list=`for p in $$list; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
if test -n "$$list" && \
grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
echo " typically \`make maintainer-clean' will remove them" >&2; \
exit 1; \
else :; fi; \
else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(PROGRAMS) $(MANS)
installdirs:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man1
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-man
uninstall-man: uninstall-man1
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
clean-binPROGRAMS clean-generic ctags distclean \
distclean-compile distclean-generic distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binPROGRAMS install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-man1 install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-man uninstall-man1
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -33,19 +33,19 @@
static char
baudot_decode_table[32][3] = {
// letter, U.S. figs, CCITT No.2 figs (Europe)
{ '*', '*', '*' }, // NUL
{ '_', '^', '^' }, // NUL (underscore and caret marks for debugging)
{ 'E', '3', '3' },
{ 0xA, 0xA, 0xA }, // LF
{ 'A', '-', '-' },
{ ' ', ' ', ' ' }, // SPACE
{ 'S', '*', '\'' }, // BELL or apostrophe
{ 'S', 0x7, '\'' }, // BELL or apostrophe
{ 'I', '8', '8' },
{ 'U', '7', '7' },
{ 0xD, 0xD, 0xD }, // CR
{ 'D', '$', '*' }, // '$' or ENQ
{ 'D', '$', '^' }, // '$' or ENQ
{ 'R', '4', '4' },
{ 'J', '\'', '*' }, // apostrophe or BELL
{ 'J', '\'', 0x7 }, // apostrophe or BELL
{ 'N', ',', ',' },
{ 'F', '!', '!' },
{ 'C', ':', ':' },
@ -55,7 +55,7 @@ baudot_decode_table[32][3] = {
{ 'Z', '"', '+' },
{ 'L', ')', ')' },
{ 'W', '2', '2' },
{ 'H', '#', '*' }, // '#' or British pounds symbol // FIXME
{ 'H', '#', '%' }, // '#' or British pounds symbol // FIXME
{ 'Y', '6', '6' },
{ 'P', '0', '0' },
{ 'Q', '1', '1' },
@ -63,11 +63,11 @@ baudot_decode_table[32][3] = {
{ 'O', '9', '9' },
{ 'B', '?', '?' },
{ 'G', '&', '&' },
{ '*', '*', '*' }, // FIGS
{ '%', '%', '%' }, // FIGS (symbol % for debug; won't be printed)
{ 'M', '.', '.' },
{ 'X', '/', '/' },
{ 'V', ';', '=' },
{ '*', '*', '*' }, // LTRS
{ '%', '%', '%' }, // LTRS (symbol % for debug; won't be printed)
};
static char
@ -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
@ -225,8 +225,15 @@ baudot_decode( char *char_outp, unsigned char databits )
} else if ( databits == BAUDOT_SPACE ) { /* RX un-shift on space */
baudot_charset = 1;
}
if ( stuff_char )
*char_outp = baudot_decode_table[databits][baudot_charset-1];
if ( stuff_char ) {
int t;
if ( baudot_charset == 1 )
t = 0;
else
t = 1; // U.S. figs
// t = 2; // CCITT figs
*char_outp = baudot_decode_table[databits][t];
}
return stuff_char;
}

90
src/databits.h Normal file
View File

@ -0,0 +1,90 @@
/*
* databits.h
*
* Copyright (C) 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/>.
*/
// Reverses the ordering of the bits on an integer
static inline unsigned long long
bit_reverse(unsigned long long value,
unsigned int bits)
{
unsigned int out = 0;
while (bits--) {
out = (out << 1) | (value & 1);
value >>= 1;
}
return out;
}
// Gets "bits" bits from "value" starting "offset" bits from the start
static inline unsigned long long
bit_window(unsigned long long value,
unsigned int offset,
unsigned int bits)
{
unsigned long long mask = (1ULL << bits) - 1;
value = (value >> offset) & mask;
return value;
}
typedef int (databits_encoder)(
unsigned int *databits_outp, char char_out );
typedef unsigned int (databits_decoder)(
char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
int
databits_encode_ascii8( unsigned int *databits_outp, char char_out );
unsigned int
databits_decode_ascii8( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
#include "baudot.h"
#define databits_encode_baudot baudot_encode // from baudot.h
//int
//databits_encode_baudot( unsigned int *databits_outp, char char_out );
unsigned int
databits_decode_baudot( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
int
databits_encode_binary( unsigned int *databits_outp, char char_out );
unsigned int
databits_decode_binary( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
unsigned int
databits_decode_callerid( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
unsigned int
databits_decode_uic_ground( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
unsigned int
databits_decode_uic_train( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );

45
src/databits_ascii.c Normal file
View File

@ -0,0 +1,45 @@
/*
* databits_ascii.c
*
* Copyright (C) 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/>.
*/
#include "databits.h"
/*
* ASCII 8-bit data databits decoder/encoder (passthrough)
*/
/* returns the number of datawords stuffed into *databits_outp */
int
databits_encode_ascii8( unsigned int *databits_outp, char char_out )
{
*databits_outp = char_out;
return 1;
}
/* returns nbytes decoded */
unsigned int
databits_decode_ascii8( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits )
{
if ( ! dataout_p ) // databits processor reset: noop
return 0;
bits &= 0xFF;
*dataout_p = bits;
return 1;
}

40
src/databits_baudot.c Normal file
View File

@ -0,0 +1,40 @@
/*
* databits_baudot.c
*
* Copyright (C) 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/>.
*/
#include "databits.h"
/*
* Baudot 5-bit data databits decoder/encoder
*/
#include "baudot.h"
/* returns nbytes decoded */
unsigned int
databits_decode_baudot( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits )
{
if ( ! dataout_p ) { // databits processor reset: reset Baudot state
baudot_reset();
return 0;
}
bits &= 0x1F;
return baudot_decode(dataout_p, bits);
}

42
src/databits_binary.c Normal file
View File

@ -0,0 +1,42 @@
/*
* databits_binary.c
*
* Copyright (C) 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/>.
*/
#include "databits.h"
/*
* Rawbits N-bit binary data decoder/encoder
*/
#include <assert.h>
// returns nbytes decoded
unsigned int
databits_decode_binary( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits )
{
if ( ! dataout_p ) // databits processor reset: noop
return 0;
assert( dataout_size >= n_databits + 1 );
int j;
for ( j=0; j<n_databits; j++ )
dataout_p[j] = (bits>>j & 1) + '0';
dataout_p[j] = '\n';
return n_databits + 1;
}

210
src/databits_callerid.c Normal file
View File

@ -0,0 +1,210 @@
/*
* databits_callerid.c
*
* Copyright (C) 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/>.
*/
#include "databits.h"
#include <stdio.h>
/*
* Caller-ID (USA SDMF/MDMF) databits decoder
*
* Reference: http://melabs.com/resources/callerid.htm
*/
#define CID_MSG_MDMF 0x80
#define CID_MSG_SDMF 0x04
#define CID_DATA_DATETIME 0x01
#define CID_DATA_PHONE 0x02
#define CID_DATA_PHONE_NA 0x04
#define CID_DATA_NAME 0x07
#define CID_DATA_NAME_NA 0x08
static const char *cid_datatype_names[] = {
"unknown0:", "Time:", "Phone:", "unknown3:",
"Phone:", "unknown5:", "unknown6:", "Name:",
"Name:"
};
static int cid_msgtype = 0;
static int cid_ndata = 0;
static unsigned char cid_buf[256];
static unsigned int
decode_mdmf_callerid( char *dataout_p, unsigned int dataout_size )
{
unsigned int dataout_n = 0;
unsigned int cid_i = 0;
unsigned int cid_msglen = cid_buf[1];
unsigned char *m = cid_buf + 2;
while ( cid_i < cid_msglen ) {
unsigned int cid_datatype = *m++;
if ( cid_datatype > CID_DATA_NAME_NA ) {
// FIXME: bad datastream -- print something here
return 0;
}
unsigned int cid_datalen = *m++;
if ( m + 2 + cid_datalen >= cid_buf + sizeof(cid_buf) ) {
// FIXME: bad datastream -- print something here
return 0;
}
// dataout_n += sprintf(dataout_p+dataout_n, "CID: %d (%d)\n", cid_datatype, cid_datalen);
dataout_n += sprintf(dataout_p+dataout_n, "%-6s ",
cid_datatype_names[cid_datatype]);
int prlen = 0;
char *prdata = NULL;
switch ( cid_datatype ) {
case CID_DATA_DATETIME:
dataout_n += sprintf(dataout_p+dataout_n,
"%.2s/%.2s %.2s:%.2s\n", m+0, m+2, m+4, m+6);
break;
case CID_DATA_PHONE:
if ( cid_datalen == 10 ) {
dataout_n += sprintf(dataout_p+dataout_n,
"%.3s-%.3s-%.4s\n", m+0, m+3, m+6);
break;
} else {
// fallthrough
}
case CID_DATA_NAME:
prdata = (char *)m;
prlen = cid_datalen;
break;
case CID_DATA_PHONE_NA:
case CID_DATA_NAME_NA:
if ( cid_datalen == 1 && *m == 'O' ) {
prdata = "[N/A]";
prlen = 5;
} else if ( cid_datalen == 1 && *m == 'P' ) {
prdata = "[blocked]";
prlen = 9;
}
break;
default:
// FIXME: warning here?
break;
}
if ( prdata )
dataout_n += sprintf(dataout_p+dataout_n, "%.*s\n", prlen, prdata);
m += cid_datalen;
cid_i += cid_datalen + 2;
}
return dataout_n;
}
static unsigned int
decode_sdmf_callerid( char *dataout_p, unsigned int dataout_size )
{
unsigned int dataout_n = 0;
unsigned int cid_msglen = cid_buf[1];
unsigned char *m = cid_buf + 2;
dataout_n += sprintf(dataout_p+dataout_n, "%-6s ",
cid_datatype_names[CID_DATA_DATETIME]);
dataout_n += sprintf(dataout_p+dataout_n, "%.2s/%.2s %.2s:%.2s\n",
m+0, m+2, m+4, m+6);
m += 8;
dataout_n += sprintf(dataout_p+dataout_n, "%-6s ",
cid_datatype_names[CID_DATA_PHONE]);
unsigned int cid_datalen = cid_msglen - 8;
if ( cid_datalen == 10 )
dataout_n += sprintf(dataout_p+dataout_n, "%.3s-%.3s-%.4s\n",
m+0, m+3, m+6);
else
dataout_n += sprintf(dataout_p+dataout_n, "%.*s\n",
cid_datalen, m);
return dataout_n;
}
static unsigned int
decode_cid_reset()
{
cid_msgtype = 0;
cid_ndata = 0;
return 0;
}
// FIXME: doesn't respect dataout_size at all!
/* returns nbytes decoded */
unsigned int
databits_decode_callerid( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits )
{
if ( ! dataout_p ) // databits processor reset
return decode_cid_reset();
if ( cid_msgtype == 0 ) {
if ( bits == CID_MSG_MDMF )
cid_msgtype = CID_MSG_MDMF;
else if ( bits == CID_MSG_SDMF )
cid_msgtype = CID_MSG_SDMF;
else
return 0;
cid_buf[cid_ndata++] = bits;
return 0;
}
if ( cid_ndata >= sizeof(cid_buf) ) {
// FIXME? buffer overflow; do what here?
return decode_cid_reset();
}
cid_buf[cid_ndata++] = bits;
// Collect input bytes until we've collected as many as the message
// length byte says there will be, plus two (the message type byte
// and the checksum byte)
unsigned long long cid_msglen = cid_buf[1];
if ( cid_ndata < cid_msglen + 2)
return 0;
// Now we have a whole CID message in cid_buf[] -- decode it
// FIXME: check the checksum
unsigned int dataout_n = 0;
dataout_n += sprintf(dataout_p+dataout_n, "CALLER-ID\n");
if ( cid_msgtype == CID_MSG_MDMF )
dataout_n += decode_mdmf_callerid(dataout_p+dataout_n,
dataout_size-dataout_n);
else
dataout_n += decode_sdmf_callerid(dataout_p+dataout_n,
dataout_size-dataout_n);
// All done; reset for the next one
decode_cid_reset();
return dataout_n;
}

74
src/databits_uic.c Executable file
View File

@ -0,0 +1,74 @@
/*
* databits_uic.c
*
* Copyright (C) 2014 Marcos Vives Del Sol <socram8888@gmail.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/>.
*/
#include <stdio.h>
#include "databits.h"
#include "uic_codes.h"
/*
* UIC-751-3 Ground-train decoder
*/
unsigned int
databits_decode_uic(char *output,
unsigned long long input,
unsigned int type)
{
int written;
if (!output) {
return 0;
}
unsigned int code = (unsigned int) bit_reverse(bit_window(input, 24, 8), 8);
written = sprintf(output, "Train ID: %X%X%X%X%X%X - Message: %02X (%s)\n",
(unsigned int) bit_window(input, 0, 4),
(unsigned int) bit_window(input, 4, 4),
(unsigned int) bit_window(input, 8, 4),
(unsigned int) bit_window(input, 12, 4),
(unsigned int) bit_window(input, 16, 4),
(unsigned int) bit_window(input, 20, 4),
code,
uic_message_meaning(code, type)
);
return written;
}
unsigned int
databits_decode_uic_ground(char *output,
unsigned int outputSize,
unsigned long long input,
unsigned int inputSize)
{
return databits_decode_uic(output,
input,
UIC_TYPE_GROUNDTRAIN);
}
unsigned int
databits_decode_uic_train(char *output,
unsigned int outputSize,
unsigned long long input,
unsigned int inputSize)
{
return databits_decode_uic(output,
input,
UIC_TYPE_TRAINGROUND);
}

489
src/fsk.c
View File

@ -1,7 +1,7 @@
/*
* fsk.c
*
* Copyright (C) 2011 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
* it under the terms of the GNU General Public License as published by
@ -18,12 +18,14 @@
*/
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> // fabs, hypotf
#include <math.h> // fabsf, hypotf
#include <float.h> // FLT_EPSILON
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include "fsk.h"
@ -33,8 +35,7 @@ fsk_plan_new(
float sample_rate,
float f_mark,
float f_space,
float filter_bw,
unsigned int n_data_bits
float filter_bw
)
{
fsk_plan *fskp = malloc(sizeof(fsk_plan));
@ -44,15 +45,11 @@ fsk_plan_new(
fskp->sample_rate = sample_rate;
fskp->f_mark = f_mark;
fskp->f_space = f_space;
fskp->n_data_bits = n_data_bits;
/* 1 prev_stop + n_data_bits + 1 start + 1 stop == n_data_bits + 3 */
fskp->n_frame_bits = fskp->n_data_bits + 3;
#ifdef USE_FFT
fskp->band_width = filter_bw;
float fft_half_bw = fskp->band_width / 2.0;
float fft_half_bw = fskp->band_width / 2.0f;
fskp->fftsize = (sample_rate + fft_half_bw) / fskp->band_width;
fskp->nbands = fskp->fftsize / 2 + 1;
@ -65,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);
@ -74,6 +71,7 @@ fsk_plan_new(
// FIXME check these:
fskp->fftin = fftwf_malloc(fskp->fftsize * sizeof(float) * pa_nchannels);
bzero(fskp->fftin, (fskp->fftsize * sizeof(float) * pa_nchannels));
fskp->fftout = fftwf_malloc(fskp->nbands * sizeof(fftwf_complex) * pa_nchannels);
/* complex fftw plan, works for N channels: */
@ -118,194 +116,425 @@ band_mag( fftwf_complex * const cplx, unsigned int band, float scalar )
static void
fsk_bit_analyze( fsk_plan *fskp, float *samples, unsigned int bit_nsamples,
unsigned int *bit_outp, float *bit_strength_outp)
unsigned int *bit_outp,
float *bit_signal_mag_outp,
float *bit_noise_mag_outp
)
{
unsigned int pa_nchannels = 1; // FIXME
bzero(fskp->fftin, (fskp->fftsize * sizeof(float) * pa_nchannels));
// FIXME: Fast and loose ... don't bzero fftin, just assume its only ever
// been used for bit_nsamples so the remainder is still zeroed. Sketchy.
//
// unsigned int pa_nchannels = 1; // FIXME
// bzero(fskp->fftin, (fskp->fftsize * sizeof(float) * pa_nchannels));
memcpy(fskp->fftin, samples, bit_nsamples * sizeof(float));
float magscalar = 2.0f / (float)bit_nsamples;
#if 0
//// apodization window
//// raised cosine windows
# if 0
float a0=0.54, a1=(1.0f - a0); // Hamming window
# else
float a0=0.5, a1=0.5; // Hann window
# endif
magscalar /= a0; // true for all raised cosine windows (I think)
int i;
for ( i=0; i<bit_nsamples; i++ ) {
float zoff = 0.0; // 0.5 // FIXME which is it??
unsigned int z = bit_nsamples /* not -1 ... explain */;
float w = a0
- a1 * cosf((2.0*M_PI*((float)i+zoff)) / z);
fskp->fftin[i] *= w;
}
#endif
fftwf_execute(fskp->fftplan);
float magscalar = 1.0 / ((float)bit_nsamples/2.0);
float mag_mark = band_mag(fskp->fftout, fskp->b_mark, magscalar);
float mag_space = band_mag(fskp->fftout, fskp->b_space, magscalar);
*bit_outp = mag_mark > mag_space ? 1 : 0; // mark==1, space==0
*bit_strength_outp = fabs(mag_mark - mag_space);
debug_log( "\t%.2f %.2f %s bit=%u bit_strength=%.2f\n",
// mark==1, space==0
if ( mag_mark > mag_space ) {
*bit_outp = 1;
*bit_signal_mag_outp = mag_mark;
*bit_noise_mag_outp = mag_space;
} else {
*bit_outp = 0;
*bit_signal_mag_outp = mag_space;
*bit_noise_mag_outp = mag_mark;
}
debug_log( "\t%.2f %.2f %s bit=%u sig=%.2f noise=%.2f\n",
mag_mark, mag_space,
mag_mark > mag_space ? "mark " : " space",
*bit_outp, *bit_strength_outp);
*bit_outp, *bit_signal_mag_outp, *bit_noise_mag_outp);
}
/* returns confidence value [0.0 to 1.0] */
static void
fsk_bits_analyze( fsk_plan *fskp, float *samples, float samples_per_bit,
unsigned int *bits_outp, float *bit_strengths_outp )
{
unsigned int bit_nsamples = (float)(samples_per_bit + 0.5);
unsigned int nbits = fskp->n_data_bits;
unsigned int bits_out = 0;
int i;
for ( i=0; i<nbits; i++ ) {
unsigned int begin_databit = (float)(samples_per_bit * i + 0.5);
unsigned int bit;
debug_log("\t\tdata begin_data_bit=%u ", begin_databit);
fsk_bit_analyze(fskp, samples+begin_databit, bit_nsamples,
&bit, &bit_strengths_outp[i]);
bits_out |= bit << i;
}
*bits_outp = bits_out;
}
/* returns confidence value [0.0 to 1.0] */
/* returns confidence value [0.0 to INFINITY] */
static float
fsk_frame_analyze( fsk_plan *fskp, float *samples, float samples_per_bit,
unsigned int *bits_outp )
int n_bits, const char *expect_bits_string,
unsigned long long *bits_outp, float *ampl_outp )
{
float v = 0;
unsigned int bit_nsamples = (float)(samples_per_bit + 0.5f);
unsigned int bit_nsamples = (float)(samples_per_bit + 0.5);
unsigned int bit_values[64];
float bit_sig_mags[64];
float bit_noise_mags[64];
unsigned int bit_begin_sample;
int bitnum;
// 0123456789A
// isddddddddp i == idle bit (a.k.a. prev_stop bit)
// s == start bit
// d == data bits
// p == stop bit
// MSddddddddM <-- expected mark/space framing pattern
// various deprecated noise limiter schemes:
//#define FSK_MIN_BIT_SNR 1.4
//#define FSK_MIN_MAGNITUDE 0.10
//#define FSK_AVOID_TRANSIENTS 0.7
unsigned int begin_idlebit = 0;
unsigned int begin_startbit = (float)(samples_per_bit * 1 + 0.5);
unsigned int begin_databits = (float)(samples_per_bit * 2 + 0.5);
unsigned int begin_stopbit = (float)(samples_per_bit * (fskp->n_data_bits+2) + 0.5);
const char *expect_bits = expect_bits_string;
/*
* To optimize performance for a streaming scenario, check start bit first,
* then stop, then idle bits... we're "searching" for start, must validate
* stop, and finally we want to to collect idle's v value. After all that
* collect the n_data_bits
*/
/* pass #1 - process and check only the "required" (1/0) expect_bits */
for ( bitnum=0; bitnum<n_bits; bitnum++ ) {
if ( expect_bits[bitnum] == 'd' )
continue;
assert( expect_bits[bitnum] == '1' || expect_bits[bitnum] == '0' );
float s_str, p_str, i_str;
unsigned int bit;
bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f);
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],
&bit_noise_mags[bitnum]);
debug_log("\t\tstart ");
fsk_bit_analyze(fskp, samples+begin_startbit, bit_nsamples, &bit, &s_str);
if ( bit != 0 )
return 0.0;
v += s_str;
if ( (expect_bits[bitnum] - '0') != bit_values[bitnum] )
return 0.0; /* does not match expected; abort frame analysis. */
debug_log("\t\tstop ");
fsk_bit_analyze(fskp, samples+begin_stopbit, bit_nsamples, &bit, &p_str);
if ( bit != 1 )
return 0.0;
v += p_str;
#ifdef FSK_MIN_BIT_SNR
float bit_snr = bit_sig_mags[bitnum] / bit_noise_mags[bitnum];
if ( bit_snr < FSK_MIN_BIT_SNR )
return 0.0;
#endif
#define AVOID_TRANSIENTS 0.7
#ifdef AVOID_TRANSIENTS
# ifdef FSK_MIN_MAGNITUDE
// Performance hack: reject frame early if sig mag isn't even half
// of FSK_MIN_MAGNITUDE
if ( bit_sig_mags[bitnum] < FSK_MIN_MAGNITUDE/2.0 )
return 0.0; // too weak; abort frame analysis
# endif
}
#ifdef FSK_AVOID_TRANSIENTS
// FIXME: fsk_frame_analyze shouldn't care about start/stop bits,
// and this really is only correct for "10dd..dd1" format frames anyway:
// FIXME: this is totally defective, if the checked bits weren't
// even calculated in pass #1 (e.g. if there are no pass #1 expect bits).
/* Compare strength of stop bit and start bit, to avoid detecting
* a transient as a start bit, as often results in a single false
* character when the mark "leader" tone begins. Require that the
* diff between start bit and stop bit strength not be "large". */
if ( fabs(s_str-p_str) > (s_str * AVOID_TRANSIENTS) ) {
debug_log("avoid_transient\n");
float s_mag = bit_sig_mags[1]; // start bit
float p_mag = bit_sig_mags[n_bits-1]; // stop bit
if ( fabsf(s_mag-p_mag) > (s_mag * FSK_AVOID_TRANSIENTS) ) {
debug_log(" avoid transient\n");
return 0.0;
}
#endif
debug_log("\t\tidle ");
fsk_bit_analyze(fskp, samples+begin_idlebit, bit_nsamples, &bit, &i_str);
if ( bit != 1 )
return 0.0;
v += i_str;
/* pass #2 - process only the dontcare ('d') expect_bits */
for ( bitnum=0; bitnum<n_bits; bitnum++ ) {
if ( expect_bits[bitnum] != 'd' )
continue;
bit_begin_sample = (float)(samples_per_bit * bitnum + 0.5f);
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],
&bit_noise_mags[bitnum]);
// Analyze the actual data payload bits
float databit_strengths[32];
fsk_bits_analyze(fskp, samples+begin_databits, samples_per_bit,
bits_outp, databit_strengths);
#ifdef FSK_MIN_BIT_SNR
float bit_snr = bit_sig_mags[bitnum] / bit_noise_mags[bitnum];
if ( bit_snr < FSK_MIN_BIT_SNR )
return 0.0;
#endif
}
// compute average bit strength 'v'
int i;
for ( i=0; i<fskp->n_data_bits; i++ )
v += databit_strengths[i];
v /= (fskp->n_data_bits + 3);
#define FSK_MIN_STRENGTH 0.005
if ( v < FSK_MIN_STRENGTH )
return 0.0;
//#define CONFIDENCE_ALGO 5
#define CONFIDENCE_ALGO 6
#define CONFIDENCE_ALGO 2
float confidence;
#if ( CONFIDENCE_ALGO == 1 )
#if CONFIDENCE_ALGO == 5 || CONFIDENCE_ALGO == 6
float confidence = 0;
confidence += 1.0 - fabs(i_str - v);
confidence += 1.0 - fabs(s_str - v);
confidence += 1.0 - fabs(p_str - v);
for ( i=0; i<fskp->n_data_bits; i++ )
confidence += 1.0 - fabs(databit_strengths[i] - v);
confidence /= (fskp->n_data_bits + 3);
float total_bit_sig = 0.0, total_bit_noise = 0.0;
float avg_mark_sig = 0.0, avg_space_sig = 0.0;
unsigned int n_mark = 0, n_space = 0;
for ( bitnum=0; bitnum<n_bits; bitnum++ ) {
// Deal with floating point data type quantization noise...
// If total_bit_noise <= FLT_EPSILON, then assume it to be 0.0,
// so that we end up with snr==inf.
total_bit_sig += bit_sig_mags[bitnum];
if ( bit_noise_mags[bitnum] > FLT_EPSILON )
total_bit_noise += bit_noise_mags[bitnum];
#elif ( CONFIDENCE_ALGO == 2 )
if ( bit_values[bitnum] == 1 ) {
avg_mark_sig += bit_sig_mags[bitnum];
n_mark++;
} else {
avg_space_sig += bit_sig_mags[bitnum];
n_space++;
}
}
float confidence = 0;
confidence += i_str;
confidence += s_str;
confidence += p_str;
for ( i=0; i<fskp->n_data_bits; i++ )
confidence += databit_strengths[i];
confidence /= (fskp->n_data_bits + 3);
// Compute the "frame SNR"
float snr = total_bit_sig / total_bit_noise;
// Compute avg bit sig and noise magnitudes
float avg_bit_sig = total_bit_sig / n_bits;
// Compute separate avg bit sig for mark and space
if ( n_mark )
avg_mark_sig /= n_mark;
if ( n_space )
avg_space_sig /= n_space;
#if CONFIDENCE_ALGO == 6
// Compute average "divergence": bit_mag_divergence / other_bits_mag
float divergence = 0.0;
for ( bitnum=0; bitnum<n_bits; bitnum++ ) {
float avg_bit_sig_other;
avg_bit_sig_other = bit_values[bitnum] ? avg_mark_sig : avg_space_sig;
divergence += fabsf(bit_sig_mags[bitnum] - avg_bit_sig_other)
/ avg_bit_sig_other;
}
divergence *= 2;
divergence /= n_bits;
#endif
debug_log(" frame confidence (algo #%u) = %f\n",
CONFIDENCE_ALGO, confidence);
#ifdef FSK_DEBUG
float avg_bit_noise = total_bit_noise / n_bits;
debug_log(" divg=%.3f snr=%.3f avg{bit_sig=%.3f bit_noise=%.3f(%s)}\n",
# if CONFIDENCE_ALGO == 6
divergence,
# else
0.0,
# endif
snr, avg_bit_sig, avg_bit_noise,
avg_bit_noise == 0.0 ? "zero" : "non-zero"
);
#endif
# ifdef FSK_MIN_MAGNITUDE
if ( avg_bit_sig < FSK_MIN_MAGNITUDE )
return 0.0; // too weak; reject frame
# endif
#if CONFIDENCE_ALGO == 6
// Frame confidence is the frame ( SNR * consistency )
confidence = snr * (1.0f - divergence);
#else
// Frame confidence is the frame SNR
confidence = snr;
#endif
*ampl_outp = avg_bit_sig;
#elif CONFIDENCE_ALGO == 4
/* compute average bit strengths: v_mark and v_space */
/* compute average bit strength */
/* don't consider the stop bit -- we'll look at it next time around */
float v_mark=0.0, v_space=0.0, avg_bit_strength=0.0;
unsigned int v_mark_count=0, v_space_count=0;
for ( bitnum=0; bitnum<(n_bits-1); bitnum++ ) {
if ( bit_values[bitnum] == 1 ) {
v_mark += bit_strengths[bitnum];
v_mark_count++;
} else {
v_space += bit_strengths[bitnum];
v_space_count++;
}
avg_bit_strength += bit_strengths[bitnum];
}
if ( v_mark_count )
v_mark /= v_mark_count;
if ( v_space_count )
v_space /= v_space_count;
avg_bit_strength /= (n_bits-1);
#ifdef FSK_DEBUG
debug_log(" bit_mag ");
for ( bitnum=0; bitnum<n_bits-1; bitnum++ )
debug_log("%.2f ", bit_sig_mags[bitnum]);
debug_log("\n");
debug_log(" bit_str ");
for ( bitnum=0; bitnum<n_bits-1; bitnum++ )
debug_log("%.2f ", bit_strengths[bitnum]);
debug_log("\n");
#endif
/* determine the worst bit strength divergence */
float worst_divergence = 0;
/* nbits-1: don't consider the stop bit */
debug_log("mag_diverge ");
for ( bitnum=0; bitnum<n_bits-1; bitnum++ )
{
float normalized_bit_str;
if ( bit_values[bitnum] == 1 )
normalized_bit_str = bit_strengths[bitnum] - v_mark;
else
normalized_bit_str = bit_strengths[bitnum] - v_space;
debug_log("%.2f ", normalized_bit_str);
// float divergence = fabsf(1.0 - normalized_bit_str);
float divergence = fabsf(normalized_bit_str);
if ( worst_divergence < divergence )
worst_divergence = divergence;
}
debug_log("\n");
debug_log(" avg_str=%.6f avg_mark=%.6f avg_space=%.6f, worst_div=%.6f\n",
avg_bit_strength, v_mark, v_space, worst_divergence);
// confidence = (1.0 - worst_divergence) * avg_bit_strength;
confidence = (1.0 - worst_divergence);
if ( confidence <= 0.0 )
return 0.0;
#else /* CONFIDENCE_ALGO 3 */
/* compute average bit strength 'v' */
/* don't consider the stop bit -- we'll look at it next time around */
float v = 0.0;
for ( bitnum=0; bitnum<(n_bits-1); bitnum++ )
v += bit_strengths[bitnum];
v /= (n_bits-1);
// #define FSK_MIN_STRENGTH 0.005
# ifdef FSK_MIN_STRENGTH
if ( v < FSK_MIN_STRENGTH )
return 0.0;
# endif
float worst_divergence = 0;
/* nbits-1: don't consider the stop bit */
for ( bitnum=0; bitnum<n_bits-1; bitnum++ )
{
float normalized_bit_str = bit_strengths[bitnum] / v;
float divergence = fabsf(1.0 - normalized_bit_str);
if ( worst_divergence < divergence )
worst_divergence = divergence;
}
confidence = 1.0 - worst_divergence;
if ( confidence <= 0.0 )
return 0.0;
#endif /* CONFIDENCE_ALGO */
// least significant bit first ... reverse the bits as we place them
// into the bits_outp word.
*bits_outp = 0;
for ( bitnum=0; bitnum<n_bits; bitnum++ )
*bits_outp |= (unsigned long long) bit_values[bitnum] << bitnum;
debug_log(" frame algo=%d confidence=%f ampl=%f\n",
CONFIDENCE_ALGO, confidence, *ampl_outp);
return confidence;
}
/* returns confidence value [0.0 to 1.0] */
float
fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples,
unsigned int try_first_sample,
unsigned int try_max_nsamples,
unsigned int try_step_nsamples,
unsigned int *bits_outp,
float try_confidence_search_limit,
const char *expect_bits_string,
unsigned long long *bits_outp,
float *ampl_outp,
unsigned int *frame_start_outp
)
{
float samples_per_bit = (float)frame_nsamples / fskp->n_frame_bits;
int expect_n_bits = strlen(expect_bits_string);
float samples_per_bit = (float)frame_nsamples / expect_n_bits;
// try_step_nsamples = 1; // pedantic TEST
unsigned int t;
unsigned int best_t = 0;
float best_c = 0.0;
unsigned int best_bits = 0;
for ( t=0; t<(try_max_nsamples+try_step_nsamples); t+=try_step_nsamples )
float best_c = 0.0, best_a = 0.0;
unsigned long long best_bits = 0;
// Scan the frame positions starting with the one try_first_sample,
// alternating between a step above that, a step below that, above, below,
// and so on, until we've scanned the whole try_max_nsamples range.
int j;
for ( j=0; ; j++ )
{
float c;
unsigned int bits_out = 0;
debug_log("try fsk_frame_analyze(skip=%+d)\n", t);
c = fsk_frame_analyze(fskp, samples+t, samples_per_bit, &bits_out);
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 = 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,
expect_n_bits, expect_bits_string,
&bits_out, &ampl_out);
if ( best_c < c ) {
best_t = t;
best_c = c;
best_a = ampl_out;
best_bits = bits_out;
// If we find a frame with confidence > try_confidence_search_limit
// quit searching.
if ( best_c >= try_confidence_search_limit )
break;
}
}
*bits_outp = best_bits;
*ampl_outp = best_a;
*frame_start_outp = best_t;
float confidence = best_c;
debug_log("FSK_FRAME datum='%c' (0x%02x) c=%f t=%d\n",
isprint(best_bits)||isspace(best_bits) ? best_bits : '.',
best_bits,
confidence, best_t);
if ( confidence == 0 )
return 0;
#ifdef FSK_DEBUG
unsigned char bitchar;
// FIXME? hardcoded chop off framing bits for debug
// Hmmm... we have now way to distinguish between:
// 8-bit data with no start/stopbits == 8 bits
// 5-bit with prevstop+start+stop == 8 bits
switch ( expect_n_bits ) {
case 11: bitchar = ( *bits_outp >> 2 ) & 0xFF;
break;
case 8:
default:
bitchar = *bits_outp & 0xFF;
break;
}
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=%u\n",
isprint(bitchar)||isspace(bitchar) ? bitchar : '.',
bitchar,
confidence, best_a, best_t);
#endif
return confidence;
}
#include <assert.h> // FIXME
// #define FSK_AUTODETECT_MIN_FREQ 600
// #define FSK_AUTODETECT_MAX_FREQ 5000
@ -319,7 +548,7 @@ fsk_detect_carrier(fsk_plan *fskp, float *samples, unsigned int nsamples,
bzero(fskp->fftin, (fskp->fftsize * sizeof(float) * pa_nchannels));
memcpy(fskp->fftin, samples, nsamples * sizeof(float));
fftwf_execute(fskp->fftplan);
float magscalar = 1.0 / ((float)nsamples/2.0);
float magscalar = 1.0f / ((float)nsamples/2.0f);
float max_mag = 0.0;
int max_mag_band = -1;
int i = 1; /* start detection at the first non-DC band */

View File

@ -1,7 +1,7 @@
/*
* fsk.h
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -32,9 +32,7 @@ struct fsk_plan {
float f_mark;
float f_space;
float filter_bw;
unsigned int n_data_bits;
unsigned int n_frame_bits;
#ifdef USE_FFT
int fftsize;
unsigned int nbands;
@ -53,8 +51,7 @@ fsk_plan_new(
float sample_rate,
float f_mark,
float f_space,
float filter_bw,
unsigned int n_data_bits
float filter_bw
);
void
@ -63,9 +60,13 @@ fsk_plan_destroy( fsk_plan *fskp );
/* returns confidence value [0.0 to 1.0] */
float
fsk_find_frame( fsk_plan *fskp, float *samples, unsigned int frame_nsamples,
unsigned int try_first_sample,
unsigned int try_max_nsamples,
unsigned int try_step_nsamples,
unsigned int *bits_outp,
float try_confidence_search_limit,
const char *expect_bits_string,
unsigned long long *bits_outp,
float *ampl_outp,
unsigned int *frame_start_outp
);
@ -78,7 +79,7 @@ fsk_set_tones_by_bandshift( fsk_plan *fskp, unsigned int b_mark, int b_shift );
// FIXME move this?:
//#define FSK_DEBUG
// #define FSK_DEBUG
#ifdef FSK_DEBUG
# define debug_log(format, args...) fprintf(stderr, format, ## args)
#else

View File

@ -1,112 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH MINIMODEM 1 "June 22, 2011"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
minimodem \- software audio Bell-type or RTTY FSK modem
.SH SYNOPSIS
.B minimodem --tx
.RI [ options ]
.I {baudmode}
.br
.B minimodem --rx
.RI [ options ]
.I {baudmode}
.SH DESCRIPTION
.B minimodem
is a command-line program which generates (or decodes) audio modem tones,
emulating an old Bell-type or radio-teletype FSK modem.
The tones can be played to (or recorded from) the PulseAudio system
or to an audio file.
.PP
.B 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.
.SH "TX/RX MODE"
.TP
.B \-t, \-\-tx, \-\-transmit, \-\-write
transmit mode: generate audio tones
.TP
.B \-r, \-\-rx, \-\-receive, \-\-read
receive mode: decode audio tones
.SH OPTIONS
.TP
.B \-8, \-\-ascii
ASCII 8\-N\-1
.TP
.B \-5, \-\-baudot
Baudot 5\-N\-1.5
.TP
.B \-f, \-\-file filename.wav
encode or decode an audio file (extension sets audio format)
.TP
.B \-b, \-\-bandwidth {rx_bandwidth}
.TP
.B \-M, \-\-mark {mark_freq}
.TP
.B \-S, \-\-space {space_freq}
.TP
.B \-T, \-\-txstopbits {m.n}
.TP
.B \-V, \-\-version
print program version
.SH {baudmode}
The required \fI{baudmode}\fR parameter may be any floating-point value to
specify a baud rate, or the string "rtty".
The \fI{baudmode}\fR also implies certain other parameter defaults
depending on the rate.
.TP
.B 1200
: Bell202 1200 bps \-\-ascii
.TP
.B 300
: Bell103 300 bps \-\-ascii (auto-rx-carrier)
.TP
.B N>=100
: Bellxxx N bps \-\-ascii
.TP
.B N<100
: RTTY N bps \-\-baudot
.TP
.B rtty
: RTTY 45.45 bps \-\-baudot
.SH EXAMPLES
.TP
.B minimodem --tx 100
Transmit 100 baud tones from one computer ...
.TP
.B minimodem --rx 100
and receive 100 baud tones on another nearby computer.
.TP
.B minimodem --rx rtty
Decode amateur radio RTTY signals (listen near 14.085 MHz).
.SH NOTES
.B minimodem
does not decode AX.25 framed packets.
.PP
.B minimodem
does not support modem control ("AT") commands, nor does it produce
DTMF telephone dialing tones.
.SH AUTHOR
.B minimodem
was written by Kamal Mostafa <kamal@whence.com>.
.SH COPYRIGHT
Copyright \(co 2011 by Kamal Mostafa <kamal@whence.com>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

246
src/minimodem.1.in Normal file
View File

@ -0,0 +1,246 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH MINIMODEM 1 "June 10, 2013"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
minimodem \- general-purpose software audio FSK modem
.SH SYNOPSIS
.B minimodem --tx
.RI [ options ]
.I {baudmode}
.br
.B minimodem --rx
.RI [ options ]
.I {baudmode}
.SH DESCRIPTION
.B Minimodem
is a command-line program which decodes (or generates) audio
modem tones at any specified baud rate, using various framing protocols.
It acts a general-purpose software FSK modem, and includes support for
various standard FSK protocols such as Bell103, Bell202, RTTY, TTY/TDD,
NOAA SAME, and Caller-ID.
.PP
.B Minimodem
can play and capture audio modem tones in real-time via the system
audio device, or in batched mode via audio files.
.PP
.B 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.
.SH "TX/RX MODE"
.TP
.B \-t, \-\-tx, \-\-transmit, \-\-write
transmit mode: generate audio tones
.TP
.B \-r, \-\-rx, \-\-receive, \-\-read
receive mode: decode audio tones
.SH {baudmode}
The required \fI{baudmode}\fR parameter may be any floating-point value to
specify a baud rate, or any of the special keywords listed below.
The \fI{baudmode}\fR also implies certain other parameter defaults
depending on the rate, including standard (or at least reasonable)
default mark and space tone frequencies.
.TP
.B {any floating point value N}
: Bell202-style at N bps \-\-ascii
.TP
.B 1200
: Bell202 1200 bps \-\-ascii
.TP
.B 300
: Bell103 300 bps \-\-ascii
.TP
.B rtty
: RTTY 45.45 bps \-\-baudot \-\-stopbits 1.5
.TP
.B tdd
: TTY/TDD 45.45 bps \-\-baudot \-\-stopbits 2.0
.TP
.B same
: SAME 520.83 bps \-\-startbits 0 \-\-stopbits 0 \-\-sync-byte 0xAB
.br
NOAA Specific Area Message Encoding (SAME) protocol
.TP
.B callerid
: Bell202 1200 bps Caller-ID (MDMF or SDMF) protocol
.TP
.B uic-train
: UIC-751-3 600 bps train-to-ground message protocol
.TP
.B uic-ground
: UIC-751-3 600 bps ground-to-train message protocol
.SH OPTIONS
.TP
.B \-a, \-\-auto-carrier
Automatically detect mark and space frequences from carrier.
.TP
.B \-i, \-\-inverted
Invert the mark and space frequencies (applies whether the
frequencies are defaults, discovered by \-\-auto-carrier,
or specified manually).
.TP
.B \-c, \-\-confidence min-confidence-threshold
Set receive confidence minimum threshold (default 1.5).
The "confidence" value is a metric based primarily on
the SNR (signal-to-noise ratio) of the received signal.
This value acts as an FSK decoder "squelch" control.
Increase to accept only very clean signals (up to INFINITY, but
a value around 5.0 is more practical). Decrease to accept partial
decoding of noisy signals (down to a minimum value of 1.0).
(This option applies to \-\-rx mode only).
.B \-l, \-\-limit max-confidence-search-limit
Set receive confidence maximum search limit (default 2.3).
The "confidence" value is as described above.
This value acts as a performance vs. analysis quality control.
Increase (up to INFINITY) for a more pedantic analysis
and higher CPU usage. Decrease (down to the min-confidence-threshold)
for a sloppier analysis, with lower CPU usage.
(This option applies to \-\-rx mode only).
.TP
.B \-8, \-\-ascii
ASCII 8\-N\-1
.TP
.B \-5, \-\-baudot
Baudot 5\-N\-1.5
.TP
.B \-f, \-\-file filename.wav
encode or decode an audio file (extension sets audio format)
.TP
.B \-b, \-\-bandwidth {rx_bandwidth}
.TP
.B \-v, \-\-volume {tx_amplitude or 'E'}
Sets the generated signal amplitude (default is 1.0). As a special case
useful for testing, the value 'E' sets the amplitude to the very small value
FLT_EPSILON. (This option applies to \-\-tx mode only).
.TP
.B \-M, \-\-mark {mark_freq}
.TP
.B \-S, \-\-space {space_freq}
.TP
.B \-\-startbits {n}
Sets the number of start bits (default is 1 for most baudmodes).
.TP
.B \-\-stopbits {n.n}
Sets the number of stop bits (default is 1.0 for most baudmodes).
.TP
.B \-\-sync-byte {0xXX}
If this option is used, initial carrier acquisition will be suppressed
until after one or more consecutive data frame(s) containing this value
are received. This can be used to synchronize the stream for protocols
which include a fixed preamble byte.
(This option applies to \-\-rx mode only).
.TP
.B \-q, \-\-quiet
Do not report CARRIER / NOCARRIER or signal analysis metrics.
.TP
.B \-R, \-\-samplerate {rate}
Set the audio sample rate (default rate is 48000 Hz).
.TP
.B \-A, \-\-alsa[={plughw:X,Y | X,Y | X }]
Use ALSA as the audio output system instead of the default
PulseAudio (depending on build configuration options). The ALSA
device alias "default" is used, if a specific device is not specified.
For example, the following options all select ALSA device #1, sub-device #0:
\-\-alsa=plughw:1,0 \-\-alsa=1,0 \-A1
.TP
.B \-\-lut={tx_sin_table_len}
Minimodem uses a precomputed sine wave lookup table of 1024 elements,
or the size specified here. Use \-\-lut=0 to disable the use of
the sine wave lookup table. (This option applies to \-\-tx mode only).
.TP
.B \-\-float-samples
Generate 32-bit floating-point format audio samples, instead of the
default 16-bit signed integer format (applies to \-\-tx mode only;
\-\-rx mode always uses 32-bit floating-point).
.TP
.B \-\-rx-one
Quit after the first carrier/no-carrier event (applies to \-\-rx mode only).
.TP
.B \-\-binary-output
Print received data bits as raw binary output using characters '0' and '1'.
The bits are printed in the order they are received. Framing bits (start
and stop bits) are omitted from the output.
(This option applies to \-\-rx mode only).
.TP
.B \-\-binary-raw {nbits}
Print all received bits (data bits and any framing bits) as raw binary output
using characters '0' and '1'. Framing bits are not interpreted, but simply
passed through to the output. The bits are printed in the order they are
received, in lines {nbits} wide. So in order to display a standard 8-N-1
bitstream (8 databits + 1 start bit + 1 stop bit), use "--binary-raw 10"
or a multiple of 10.
(This option applies to \-\-rx mode only).
.TP
.B \-\-print-filter
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.
.TP
.B \-\-benchmarks
Run and report internal performance tests (all other flags are ignored).
.TP
.B \-V, \-\-version
print program version
.SH EXAMPLES
.TP
.B minimodem --tx 100
Transmit 100 baud tones from one computer ...
.TP
.B minimodem --rx 100
and receive 100 baud tones on another nearby computer.
.TP
.B minimodem --rx -a rtty
Decode amateur radio RTTY signals (listen near 14.085 MHz).
.TP
.B minimodem --rx same
Decode NOAA SAME protocol emergency alert transmissions, e.g.
.br
<http://en.wikipedia.org/wiki/Specific_Area_Message_Encoding>.
.TP
.B minimodem --tx 0.5
Experiment with very low baud rates (works in noisy conditions).
.TP
.B minimodem --tx 12000
Experiment with very high baud rates (works with audio files).
.SH NOTES
.B minimodem
does not decode AX.25 framed packets.
.PP
.B minimodem
does not support modem control ("AT") commands, nor does it produce
DTMF telephone dialing tones.
.SH VERSION
This page documents
.B minimodem
version @PACKAGE_VERSION@.
The latest version is available at <http://www.whence.com/minimodem>.
.SH AUTHOR
.B minimodem
was written by Kamal Mostafa <kamal@whence.com>.
.SH COPYRIGHT
Copyright \(co 2011-2016 by Kamal Mostafa <kamal@whence.com>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

File diff suppressed because it is too large Load Diff

9
src/run-test Executable file → Normal file
View File

@ -2,12 +2,13 @@
#
# run-test
#
# Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
# Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com>
#
# NO LICENSE HAS BEEN SPECIFIED OR GRANTED FOR THIS WORK.
#
#
MINIMODEM="${MINIMODEM-./minimodem}"
TMPDIR=/tmp/run-test-$$
mkdir "$TMPDIR" || exit
@ -26,8 +27,10 @@ do
txtnum="${i##*/}"
txtnum="${txtnum%%-*}"
echo TEST ./minimodem -f "$i" "$rate"
./minimodem -f "$i" "$rate" >$TMPDIR/out 2>$TMPDIR/err
unset flags
[ $rate = rtty ] || [ $rate -le 300 ] && flags="--auto-carrier"
echo TEST $MINIMODEM $flags -f "$i" "$rate"
$MINIMODEM $flags -f "$i" "$rate" >$TMPDIR/out 2>$TMPDIR/err
t="${f%%-*}"

View File

@ -1,17 +0,0 @@
#!/bin/bash
[ $# -eq 2 ] || {
echo "usage: self-test baudmode textfile" 1>&2
exit 1
}
baudmode="$1"
textfile="$2"
TMPF="/tmp/minimodem-test-$$.wav"
trap "rm -f $TMPF" 0
set -e
./minimodem --tx --file $TMPF "$baudmode" < "$textfile"
# ls -l $TMPF
./minimodem --rx --file $TMPF "$baudmode" | diff "$textfile" -

View File

@ -1,7 +1,7 @@
/*
* simple-tone-generator.c
*
* Copyright (C) 2011 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
* it under the terms of the GNU General Public License as published by
@ -20,12 +20,80 @@
#include <math.h>
#include <strings.h>
#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "simpleaudio.h"
static float tone_mag = 1.0;
static unsigned int sin_table_len;
static short *sin_table_short;
static float *sin_table_float;
void
simpleaudio_tone_init( unsigned int new_sin_table_len, float mag )
{
sin_table_len = new_sin_table_len;
tone_mag = mag;
if ( sin_table_len != 0 ) {
sin_table_short = realloc(sin_table_short, sin_table_len * sizeof(short));
sin_table_float = realloc(sin_table_float, sin_table_len * sizeof(float));
if ( !sin_table_short || !sin_table_float ) {
perror("malloc");
assert(0);
}
unsigned int i;
unsigned short mag_s = 32767.0f * tone_mag + 0.5f;
if ( tone_mag > 1.0f ) // clamp to 1.0 to avoid overflow
mag_s = 32767;
if ( mag_s < 1 ) // "short epsilon"
mag_s = 1;
for ( i=0; i<sin_table_len; i++ )
sin_table_short[i] = lroundf( mag_s * sinf((float)M_PI*2*i/sin_table_len) );
for ( i=0; i<sin_table_len; i++ )
sin_table_float[i] = tone_mag * sinf((float)M_PI*2*i/sin_table_len);
} else {
if ( sin_table_short ) {
free(sin_table_short);
sin_table_short = NULL;
}
if ( sin_table_float ) {
free(sin_table_float);
sin_table_float = NULL;
}
}
}
/*
* in: turns (0.0 to 1.0) out: (-32767 to +32767)
*/
static inline short
sin_lu_short( float turns )
{
int t = (float)sin_table_len * turns + 0.5f;
t %= sin_table_len;
return sin_table_short[t];
}
/*
* in: turns (0.0 to 1.0) out: -1.0 to +1.0
*/
static inline float
sin_lu_float( float turns )
{
int t = (float)sin_table_len * turns + 0.5f;
t %= sin_table_len;
return sin_table_float[t];
}
/* "current" phase state of the tone generator */
static float sa_tone_cphase = 0.0;
@ -38,23 +106,65 @@ simpleaudio_tone_reset()
void
simpleaudio_tone(simpleaudio *sa_out, float tone_freq, size_t nsamples_dur)
{
float *buf = malloc(nsamples_dur * sizeof(float));
unsigned int framesize = simpleaudio_get_framesize(sa_out);
void *buf = malloc(nsamples_dur * framesize);
assert(buf);
if ( tone_freq != 0 ) {
float wave_nsamples = 48000.0 / tone_freq; // FIXME rate
float wave_nsamples = simpleaudio_get_rate(sa_out) / tone_freq;
size_t i;
for ( i=0; i<nsamples_dur; i++ )
buf[i] = sinf( M_PI*2.0*( i/wave_nsamples + sa_tone_cphase) );
#define TURNS_TO_RADIANS(t) ( (float)M_PI*2 * (t) )
#define SINE_PHASE_TURNS ( (float)i/wave_nsamples + sa_tone_cphase )
#define SINE_PHASE_RADIANS TURNS_TO_RADIANS(SINE_PHASE_TURNS)
switch ( simpleaudio_get_format(sa_out) ) {
case SA_SAMPLE_FORMAT_FLOAT:
{
float *float_buf = buf;
if ( sin_table_float ) {
for ( i=0; i<nsamples_dur; i++ )
float_buf[i] = sin_lu_float(SINE_PHASE_TURNS);
} else {
for ( i=0; i<nsamples_dur; i++ )
float_buf[i] = tone_mag * sinf(SINE_PHASE_RADIANS);
}
}
break;
case SA_SAMPLE_FORMAT_S16:
{
short *short_buf = buf;
if ( sin_table_short ) {
for ( i=0; i<nsamples_dur; i++ )
short_buf[i] = sin_lu_short(SINE_PHASE_TURNS);
} else {
unsigned short mag_s = 32767.0f * tone_mag + 0.5f;
if ( tone_mag > 1.0f ) // clamp to 1.0 to avoid overflow
mag_s = 32767;
if ( mag_s < 1 ) // "short epsilon"
mag_s = 1;
for ( i=0; i<nsamples_dur; i++ )
short_buf[i] = lroundf( mag_s * sinf(SINE_PHASE_RADIANS) );
}
break;
}
default:
assert(0);
break;
}
sa_tone_cphase
= fmodf(sa_tone_cphase + (float)nsamples_dur/wave_nsamples, 1.0);
} else {
bzero(buf, nsamples_dur*sizeof(float));
bzero(buf, nsamples_dur * framesize);
sa_tone_cphase = 0.0;
}

199
src/simpleaudio-alsa.c Normal file
View File

@ -0,0 +1,199 @@
/*
* simpleaudio-alsa.c
*
* Copyright (C) 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if USE_ALSA
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <alsa/asoundlib.h>
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
/*
* ALSA backend for simpleaudio
*/
static ssize_t
sa_alsa_read( simpleaudio *sa, void *buf, size_t nframes )
{
ssize_t frames_read = 0;
snd_pcm_t *pcm = (snd_pcm_t *)sa->backend_handle;
while ( frames_read < nframes ) {
ssize_t r;
void * data = buf+frames_read*sa->backend_framesize;
ssize_t count = nframes-frames_read;
r = snd_pcm_readi(pcm, data, count);
if ( r >= 0 ) {
frames_read += r;
if ( r != count )
fprintf(stderr, "#short+%zd#\n", r);
continue;
}
if (r == -EPIPE) { // Underrun
fprintf(stderr, "#");
snd_pcm_prepare(pcm);
} else {
fprintf(stderr, "snd_pcm_readi: %s\n", snd_strerror(r));
if (r == -EAGAIN || r== -ESTRPIPE)
snd_pcm_wait(pcm, 1000);
else
return r;
}
}
// fprintf(stderr,("[%zd]\n"), frames_read);
return frames_read;
}
static ssize_t
sa_alsa_write( simpleaudio *sa, void *buf, size_t nframes )
{
ssize_t frames_written = 0;
snd_pcm_t *pcm = (snd_pcm_t *)sa->backend_handle;
while ( frames_written < nframes ) {
ssize_t r;
r = snd_pcm_writei(pcm, buf+frames_written*sa->backend_framesize, nframes-frames_written);
if (r < 0) {
/* recover from e.g. underruns, and try once more */
snd_pcm_recover(pcm, r, 0 /*silent*/);
r = snd_pcm_writei(pcm, buf+frames_written*sa->backend_framesize, nframes-frames_written);
}
if (r < 0) {
fprintf(stderr, "E: %s\n", snd_strerror(frames_written));
return -1;
}
frames_written += r;
}
assert (frames_written == nframes);
return frames_written;
}
static void
sa_alsa_close( simpleaudio *sa )
{
snd_pcm_drain(sa->backend_handle);
snd_pcm_close(sa->backend_handle);
}
static int
sa_alsa_open_stream(
simpleaudio *sa,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name )
{
snd_pcm_t *pcm;
int error;
char *be_device;
if ( ! backend_device ) {
be_device = "default";
} else {
be_device = alloca(32);
if ( strchr(backend_device, ':') )
snprintf(be_device, 32, "%s", backend_device);
else if ( strchr(backend_device, ',') )
snprintf(be_device, 32, "plughw:%s", backend_device);
else
snprintf(be_device, 32, "plughw:%s,0", backend_device);
}
error = snd_pcm_open(&pcm,
be_device,
sa_stream_direction == SA_STREAM_RECORD ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
0 /*mode*/);
if (error) {
fprintf(stderr, "E: Cannot create ALSA stream: %s\n", snd_strerror(error));
return 0;
}
snd_pcm_format_t pcm_format;
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_FLOAT:
pcm_format = SND_PCM_FORMAT_FLOAT;
break;
case SA_SAMPLE_FORMAT_S16:
pcm_format = SND_PCM_FORMAT_S16;
break;
default:
assert(0);
}
/* set up ALSA hardware params */
error = snd_pcm_set_params(pcm,
pcm_format,
SND_PCM_ACCESS_RW_INTERLEAVED,
channels,
rate,
1 /* soft_resample (allow) */,
100000 /* latency (us) */);
if (error) {
fprintf(stderr, "E: %s\n", snd_strerror(error));
snd_pcm_close(pcm);
return 0;
}
#if 0
snd_pcm_sw_params_t *swparams;
snd_pcm_sw_params_alloca(&swparams);
error = snd_pcm_sw_params_current(pcm, swparams);
if (error) {
fprintf(stderr, "E: %s\n", snd_strerror(error));
snd_pcm_close(pcm);
return NULL;
}
snd_pcm_sw_params_set_start_threshold(pcm, swparams, NFRAMES_VAL);
snd_pcm_sw_params_set_stop_threshold(pcm, swparams, NFRAMES_VAL);
snd_pcm_sw_params_set_silence_threshold(pcm, swparams, NFRAMES_VAL);
error = snd_pcm_sw_params(pcm, swparams);
if (error) {
fprintf(stderr, "E: %s\n", snd_strerror(error));
snd_pcm_close(pcm);
return NULL;
}
#endif
sa->backend_handle = pcm;
sa->backend_framesize = sa->channels * sa->samplesize;
return 1;
}
const struct simpleaudio_backend simpleaudio_backend_alsa = {
sa_alsa_open_stream,
sa_alsa_read,
sa_alsa_write,
sa_alsa_close,
};
#endif /* USE_ALSA */

117
src/simpleaudio-benchmark.c Normal file
View File

@ -0,0 +1,117 @@
/*
* simpleaudio-benchmark.c
*
* 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if USE_BENCHMARKS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/time.h>
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
/*
* benchmark backend for simpleaudio
*/
struct benchmark_data {
struct timeval tv_start;
unsigned long long total_nframes;
};
static ssize_t
sa_benchmark_dummy_readwrite( simpleaudio *sa, void *buf, size_t nframes )
{
struct benchmark_data *d = sa->backend_handle;
d->total_nframes += nframes;
return nframes;
}
static void
sa_benchmark_close( simpleaudio *sa )
{
struct timeval tv_stop;
gettimeofday(&tv_stop, NULL);
struct benchmark_data *d = sa->backend_handle;
unsigned long long runtime_usec, playtime_usec;
runtime_usec = (tv_stop.tv_sec - d->tv_start.tv_sec) * 1000000;
runtime_usec += tv_stop.tv_usec;
runtime_usec -= d->tv_start.tv_usec;
playtime_usec = d->total_nframes * 1000000 / sa->rate;
unsigned long long performance = d->total_nframes * 1000000 / runtime_usec;
fprintf(stdout, " frames count: \t%llu\n", d->total_nframes);
fprintf(stdout, " audio playtime: \t%2llu.%06llu sec\n",
playtime_usec/1000000, playtime_usec%1000000);
fprintf(stdout, " elapsed runtime: \t%2llu.%06llu sec\n",
runtime_usec/1000000, runtime_usec%1000000);
fprintf(stdout, " performance: \t%llu samples/sec\n",
performance);
fflush(stdout);
free(sa->backend_handle);
}
static int
sa_benchmark_open_stream(
simpleaudio *sa,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name )
{
struct benchmark_data *d = calloc(1, sizeof(struct benchmark_data));
if ( !d ) {
perror("malloc");
return 0;
}
sa->backend_handle = d;
sa->backend_framesize = sa->channels * sa->samplesize;
fprintf(stdout, " %s\n", stream_name);
fflush(stdout);
gettimeofday(&d->tv_start, NULL);
return 1;
}
const struct simpleaudio_backend simpleaudio_backend_benchmark = {
sa_benchmark_open_stream,
sa_benchmark_dummy_readwrite /* read */,
sa_benchmark_dummy_readwrite /* write */,
sa_benchmark_close,
};
#endif /* USE_BENCHMARKS */

View File

@ -1,7 +1,7 @@
/*
* simpleaudio-pulse.c
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -17,9 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if USE_PULSEAUDIO
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <assert.h>
#include <pulse/simple.h>
@ -36,7 +41,7 @@
static ssize_t
sa_pulse_read( simpleaudio *sa, float *buf, size_t nframes )
sa_pulse_read( simpleaudio *sa, void *buf, size_t nframes )
{
int error;
pa_simple *s = (pa_simple *)sa->backend_handle;
@ -52,7 +57,7 @@ sa_pulse_read( simpleaudio *sa, float *buf, size_t nframes )
static ssize_t
sa_pulse_write( simpleaudio *sa, float *buf, size_t nframes )
sa_pulse_write( simpleaudio *sa, void *buf, size_t nframes )
{
int error;
pa_simple *s = (pa_simple *)sa->backend_handle;
@ -70,20 +75,17 @@ sa_pulse_write( simpleaudio *sa, float *buf, size_t nframes )
static void
sa_pulse_close( simpleaudio *sa )
{
pa_simple_drain(sa->backend_handle, NULL);
pa_simple_free(sa->backend_handle);
}
static const struct simpleaudio_backend simpleaudio_backend_pulse = {
sa_pulse_read,
sa_pulse_write,
sa_pulse_close,
};
simpleaudio *
simpleaudio_open_stream_pulseaudio(
// unsigned int rate, unsigned int channels,
int sa_stream_direction,
static int
sa_pulse_open_stream(
simpleaudio *sa,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name )
{
int error;
@ -91,40 +93,66 @@ simpleaudio_open_stream_pulseaudio(
// FIXME - use source for something
// just take the default pulseaudio source for now
pa_sample_format_t pa_format;
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_FLOAT:
pa_format = PA_SAMPLE_FLOAT32;
break;
case SA_SAMPLE_FORMAT_S16:
pa_format = PA_SAMPLE_S16LE; // FIXME: handle S16BE
break;
default:
assert(0);
}
/* The sample type to use */
pa_sample_spec ss = {
.format = PA_SAMPLE_FLOAT32,
// .rate = rate,
.rate = 48000,
// .channels = channels,
.channels = 1,
.format = pa_format,
.rate = rate,
.channels = channels,
};
pa_buffer_attr attr = {
.maxlength = (uint32_t)-1,
.tlength = (uint32_t)-1,
.prebuf = (uint32_t)-1,
.minreq = (uint32_t)-1,
.fragsize = (uint32_t)-1,
};
attr.fragsize = 0; /* set for lowest possible capture latency */
attr.tlength = 0; /* set lowest possible playback latency */
// Do not mess with attr.prebuf! Setting it =1 causes some playback (--tx)
// sessions to be wiped out by noise (I do not know why).
/* Create the playback or recording stream */
pa_simple *s;
s = pa_simple_new(NULL, app_name,
sa_stream_direction == SA_STREAM_RECORD ? PA_STREAM_RECORD : PA_STREAM_PLAYBACK,
NULL, stream_name,
&ss, NULL, NULL, &error);
&ss, NULL, &attr, &error);
if ( !s ) {
fprintf(stderr, "E: Cannot create PulseAudio stream: %s\n ", pa_strerror(error));
return NULL;
return 0;
}
simpleaudio *sa = malloc(sizeof(simpleaudio));
if ( !sa ) {
perror("malloc");
pa_simple_free(s);
return NULL;
}
/* good or bad to override these? */
sa->rate = ss.rate;
sa->channels = ss.channels;
sa->backend = &simpleaudio_backend_pulse;
sa->backend_handle = s;
sa->backend_framesize = pa_frame_size(&ss);
assert( sa->backend_framesize == ss.channels * sizeof(float) );
return sa;
return 1;
}
const struct simpleaudio_backend simpleaudio_backend_pulseaudio = {
sa_pulse_open_stream,
sa_pulse_read,
sa_pulse_write,
sa_pulse_close,
};
#endif /* USE_PULSEAUDIO */

View File

@ -1,7 +1,7 @@
/*
* simpleaudio-sndfile.c
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -17,9 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if USE_SNDFILE
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
@ -35,28 +40,59 @@
static ssize_t
sa_sndfile_read( simpleaudio *sa, float *buf, size_t nframes )
sa_sndfile_read( simpleaudio *sa, void *buf, size_t nframes )
{
SNDFILE *s = (SNDFILE *)sa->backend_handle;
int n;
if ((n = sf_readf_float(s, buf, nframes)) < 0) {
fprintf(stderr, "sf_read_float: ");
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_FLOAT:
n = sf_readf_float(s, buf, nframes);
break;
case SA_SAMPLE_FORMAT_S16:
n = sf_readf_short(s, buf, nframes);
break;
default:
assert(0);
break;
}
if ( n < 0 ) {
fprintf(stderr, "sf_read: ");
sf_perror(s);
return -1;
}
//fprintf(stderr, "sf_readf_float: nframes=%ld n=%d\n", nframes, n);
if ( sa->rxnoise != 0.0f ) {
int i;
float *fbuf = buf;
float f = sa->rxnoise * 2;
for ( i=0; i<nframes; i++ )
fbuf[i] += (rand()/RAND_MAX - 0.5f) * f;
}
// fprintf(stderr, "sf_read: nframes=%ld n=%d\n", nframes, n);
return n;
}
static ssize_t
sa_sndfile_write( simpleaudio *sa, float *buf, size_t nframes )
sa_sndfile_write( simpleaudio *sa, void *buf, size_t nframes )
{
//fprintf(stderr, "sf_writef_float: nframes=%ld\n", nframes);
// fprintf(stderr, "sf_write: nframes=%ld\n", nframes);
SNDFILE *s = (SNDFILE *)sa->backend_handle;
int n;
if ((n = sf_writef_float(s, buf, nframes)) < 0) {
fprintf(stderr, "sf_read_float: ");
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_FLOAT:
n = sf_writef_float(s, buf, nframes);
break;
case SA_SAMPLE_FORMAT_S16:
n = sf_writef_short(s, buf, nframes);
break;
default:
assert(0);
break;
}
if ( n < 0 ) {
fprintf(stderr, "sf_write: ");
sf_perror(s);
return -1;
}
@ -71,13 +107,6 @@ sa_sndfile_close( simpleaudio *sa )
}
static const struct simpleaudio_backend simpleaudio_backend_sndfile = {
sa_sndfile_read,
sa_sndfile_write,
sa_sndfile_close,
};
/* (Why) doesn't libsndfile provide an API for this?... */
static const struct sndfile_format {
unsigned int major_format;
@ -127,20 +156,38 @@ sndfile_format_from_path( const char *path )
return SF_FORMAT_WAV;
}
simpleaudio *
simpleaudio_open_stream_sndfile(
int sa_stream_direction,
char *path )
static int
sa_sndfile_open_stream(
simpleaudio *sa,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name )
{
const char *path = stream_name;
int sf_format;
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_FLOAT:
sf_format = SF_FORMAT_FLOAT;
break;
case SA_SAMPLE_FORMAT_S16:
sf_format = SF_FORMAT_PCM_16;
break;
default:
assert(0);
}
/* setting for SA_STREAM_PLAYBACK (file write) */
SF_INFO sfinfo = {
.format = 0,
.samplerate = 48000,
.channels = 1,
.format = sf_format,
.samplerate = rate,
.channels = channels,
};
if ( sa_stream_direction == SA_STREAM_PLAYBACK )
sfinfo.format = sndfile_format_from_path(path) | SF_FORMAT_PCM_16;
sfinfo.format = sndfile_format_from_path(path) | sf_format;
/* Create the recording stream */
SNDFILE *s;
@ -150,21 +197,34 @@ simpleaudio_open_stream_sndfile(
if ( !s ) {
fprintf(stderr, "%s: ", path);
sf_perror(s);
return NULL;
return 0;
}
simpleaudio *sa = malloc(sizeof(simpleaudio));
if ( !sa ) {
perror("malloc");
sf_close(s);
return NULL;
}
// 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;
sa->backend = &simpleaudio_backend_sndfile;
sa->backend_handle = s;
sa->backend_framesize = sa->channels * sizeof(float);
return sa;
sa->backend_handle = s;
sa->backend_framesize = sa->channels * sa->samplesize;
return 1;
}
const struct simpleaudio_backend simpleaudio_backend_sndfile = {
sa_sndfile_open_stream,
sa_sndfile_read,
sa_sndfile_write,
sa_sndfile_close,
};
#endif /* USE_SNDFILE */

View File

@ -1,7 +1,7 @@
/*
* simpleaudio.c
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -19,7 +19,120 @@
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
#include "malloc.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
# define USE_PULSEAUDIO 1
# define USE_ALSA 1
#endif
simpleaudio *
simpleaudio_open_stream(
sa_backend_t sa_backend,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name )
{
simpleaudio *sa = calloc(1, sizeof(simpleaudio));
if ( !sa ) {
perror("malloc");
return NULL;
}
sa->format = sa_format;
sa->rate = rate;
sa->channels = channels;
switch ( sa_format ) {
case SA_SAMPLE_FORMAT_FLOAT:
assert( sizeof(float) == 4 );
sa->samplesize = sizeof(float);
break;
case SA_SAMPLE_FORMAT_S16:
assert( sizeof(short) == 2 );
sa->samplesize = sizeof(short);
break;
default:
fprintf(stderr, "simpleaudio_open_stream: no such sa_format (%d)\n", sa_format);
goto err_out;
break;
}
switch ( sa_backend ) {
#if USE_SNDFILE
case SA_BACKEND_FILE:
sa->backend = &simpleaudio_backend_sndfile;
break;
#endif
#if USE_BENCHMARKS
case SA_BACKEND_BENCHMARK:
sa->backend = &simpleaudio_backend_benchmark;
break;
#endif
case SA_BACKEND_SYSDEFAULT:
#if USE_PULSEAUDIO
sa->backend = &simpleaudio_backend_pulseaudio;
#elif USE_ALSA
sa->backend = &simpleaudio_backend_alsa;
#else
fprintf(stderr, "simpleaudio_open_stream: no SA_BACKEND_SYSDEFAULT was configured\n");
goto err_out;
#endif
break;
#if USE_ALSA
case SA_BACKEND_ALSA:
sa->backend = &simpleaudio_backend_alsa;
break;
#endif
#if USE_PULSEAUDIO
case SA_BACKEND_PULSEAUDIO:
sa->backend = &simpleaudio_backend_pulseaudio;
break;
#endif
default:
fprintf(stderr, "simpleaudio_open_stream: no such sa_backend (%d). not configured at build?\n", sa_backend);
goto err_out;
}
int ok = sa->backend->simpleaudio_open_stream(sa,
backend_device, sa_stream_direction, sa_format,
rate, channels, app_name, stream_name);
if ( sa->channels != channels ) {
fprintf(stderr, "%s: input stream must be %u-channel (not %u)\n",
stream_name, channels, sa->channels);
simpleaudio_close(sa);
return 0;
}
if ( ok ) {
assert( sa->backend_framesize == sa->channels * sa->samplesize );
return sa;
}
err_out:
free(sa);
return NULL;
}
sa_format_t
simpleaudio_get_format( simpleaudio *sa )
{
return sa->format;
}
unsigned int
simpleaudio_get_rate( simpleaudio *sa )
@ -33,14 +146,32 @@ simpleaudio_get_channels( simpleaudio *sa )
return sa->channels;
}
unsigned int
simpleaudio_get_framesize( simpleaudio *sa )
{
return sa->backend_framesize;
}
unsigned int
simpleaudio_get_samplesize( simpleaudio *sa )
{
return sa->samplesize;
}
void
simpleaudio_set_rxnoise( simpleaudio *sa, float rxnoise_factor )
{
sa->rxnoise = rxnoise_factor;
}
ssize_t
simpleaudio_read( simpleaudio *sa, float *buf, size_t nframes )
simpleaudio_read( simpleaudio *sa, void *buf, size_t nframes )
{
return sa->backend->simpleaudio_read(sa, buf, nframes);
}
ssize_t
simpleaudio_write( simpleaudio *sa, float *buf, size_t nframes )
simpleaudio_write( simpleaudio *sa, void *buf, size_t nframes )
{
return sa->backend->simpleaudio_write(sa, buf, nframes);
}

View File

@ -1,7 +1,7 @@
/*
* simpleaudio.h
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -31,37 +31,59 @@ typedef struct simpleaudio simpleaudio;
*
*/
enum {
SA_STREAM_PLAYBACK,
SA_STREAM_RECORD,
};
/* sa_backend */
typedef enum {
SA_BACKEND_SYSDEFAULT=0,
SA_BACKEND_FILE,
SA_BACKEND_BENCHMARK,
SA_BACKEND_ALSA,
SA_BACKEND_PULSEAUDIO,
} sa_backend_t;
/* sa_stream_direction */
typedef enum {
SA_STREAM_PLAYBACK,
SA_STREAM_RECORD,
} sa_direction_t;
/* sa_stream_format */
typedef enum {
SA_SAMPLE_FORMAT_S16,
SA_SAMPLE_FORMAT_FLOAT,
} sa_format_t;
simpleaudio *
simpleaudio_open_stream_pulseaudio(
// unsigned int rate, unsigned int channels,
int sa_stream_direction,
simpleaudio_open_stream(
sa_backend_t sa_backend,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name );
simpleaudio *
simpleaudio_open_stream_sndfile(
int sa_stream_direction,
char *path );
/*
* common simpleaudio_ API routines available to any backend:
*/
unsigned int
simpleaudio_get_rate( simpleaudio *sa );
unsigned int
simpleaudio_get_channels( simpleaudio *sa );
ssize_t
simpleaudio_read( simpleaudio *sa, float *buf, size_t nframes );
unsigned int
simpleaudio_get_framesize( simpleaudio *sa );
sa_format_t
simpleaudio_get_format( simpleaudio *sa );
unsigned int
simpleaudio_get_samplesize( simpleaudio *sa );
void
simpleaudio_set_rxnoise( simpleaudio *sa, float rxnoise_factor );
ssize_t
simpleaudio_write( simpleaudio *sa, float *buf, size_t nframes );
simpleaudio_read( simpleaudio *sa, void *buf, size_t nframes );
ssize_t
simpleaudio_write( simpleaudio *sa, void *buf, size_t nframes );
void
simpleaudio_close( simpleaudio *sa );
@ -77,5 +99,7 @@ simpleaudio_tone_reset();
void
simpleaudio_tone(simpleaudio *sa_out, float tone_freq, size_t nsamples_dur);
void
simpleaudio_tone_init( unsigned int new_sin_table_len, float mag );
#endif

View File

@ -1,7 +1,7 @@
/*
* simpleaudio_internal.h
*
* Copyright (C) 2011 Kamal Mostafa <kamal@whence.com>
* 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
@ -23,30 +23,45 @@
#include "simpleaudio.h"
/*
* Backend modules must provide an "open" routine which returns a
* (simpleaudio *) to the caller.
*/
struct simpleaudio_backend;
typedef struct simpleaudio_backend simpleaudio_backend;
struct simpleaudio {
const struct simpleaudio_backend *backend;
sa_format_t format;
unsigned int rate;
unsigned int channels;
void * backend_handle;
unsigned int samplesize;
unsigned int backend_framesize;
float rxnoise; // only for the sndfile backend
};
struct simpleaudio_backend {
int /* boolean 'ok' value */
(*simpleaudio_open_stream)(
simpleaudio * sa,
const char *backend_device,
sa_direction_t sa_stream_direction,
sa_format_t sa_format,
unsigned int rate, unsigned int channels,
char *app_name, char *stream_name );
ssize_t
(*simpleaudio_read)( simpleaudio *sa, float *buf, size_t nframes );
(*simpleaudio_read)( simpleaudio *sa, void *buf, size_t nframes );
ssize_t
(*simpleaudio_write)( simpleaudio *sa, float *buf, size_t nframes );
(*simpleaudio_write)( simpleaudio *sa, void *buf, size_t nframes );
void
(*simpleaudio_close)( simpleaudio *sa );
};
extern const struct simpleaudio_backend simpleaudio_backend_benchmark;
extern const struct simpleaudio_backend simpleaudio_backend_sndfile;
extern const struct simpleaudio_backend simpleaudio_backend_alsa;
extern const struct simpleaudio_backend simpleaudio_backend_pulseaudio;
#endif

View File

@ -1,2 +0,0 @@
# use fsk.c as the sample text file
exec ./self-test 1200 fsk.c

View File

@ -1,2 +0,0 @@
# use fsk.c as the sample text file
exec ./self-test 300 fsk.c

View File

@ -1,2 +0,0 @@
# use self-test-baudot.txt as the sample text file
exec ./self-test rtty testcases/self-test-baudot.txt

68
src/uic_codes.c Executable file
View File

@ -0,0 +1,68 @@
/*
* uic_codes.c
*
* Copyright (C) 2014 Marcos Vives Del Sol <socram8888@gmail.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/>.
*/
#include <stdlib.h>
#include <assert.h>
#include "uic_codes.h"
uic_message uic_ground_to_train_messages[] = {
{ 0x00, "Test" },
{ 0x02, "Run slower" },
{ 0x03, "Extension of telegram" },
{ 0x04, "Run faster" },
{ 0x06, "Written order" },
{ 0x08, "Speech" },
{ 0x09, "Emergency stop" },
{ 0x0C, "Announcem. by loudspeaker" },
{ 0x55, "Idle" },
{ -1, NULL }
};
uic_message uic_train_to_ground_messages[] = {
{ 0x08, "Communic. desired" },
{ 0x0A, "Acknowl. of order" },
{ 0x06, "Advice" },
{ 0x00, "Test" },
{ 0x09, "Train staff wish to comm." },
{ 0x0C, "Telephone link desired" },
{ 0x03, "Extension of telegram" },
{ -1, NULL }
};
const char * uic_message_meaning(unsigned int code,
unsigned int type)
{
uic_message * messages;
if (type == UIC_TYPE_GROUNDTRAIN) {
messages = uic_ground_to_train_messages;
} else if (type == UIC_TYPE_TRAINGROUND) {
messages = uic_train_to_ground_messages;
} else {
assert(0);
}
while (messages->code != -1) {
if (messages->code == code) {
return messages->meaning;
}
messages++;
}
return "Unknown";
}

34
src/uic_codes.h Executable file
View File

@ -0,0 +1,34 @@
/*
* uic_codes.h
*
* Copyright (C) 2014 Marcos Vives Del Sol <socram8888@gmail.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/>.
*/
typedef struct {
unsigned int code;
char * meaning;
} uic_message;
enum {
UIC_TYPE_GROUNDTRAIN,
UIC_TYPE_TRAINGROUND,
};
extern uic_message uic_ground_to_train_messages[];
extern uic_message uic_train_to_ground_messages[];
const char * uic_message_meaning(unsigned int code,
unsigned int type);

1
tests/01-self-test-1200.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 1200

1
tests/02-self-test-300.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 300

2
tests/03-self-test-rtty.test Executable file
View File

@ -0,0 +1,2 @@
# use testdata-ascii-baudot.txt as the sample text file
exec ./self-test testdata-baudot.txt rtty

View File

@ -2,4 +2,4 @@
TMPF=/tmp/minimodem-test.$$
trap "rm -f $TMPF" 0
echo "KAMAL" > $TMPF
./self-test 0.5 $TMPF
./self-test $TMPF 0.5

1
tests/05-self-test-12000.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 12000

View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt --float-samples 12000

1
tests/07-self-test-no-lut.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 1200 --lut=0

1
tests/08-self-test-lut16.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 1200 --lut=16

View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt 1200 --lut=16 --float-samples

4
tests/10-verify-perfect.test Executable file
View File

@ -0,0 +1,4 @@
# test for confidence=1.00 when using exact integer multiple frequencies
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400

View File

@ -0,0 +1,2 @@
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400 --lut=0

View File

@ -0,0 +1,2 @@
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400 --lut=16

View File

@ -0,0 +1,2 @@
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400 --lut=0 --float-samples

View File

@ -0,0 +1,2 @@
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400 --lut=16 --float-samples

View File

@ -0,0 +1,2 @@
exec ./self-test -P testdata-ascii.txt \
1200 --samplerate 24000 -M 1200 -S 2400 --float-samples

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

29
tests/21-rate-slop.test Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
let rx_rate=300
let count=0
let fail=0
function try_tx_rx_rate
{
txr=$1
echo -n "$txr "
let count++
./self-test testdata-ascii.txt $txr -- $rx_rate || let fail++
}
# for adj in -8 -5 -3 -2 -1 0 +1 +2 +3 +5 +8
for adj in -8 -1 0 +1 +8
do
let tx_rate="rx_rate + adj"
try_tx_rx_rate $tx_rate
done
if [ $fail -eq 0 ]
then
echo " (all $count rate-slop tests passed)"
else
echo " ($fail/$count rate-slop tests failed)"
fi
exit $fail

27
tests/30-amplitude.test Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
flags="1200 $*"
let count=0
let fail=0
function try_tx_rx_ampl
{
a="$1"
echo -n "$a "
let count++
./self-test testdata-ascii.txt --volume $a $flags -- $flags || let fail++
}
for ampl in 3.50 1.00 0.30 0.01 " E "
do
try_tx_rx_ampl "$ampl"
done
if [ $fail -eq 0 ]
then
echo " (all $count amplitude tests passed)"
else
echo " ($fail/$count amplitude tests failed)"
fi
exit $fail

2
tests/31-amplitude-float.test Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
exec ./30-amplitude.test --float

31
tests/40-noise.test Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
flags="$*"
[ -z "$flags" ] && flags="1200"
let count=0
let fail=0
function try_tx_rx_noise
{
a="$1"
echo -n "$a "
let count++
./self-test testdata-ascii.txt \
$flags --volume 0.5 \
-- \
$flags --Xrxnoise $noise --rx-one || let fail++
}
for noise in 0.00 0.05 0.10 0.50
do
try_tx_rx_noise "$noise"
done
if [ $fail -eq 0 ]
then
echo " (all $count noise tests passed)"
else
echo " ($fail/$count noise tests failed)"
fi
exit $fail

1
tests/41-noise-purefreqs.test Executable file
View File

@ -0,0 +1 @@
exec ./40-noise.test 1200 -M 1200 -S 2400

1
tests/60-multibyte.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-multibyte.txt 1200

54
tests/70-callerid-mdmf.test Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
MINIMODEM="${MINIMODEM-./minimodem}"
[ -f "$MINIMODEM" ] || {
MINIMODEM="../src/minimodem"
[ -f "$MINIMODEM" ] || {
echo "E: cannot find minimodem in ./ or ../src/" 1>&2
exit 1
}
}
bytesfile="testdata-callerid-mdmf.bytes"
[ "$1" != "" ] && bytesfile="$1"
TMPF="/tmp/minimodem-test-$$"
trap "rm -f $TMPF.*" 0
set -e
textfile="${bytesfile%%.bytes}.txt"
minimodem_tx_args="1200 --ascii"
minimodem_rx_args="callerid"
$MINIMODEM --tx --file $TMPF.wav $minimodem_tx_args < "$bytesfile"
# cp $TMPF.wav /tmp/x.wav
$MINIMODEM --rx --file $TMPF.wav $minimodem_rx_args \
> $TMPF.out 2> $TMPF.err || {
cat $TMPF.err
exit 1
}
cmp "$textfile" $TMPF.out
{
read xlitcarrier
read xlitblankline
read xlithashes xlitnocarrier stats
stats="${stats% ###}"
} < $TMPF.err
result="OK "
exitcode=0
echo -e "$result $stats"
exit $exitcode

2
tests/71-callerid-sdmf.test Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
exec ./70-callerid-mdmf.test testdata-callerid-sdmf.bytes

1
tests/80-SAME.test Executable file
View File

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt SAME

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

@ -0,0 +1 @@
exec ./self-test testdata-ascii.txt -7 1200

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

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

27
tests/Makefile.am Normal file
View File

@ -0,0 +1,27 @@
#
# Makefile.am
#
# 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/>.
#
EXTRA_DIST = \
run-self-tests \
self-test \
*.test \
testdata-*
TESTS = @auto_find_tests@

11
tests/run-self-tests Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
for testcase in ./*.test
do
$testcase
if [ $? -eq 0 ]
then echo "PASS: $testcase"
else echo "FAIL: $testcase"
fi
done

88
tests/self-test Executable file
View File

@ -0,0 +1,88 @@
#!/bin/bash
MINIMODEM="${MINIMODEM-./minimodem}"
[ -f "$MINIMODEM" ] || {
MINIMODEM="../src/minimodem"
[ -f "$MINIMODEM" ] || {
echo "E: cannot find minimodem in ./ or ../src/" 1>&2
exit 1
}
}
test_perfect=0
[ "$1" = "-P" ] && {
test_perfect=1
shift
}
[ $# -ge 2 ] || {
echo "usage: self-test [-P] textfile minimodem_tx_args [ -- minimodem_rx_args ]" 1>&2
exit 1
}
textfile="$1"
shift
minimodem_tx_args="$1"
shift
while [ $# -gt 0 ]
do
[ "$1" = "--" ] && {
shift
break
}
minimodem_tx_args="$minimodem_tx_args $1"
shift
done
if [ $# -gt 0 ]
then
minimodem_rx_args="$*"
else
minimodem_rx_args="$minimodem_tx_args"
fi
TMPF="/tmp/minimodem-test-$$"
trap "rm -f $TMPF.*" 0
set -e
#echo
#echo "$MINIMODEM --tx ... $minimodem_tx_args"
#echo "$MINIMODEM --rx ... $minimodem_rx_args"
$MINIMODEM --tx --file $TMPF.wav $minimodem_tx_args < "$textfile"
# cp $TMPF.wav /tmp/x.wav
$MINIMODEM --rx --file $TMPF.wav $minimodem_rx_args \
> $TMPF.out 2> $TMPF.err || {
cat $TMPF.err
exit 1
}
cmp "$textfile" $TMPF.out
{
read xlitcarrier
read xlitblankline
read xlithashes xlitnocarrier stats
stats="${stats% ###}"
} < $TMPF.err
result="OK "
exitcode=0
[ $test_perfect -eq 1 ] && {
match="confidence=inf .* (rate perfect)"
if grep -q "$match" $TMPF.err
then
result="PERFECT"
else
result="IMPERFECT"
exitcode=1
fi
}
echo -e "$result $stats"
exit $exitcode

17
tests/testdata-ascii.txt Normal file
View File

@ -0,0 +1,17 @@
This is a minimodem ascii data test file.
http://www.whence.com/minimodem/
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
the quick brown fox jumps over the lazy dog
1234567890 !@#$%^&*()-=_+`~[]\;',./{}|:"<>? tab> <tab
----------------------------------------------------------------------------
"Airbus", a haiku by Kamal Mostafa <kamal@whence.com>
Aluminum tube
Three hundred twenty sardines
Earning our SkyMiles
----------------------------------------------------------------------------

View File

@ -0,0 +1,2 @@
03240902JOHN DOE
8005551212}

View File

@ -0,0 +1,4 @@
CALLER-ID
Time: 03/24 09:02
Name: JOHN DOE
Phone: 800-555-1212

View File

@ -0,0 +1 @@
093012246095551212Q

View File

@ -0,0 +1,3 @@
CALLER-ID
Time: 09/30 12:24
Phone: 609-555-1212

View File

@ -0,0 +1,4 @@
Minimodem unterstützt jetzt Deutsch!
Beachten sie, dass wörter mit multibyte-zeichen korrekt gedruckt werden.
Minimodem ahora soporta Español!
Minimodem prend désormais en Français!