romanz / amodem

Audio MODEM Communication Library in Python
Other
965 stars 121 forks source link

Decoding failed #33

Closed jwoillez closed 6 years ago

jwoillez commented 6 years ago

Trying to use amodem with I/O redirection, I get the following timeout, with the latest checkout from trunk. I am on macOS High Sierra, with the latest stable release of portaudio. I get a similar behavior when going the audio way. Any more diagnostics I could send?

$ echo "Hello, how are you doing?" | amodem send -l /opt/local/lib/libportaudio.dylib -o data.pcm
Audio OFDM MODEM v1.14.0: 1.0 kb/s (2-QAM x 1 carriers) Fs=8.0 kHz
Sending 0.800 seconds of training audio
Starting modulation
Sent 0.026 kB @ 0.289 seconds

$ amodem recv -l /opt/local/lib/libportaudio.dylib -i data.pcm
Audio OFDM MODEM v1.14.0: 1.0 kb/s (2-QAM x 1 carriers) Fs=8.0 kHz
Waiting for carrier tone: 2.0 kHz
Carrier detected at ~150.0 ms @ 2.0 kHz
Carrier coherence: 100.000%
Carrier symbols amplitude : 1.000
Frequency error: 0.000 ppm
Starting demodulation
Decoding failed
Traceback (most recent call last):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/main.py", line 63, in recv
    receiver.run(sampler, gain=1.0/amplitude, output=dst)
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/recv.py", line 168, in run
    for frame in framing.decode_frames(bitstream):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/framing.py", line 123, in decode_frames
    for frame in framer.decode(_to_bytes(bits)):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/framing.py", line 59, in decode
    frame = _take_len(data, length)
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/framing.py", line 77, in _take_len
    chunk = bytearray(itertools.islice(data, length))
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/framing.py", line 117, in _to_bytes
    func=tuple, truncate=True):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/common.py", line 41, in iterate
    buf = list(itertools.islice(data, size))
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/recv.py", line 129, in _demodulate
    for i, block_of_bits in enumerate(stream, 1):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/common.py", line 81, in izip
    yield tuple([next(iterable) for iterable in iterables])
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/common.py", line 81, in <listcomp>
    yield tuple([next(iterable) for iterable in iterables])
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/dsp.py", line 105, in decode
    for received in symbols:
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/common.py", line 66, in icapture
    for i in iter(iterable):
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/common.py", line 57, in _gen
    for item in it:
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/dsp.py", line 33, in next
    frame = self.sampler.take(size=self.Nsym)
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/sampling.py", line 71, in _take
    self.buff[-1] = next(self.src)  # throws StopIteration
  File "/Users/jwoillez/Library/Python/3.6/lib/python/site-packages/amodem-1.14.0-py3.6.egg/amodem/stream.py", line 43, in next
    raise IOError('timeout')
OSError: timeout
Received 0.000 kB @ 2.056 seconds = 0.000 kB/s
romanz commented 6 years ago

Thanks for testing this tool on macOS and for reporting this issue :) Could you please re-run the receiver with ALSA (instead of PortAudio)?

$ amodem recv -vvv -l ALSA

It should run arecord as a subprocess, reading the raw audio via its stdout.

jwoillez commented 6 years ago

I'm not sure ALSA is available on macOS. I've tried again on a raspberry pi with Debian on it. This time the message gets through, but I still get the timeout from the receiver.

romanz commented 6 years ago

Can you run the receiver and sender in calibration mode, to see if the timeouts happen there as well?

$ amodem send -l /opt/local/lib/libportaudio.dylib -vv -c &
$ amodem recv -l /opt/local/lib/libportaudio.dylib -vv -c &

Please attach the verbose logs (they should contain DEBUG messages).

romanz commented 6 years ago

BTW, can you increase Reader.timeout from 2s to (say) 60s, to see if it improves the issue? https://github.com/romanz/amodem/blob/ac2e66bddd440ccc33c2cedac5fdcd3dc7f0c7b3/amodem/stream.py#L7

jwoillez commented 6 years ago

If I increase the Reader.timeout, I just get the same behavior, but with the timeout happening later. I however did another test, where I sent to a data.pcm on linux and received from it on the Mac. I get the same behavior as if I had done everything on Linux. It seems that on a Mac, amodem send -o data.pcm creates a corrupted data.pcm...

jwoillez commented 6 years ago

No timeouts in calibration mode. The debug output for the receiver is below:

2018-07-19 23:29:12,993 INFO       Audio OFDM MODEM v1.14.0: 1.0 kb/s (2-QAM x 1 carriers) Fs=8.0 kHz                                   __main__.py:228
2018-07-19 23:29:13,001 INFO       b'PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4' loaded                 audio.py:21
2018-07-19 23:29:13,029 DEBUG      AsyncReader thread started                                                                           async_reader.py:26
2018-07-19 23:29:13,030 INFO       verbose: 2                                                                                           calib.py:136

2018-07-19 23:29:29,204 INFO         2000 Hz: good signal         total=0.1561, rms=0.1560, coherency=0.9990, peak=0.1397               calib.py:142
2018-07-19 23:29:29,391 INFO         2000 Hz: good signal         total=0.1572, rms=0.1570, coherency=0.9989, peak=0.1397               calib.py:142
2018-07-19 23:29:29,572 INFO         2000 Hz: good signal         total=0.1575, rms=0.1573, coherency=0.9989, peak=0.1389               calib.py:142
2018-07-19 23:29:29,751 INFO         2000 Hz: good signal         total=0.1574, rms=0.1573, coherency=0.9993, peak=0.1351               calib.py:142
jwoillez commented 6 years ago

Just an update on the issue. I was trying to use the same mac laptop to send and recv with the internal speakers and mics. This must have made the audio signal bad enough to make it fail. If I plug a earpiece and place it next to the speaker, things work much better. I will probably close the issue.

romanz commented 6 years ago

Thanks for the debugging :)