romanz / amodem

Audio MODEM Communication Library in Python
Other
950 stars 118 forks source link

How to use with uv-5r #55

Open MakisChristou opened 2 years ago

MakisChristou commented 2 years ago

As the title suggests I am trying to use amodem to transfer files using a pair of uv-5rs. I have two APRS cables and two TRRS USB sound cards that I bought off Amazon. I am testing this on a single Linux machine. During the calibration process I managed to get a good signal indication with the following settings:

On the sender's side:

makis@nuc:~/.local/bin$ BITRATE=8 ./amodem send --calibrate
Audio OFDM MODEM v1.15.3: 8.0 kb/s (16-QAM x 2 carriers) Fs=8.0 kHz
b'PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4' loaded
ALSA lib pcm_dsnoop.c:638:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card

and on the receiver's side:

makis@nuc:~/.local/bin$ BITRATE=8 ./amodem recv --calibrate
Audio OFDM MODEM v1.15.3: 8.0 kb/s (16-QAM x 2 carriers) Fs=8.0 kHz
b'PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4' loaded
ALSA lib pcm_dsnoop.c:638:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
verbose: 0
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  1000 Hz: good signal         
  1000 Hz: good signal         
  1000 Hz: good signal         
  1000 Hz: good signal         
  1000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  2000 Hz: good signal         
  1000 Hz: good signal         
  1000 Hz: good signal     

But when I actually attempt to send files with the same exact settings I always get invalid check-sums.

On the receiver's side:

makis@nuc:~/.local/bin$ BITRATE=8 ./amodem recv -vv -o ~/amodem
2022-04-10 11:16:36,171 INFO       Audio OFDM MODEM v1.15.3: 8.0 kb/s (16-QAM x 2 carriers) Fs=8.0 kHz                                  __main__.py:230
2022-04-10 11:16:36,172 INFO       b'PortAudio V19.6.0-devel, revision 396fe4b6699ae929d3a685b3ef8a7e97396139a4' loaded                 audio.py:21
ALSA lib pcm_dsnoop.c:638:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2660:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_route.c:877:(find_matching_chmap) Found no matching channel map
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_oss.c:377:(_snd_pcm_oss_open) Unknown field port
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
ALSA lib pcm_usb_stream.c:486:(_snd_pcm_usb_stream_open) Invalid type for card
2022-04-10 11:16:36,190 DEBUG      AsyncReader thread started                                                                           async_reader.py:26
2022-04-10 11:16:36,190 DEBUG      Skipping 0.100 seconds                                                                               main.py:46
2022-04-10 11:16:36,815 INFO       Waiting for carrier tone: 1.0 kHz                                                                    main.py:53
2022-04-10 11:16:39,798 INFO       Carrier detected at ~2900.0 ms @ 1.0 kHz                                                             detect.py:60
2022-04-10 11:16:39,798 DEBUG      Buffered 1000 ms of audio                                                                            detect.py:63
2022-04-10 11:16:39,799 INFO       Carrier coherence: 96.556%                                                                           detect.py:94
2022-04-10 11:16:39,799 DEBUG      Carrier starts at 2899.875 ms                                                                        detect.py:73
2022-04-10 11:16:39,800 INFO       Carrier symbols amplitude : 0.387                                                                    detect.py:105
2022-04-10 11:16:39,801 INFO       Frequency error: -2259.673 ppm                                                                       detect.py:115
2022-04-10 11:16:39,801 DEBUG      Frequency correction: 2264.791 ppm                                                                   main.py:57
2022-04-10 11:16:39,801 DEBUG      Gain correction: 2.581                                                                               main.py:60
2022-04-10 11:16:39,801 DEBUG      Receiving                                                                                            recv.py:161
2022-04-10 11:16:39,814 DEBUG      Prefix OK                                                                                            recv.py:50
2022-04-10 11:16:39,828 DEBUG      Training completed                                                                                   recv.py:73
2022-04-10 11:16:39,842 DEBUG        1.0 kHz: SNR =  0.44 dB                                                                            recv.py:95
2022-04-10 11:16:39,842 DEBUG        2.0 kHz: SNR =  0.40 dB                                                                            recv.py:95
2022-04-10 11:16:39,842 ERROR      Decoding failed                                                                                      main.py:67
Traceback (most recent call last):
  File "/home/makis/.local/lib/python3.9/site-packages/amodem/main.py", line 64, in recv
    receiver.run(sampler, gain=1.0/amplitude, output=dst)
  File "/home/makis/.local/lib/python3.9/site-packages/amodem/recv.py", line 165, in run
    filt = self._train(sampler, order=10, lookahead=10)
  File "/home/makis/.local/lib/python3.9/site-packages/amodem/recv.py", line 77, in _train
    self._verify_training(equalized, train_symbols)
  File "/home/makis/.local/lib/python3.9/site-packages/amodem/recv.py", line 98, in _verify_training
    assert error_rate == 0, error_rate
AssertionError: 1.0
2022-04-10 11:16:39,916 DEBUG      AsyncReader thread stopped (read 59200 bytes)                                                        async_reader.py:31
2022-04-10 11:16:39,917 DEBUG      Finished I/O                                                                                         __main__.py:261

Can anyone point me into the right direction? Any other logs you want me to provide? I have little to no experience with signal processing so any help would be appreciated!

manotroll commented 10 months ago

Python support is still experimental I think use binaries in c

ke4ahr commented 1 month ago

You'll need to edit amodem/config.py and setup an arbritrary BITRATE answer (see below) that uses frequencies 1e3 and/or 2e3. Out of the box, the program assumes you have 0-15 kHz to play with, which is appropriate if you are using a wideband broadcast remote transmitter like a Marti RPT-25. Using 1e3 will use up 0-2 kHz, 2e3 will use 2-4 kHz, and combining the two will give you the best possible throughput for a 0-4 kHz audio path.


export BITRATE=99
pip install . 

amodem/config.py:

# MODEM configurations for various bitrates [kbps]
bitrates = {
    1: Configuration(Fs=8e3, Npoints=2, frequencies=[2e3]),
    2: Configuration(Fs=8e3, Npoints=4, frequencies=[2e3]),
    4: Configuration(Fs=8e3, Npoints=16, frequencies=[2e3]),
    8: Configuration(Fs=8e3, Npoints=16, frequencies=[1e3, 2e3]),
    12: Configuration(Fs=16e3, Npoints=16, frequencies=[3e3, 5e3]),
    16: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 5e3]),
    20: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 6e3]),
    24: Configuration(Fs=16e3, Npoints=16, frequencies=[1e3, 6e3]),
    28: Configuration(Fs=32e3, Npoints=16, frequencies=[3e3, 9e3]),
    32: Configuration(Fs=32e3, Npoints=16, frequencies=[2e3, 9e3]),
    36: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 9e3]),
    42: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 10e3]),
    48: Configuration(Fs=32e3, Npoints=64, frequencies=[3e3, 10e3]),
    54: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 10e3]),
    60: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 11e3]),
    64: Configuration(Fs=32e3, Npoints=256, frequencies=[3e3, 10e3]),
    72: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 10e3]),
    80: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 11e3]),
    97: Configuration(Fs=32e3, Npoints=256, frequencies=[1e3]),
    98: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3]),
    99: Configuration(Fs=32e3, Npoints=256, frequencies=[1e3,2e3]),
}

The audio out needs to be low-pass filtered to below 4100 Hz with a brick-wall or FIR filter. There is a notch in the output audio around that frequency. Otherwise the spectrum looks like sin (x^2/x), and harmonics all the way up. However, you need flat audio (discriminator/modulator access in the radio, no pre-emphasis or de-emphasis) to take advantage of the QAM between 0-2 kHz.

karkapur commented 1 month ago

You'll need to edit amodem/config.py and setup an arbritrary BITRATE answer (see below) that uses frequencies 1e3 and/or 2e3. Out of the box, the program assumes you have 0-15 kHz to play with, which is appropriate if you are using a wideband broadcast remote transmitter like a Marti RPT-25. Using 1e3 will use up 0-2 kHz, 2e3 will use 2-4 kHz, and combining the two will give you the best possible throughput for a 0-4 kHz audio path.


export BITRATE=99
pip install . 

amodem/config.py:

# MODEM configurations for various bitrates [kbps]
bitrates = {
    1: Configuration(Fs=8e3, Npoints=2, frequencies=[2e3]),
    2: Configuration(Fs=8e3, Npoints=4, frequencies=[2e3]),
    4: Configuration(Fs=8e3, Npoints=16, frequencies=[2e3]),
    8: Configuration(Fs=8e3, Npoints=16, frequencies=[1e3, 2e3]),
    12: Configuration(Fs=16e3, Npoints=16, frequencies=[3e3, 5e3]),
    16: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 5e3]),
    20: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 6e3]),
    24: Configuration(Fs=16e3, Npoints=16, frequencies=[1e3, 6e3]),
    28: Configuration(Fs=32e3, Npoints=16, frequencies=[3e3, 9e3]),
    32: Configuration(Fs=32e3, Npoints=16, frequencies=[2e3, 9e3]),
    36: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 9e3]),
    42: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 10e3]),
    48: Configuration(Fs=32e3, Npoints=64, frequencies=[3e3, 10e3]),
    54: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 10e3]),
    60: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 11e3]),
    64: Configuration(Fs=32e3, Npoints=256, frequencies=[3e3, 10e3]),
    72: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 10e3]),
    80: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 11e3]),
    97: Configuration(Fs=32e3, Npoints=256, frequencies=[1e3]),
    98: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3]),
    99: Configuration(Fs=32e3, Npoints=256, frequencies=[1e3,2e3]),
}

The audio out needs to be low-pass filtered to below 4100 Hz with a brick-wall or FIR filter. There is a notch in the output audio around that frequency. Otherwise the spectrum looks like sin (x^2/x), and harmonics all the way up. However, you need flat audio (discriminator/modulator access in the radio, no pre-emphasis or de-emphasis) to take advantage of the QAM between 0-2 kHz.

@ke4ahr this still doesn't solve the issue. I'm getting the following error after including your code and installing it again:

Traceback (most recent call last): File "/home/karan/voice_modem/amodem/amodem/main.py", line 64, in recv receiver.run(sampler, gain=1.0/amplitude, output=dst) File "/home/karan/voice_modem/amodem/amodem/recv.py", line 165, in run filt = self._train(sampler, order=10, lookahead=10) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/karan/voice_modem/amodem/amodem/recv.py", line 77, in _train self._verify_training(equalized, train_symbols) File "/home/karan/voice_modem/amodem/amodem/recv.py", line 98, in _verify_training assert error_rate == 0, error_rate AssertionError: 0.003