kopia lustrzana https://github.com/Guenael/rtlsdr-wsprd
Porównaj commity
67 Commity
Autor | SHA1 | Data |
---|---|---|
Guenael, VA2GKA | 17502db2f3 | |
Yury Krasouski | 876f6ff57c | |
Guenael, VA2GKA | a6416c5ed6 | |
Yury Krasouski | 901e3f931d | |
Guenael, VA2GKA | f2f316ec8b | |
Guenael, VA2GKA | 748f122d22 | |
Daniele Forsi | 3b75fb4419 | |
Guenael, VA2GKA | 061e753db5 | |
Guenael | 9734f3bf82 | |
Guenael, VA2GKA | dd8737313b | |
Guenael | e35adbe200 | |
Guenael, VA2GKA | 967d29200f | |
Guenael | 8fa25cd966 | |
Guenael, VA2GKA | 1df0b5d330 | |
Guenael | 7251af415f | |
Guenael, VA2GKA | 8c989cc200 | |
Guenael, VA2GKA | 1b40437180 | |
Guenael | d3009fd8e8 | |
Guenael, VA2GKA | 7e3070a39f | |
Guenael, VA2GKA | 54076999fc | |
Guenael, VA2GKA | 6018d8bb89 | |
Guenael, VA2GKA | 6a5e843ecb | |
Daniele Forsi | 5790d02ceb | |
Guenael, VA2GKA | 692a64efad | |
Guenael, VA2GKA | 38bac46e63 | |
Daniele Forsi | 3a7cdc823c | |
Daniele Forsi | 4bfc01bba3 | |
Guenael, VA2GKA | 5d05552a0f | |
Guenael | 0b5705f0b5 | |
Guenael, VA2GKA | 5a25fad1bd | |
Guenael | 2d87d2949c | |
Guenael, VA2GKA | 1a3f36b513 | |
Guenael | f6af4e0b0b | |
Guenael, VA2GKA | 2d8d938a24 | |
Guenael | 56fd3dd178 | |
Guenael | 9410fd04c2 | |
Guenael | 8c60c0747c | |
Guenael | bc4abbcecf | |
Guenael | c38396cb5e | |
Guenael | 242d593156 | |
Guenael, VA2GKA | 94129c54a1 | |
Guenael | 296a3eb30b | |
Guenael, VA2GKA | 3d456a562d | |
Guenael | 15913219f2 | |
Guenael | 6b7521102f | |
Guenael | f2ce421e87 | |
Guenael | 73f4e8c411 | |
Guenael | df6e87068b | |
Guenael | 7dc970ee74 | |
Guenael | 92d3e34213 | |
Guenael | 474c95df29 | |
Guenael | 1a167c87bf | |
Guenael | b248ceb121 | |
Guenael, VA2GKA | e54f2c865c | |
Guenael, VA2GKA | 8246737f15 | |
Guenael, VA2GKA | 1b63e29882 | |
Daniele Forsi | 1600023c54 | |
Daniele Forsi | bf756adadf | |
Guenael, VA2GKA | 45246e636f | |
Steven Honson | c24d312d39 | |
Steven Honson | 42a83ecd4b | |
Guenael, VA2GKA | b18858076c | |
Guenael, VA2GKA | e781a940a2 | |
Steven Honson | 20c347d136 | |
Steven Honson | e1c3db4a6d | |
Guenael, VA2GKA | a441bc2fc9 | |
Steven Honson | ad3dfe5bde |
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: ''
|
||||
title: ''
|
||||
labels: 'bug'
|
||||
assignees: Guenael
|
||||
---
|
||||
|
||||
## Bug description
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
## Setup & hardware used
|
||||
- Version of `rtlsdr-wsprd` & source used (git pull or release archive for example)
|
||||
- Version of `librtlsdr` intalled (with `ls -la /usr/lib/arm-linux-gnueabihf/librtlsdr.so.0`)
|
||||
- Computer hardware (ex. RaspberryPi 3, Laptop with Intel processor, etc...)
|
||||
- OS/Distro version (ex. `Raspbian GNU/Linux 10 (buster)`, or use `cat /etc/os-release`)
|
||||
- Kernel used (with `uname -a`)
|
||||
- Reference of your RTLsdr dongle in use (& info reported by `rtlsdr-wsprd` at start)
|
||||
|
||||
## Options used
|
||||
Please provide the command line used with `rtlsdr-wsprd` and copy the first bloc that show the init. process.
|
||||
|
||||
## Samples (optionnal)
|
||||
`rtlsdr-wsprd` allows to save samples with `-w <file prefix>` option, for debugging purpose. You can open these files with an editor like Audacity and use the spectrogram to inspect your signal. Zipping and adding these files could help to solve some issues.
|
||||
|
||||
## Additional context
|
||||
Add any other context about the problem here.
|
|
@ -34,8 +34,8 @@ jobs:
|
|||
|
||||
- name: Install dependencies and build
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install build-essential cmake libfftw3-dev libusb-1.0-0-dev librtlsdr-dev libcurl4-gnutls-dev cppcheck iwyu
|
||||
sudo apt-get update
|
||||
sudo apt-get -y --no-install-recommends install build-essential cmake libfftw3-dev libusb-1.0-0-dev librtlsdr-dev libcurl4-gnutls-dev cppcheck
|
||||
make
|
||||
|
||||
- name: Perform CodeQL Analysis (SAST)
|
||||
|
@ -52,14 +52,14 @@ jobs:
|
|||
echo "===== CPPLINT ====="
|
||||
cpplint --linelength=1000 --extensions=c --headers=h --recursive * || true
|
||||
|
||||
- name: Codespell check (beacause of my spelling...)
|
||||
- name: Codespell check (because of my spelling...)
|
||||
run: |
|
||||
pip install codespell
|
||||
echo "===== CODESPELL ====="
|
||||
codespell -L 'rcall' *.c *.h wsprd/*.c wsprd/*.h
|
||||
codespell -L 'rcall' *.md *.c *.h wsprd/*.c wsprd/*.h .github/workflows/ci.yml
|
||||
|
||||
- name: Unit-Test
|
||||
run: |
|
||||
echo "===== Decoder self-test ====="
|
||||
./rtlsdr_wsprd -r ./signals/refSignalSnr0dB.iq
|
||||
./rtlsdr_wsprd -t
|
||||
./rtlsdr_wsprd -f 2m -c A1XYZ -l AB12CD -r ./signals/refSignalSnr0dB.iq
|
||||
./rtlsdr_wsprd -f 2m -c A1XYZ -l AB12CD -t
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
name: Container Images
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Calculate Container Metadata
|
||||
id: meta
|
||||
uses: crazy-max/ghaction-docker-meta@v1
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Push Images
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64, linux/386, linux/arm64, linux/arm/v6, linux/arm/v7
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
|
@ -1,6 +1,7 @@
|
|||
*.o
|
||||
*.a
|
||||
*.iq
|
||||
*.c2
|
||||
rtlsdr_wsprd
|
||||
fftw_wisdom.dat
|
||||
hashtable.txt
|
||||
|
|
24
.gitpod.yml
24
.gitpod.yml
|
@ -1,24 +0,0 @@
|
|||
|
||||
tasks:
|
||||
- init: make
|
||||
|
||||
github:
|
||||
prebuilds:
|
||||
# enable for the master/default branch (defaults to true)
|
||||
master: true
|
||||
# enable for all branches in this repo (defaults to false)
|
||||
branches: true
|
||||
# enable for pull requests coming from this repo (defaults to true)
|
||||
pullRequests: true
|
||||
# enable for pull requests coming from forks (defaults to false)
|
||||
pullRequestsFromForks: true
|
||||
# add a "Review in Gitpod" button as a comment to pull requests (defaults to true)
|
||||
addComment: false
|
||||
# add a "Review in Gitpod" button to pull requests (defaults to false)
|
||||
addBadge: false
|
||||
# add a label once the prebuild is ready to pull requests (defaults to false)
|
||||
addLabel: prebuilt-in-gitpod
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- esbenp.prettier-vscode
|
|
@ -0,0 +1,51 @@
|
|||
# -------------------
|
||||
# The build container
|
||||
# -------------------
|
||||
FROM debian:bullseye-slim AS build
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y --no-install-recommends install \
|
||||
build-essential \
|
||||
clang \
|
||||
cmake \
|
||||
libcurl4-openssl-dev \
|
||||
libfftw3-dev \
|
||||
libusb-1.0-0-dev \
|
||||
pkg-config \
|
||||
unzip && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ADD https://github.com/steve-m/librtlsdr/archive/master.zip /root/librtlsdr-master.zip
|
||||
RUN unzip /root/librtlsdr-master.zip -d /root && \
|
||||
rm /root/librtlsdr-master.zip && \
|
||||
cd /root/librtlsdr-master && \
|
||||
mkdir -p /root/librtlsdr-master/build && \
|
||||
cd /root/librtlsdr-master/build && \
|
||||
cmake -Wno-dev ../ && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf /root/librtlsdr-master
|
||||
|
||||
COPY . /root/rtlsdr-wsprd
|
||||
|
||||
RUN cd /root/rtlsdr-wsprd && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
# -------------------------
|
||||
# The application container
|
||||
# -------------------------
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get -y --no-install-recommends install \
|
||||
libcurl4 \
|
||||
libfftw3-single3 \
|
||||
usbutils && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=build /usr/local/lib/librtlsdr.so.0 /usr/local/lib/librtlsdr.so.0
|
||||
COPY --from=build /usr/local/bin/rtlsdr_wsprd /usr/local/bin/rtlsdr_wsprd
|
||||
RUN ldconfig
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/rtlsdr_wsprd"]
|
52
README.md
52
README.md
|
@ -16,7 +16,7 @@ To install and use your dongle on a Raspberry Pi with a Raspberry Pi OS, follow
|
|||
|
||||
```bash
|
||||
echo "== Install dependencies"
|
||||
sudo apt-get update && sudo apt-get -y install build-essential clang cmake libfftw3-dev libusb-1.0-0-dev libcurl4-gnutls-dev ntp git
|
||||
sudo apt-get update && sudo apt-get -y install build-essential clang cmake libfftw3-dev libusb-1.0-0-dev libcurl4-gnutls-dev help2man ntp git
|
||||
|
||||
echo "== Install rtl-sdr library (on RPi, don't use your distro package)"
|
||||
git clone https://github.com/osmocom/rtl-sdr
|
||||
|
@ -32,7 +32,7 @@ echo "== Install rtlsdr-wsprd"
|
|||
git clone https://github.com/Guenael/rtlsdr-wsprd
|
||||
cd rtlsdr-wsprd
|
||||
make
|
||||
make install
|
||||
sudo make install
|
||||
|
||||
echo "== Start/test rtlsdr-wsprd"
|
||||
rtlsdr_wsprd -f 2m -c A1XYZ -l AB12cd -g 29
|
||||
|
@ -54,9 +54,9 @@ This application written in C does:
|
|||
## Installation
|
||||
|
||||
1. Install a Linux compatible distro on your device.
|
||||
|
||||
|
||||
For Raspberry Pi, you can download official images [here](https://www.raspberrypi.com/software/operating-systems/).
|
||||
|
||||
|
||||
2. It's a good practice to update your OS. With Pi OS, run this command as usual:
|
||||
```bash
|
||||
sudo apt-get update && sudo apt-get upgrade
|
||||
|
@ -64,9 +64,9 @@ This application written in C does:
|
|||
|
||||
3. Install dependencies & useful tools (for example, [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) for time synchronization). Example with a Debian based OS, like Rasbian, or Raspberry Pi OS:
|
||||
```bash
|
||||
sudo apt-get update && sudo apt-get -y install build-essential clang cmake libfftw3-dev libusb-1.0-0-dev libcurl4-gnutls-dev ntp git
|
||||
sudo apt-get update && sudo apt-get -y install build-essential clang cmake libfftw3-dev libusb-1.0-0-dev libcurl4-gnutls-dev help2man ntp git
|
||||
```
|
||||
|
||||
|
||||
4. Install `rtl-sdr` library manually. **Do not use the `librtlsdr-dev` package on Raspberry PiOS**. There is a know bug with this lib and rtlsdr_wsprd will not be able to get enough samples (don't decode anything & 100% CPU pattern).
|
||||
```bash
|
||||
git clone https://github.com/osmocom/rtl-sdr
|
||||
|
@ -79,24 +79,43 @@ This application written in C does:
|
|||
cd ../..
|
||||
```
|
||||
Note: You may have to re-plug you dongle if it was already connected, or play with `udev` if not automatically detected.
|
||||
|
||||
|
||||
5. Clone this repository:
|
||||
```bash
|
||||
git clone https://github.com/Guenael/rtlsdr-wsprd
|
||||
```
|
||||
|
||||
|
||||
6. Build the application:
|
||||
```bash
|
||||
cd rtlsdr-wsprd
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
|
||||
7. Finally, start the application with the right parameters/options for you (frequency, callsign, locator etc... Fake example below):
|
||||
```bash
|
||||
rtlsdr_wsprd -f 2m -c A1XYZ -l AB12cd -g 29
|
||||
```
|
||||
|
||||
## Container Image
|
||||
|
||||
As an alternative to the above steps, a pre-built container image containing rtlsdr-wsprd is available for use with [Docker](https://www.docker.com/) or [Podman](https://podman.io/).
|
||||
|
||||
The RTL DVB kernel modules must first be blacklisted on the host running the container. RTL-SDR itself is not required on the host running the container. This can be permanently accomplished using the following commands:
|
||||
|
||||
```bash
|
||||
echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/blacklist-dvb_usb_rtl28xxu.conf
|
||||
sudo modprobe -r dvb_usb_rtl28xxu
|
||||
```
|
||||
|
||||
If the `modprobe -r` command errors, a reboot is recommended to unload the module.
|
||||
|
||||
You can then start the container with the right parameters/options for you (frequency, callsign, locator etc... Fake example below):
|
||||
|
||||
```bash
|
||||
docker run --rm -it --pull=always --device=/dev/bus/usb ghcr.io/guenael/rtlsdr-wsprd:latest -f 2m -c A1XYZ -l AB12cd -g 29
|
||||
```
|
||||
|
||||
## Tips (for your Raspberry Pi and SDR dongles)
|
||||
|
||||
- Use ferrite bead on the USB cable to limit the QRN
|
||||
|
@ -117,3 +136,18 @@ Some manufacturers integrate a 0.5ppm TCXO. It's the best second option, after a
|
|||
- NooElec NESDR SMART : Works fine out of the box
|
||||
- RTL-SDR Blog 1PPM TCXO : Works with some drift, require additional mass, or a better enclosure
|
||||
- Other no-name like : RT820, E4000, FC0012, FC0013, can work, but require modification and usually drift a lot
|
||||
|
||||
## Performance & hardware tests
|
||||
|
||||
Some performance tests using:
|
||||
- Raspbian GNU/Linux 11 (bullseye) for Raspberry Pi devices
|
||||
- rtlsdr-wsprd version 0.4.2
|
||||
- Build with `clang -O3 -std=gnu17`
|
||||
|
||||
| Hardware | Supported | RX Load | Decode burst |
|
||||
| ------------- | ------------------ | ------- | ------------ |
|
||||
| RPi-1 | :heavy_check_mark: | 23.2% | 8.4s |
|
||||
| RPi-2 | :heavy_check_mark: | 13.5% | 4.1s |
|
||||
| RPi-3 | :heavy_check_mark: | 10.9% | 2.1s |
|
||||
| RPi-4 | :heavy_check_mark: | 5.8% | 1.1s |
|
||||
| PC (i7-5820K) | :heavy_check_mark: | 1.7% | 0.5s |
|
||||
|
|
358
rtlsdr_wsprd.c
358
rtlsdr_wsprd.c
|
@ -20,6 +20,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -32,10 +33,6 @@
|
|||
#include "./wsprd/wsprsim_utils.h"
|
||||
|
||||
|
||||
#define safe_cond_signal(n, m) pthread_mutex_lock(m); pthread_cond_signal(n); pthread_mutex_unlock(m)
|
||||
#define safe_cond_wait(n, m) pthread_mutex_lock(m); pthread_cond_wait(n, m); pthread_mutex_unlock(m)
|
||||
|
||||
|
||||
/* Sampling definition for RTL devices & WSPR protocol */
|
||||
#define SIGNAL_LENGHT 120
|
||||
#define SIGNAL_SAMPLE_RATE 375
|
||||
|
@ -46,6 +43,19 @@
|
|||
#define FIR_TAPS 32
|
||||
|
||||
|
||||
/* Debugging logs */
|
||||
#define LOG_DEBUG 0
|
||||
#define LOG_INFO 1
|
||||
#define LOG_WARN 2
|
||||
#define LOG_ERROR 3
|
||||
#define LOG_LEVEL LOG_ERROR
|
||||
#define LOG(level, ...) if (level >= LOG_LEVEL) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
|
||||
#define safe_cond_signal(n, m) pthread_mutex_lock(m); pthread_cond_signal(n); pthread_mutex_unlock(m)
|
||||
#define safe_cond_wait(n, m) pthread_mutex_lock(m); pthread_cond_wait(n, m); pthread_mutex_unlock(m)
|
||||
|
||||
|
||||
/* Thread for decoding */
|
||||
struct decoder_state {
|
||||
pthread_t thread;
|
||||
|
@ -90,11 +100,13 @@ struct receiver_options {
|
|||
int32_t upconverter;
|
||||
int32_t directsampling;
|
||||
int32_t maxloop;
|
||||
int32_t nloop;
|
||||
int32_t device;
|
||||
bool noreport;
|
||||
bool selftest;
|
||||
bool writefile;
|
||||
bool readfile;
|
||||
char filename[33];
|
||||
char *filename;
|
||||
};
|
||||
|
||||
|
||||
|
@ -105,6 +117,11 @@ struct decoder_options dec_options;
|
|||
struct decoder_results dec_results[50];
|
||||
|
||||
|
||||
/* Could be nice to update this one with the CI */
|
||||
const char rtlsdr_wsprd_version[] = "0.5.4";
|
||||
const char wsprnet_app_version[] = "rtlsdr-054"; // 10 chars max.!
|
||||
|
||||
|
||||
/* Callback for each buffer received */
|
||||
static void rtlsdr_callback(unsigned char *samples, uint32_t samples_count, void *ctx) {
|
||||
int8_t *sigIn = (int8_t *)samples;
|
||||
|
@ -122,17 +139,16 @@ static void rtlsdr_callback(unsigned char *samples, uint32_t samples_count, void
|
|||
Using : Octave/MATLAB code for generating compensation FIR coefficients
|
||||
URL : https://github.com/WestCoastDSP/CIC_Octave_Matlab
|
||||
*/
|
||||
/* Coefs with R=6400, M=1, N=2, F0=0.45, L=32 */
|
||||
const static float zCoef[33] = {
|
||||
-0.0018102029, 0.0021374727, 0.0039187458, -0.0025019918,
|
||||
-0.0097042058, 0.0007581166, 0.0199914435, 0.0076257829,
|
||||
-0.0333186890, -0.0286290175, 0.0447517831, 0.0705913907,
|
||||
-0.0423330196, -0.1501946045, -0.0158817961, 0.3175072196,
|
||||
-0.0027772683, -0.0005058826, 0.0049745750, -0.0034059318,
|
||||
-0.0077557814, 0.0139375423, 0.0039896935, -0.0299394142,
|
||||
0.0162250643, 0.0405130860, -0.0580746013, -0.0272104968,
|
||||
0.1183705475, -0.0306029022, -0.2011241667, 0.1615898423,
|
||||
0.5000000000,
|
||||
0.3175072196, -0.0158817961, -0.1501946045, -0.0423330196,
|
||||
0.0705913907, 0.0447517831, -0.0286290175, -0.0333186890,
|
||||
0.0076257829, 0.0199914435, 0.0007581166, -0.0097042058,
|
||||
-0.0025019918, 0.0039187458, 0.0021374727, -0.0018102029,
|
||||
0.1615898423, -0.2011241667, -0.0306029022, 0.1183705475,
|
||||
-0.0272104968, -0.0580746013, 0.0405130860, 0.0162250643,
|
||||
-0.0299394142, 0.0039896935, 0.0139375423, -0.0077557814,
|
||||
-0.0034059318, 0.0049745750, -0.0005058826, -0.0027772683
|
||||
};
|
||||
|
||||
/* FIR compensation filter buffers */
|
||||
|
@ -220,8 +236,8 @@ static void rtlsdr_callback(unsigned char *samples, uint32_t samples_count, void
|
|||
/* Save the result in the buffer */
|
||||
uint32_t idx = rx_state.bufferIndex;
|
||||
if (rx_state.iqIndex[idx] < (SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE)) {
|
||||
rx_state.iSamples[idx][rx_state.iqIndex[idx]] = Isum / (32768.0 * DOWNSAMPLING);
|
||||
rx_state.qSamples[idx][rx_state.iqIndex[idx]] = Qsum / (32768.0 * DOWNSAMPLING);
|
||||
rx_state.iSamples[idx][rx_state.iqIndex[idx]] = Isum;
|
||||
rx_state.qSamples[idx][rx_state.iqIndex[idx]] = Qsum;
|
||||
rx_state.iqIndex[idx]++;
|
||||
}
|
||||
}
|
||||
|
@ -250,14 +266,43 @@ static void *decoder(void *arg) {
|
|||
while (!rx_state.exit_flag) {
|
||||
safe_cond_wait(&decState.ready_cond, &decState.ready_mutex);
|
||||
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Got a signal!\n");
|
||||
|
||||
if (rx_state.exit_flag)
|
||||
break; /* Abort case, final sig */
|
||||
|
||||
/* Select the previous transmission / other buffer */
|
||||
uint32_t prevBuffer = (rx_state.bufferIndex + 1) % 2;
|
||||
|
||||
if (rx_state.iqIndex[prevBuffer] < ( (SIGNAL_LENGHT - 3) * SIGNAL_SAMPLE_RATE ) )
|
||||
if (rx_state.iqIndex[prevBuffer] < ( (SIGNAL_LENGHT - 3) * SIGNAL_SAMPLE_RATE ) ) {
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Signal too short, skipping!\n");
|
||||
continue; /* Partial buffer during the first RX, skip it! */
|
||||
} else {
|
||||
rx_options.nloop++; /* Decoding this signal, count it! */
|
||||
}
|
||||
|
||||
/* Delete any previous samples tail */
|
||||
for (int i = rx_state.iqIndex[prevBuffer]; i < SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE; i++) {
|
||||
rx_state.iSamples[prevBuffer][i] = 0.0;
|
||||
rx_state.qSamples[prevBuffer][i] = 0.0;
|
||||
}
|
||||
|
||||
/* Normalize the sample @-3dB */
|
||||
float maxSig = 1e-24f;
|
||||
for (int i = 0; i < SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE; i++) {
|
||||
float absI = fabs(rx_state.iSamples[prevBuffer][i]);
|
||||
float absQ = fabs(rx_state.qSamples[prevBuffer][i]);
|
||||
|
||||
if (absI > maxSig)
|
||||
maxSig = absI;
|
||||
if (absQ > maxSig)
|
||||
maxSig = absQ;
|
||||
}
|
||||
maxSig = 0.5 / maxSig;
|
||||
for (int i = 0; i < SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE; i++) {
|
||||
rx_state.iSamples[prevBuffer][i] *= maxSig;
|
||||
rx_state.qSamples[prevBuffer][i] *= maxSig;
|
||||
}
|
||||
|
||||
/* Get the date at the beginning last recording session
|
||||
with 1 second margin added, just to be sure to be on this even minute
|
||||
|
@ -274,6 +319,7 @@ static void *decoder(void *arg) {
|
|||
dec_options,
|
||||
dec_results,
|
||||
&n_results);
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Decoding completed\n");
|
||||
saveSample(rx_state.iSamples[prevBuffer], rx_state.qSamples[prevBuffer]);
|
||||
postSpots(n_results);
|
||||
printSpots(n_results);
|
||||
|
@ -287,6 +333,7 @@ void initSampleStorage() {
|
|||
rx_state.bufferIndex = 0;
|
||||
rx_state.iqIndex[0] = 0;
|
||||
rx_state.iqIndex[1] = 0;
|
||||
rx_state.exit_flag = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -298,13 +345,14 @@ void initrx_options() {
|
|||
rx_options.shift = 0;
|
||||
rx_options.directsampling = 0;
|
||||
rx_options.maxloop = 0;
|
||||
rx_options.nloop = 0;
|
||||
rx_options.device = 0;
|
||||
rx_options.selftest = false;
|
||||
rx_options.writefile = false;
|
||||
rx_options.readfile = false;
|
||||
rx_options.noreport = false;
|
||||
}
|
||||
|
||||
|
||||
/* Default options for the decoder */
|
||||
void initDecoder_options() {
|
||||
dec_options.usehashtable = 0;
|
||||
|
@ -320,18 +368,25 @@ void postSpots(uint32_t n_results) {
|
|||
CURLcode res;
|
||||
char url[256];
|
||||
|
||||
if (rx_options.noreport) {
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Skipping the reporting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* No spot to report, stat option used */
|
||||
// "Table 'wsprnet_db.activity' doesn't exist" reported on web site...
|
||||
// Anyone has doc about this?
|
||||
if (n_results == 0) {
|
||||
snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wsprstat&rcall=%s&rgrid=%s&rqrg=%.6f&tpct=%.2f&tqrg=%.6f&dbm=%d&version=rtlsdr-wsprd_v0.4.2&mode=2",
|
||||
snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wsprstat&rcall=%s&rgrid=%s&rqrg=%.6f&tpct=%.2f&tqrg=%.6f&dbm=%d&version=%s&mode=2",
|
||||
dec_options.rcall,
|
||||
dec_options.rloc,
|
||||
rx_options.realfreq / 1e6,
|
||||
rx_options.dialfreq / 1e6,
|
||||
0.0f,
|
||||
rx_options.realfreq / 1e6,
|
||||
0);
|
||||
rx_options.dialfreq / 1e6,
|
||||
0,
|
||||
wsprnet_app_version);
|
||||
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Sending empty report using this URL: %s\n", url);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
@ -347,7 +402,7 @@ void postSpots(uint32_t n_results) {
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < n_results; i++) {
|
||||
snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wspr&rcall=%s&rgrid=%s&rqrg=%.6f&date=%02d%02d%02d&time=%02d%02d&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=rtlsdr-wsprd_v0.4.2&mode=2",
|
||||
snprintf(url, sizeof(url) - 1, "http://wsprnet.org/post?function=wspr&rcall=%s&rgrid=%s&rqrg=%.6f&date=%02d%02d%02d&time=%02d%02d&sig=%.0f&dt=%.1f&tqrg=%.6f&tcall=%s&tgrid=%s&dbm=%s&version=%s&mode=2",
|
||||
dec_options.rcall,
|
||||
dec_options.rloc,
|
||||
dec_results[i].freq,
|
||||
|
@ -361,8 +416,10 @@ void postSpots(uint32_t n_results) {
|
|||
dec_results[i].freq,
|
||||
dec_results[i].call,
|
||||
dec_results[i].loc,
|
||||
dec_results[i].pwr);
|
||||
dec_results[i].pwr,
|
||||
wsprnet_app_version);
|
||||
|
||||
LOG(LOG_DEBUG, "Decoder thread -- Sending spot using this URL: %s\n", url);
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
@ -391,13 +448,12 @@ void printSpots(uint32_t n_results) {
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < n_results; i++) {
|
||||
printf("Spot : %04d-%02d-%02d %02d:%02d:%02d %6.2f %6.2f %10.6f %2d %7s %6s %2s\n",
|
||||
printf("Spot : %04d-%02d-%02d %02d:%02dz %6.2f %6.2f %10.6f %2d %7s %6s %2s\n",
|
||||
rx_state.gtm->tm_year + 1900,
|
||||
rx_state.gtm->tm_mon + 1,
|
||||
rx_state.gtm->tm_mday,
|
||||
rx_state.gtm->tm_hour,
|
||||
rx_state.gtm->tm_min,
|
||||
rx_state.gtm->tm_sec,
|
||||
dec_results[i].snr,
|
||||
dec_results[i].dt,
|
||||
dec_results[i].freq,
|
||||
|
@ -496,26 +552,9 @@ int32_t readRawIQfile(float *iSamples, float *qSamples, char *filename) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Get the size of the file */
|
||||
fseek(fd, 0L, SEEK_END);
|
||||
int32_t recsize = ftell(fd) / (2 * sizeof(float));
|
||||
fseek(fd, 0L, SEEK_SET);
|
||||
|
||||
|
||||
/* Limit the file/buffer to the max samples */
|
||||
if (recsize > SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE) {
|
||||
recsize = SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
/* Read the IQ file */
|
||||
int32_t nread = fread(filebuffer, sizeof(float), 2 * recsize, fd);
|
||||
if (nread != 2 * recsize) {
|
||||
fprintf(stderr, "Cannot read all the data! %d\n", nread);
|
||||
fclose(fd);
|
||||
return 0;
|
||||
} else {
|
||||
fclose(fd);
|
||||
}
|
||||
int32_t nread = fread(filebuffer, sizeof(float), 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE, fd);
|
||||
int32_t recsize = nread / 2;
|
||||
|
||||
/* Convert the interleaved buffer into 2 buffers */
|
||||
for (int32_t i = 0; i < recsize; i++) {
|
||||
|
@ -523,6 +562,23 @@ int32_t readRawIQfile(float *iSamples, float *qSamples, char *filename) {
|
|||
qSamples[i] = -filebuffer[2 * i + 1]; // neg, convention used by wsprsim
|
||||
}
|
||||
|
||||
/* Normalize the sample @-3dB */
|
||||
float maxSig = 1e-24f;
|
||||
for (int i = 0; i < recsize; i++) {
|
||||
float absI = fabs(iSamples[i]);
|
||||
float absQ = fabs(qSamples[i]);
|
||||
|
||||
if (absI > maxSig)
|
||||
maxSig = absI;
|
||||
if (absQ > maxSig)
|
||||
maxSig = absQ;
|
||||
}
|
||||
maxSig = 0.5 / maxSig;
|
||||
for (int i = 0; i <recsize; i++) {
|
||||
iSamples[i] *= maxSig;
|
||||
qSamples[i] *= maxSig;
|
||||
}
|
||||
|
||||
return recsize;
|
||||
}
|
||||
|
||||
|
@ -552,13 +608,71 @@ int32_t writeRawIQfile(float *iSamples, float *qSamples, char *filename) {
|
|||
}
|
||||
|
||||
|
||||
int32_t readC2file(float *iSamples, float *qSamples, char *filename) {
|
||||
float filebuffer[2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE];
|
||||
FILE *fd = fopen(filename, "rb");
|
||||
int32_t nread;
|
||||
double frequency;
|
||||
int type;
|
||||
char name[15];
|
||||
|
||||
if (fd == NULL) {
|
||||
fprintf(stderr, "Cannot open data file...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the header */
|
||||
nread = fread(name, sizeof(char), 14, fd);
|
||||
nread = fread(&type, sizeof(int), 1, fd);
|
||||
nread = fread(&frequency, sizeof(double), 1, fd);
|
||||
rx_options.dialfreq = frequency;
|
||||
|
||||
/* Read the IQ file */
|
||||
nread = fread(filebuffer, sizeof(float), 2 * SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE, fd);
|
||||
int32_t recsize = nread / 2;
|
||||
|
||||
/* Convert the interleaved buffer into 2 buffers */
|
||||
for (int32_t i = 0; i < recsize; i++) {
|
||||
iSamples[i] = filebuffer[2 * i];
|
||||
qSamples[i] = -filebuffer[2 * i + 1]; // neg, convention used by wsprsim
|
||||
}
|
||||
|
||||
/* Normalize the sample @-3dB */
|
||||
float maxSig = 1e-24f;
|
||||
for (int i = 0; i < recsize; i++) {
|
||||
float absI = fabs(iSamples[i]);
|
||||
float absQ = fabs(qSamples[i]);
|
||||
|
||||
if (absI > maxSig)
|
||||
maxSig = absI;
|
||||
if (absQ > maxSig)
|
||||
maxSig = absQ;
|
||||
}
|
||||
maxSig = 0.5 / maxSig;
|
||||
for (int i = 0; i <recsize; i++) {
|
||||
iSamples[i] *= maxSig;
|
||||
qSamples[i] *= maxSig;
|
||||
}
|
||||
|
||||
return recsize;
|
||||
}
|
||||
|
||||
|
||||
void decodeRecordedFile(char *filename) {
|
||||
static float iSamples[SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE] = {0};
|
||||
static float qSamples[SIGNAL_LENGHT * SIGNAL_SAMPLE_RATE] = {0};
|
||||
static uint32_t samples_len;
|
||||
int32_t n_results = 0;
|
||||
|
||||
samples_len = readRawIQfile(iSamples, qSamples, filename);
|
||||
if (strcmp(&filename[strlen(filename)-3], ".iq") == 0) {
|
||||
samples_len = readRawIQfile(iSamples, qSamples, filename);
|
||||
} else if (strcmp(&filename[strlen(filename)-3], ".c2") == 0) {
|
||||
samples_len = readC2file(iSamples, qSamples, filename);
|
||||
} else {
|
||||
fprintf(stderr, "Not a valid extension!! (only .iq & .c2 files)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Number of samples: %d\n", samples_len);
|
||||
|
||||
if (samples_len) {
|
||||
|
@ -612,10 +726,10 @@ int32_t decoderSelfTest() {
|
|||
unsigned char symbols[162];
|
||||
char message[] = "K1JT FN20QI 20";
|
||||
char hashtab[32768*13] = {0};
|
||||
//char loctab[32768*5] = {0}; // EVAL: code update from wsprd
|
||||
char loctab[32768*5] = {0}; // EVAL: code update from wsprd
|
||||
|
||||
// Compute sympbols from the message
|
||||
get_wspr_channel_symbols(message, hashtab, symbols);
|
||||
get_wspr_channel_symbols(message, hashtab, loctab, symbols);
|
||||
|
||||
float f0 = 50.0;
|
||||
float t0 = 2.0; // Caution!! Possible buffer overflow with the index calculation (no user input here!)
|
||||
|
@ -666,8 +780,8 @@ int32_t decoderSelfTest() {
|
|||
}
|
||||
|
||||
|
||||
void usage(void) {
|
||||
fprintf(stderr,
|
||||
void usage(FILE *stream, int32_t status) {
|
||||
fprintf(stream,
|
||||
"rtlsdr_wsprd, a simple WSPR daemon for RTL receivers\n\n"
|
||||
"Use:\trtlsdr_wsprd -f frequency -c callsign -l locator [options]\n"
|
||||
"\t-f dial frequency [(,k,M) Hz] or band string\n"
|
||||
|
@ -681,26 +795,37 @@ void usage(void) {
|
|||
"\t-o frequency offset (default: 0)\n"
|
||||
"\t-p crystal correction factor (ppm) (default: 0)\n"
|
||||
"\t-u upconverter (default: 0, example: 125M)\n"
|
||||
"\t-d direct dampling [0,1,2] (default: 0, 1 for I input, 2 for Q input)\n"
|
||||
"\t-d direct sampling [0,1,2] (default: 0, 1 for I input, 2 for Q input)\n"
|
||||
"\t-n max iterations (default: 0 = infinite loop)\n"
|
||||
"\t-i device index (in case of multiple receivers, default: 0)\n"
|
||||
"Decoder extra options:\n"
|
||||
"\t-H use the hash table (could caught signal 11 on RPi, no parameter)\n"
|
||||
"\t-Q quick mode, doesn't dig deep for weak signals, no parameter\n"
|
||||
"\t-S single pass mode, no subtraction (same as original wsprd), no parameter\n"
|
||||
"\t-x do not report any spots on web clusters (WSPRnet, PSKreporter...)\n"
|
||||
"Debugging options:\n"
|
||||
"\t-t decoder self-test (generate a signal & decode), no parameter\n"
|
||||
"\t-w write received signal and exit [filename prefix]\n"
|
||||
"\t-r read signal, decode and exit [filename]\n"
|
||||
"\t-r read signal with .iq or .c2 format, decode and exit [filename]\n"
|
||||
"\t (raw format: 375sps, float 32 bits, 2 channels)\n"
|
||||
"Other options:\n"
|
||||
"\t--help show list of options\n"
|
||||
"\t--version show version of program\n"
|
||||
"Example:\n"
|
||||
"\trtlsdr_wsprd -f 2m -c A1XYZ -l AB12cd -g 29 -o -4200\n");
|
||||
exit(1);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uint32_t opt;
|
||||
char *short_options = "f:c:l:g:ao:p:u:d:n:i:tw:r:HQSx";
|
||||
int32_t option_index = 0;
|
||||
struct option long_options[] = {
|
||||
{"help", no_argument, 0, 0 },
|
||||
{"version", no_argument, 0, 0 },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int32_t rtl_result;
|
||||
int32_t rtl_count;
|
||||
|
@ -709,40 +834,71 @@ int main(int argc, char **argv) {
|
|||
initrx_options();
|
||||
initDecoder_options();
|
||||
|
||||
/* Stop condition setup */
|
||||
rx_state.exit_flag = false;
|
||||
uint32_t nLoop = 0;
|
||||
|
||||
if (argc <= 1)
|
||||
usage();
|
||||
usage(stdout, EXIT_SUCCESS);
|
||||
|
||||
while ((opt = getopt(argc, argv, "f:c:l:g:ao:p:u:d:n:i:tw:r:HQS")) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 0:
|
||||
switch (option_index) {
|
||||
case 0: // --help
|
||||
usage(stdout, EXIT_SUCCESS);
|
||||
break;
|
||||
case 1: // --version
|
||||
printf("rtlsdr_wsprd v%s\n", rtlsdr_wsprd_version);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
case 'f': // Frequency
|
||||
if (!strcasecmp(optarg, "LF")) {
|
||||
rx_options.dialfreq = 136000;
|
||||
// Implicit direct sampling for HF bands & lower
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "MF")) {
|
||||
rx_options.dialfreq = 474200;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "160m")) {
|
||||
rx_options.dialfreq = 1836600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "80m")) {
|
||||
rx_options.dialfreq = 3592600;
|
||||
rx_options.dialfreq = 3568600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "60m")) {
|
||||
rx_options.dialfreq = 5287200;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "40m")) {
|
||||
rx_options.dialfreq = 7038600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "30m")) {
|
||||
rx_options.dialfreq = 10138700;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "20m")) {
|
||||
rx_options.dialfreq = 14095600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "17m")) {
|
||||
rx_options.dialfreq = 18104600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "15m")) {
|
||||
rx_options.dialfreq = 21094600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "12m")) {
|
||||
rx_options.dialfreq = 24924600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "10m")) {
|
||||
rx_options.dialfreq = 28124600;
|
||||
if (!rx_options.directsampling)
|
||||
rx_options.directsampling = 2;
|
||||
} else if (!strcasecmp(optarg, "6m")) {
|
||||
rx_options.dialfreq = 50293000;
|
||||
} else if (!strcasecmp(optarg, "4m")) {
|
||||
|
@ -802,60 +958,42 @@ int main(int argc, char **argv) {
|
|||
dec_options.subtraction = 0;
|
||||
dec_options.npasses = 1;
|
||||
break;
|
||||
case 'x': // Decoder option, single pass mode (same as original wsprd)
|
||||
rx_options.noreport = true;
|
||||
break;
|
||||
case 't': // Seft test (used in unit-test CI pipeline)
|
||||
rx_options.selftest = true;
|
||||
break;
|
||||
case 'w': // Read a signal and decode
|
||||
case 'w': // Write a signal and exit
|
||||
rx_options.writefile = true;
|
||||
snprintf(rx_options.filename, sizeof(rx_options.filename), "%.32s", optarg);
|
||||
rx_options.filename = optarg;
|
||||
break;
|
||||
case 'r': // Write a signal and exit
|
||||
case 'r': // Read a signal and decode
|
||||
rx_options.readfile = true;
|
||||
snprintf(rx_options.filename, sizeof(rx_options.filename), "%.32s", optarg);
|
||||
rx_options.filename = optarg;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
usage(stderr, EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_options.selftest == true) {
|
||||
if (decoderSelfTest()) {
|
||||
fprintf(stdout, "Self-test SUCCESS!\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Self-test FAILED!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_options.readfile == true) {
|
||||
fprintf(stdout, "Reading IQ file: %s\n", rx_options.filename);
|
||||
decodeRecordedFile(rx_options.filename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (rx_options.writefile == true) {
|
||||
fprintf(stdout, "Saving IQ file planned with prefix: %.8s\n", rx_options.filename);
|
||||
}
|
||||
|
||||
if (rx_options.dialfreq == 0) {
|
||||
fprintf(stderr, "Please specify a dial frequency.\n");
|
||||
fprintf(stderr, " --help for usage...\n");
|
||||
exit(1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (dec_options.rcall[0] == 0) {
|
||||
fprintf(stderr, "Please specify your callsign.\n");
|
||||
fprintf(stderr, " --help for usage...\n");
|
||||
exit(1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (dec_options.rloc[0] == 0) {
|
||||
fprintf(stderr, "Please specify your locator.\n");
|
||||
fprintf(stderr, " --help for usage...\n");
|
||||
exit(1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Calcule shift offset */
|
||||
|
@ -864,6 +1002,27 @@ int main(int argc, char **argv) {
|
|||
/* Store the frequency used for the decoder */
|
||||
dec_options.freq = rx_options.dialfreq;
|
||||
|
||||
if (rx_options.selftest == true) {
|
||||
if (decoderSelfTest()) {
|
||||
fprintf(stdout, "Self-test SUCCESS!\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Self-test FAILED!\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (rx_options.readfile == true) {
|
||||
fprintf(stdout, "Reading IQ file: %s\n", rx_options.filename);
|
||||
decodeRecordedFile(rx_options.filename);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (rx_options.writefile == true) {
|
||||
fprintf(stdout, "Saving IQ file planned with prefix: %.8s\n", rx_options.filename);
|
||||
}
|
||||
|
||||
/* If something goes wrong... */
|
||||
signal(SIGINT, &sigint_callback_handler);
|
||||
signal(SIGTERM, &sigint_callback_handler);
|
||||
|
@ -961,8 +1120,8 @@ int main(int argc, char **argv) {
|
|||
struct tm *gtm = gmtime(&rawtime);
|
||||
|
||||
/* Print used parameter */
|
||||
printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version 0.4.2\n",
|
||||
gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min);
|
||||
printf("\nStarting rtlsdr-wsprd (%04d-%02d-%02d, %02d:%02dz) -- Version %s\n",
|
||||
gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, gtm->tm_hour, gtm->tm_min, rtlsdr_wsprd_version);
|
||||
printf(" Callsign : %s\n", dec_options.rcall);
|
||||
printf(" Locator : %s\n", dec_options.rloc);
|
||||
printf(" Dial freq. : %d Hz\n", rx_options.dialfreq);
|
||||
|
@ -979,7 +1138,7 @@ int main(int argc, char **argv) {
|
|||
uint32_t usec = sec * 1000000 + lTime.tv_usec;
|
||||
uint32_t uwait = 120000000 - usec;
|
||||
printf("Wait for time sync (start in %d sec)\n\n", uwait / 1000000);
|
||||
printf(" Date Time(z) SNR DT Freq Dr Call Loc Pwr\n");
|
||||
printf(" Date Time SNR DT Freq Dr Call Loc Pwr\n");
|
||||
|
||||
/* Prepare a low priority param for the decoder thread */
|
||||
struct sched_param param;
|
||||
|
@ -998,37 +1157,38 @@ int main(int argc, char **argv) {
|
|||
pthread_create(&decState.thread, &decState.tattr, decoder, NULL);
|
||||
|
||||
/* Main loop : Wait, read, decode */
|
||||
while (!rx_state.exit_flag && !(rx_options.maxloop && (nLoop >= rx_options.maxloop))) {
|
||||
while (!rx_state.exit_flag && !(rx_options.maxloop && (rx_options.nloop >= rx_options.maxloop))) {
|
||||
/* Wait for time Sync on 2 mins */
|
||||
gettimeofday(&lTime, NULL);
|
||||
sec = lTime.tv_sec % 120;
|
||||
usec = sec * 1000000 + lTime.tv_usec;
|
||||
uwait = 120000000 - usec;
|
||||
LOG(LOG_DEBUG, "Main thread -- Waiting %d seconds\n", uwait/1000000);
|
||||
usleep(uwait);
|
||||
LOG(LOG_DEBUG, "Main thread -- Sending a GO to the decoder thread\n");
|
||||
|
||||
/* Switch to the other buffer and trigger the decoder */
|
||||
rx_state.bufferIndex = (rx_state.bufferIndex + 1) % 2;
|
||||
rx_state.iqIndex[rx_state.bufferIndex] = 0;
|
||||
safe_cond_signal(&decState.ready_cond, &decState.ready_mutex);
|
||||
|
||||
nLoop++;
|
||||
usleep(100000); /* Give a chance to the other thread to update the nloop counter */
|
||||
}
|
||||
|
||||
/* Stop the decoder thread */
|
||||
rx_state.exit_flag = true;
|
||||
safe_cond_signal(&decState.ready_cond, &decState.ready_mutex);
|
||||
|
||||
/* Stop the RX and free the blocking function */
|
||||
rtlsdr_cancel_async(rtl_device);
|
||||
|
||||
/* Close the RTL device */
|
||||
rtlsdr_close(rtl_device);
|
||||
|
||||
/* Wait the thread join (send a signal before to terminate the job) */
|
||||
safe_cond_signal(&decState.ready_cond, &decState.ready_mutex);
|
||||
pthread_join(decState.thread, NULL);
|
||||
pthread_join(dongle, NULL);
|
||||
|
||||
/* Destroy the lock/cond/thread */
|
||||
pthread_cond_destroy(&decState.ready_cond);
|
||||
pthread_mutex_destroy(&decState.ready_mutex);
|
||||
pthread_exit(NULL);
|
||||
|
||||
printf("Bye!\n");
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ double atofs(char *s);
|
|||
int32_t parse_u64(char *s, uint64_t *const value);
|
||||
int32_t readRawIQfile(float *iSamples, float *qSamples, char *filename);
|
||||
int32_t writeRawIQfile(float *iSamples, float *qSamples, char *filename);
|
||||
int32_t readC2file(float *iSamples, float *qSamples, char *filename);
|
||||
void decodeRecordedFile(char *filename);
|
||||
float whiteGaussianNoise(float factor);
|
||||
int32_t decoderSelfTest();
|
||||
void usage(void);
|
||||
void usage(FILE *stream, int32_t status);
|
||||
|
|
11
wsprd/fano.c
11
wsprd/fano.c
|
@ -166,8 +166,7 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
*/
|
||||
while (ngamma >= t + delta) t += delta;
|
||||
}
|
||||
// Move forward
|
||||
np[1].gamma = ngamma;
|
||||
np[1].gamma = ngamma; // Move forward
|
||||
np[1].encstate = np->encstate << 1;
|
||||
if (++np == (lastnode + 1)) {
|
||||
break; // Done!
|
||||
|
@ -194,14 +193,11 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
np->encstate++; // Set low bit
|
||||
}
|
||||
}
|
||||
np->i = 0;
|
||||
// Start with best branch
|
||||
np->i = 0; // Start with best branch
|
||||
continue;
|
||||
}
|
||||
|
||||
// Threshold violated, can't go forward
|
||||
for (;;) {
|
||||
// Look backward
|
||||
for (;;) { // Look backward
|
||||
if (np == nodes || np[-1].gamma < t) {
|
||||
/* Can't back up either.
|
||||
* Relax threshold and and look
|
||||
|
@ -214,7 +210,6 @@ int fano(unsigned int *metric, // Final path metric (returned value)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Back up
|
||||
if (--np < tail && np->i != 1) {
|
||||
np->i++; // Search next best branch
|
||||
|
|
|
@ -4,114 +4,136 @@
|
|||
* should be normalized to have rms amplitude equal to "symbol_scale".
|
||||
********************************************************************************/
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
// float symbol_scale[4]={42.6, 53.3, 72.7, 100.2};
|
||||
static const float metric_tables[4][256] = {
|
||||
0.9782, 0.9695, 0.9689, 0.9669, 0.9666, 0.9653, 0.9638, 0.9618, 0.9599, 0.9601,
|
||||
0.9592, 0.9570, 0.9556, 0.9540, 0.9525, 0.9527, 0.9486, 0.9477, 0.9450, 0.9436,
|
||||
0.9424, 0.9400, 0.9381, 0.9360, 0.9340, 0.9316, 0.9301, 0.9272, 0.9254, 0.9224,
|
||||
0.9196, 0.9171, 0.9154, 0.9123, 0.9076, 0.9061, 0.9030, 0.9000, 0.8965, 0.8934,
|
||||
0.8903, 0.8874, 0.8834, 0.8792, 0.8760, 0.8726, 0.8685, 0.8639, 0.8599, 0.8550,
|
||||
0.8504, 0.8459, 0.8422, 0.8364, 0.8320, 0.8262, 0.8215, 0.8159, 0.8111, 0.8052,
|
||||
0.7996, 0.7932, 0.7878, 0.7812, 0.7745, 0.7685, 0.7616, 0.7550, 0.7479, 0.7405,
|
||||
0.7336, 0.7255, 0.7184, 0.7102, 0.7016, 0.6946, 0.6860, 0.6769, 0.6687, 0.6598,
|
||||
0.6503, 0.6416, 0.6325, 0.6219, 0.6122, 0.6016, 0.5920, 0.5818, 0.5711, 0.5606,
|
||||
0.5487, 0.5374, 0.5266, 0.5142, 0.5020, 0.4908, 0.4784, 0.4663, 0.4532, 0.4405,
|
||||
0.4271, 0.4144, 0.4006, 0.3865, 0.3731, 0.3594, 0.3455, 0.3304, 0.3158, 0.3009,
|
||||
0.2858, 0.2708, 0.2560, 0.2399, 0.2233, 0.2074, 0.1919, 0.1756, 0.1590, 0.1427,
|
||||
0.1251, 0.1074, 0.0905, 0.0722, 0.0550, 0.0381, 0.0183, 0.0000, -0.0185, -0.0391,
|
||||
-0.0571, -0.0760, -0.0966, -0.1160, -0.1370, -0.1584, -0.1787, -0.1999, -0.2214, -0.2423,
|
||||
-0.2643, -0.2879, -0.3114, -0.3336, -0.3568, -0.3806, -0.4050, -0.4293, -0.4552, -0.4798,
|
||||
-0.5046, -0.5296, -0.5564, -0.5836, -0.6093, -0.6372, -0.6645, -0.6933, -0.7208, -0.7495,
|
||||
-0.7763, -0.8065, -0.8378, -0.8660, -0.8964, -0.9293, -0.9592, -0.9907, -1.0214, -1.0509,
|
||||
-1.0850, -1.1168, -1.1528, -1.1847, -1.2157, -1.2511, -1.2850, -1.3174, -1.3540, -1.3900,
|
||||
-1.4201, -1.4580, -1.4956, -1.5292, -1.5683, -1.6030, -1.6411, -1.6789, -1.7147, -1.7539,
|
||||
-1.7887, -1.8289, -1.8699, -1.9043, -1.9469, -1.9849, -2.0267, -2.0610, -2.1028, -2.1391,
|
||||
-2.1855, -2.2215, -2.2712, -2.3033, -2.3440, -2.3870, -2.4342, -2.4738, -2.5209, -2.5646,
|
||||
-2.6016, -2.6385, -2.6868, -2.7356, -2.7723, -2.8111, -2.8524, -2.9009, -2.9428, -2.9879,
|
||||
-3.0103, -3.0832, -3.1340, -3.1628, -3.2049, -3.2557, -3.3101, -3.3453, -3.4025, -3.4317,
|
||||
-3.4828, -3.5270, -3.5745, -3.6181, -3.6765, -3.7044, -3.7410, -3.8118, -3.8368, -3.9549,
|
||||
-3.9488, -3.9941, -4.0428, -4.0892, -4.1648, -4.1965, -4.1892, -4.2565, -4.3356, -4.3948,
|
||||
-4.4481, -4.4607, -4.5533, -4.5809, -4.5927, -5.1047,
|
||||
0.9978, 0.9962, 0.9961, 0.9959, 0.9958, 0.9954, 0.9949, 0.9950, 0.9947, 0.9942,
|
||||
0.9940, 0.9939, 0.9933, 0.9931, 0.9928, 0.9924, 0.9921, 0.9916, 0.9911, 0.9909,
|
||||
0.9903, 0.9900, 0.9892, 0.9887, 0.9883, 0.9877, 0.9869, 0.9863, 0.9857, 0.9848,
|
||||
0.9842, 0.9835, 0.9825, 0.9817, 0.9808, 0.9799, 0.9791, 0.9777, 0.9767, 0.9757,
|
||||
0.9744, 0.9729, 0.9716, 0.9704, 0.9690, 0.9674, 0.9656, 0.9641, 0.9625, 0.9609,
|
||||
0.9587, 0.9567, 0.9548, 0.9524, 0.9501, 0.9478, 0.9453, 0.9426, 0.9398, 0.9371,
|
||||
0.9339, 0.9311, 0.9277, 0.9242, 0.9206, 0.9168, 0.9131, 0.9087, 0.9043, 0.8999,
|
||||
0.8953, 0.8907, 0.8857, 0.8803, 0.8747, 0.8690, 0.8632, 0.8572, 0.8507, 0.8439,
|
||||
0.8368, 0.8295, 0.8217, 0.8138, 0.8058, 0.7972, 0.7883, 0.7784, 0.7694, 0.7597,
|
||||
0.7489, 0.7378, 0.7269, 0.7152, 0.7030, 0.6911, 0.6782, 0.6643, 0.6506, 0.6371,
|
||||
0.6211, 0.6054, 0.5897, 0.5740, 0.5565, 0.5393, 0.5214, 0.5027, 0.4838, 0.4643,
|
||||
0.4436, 0.4225, 0.4004, 0.3787, 0.3562, 0.3324, 0.3089, 0.2839, 0.2584, 0.2321,
|
||||
0.2047, 0.1784, 0.1499, 0.1213, 0.0915, 0.0628, 0.0314, 0.0000, -0.0321, -0.0657,
|
||||
-0.0977, -0.1324, -0.1673, -0.2036, -0.2387, -0.2768, -0.3150, -0.3538, -0.3936, -0.4327,
|
||||
-0.4739, -0.5148, -0.5561, -0.6000, -0.6438, -0.6889, -0.7331, -0.7781, -0.8247, -0.8712,
|
||||
-0.9177, -0.9677, -1.0142, -1.0631, -1.1143, -1.1686, -1.2169, -1.2680, -1.3223, -1.3752,
|
||||
-1.4261, -1.4806, -1.5356, -1.5890, -1.6462, -1.7041, -1.7591, -1.8124, -1.8735, -1.9311,
|
||||
-1.9891, -2.0459, -2.1048, -2.1653, -2.2248, -2.2855, -2.3466, -2.4079, -2.4668, -2.5263,
|
||||
-2.5876, -2.6507, -2.7142, -2.7761, -2.8366, -2.8995, -2.9620, -3.0279, -3.0973, -3.1576,
|
||||
-3.2238, -3.2890, -3.3554, -3.4215, -3.4805, -3.5518, -3.6133, -3.6812, -3.7473, -3.8140,
|
||||
-3.8781, -3.9450, -4.0184, -4.0794, -4.1478, -4.2241, -4.2853, -4.3473, -4.4062, -4.4839,
|
||||
-4.5539, -4.6202, -4.6794, -4.7478, -4.8309, -4.9048, -4.9669, -5.0294, -5.1194, -5.1732,
|
||||
-5.2378, -5.3094, -5.3742, -5.4573, -5.5190, -5.5728, -5.6637, -5.7259, -5.7843, -5.8854,
|
||||
-5.9553, -6.0054, -6.0656, -6.1707, -6.2241, -6.3139, -6.3393, -6.4356, -6.5153, -6.5758,
|
||||
-6.6506, -6.7193, -6.7542, -6.8942, -6.9219, -6.9605, -7.1013, -7.1895, -7.1549, -7.2799,
|
||||
-7.4119, -7.4608, -7.5256, -7.5879, -7.7598, -8.4120,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997,
|
||||
0.9997, 0.9996, 0.9996, 0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9994, 0.9993,
|
||||
0.9993, 0.9992, 0.9991, 0.9991, 0.9990, 0.9989, 0.9988, 0.9988, 0.9988, 0.9986,
|
||||
0.9985, 0.9984, 0.9983, 0.9982, 0.9980, 0.9979, 0.9977, 0.9976, 0.9974, 0.9971,
|
||||
0.9969, 0.9968, 0.9965, 0.9962, 0.9960, 0.9957, 0.9953, 0.9950, 0.9947, 0.9941,
|
||||
0.9937, 0.9933, 0.9928, 0.9922, 0.9917, 0.9911, 0.9904, 0.9897, 0.9890, 0.9882,
|
||||
0.9874, 0.9863, 0.9855, 0.9843, 0.9832, 0.9819, 0.9806, 0.9792, 0.9777, 0.9760,
|
||||
0.9743, 0.9724, 0.9704, 0.9683, 0.9659, 0.9634, 0.9609, 0.9581, 0.9550, 0.9516,
|
||||
0.9481, 0.9446, 0.9406, 0.9363, 0.9317, 0.9270, 0.9218, 0.9160, 0.9103, 0.9038,
|
||||
0.8972, 0.8898, 0.8822, 0.8739, 0.8647, 0.8554, 0.8457, 0.8357, 0.8231, 0.8115,
|
||||
0.7984, 0.7854, 0.7704, 0.7556, 0.7391, 0.7210, 0.7038, 0.6840, 0.6633, 0.6408,
|
||||
0.6174, 0.5939, 0.5678, 0.5410, 0.5137, 0.4836, 0.4524, 0.4193, 0.3850, 0.3482,
|
||||
0.3132, 0.2733, 0.2315, 0.1891, 0.1435, 0.0980, 0.0493, 0.0000, -0.0510, -0.1052,
|
||||
-0.1593, -0.2177, -0.2759, -0.3374, -0.4005, -0.4599, -0.5266, -0.5935, -0.6626, -0.7328,
|
||||
-0.8051, -0.8757, -0.9498, -1.0271, -1.1019, -1.1816, -1.2642, -1.3459, -1.4295, -1.5077,
|
||||
-1.5958, -1.6818, -1.7647, -1.8548, -1.9387, -2.0295, -2.1152, -2.2154, -2.3011, -2.3904,
|
||||
-2.4820, -2.5786, -2.6730, -2.7652, -2.8616, -2.9546, -3.0526, -3.1445, -3.2445, -3.3416,
|
||||
-3.4357, -3.5325, -3.6324, -3.7313, -3.8225, -3.9209, -4.0248, -4.1278, -4.2261, -4.3193,
|
||||
-4.4220, -4.5262, -4.6214, -4.7242, -4.8234, -4.9245, -5.0298, -5.1250, -5.2232, -5.3267,
|
||||
-5.4332, -5.5342, -5.6431, -5.7270, -5.8401, -5.9350, -6.0407, -6.1418, -6.2363, -6.3384,
|
||||
-6.4536, -6.5429, -6.6582, -6.7433, -6.8438, -6.9478, -7.0789, -7.1894, -7.2714, -7.3815,
|
||||
-7.4810, -7.5575, -7.6852, -7.8071, -7.8580, -7.9724, -8.1000, -8.2207, -8.2867, -8.4017,
|
||||
-8.5287, -8.6347, -8.7082, -8.8319, -8.9448, -9.0355, -9.1885, -9.2095, -9.2863, -9.4186,
|
||||
-9.5064, -9.6386, -9.7207, -9.8286, -9.9453, -10.0701, -10.1735, -10.3001, -10.2858, -10.5427,
|
||||
-10.5982, -10.7361, -10.7042, -10.9212, -11.0097, -11.0469, -11.1155, -11.2812, -11.3472, -11.4988,
|
||||
-11.5327, -11.6692, -11.9376, -11.8606, -12.1372, -13.2539,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||
-10.1730, -10.2427, -10.4573, -10.5413, -10.7303, -10.9339, -11.0215, -11.2047, -11.2894, -11.4572,
|
||||
-11.6256, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527, -12.8247, -12.9560,
|
||||
-13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049, -14.1653, -14.4348,
|
||||
-14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161, -15.9185, -15.9490,
|
||||
-16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644, -17.5973, -17.0403,
|
||||
-17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
//float symbol_scale[5]={42.6, 53.3, 72.7, 100.2, 125.4};
|
||||
float metric_tables[5][256]={
|
||||
{0.9782, 0.9695, 0.9689, 0.9669, 0.9666, 0.9653, 0.9638, 0.9618, 0.9599, 0.9601,
|
||||
0.9592, 0.9570, 0.9556, 0.9540, 0.9525, 0.9527, 0.9486, 0.9477, 0.9450, 0.9436,
|
||||
0.9424, 0.9400, 0.9381, 0.9360, 0.9340, 0.9316, 0.9301, 0.9272, 0.9254, 0.9224,
|
||||
0.9196, 0.9171, 0.9154, 0.9123, 0.9076, 0.9061, 0.9030, 0.9000, 0.8965, 0.8934,
|
||||
0.8903, 0.8874, 0.8834, 0.8792, 0.8760, 0.8726, 0.8685, 0.8639, 0.8599, 0.8550,
|
||||
0.8504, 0.8459, 0.8422, 0.8364, 0.8320, 0.8262, 0.8215, 0.8159, 0.8111, 0.8052,
|
||||
0.7996, 0.7932, 0.7878, 0.7812, 0.7745, 0.7685, 0.7616, 0.7550, 0.7479, 0.7405,
|
||||
0.7336, 0.7255, 0.7184, 0.7102, 0.7016, 0.6946, 0.6860, 0.6769, 0.6687, 0.6598,
|
||||
0.6503, 0.6416, 0.6325, 0.6219, 0.6122, 0.6016, 0.5920, 0.5818, 0.5711, 0.5606,
|
||||
0.5487, 0.5374, 0.5266, 0.5142, 0.5020, 0.4908, 0.4784, 0.4663, 0.4532, 0.4405,
|
||||
0.4271, 0.4144, 0.4006, 0.3865, 0.3731, 0.3594, 0.3455, 0.3304, 0.3158, 0.3009,
|
||||
0.2858, 0.2708, 0.2560, 0.2399, 0.2233, 0.2074, 0.1919, 0.1756, 0.1590, 0.1427,
|
||||
0.1251, 0.1074, 0.0905, 0.0722, 0.0550, 0.0381, 0.0183, 0.0000, -0.0185, -0.0391,
|
||||
-0.0571, -0.0760, -0.0966, -0.1160, -0.1370, -0.1584, -0.1787, -0.1999, -0.2214, -0.2423,
|
||||
-0.2643, -0.2879, -0.3114, -0.3336, -0.3568, -0.3806, -0.4050, -0.4293, -0.4552, -0.4798,
|
||||
-0.5046, -0.5296, -0.5564, -0.5836, -0.6093, -0.6372, -0.6645, -0.6933, -0.7208, -0.7495,
|
||||
-0.7763, -0.8065, -0.8378, -0.8660, -0.8964, -0.9293, -0.9592, -0.9907, -1.0214, -1.0509,
|
||||
-1.0850, -1.1168, -1.1528, -1.1847, -1.2157, -1.2511, -1.2850, -1.3174, -1.3540, -1.3900,
|
||||
-1.4201, -1.4580, -1.4956, -1.5292, -1.5683, -1.6030, -1.6411, -1.6789, -1.7147, -1.7539,
|
||||
-1.7887, -1.8289, -1.8699, -1.9043, -1.9469, -1.9849, -2.0267, -2.0610, -2.1028, -2.1391,
|
||||
-2.1855, -2.2215, -2.2712, -2.3033, -2.3440, -2.3870, -2.4342, -2.4738, -2.5209, -2.5646,
|
||||
-2.6016, -2.6385, -2.6868, -2.7356, -2.7723, -2.8111, -2.8524, -2.9009, -2.9428, -2.9879,
|
||||
-3.0103, -3.0832, -3.1340, -3.1628, -3.2049, -3.2557, -3.3101, -3.3453, -3.4025, -3.4317,
|
||||
-3.4828, -3.5270, -3.5745, -3.6181, -3.6765, -3.7044, -3.7410, -3.8118, -3.8368, -3.9549,
|
||||
-3.9488, -3.9941, -4.0428, -4.0892, -4.1648, -4.1965, -4.1892, -4.2565, -4.3356, -4.3948,
|
||||
-4.4481, -4.4607, -4.5533, -4.5809, -4.5927, -5.1047},
|
||||
{0.9978, 0.9962, 0.9961, 0.9959, 0.9958, 0.9954, 0.9949, 0.9950, 0.9947, 0.9942,
|
||||
0.9940, 0.9939, 0.9933, 0.9931, 0.9928, 0.9924, 0.9921, 0.9916, 0.9911, 0.9909,
|
||||
0.9903, 0.9900, 0.9892, 0.9887, 0.9883, 0.9877, 0.9869, 0.9863, 0.9857, 0.9848,
|
||||
0.9842, 0.9835, 0.9825, 0.9817, 0.9808, 0.9799, 0.9791, 0.9777, 0.9767, 0.9757,
|
||||
0.9744, 0.9729, 0.9716, 0.9704, 0.9690, 0.9674, 0.9656, 0.9641, 0.9625, 0.9609,
|
||||
0.9587, 0.9567, 0.9548, 0.9524, 0.9501, 0.9478, 0.9453, 0.9426, 0.9398, 0.9371,
|
||||
0.9339, 0.9311, 0.9277, 0.9242, 0.9206, 0.9168, 0.9131, 0.9087, 0.9043, 0.8999,
|
||||
0.8953, 0.8907, 0.8857, 0.8803, 0.8747, 0.8690, 0.8632, 0.8572, 0.8507, 0.8439,
|
||||
0.8368, 0.8295, 0.8217, 0.8138, 0.8058, 0.7972, 0.7883, 0.7784, 0.7694, 0.7597,
|
||||
0.7489, 0.7378, 0.7269, 0.7152, 0.7030, 0.6911, 0.6782, 0.6643, 0.6506, 0.6371,
|
||||
0.6211, 0.6054, 0.5897, 0.5740, 0.5565, 0.5393, 0.5214, 0.5027, 0.4838, 0.4643,
|
||||
0.4436, 0.4225, 0.4004, 0.3787, 0.3562, 0.3324, 0.3089, 0.2839, 0.2584, 0.2321,
|
||||
0.2047, 0.1784, 0.1499, 0.1213, 0.0915, 0.0628, 0.0314, 0.0000, -0.0321, -0.0657,
|
||||
-0.0977, -0.1324, -0.1673, -0.2036, -0.2387, -0.2768, -0.3150, -0.3538, -0.3936, -0.4327,
|
||||
-0.4739, -0.5148, -0.5561, -0.6000, -0.6438, -0.6889, -0.7331, -0.7781, -0.8247, -0.8712,
|
||||
-0.9177, -0.9677, -1.0142, -1.0631, -1.1143, -1.1686, -1.2169, -1.2680, -1.3223, -1.3752,
|
||||
-1.4261, -1.4806, -1.5356, -1.5890, -1.6462, -1.7041, -1.7591, -1.8124, -1.8735, -1.9311,
|
||||
-1.9891, -2.0459, -2.1048, -2.1653, -2.2248, -2.2855, -2.3466, -2.4079, -2.4668, -2.5263,
|
||||
-2.5876, -2.6507, -2.7142, -2.7761, -2.8366, -2.8995, -2.9620, -3.0279, -3.0973, -3.1576,
|
||||
-3.2238, -3.2890, -3.3554, -3.4215, -3.4805, -3.5518, -3.6133, -3.6812, -3.7473, -3.8140,
|
||||
-3.8781, -3.9450, -4.0184, -4.0794, -4.1478, -4.2241, -4.2853, -4.3473, -4.4062, -4.4839,
|
||||
-4.5539, -4.6202, -4.6794, -4.7478, -4.8309, -4.9048, -4.9669, -5.0294, -5.1194, -5.1732,
|
||||
-5.2378, -5.3094, -5.3742, -5.4573, -5.5190, -5.5728, -5.6637, -5.7259, -5.7843, -5.8854,
|
||||
-5.9553, -6.0054, -6.0656, -6.1707, -6.2241, -6.3139, -6.3393, -6.4356, -6.5153, -6.5758,
|
||||
-6.6506, -6.7193, -6.7542, -6.8942, -6.9219, -6.9605, -7.1013, -7.1895, -7.1549, -7.2799,
|
||||
-7.4119, -7.4608, -7.5256, -7.5879, -7.7598, -8.4120},
|
||||
{0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997,
|
||||
0.9997, 0.9996, 0.9996, 0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9994, 0.9993,
|
||||
0.9993, 0.9992, 0.9991, 0.9991, 0.9990, 0.9989, 0.9988, 0.9988, 0.9988, 0.9986,
|
||||
0.9985, 0.9984, 0.9983, 0.9982, 0.9980, 0.9979, 0.9977, 0.9976, 0.9974, 0.9971,
|
||||
0.9969, 0.9968, 0.9965, 0.9962, 0.9960, 0.9957, 0.9953, 0.9950, 0.9947, 0.9941,
|
||||
0.9937, 0.9933, 0.9928, 0.9922, 0.9917, 0.9911, 0.9904, 0.9897, 0.9890, 0.9882,
|
||||
0.9874, 0.9863, 0.9855, 0.9843, 0.9832, 0.9819, 0.9806, 0.9792, 0.9777, 0.9760,
|
||||
0.9743, 0.9724, 0.9704, 0.9683, 0.9659, 0.9634, 0.9609, 0.9581, 0.9550, 0.9516,
|
||||
0.9481, 0.9446, 0.9406, 0.9363, 0.9317, 0.9270, 0.9218, 0.9160, 0.9103, 0.9038,
|
||||
0.8972, 0.8898, 0.8822, 0.8739, 0.8647, 0.8554, 0.8457, 0.8357, 0.8231, 0.8115,
|
||||
0.7984, 0.7854, 0.7704, 0.7556, 0.7391, 0.7210, 0.7038, 0.6840, 0.6633, 0.6408,
|
||||
0.6174, 0.5939, 0.5678, 0.5410, 0.5137, 0.4836, 0.4524, 0.4193, 0.3850, 0.3482,
|
||||
0.3132, 0.2733, 0.2315, 0.1891, 0.1435, 0.0980, 0.0493, 0.0000, -0.0510, -0.1052,
|
||||
-0.1593, -0.2177, -0.2759, -0.3374, -0.4005, -0.4599, -0.5266, -0.5935, -0.6626, -0.7328,
|
||||
-0.8051, -0.8757, -0.9498, -1.0271, -1.1019, -1.1816, -1.2642, -1.3459, -1.4295, -1.5077,
|
||||
-1.5958, -1.6818, -1.7647, -1.8548, -1.9387, -2.0295, -2.1152, -2.2154, -2.3011, -2.3904,
|
||||
-2.4820, -2.5786, -2.6730, -2.7652, -2.8616, -2.9546, -3.0526, -3.1445, -3.2445, -3.3416,
|
||||
-3.4357, -3.5325, -3.6324, -3.7313, -3.8225, -3.9209, -4.0248, -4.1278, -4.2261, -4.3193,
|
||||
-4.4220, -4.5262, -4.6214, -4.7242, -4.8234, -4.9245, -5.0298, -5.1250, -5.2232, -5.3267,
|
||||
-5.4332, -5.5342, -5.6431, -5.7270, -5.8401, -5.9350, -6.0407, -6.1418, -6.2363, -6.3384,
|
||||
-6.4536, -6.5429, -6.6582, -6.7433, -6.8438, -6.9478, -7.0789, -7.1894, -7.2714, -7.3815,
|
||||
-7.4810, -7.5575, -7.6852, -7.8071, -7.8580, -7.9724, -8.1000, -8.2207, -8.2867, -8.4017,
|
||||
-8.5287, -8.6347, -8.7082, -8.8319, -8.9448, -9.0355, -9.1885, -9.2095, -9.2863, -9.4186,
|
||||
-9.5064, -9.6386, -9.7207, -9.8286, -9.9453, -10.0701, -10.1735, -10.3001, -10.2858, -10.5427,
|
||||
-10.5982, -10.7361, -10.7042, -10.9212, -11.0097, -11.0469, -11.1155, -11.2812, -11.3472, -11.4988,
|
||||
-11.5327, -11.6692, -11.9376, -11.8606, -12.1372, -13.2539},
|
||||
{1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||
-10.1730, -10.2427, -10.4573, -10.5413, -10.7303, -10.9339, -11.0215, -11.2047, -11.2894, -11.4572,
|
||||
-11.6256, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527, -12.8247, -12.9560,
|
||||
-13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049, -14.1653, -14.4348,
|
||||
-14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161, -15.9185, -15.9490,
|
||||
-16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644, -17.5973, -17.0403,
|
||||
-17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063},
|
||||
{1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000,
|
||||
0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999, 0.9999,
|
||||
0.9999, 0.9998, 0.9998, 0.9998, 0.9998, 0.9997, 0.9997, 0.9997, 0.9997, 0.9996,
|
||||
0.9996, 0.9995, 0.9995, 0.9994, 0.9994, 0.9993, 0.9992, 0.9991, 0.9991, 0.9989,
|
||||
0.9988, 0.9986, 0.9985, 0.9983, 0.9981, 0.9980, 0.9977, 0.9974, 0.9971, 0.9968,
|
||||
0.9965, 0.9962, 0.9956, 0.9950, 0.9948, 0.9941, 0.9933, 0.9926, 0.9919, 0.9910,
|
||||
0.9899, 0.9889, 0.9877, 0.9863, 0.9845, 0.9829, 0.9811, 0.9791, 0.9769, 0.9741,
|
||||
0.9716, 0.9684, 0.9645, 0.9611, 0.9563, 0.9519, 0.9463, 0.9406, 0.9344, 0.9272,
|
||||
0.9197, 0.9107, 0.9016, 0.8903, 0.8791, 0.8653, 0.8523, 0.8357, 0.8179, 0.7988,
|
||||
0.7779, 0.7562, 0.7318, 0.7024, 0.6753, 0.6435, 0.6089, 0.5700, 0.5296, 0.4860,
|
||||
0.4366, 0.3855, 0.3301, 0.2735, 0.2114, 0.1443, 0.0682, 0.0000, -0.0715, -0.1604,
|
||||
-0.2478, -0.3377, -0.4287, -0.5277, -0.6291, -0.7384, -0.8457, -0.9559, -1.0742, -1.1913,
|
||||
-1.3110, -1.4238, -1.5594, -1.6854, -1.8093, -1.9414, -2.0763, -2.2160, -2.3611, -2.4876,
|
||||
-2.6374, -2.7710, -2.9225, -3.0591, -3.2077, -3.3452, -3.4916, -3.6316, -3.7735, -3.9296,
|
||||
-4.0682, -4.2334, -4.3607, -4.5270, -4.6807, -4.8108, -4.9753, -5.1212, -5.2631, -5.4042,
|
||||
-5.5510, -5.7227, -5.8794, -6.0244, -6.1677, -6.3271, -6.4862, -6.6130, -6.7449, -6.9250,
|
||||
-7.1232, -7.1736, -7.3628, -7.5596, -7.6906, -7.8129, -7.9817, -8.1440, -8.3016, -8.4797,
|
||||
-8.5734, -8.7692, -8.9198, -9.0610, -9.1746, -9.3536, -9.5939, -9.6957, -9.8475, -9.9639,
|
||||
-10.1730, -10.2427, -10.4573, -11.7794, -11.8801, -12.1717, -12.2354, -12.3686, -12.6195, -12.6527,
|
||||
-12.8247, -12.9560, -13.3265, -13.1667, -13.4274, -13.6064, -13.5515, -13.9501, -13.9926, -14.4049,
|
||||
-14.1653, -14.4348, -14.7983, -14.7807, -15.2349, -15.3536, -15.3026, -15.2739, -15.7170, -16.2161,
|
||||
-15.9185, -15.9490, -16.6258, -16.5568, -16.4318, -16.7999, -16.4101, -17.6393, -17.7643, -17.2644,
|
||||
-17.5973, -17.0403, -17.7039, -18.0073, -18.1840, -18.3848, -18.6286, -20.7063, 1.43370769e-019,
|
||||
2.64031087e-006, 6.6908396e+031, 1.77537994e+028, 2.79322819e+020, 1.94326e-019,
|
||||
0.00019371575, 2.80722121e-041}};
|
||||
|
|
|
@ -449,10 +449,3 @@ uint32_t nhash(const void *key, size_t length, uint32_t initval) {
|
|||
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fortran argument compatible wrapper
|
||||
*/
|
||||
uint32_t nhash_(const void *key, size_t const *length, uint32_t const *initval) {
|
||||
return nhash(key, *length, *initval);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
uint32_t nhash(const void* key, size_t length, uint32_t initval);
|
||||
uint32_t nhash_(void const* key, size_t const* length, uint32_t const* initval);
|
||||
|
|
821
wsprd/wsprd.c
821
wsprd/wsprd.c
Plik diff jest za duży
Load Diff
|
@ -35,37 +35,71 @@
|
|||
|
||||
/* Option & config of decoder (Shared with the wsprd code) */
|
||||
struct decoder_options {
|
||||
uint32_t freq; // Dial frequency
|
||||
char rcall[13]; // Callsign of the RX station
|
||||
char rloc[7]; // Locator of the RX station
|
||||
uint32_t quickmode; // Decoder option & tweak
|
||||
uint32_t usehashtable; // ''
|
||||
uint32_t npasses; // ''
|
||||
uint32_t subtraction; // ''
|
||||
int freq; // Dial frequency
|
||||
char rcall[13]; // Callsign of the RX station
|
||||
char rloc[7]; // Locator of the RX station
|
||||
int quickmode; // Decoder option & tweak
|
||||
int usehashtable; // ''
|
||||
int npasses; // ''
|
||||
int subtraction; // ''
|
||||
};
|
||||
|
||||
struct cand {
|
||||
float freq;
|
||||
float snr;
|
||||
int shift;
|
||||
float drift;
|
||||
float sync;
|
||||
};
|
||||
|
||||
struct decoder_results {
|
||||
double freq;
|
||||
float sync;
|
||||
float snr;
|
||||
float dt;
|
||||
float drift;
|
||||
int32_t jitter;
|
||||
char message[23];
|
||||
char call[13];
|
||||
char loc[7];
|
||||
char pwr[3];
|
||||
uint32_t cycles;
|
||||
double freq;
|
||||
float sync;
|
||||
float snr;
|
||||
float dt;
|
||||
float drift;
|
||||
int jitter;
|
||||
char message[23];
|
||||
char call[13];
|
||||
char loc[7];
|
||||
char pwr[3];
|
||||
int cycles;
|
||||
};
|
||||
|
||||
void sync_and_demodulate(float *id, float *qd, long np,
|
||||
uint8_t *symbols, float *freq1, float fstep,
|
||||
int32_t *shift1, int32_t lagmin, int32_t lagmax, int32_t lagstep,
|
||||
float *drift1, int32_t symfac, float *sync, int32_t mode);
|
||||
void subtract_signal(float *id, float *qd, long np,
|
||||
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
|
||||
void subtract_signal2(float *id, float *qd, long np,
|
||||
float f0, int32_t shift0, float drift0, uint8_t *channel_symbols);
|
||||
int32_t wspr_decode(float *idat, float *qdat, uint32_t npoints,
|
||||
struct decoder_options options, struct decoder_results *decodes,
|
||||
int32_t *n_results);
|
||||
void sync_and_demodulate(float *id,
|
||||
float *qd,
|
||||
long np,
|
||||
unsigned char *symbols,
|
||||
float *freq,
|
||||
int ifmin,
|
||||
int ifmax,
|
||||
float fstep,
|
||||
int *shift,
|
||||
int lagmin,
|
||||
int lagmax,
|
||||
int lagstep,
|
||||
float *drift,
|
||||
int symfac,
|
||||
float *sync,
|
||||
int mode);
|
||||
void subtract_signal(float *id,
|
||||
float *qd,
|
||||
long np,
|
||||
float f0,
|
||||
int shift,
|
||||
float drift,
|
||||
unsigned char *channel_symbols);
|
||||
void subtract_signal2(float *id,
|
||||
float *qd,
|
||||
long np,
|
||||
float f0,
|
||||
int shift,
|
||||
float drift,
|
||||
unsigned char *channel_symbols);
|
||||
int wspr_decode(float *idat,
|
||||
float *qdat,
|
||||
int samples,
|
||||
struct decoder_options options,
|
||||
struct decoder_results *decodes,
|
||||
int *n_results);
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ int unpackgrid(int32_t ngrid, char *grid) {
|
|||
}
|
||||
|
||||
int unpackpfx(int32_t nprefix, char *call) {
|
||||
char nc, pfx[4] = "", tmpcall[7] = "";
|
||||
char nc, pfx[4] = {'\0'}, tmpcall[7];
|
||||
int i;
|
||||
int32_t n;
|
||||
|
||||
|
@ -172,7 +172,8 @@ int unpackpfx(int32_t nprefix, char *call) {
|
|||
n = n / 37;
|
||||
}
|
||||
|
||||
strcpy(call, pfx);
|
||||
char *p = strrchr(pfx, ' ');
|
||||
strcpy(call, p ? p + 1 : pfx);
|
||||
strncat(call, "/", 1);
|
||||
strncat(call, tmpcall, strlen(tmpcall));
|
||||
|
||||
|
@ -234,9 +235,9 @@ int floatcomp(const void *elem1, const void *elem2) {
|
|||
return *(const float *)elem1 > *(const float *)elem2;
|
||||
}
|
||||
|
||||
int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign) {
|
||||
int unpk_(signed char *message, char *hashtab, char *loctab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign) {
|
||||
int n1, n2, n3, ndbm, ihash, nadd, noprint = 0;
|
||||
char grid[5], grid6[7], cdbm[3];
|
||||
char grid[5], grid6[7], cdbm[4];
|
||||
|
||||
unpack50(message, &n1, &n2);
|
||||
if (!unpackcall(n1, callsign))
|
||||
|
@ -250,13 +251,10 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
/*
|
||||
Based on the value of ntype, decide whether this is a Type 1, 2, or
|
||||
3 message.
|
||||
|
||||
* Type 1: 6 digit call, grid, power - ntype is positive and is a member
|
||||
of the set {0,3,7,10,13,17,20...60}
|
||||
|
||||
* Type 2: extended callsign, power - ntype is positive but not
|
||||
a member of the set of allowed powers
|
||||
|
||||
* Type 3: hash, 6 digit grid, power - ntype is negative.
|
||||
*/
|
||||
|
||||
|
@ -265,7 +263,7 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
if (nu == 0 || nu == 3 || nu == 7) {
|
||||
ndbm = ntype;
|
||||
memset(call_loc_pow, 0, sizeof(char) * 23);
|
||||
sprintf(cdbm, "%2d", ndbm);
|
||||
sprintf(cdbm, "%02d", ndbm);
|
||||
strncat(call_loc_pow, callsign, strlen(callsign));
|
||||
strncat(call_loc_pow, " ", 1);
|
||||
strncat(call_loc_pow, grid, 4);
|
||||
|
@ -274,26 +272,23 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
strncat(call_loc_pow, "\0", 1);
|
||||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
strcpy(loctab + ihash * 5, grid);
|
||||
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, strlen(grid) + 1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
memset(call, 0, sizeof(char) * strlen(callsign) + 1);
|
||||
memset(loc, 0, sizeof(char) * strlen(grid) + 1);
|
||||
memset(pwr, 0, sizeof(char) * 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, grid, strlen(grid));
|
||||
strncat(loc, "\0", 1);
|
||||
strncat(pwr, cdbm, 2);
|
||||
strncat(pwr, "\0", 1);
|
||||
|
||||
} else {
|
||||
nadd = nu;
|
||||
if (nu > 3)
|
||||
nadd = nu - 3;
|
||||
if (nu > 7)
|
||||
nadd = nu - 7;
|
||||
if (nu > 3) nadd = nu - 3;
|
||||
if (nu > 7) nadd = nu - 7;
|
||||
n3 = n2 / 128 + 32768 * (nadd - 1);
|
||||
if (!unpackpfx(n3, callsign))
|
||||
return 1;
|
||||
if (!unpackpfx(n3, callsign)) return 1;
|
||||
ndbm = ntype - nadd;
|
||||
memset(call_loc_pow, 0, sizeof(char) * 23);
|
||||
sprintf(cdbm, "%2d", ndbm);
|
||||
|
@ -305,33 +300,23 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
if (nu == 0 || nu == 3 || nu == 7) { // make sure power is OK
|
||||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
} else {
|
||||
} else
|
||||
noprint = 1;
|
||||
}
|
||||
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, 1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, "\0", 1);
|
||||
strncat(pwr, cdbm, 2);
|
||||
strncat(pwr, "\0", 1);
|
||||
}
|
||||
} else if (ntype < 0) {
|
||||
ndbm = -(ntype + 1);
|
||||
memset(grid6, 0, sizeof(char) * 7);
|
||||
strncat(grid6, callsign + 5, 1);
|
||||
strncat(grid6, callsign, 5);
|
||||
// size_t len=strlen(callsign);
|
||||
size_t len = 6;
|
||||
strncat(grid6, callsign + len - 1, 1);
|
||||
strncat(grid6, callsign, len - 1);
|
||||
int nu = ndbm % 10;
|
||||
if ((nu == 0 || nu == 3 || nu == 7) &&
|
||||
(isalpha(grid6[0]) && isalpha(grid6[1]) && isdigit(grid6[2]) && isdigit(grid6[3]))) {
|
||||
if ((nu != 0 && nu != 3 && nu != 7) ||
|
||||
!isalpha(grid6[0]) || !isalpha(grid6[1]) ||
|
||||
!isdigit(grid6[2]) || !isdigit(grid6[3])) {
|
||||
// not testing 4'th and 5'th chars because of this case: <PA0SKT/2> JO33 40
|
||||
// grid is only 4 chars even though this is a hashed callsign...
|
||||
// isalpha(grid6[4]) && isalpha(grid6[5]) ) ) {
|
||||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
strcpy(hashtab + ihash * 13, callsign);
|
||||
} else {
|
||||
noprint = 1;
|
||||
}
|
||||
|
||||
|
@ -351,9 +336,9 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
strncat(call_loc_pow, cdbm, 2);
|
||||
strncat(call_loc_pow, "\0", 1);
|
||||
|
||||
memset(call, 0, strlen(callsign) + 1);
|
||||
memset(loc, 0, strlen(grid6) + 1);
|
||||
memset(pwr, 0, 2 + 1);
|
||||
memset(call, 0, sizeof(char) * strlen(callsign) + 1);
|
||||
memset(loc, 0, sizeof(char) * strlen(grid6) + 1);
|
||||
memset(pwr, 0, sizeof(char) * 2 + 1);
|
||||
strncat(call, callsign, strlen(callsign));
|
||||
strncat(call, "\0", 1);
|
||||
strncat(loc, grid6, strlen(grid6));
|
||||
|
@ -362,7 +347,7 @@ int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, c
|
|||
strncat(pwr, "\0", 1);
|
||||
|
||||
// I don't know what to do with these... They show up as "A000AA" grids.
|
||||
if (ntype == -64)
|
||||
if (ntype == -64)
|
||||
noprint = 1;
|
||||
}
|
||||
return noprint;
|
||||
|
|
|
@ -39,4 +39,4 @@ void deinterleave(unsigned char *sym);
|
|||
int doublecomp(const void *elem1, const void *elem2);
|
||||
int floatcomp(const void *elem1, const void *elem2);
|
||||
|
||||
int unpk_(signed char *message, char *hashtab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign);
|
||||
int unpk_(signed char *message, char *hashtab, char *loctab, char *call_loc_pow, char *call, char *loc, char *pwr, char *callsign);
|
||||
|
|
|
@ -38,7 +38,7 @@ char get_callsign_character_code(char ch) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
long unsigned int pack_grid4_power(char *grid4, int power) {
|
||||
long unsigned int pack_grid4_power(char const *grid4, int power) {
|
||||
long unsigned int m;
|
||||
|
||||
m = (179 - 10 * grid4[0] - grid4[2]) * 180 + 10 * grid4[1] + grid4[3];
|
||||
|
@ -46,31 +46,23 @@ long unsigned int pack_grid4_power(char *grid4, int power) {
|
|||
return m;
|
||||
}
|
||||
|
||||
long unsigned int pack_call(char *callsign) {
|
||||
int i;
|
||||
long unsigned int pack_call(char const *callsign) {
|
||||
unsigned int i;
|
||||
long unsigned int n;
|
||||
char call6[6];
|
||||
memset(call6, 32, sizeof(char) * 6);
|
||||
memset(call6, ' ', sizeof(call6));
|
||||
// callsign is 6 characters in length. Exactly.
|
||||
int call_len = strlen(callsign);
|
||||
size_t call_len = strlen(callsign);
|
||||
if (call_len > 6) {
|
||||
return 0;
|
||||
}
|
||||
if (isdigit(*(callsign + 2))) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (callsign[i] == 0) {
|
||||
call6[i] = 32;
|
||||
} else {
|
||||
call6[i] = *(callsign + i);
|
||||
}
|
||||
if (isdigit(callsign[2])) {
|
||||
for (i = 0; i < call_len; i++) {
|
||||
call6[i] = callsign[i];
|
||||
}
|
||||
} else if (isdigit(*(callsign + 1))) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (i == 0 || callsign[i - 1] == 0) {
|
||||
call6[i] = 32;
|
||||
} else {
|
||||
call6[i] = *(callsign + i - 1);
|
||||
}
|
||||
} else if (isdigit(callsign[1])) {
|
||||
for (i = 1; i < call_len + 1; i++) {
|
||||
call6[i] = callsign[i - 1];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 6; i++) {
|
||||
|
@ -86,17 +78,16 @@ long unsigned int pack_call(char *callsign) {
|
|||
}
|
||||
|
||||
void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd) {
|
||||
int i;
|
||||
char *call6;
|
||||
call6 = malloc(sizeof(char) * 6);
|
||||
memset(call6, 32, sizeof(char) * 6);
|
||||
int i1 = strcspn(callsign, "/");
|
||||
size_t i;
|
||||
char *call6 = calloc(7, sizeof(char));
|
||||
size_t i1 = strcspn(callsign, "/");
|
||||
|
||||
if (callsign[i1 + 2] == 0) {
|
||||
// single char suffix
|
||||
for (i = 0; i < i1; i++) {
|
||||
call6[i] = callsign[i];
|
||||
}
|
||||
call6[i] = '\0';
|
||||
*n = pack_call(call6);
|
||||
*nadd = 1;
|
||||
int nc = callsign[i1 + 1];
|
||||
|
@ -118,11 +109,10 @@ void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd) {
|
|||
*m = 10 * (callsign[i1 + 1] - 48) + (callsign[i1 + 2] - 48);
|
||||
*m = 60000 + 26 + *m;
|
||||
} else {
|
||||
char *pfx = strtok(callsign, "/");
|
||||
*n = pack_call(strtok(NULL, " "));
|
||||
//call6 = strtok(NULL, " ");
|
||||
//*n = pack_call(call6);
|
||||
int plen = strlen(pfx);
|
||||
char const *pfx = strtok(callsign, "/");
|
||||
char const *call = strtok(NULL, " ");
|
||||
*n = pack_call(call);
|
||||
size_t plen = strlen(pfx);
|
||||
if (plen == 1) {
|
||||
*m = 36;
|
||||
*m = 37 * (*m) + 36;
|
||||
|
@ -148,6 +138,7 @@ void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd) {
|
|||
*nadd = 1;
|
||||
}
|
||||
}
|
||||
free(call6);
|
||||
}
|
||||
|
||||
void interleave(unsigned char *sym) {
|
||||
|
@ -169,10 +160,11 @@ void interleave(unsigned char *sym) {
|
|||
}
|
||||
}
|
||||
|
||||
int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *symbols) {
|
||||
int m = 0, n = 0, ntype = 0;
|
||||
int get_wspr_channel_symbols(char *rawmessage, char *hashtab, char *loctab, unsigned char *symbols) {
|
||||
int m = 0, ntype = 0;
|
||||
long unsigned int n = 0;
|
||||
int i, j, ihash;
|
||||
unsigned char pr3[162] = {
|
||||
unsigned char pr3vector[162] = {
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,
|
||||
0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1,
|
||||
|
@ -181,7 +173,8 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1,
|
||||
0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0,
|
||||
0, 0};
|
||||
0, 0 };
|
||||
|
||||
int nu[10] = {0, -1, 1, 0, -1, 2, 1, 0, -1, 1};
|
||||
char *callsign, *grid, *powstr;
|
||||
char grid4[5], message[23];
|
||||
|
@ -193,16 +186,16 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
i++;
|
||||
}
|
||||
|
||||
int i1 = strcspn(message, " ");
|
||||
int i2 = strcspn(message, "/");
|
||||
int i3 = strcspn(message, "<");
|
||||
int i4 = strcspn(message, ">");
|
||||
int mlen = strlen(message);
|
||||
size_t i1 = strcspn(message, " ");
|
||||
size_t i2 = strcspn(message, "/");
|
||||
size_t i3 = strcspn(message, "<");
|
||||
size_t i4 = strcspn(message, ">");
|
||||
size_t mlen = strlen(message);
|
||||
|
||||
// Use the presence and/or absence of "<" and "/" to decide what
|
||||
// type of message. No sanity checks! Beware!
|
||||
|
||||
if ((i1 > 3) & (i1 < 7) & (i2 == mlen) & (i3 == mlen)) {
|
||||
if (i1 > 3 && i1 < 7 && i2 == mlen && i3 == mlen) {
|
||||
// Type 1 message: K9AN EN50 33
|
||||
// xxnxxxx xxnn nn
|
||||
callsign = strtok(message, " ");
|
||||
|
@ -232,8 +225,8 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
ihash = nhash(callsign, strlen(callsign), (uint32_t)146);
|
||||
m = 128 * ihash + ntype + 64;
|
||||
|
||||
char grid6[6];
|
||||
memset(grid6, 32, sizeof(char) * 6);
|
||||
char grid6[7];
|
||||
memset(grid6, 0, sizeof(char) * 7);
|
||||
j = strlen(grid);
|
||||
for (i = 0; i < j - 1; i++) {
|
||||
grid6[i] = grid[i + 1];
|
||||
|
@ -243,7 +236,7 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
} else if (i2 < mlen) { // just looks for a right slash
|
||||
// Type 2: PJ4/K1ABC 37
|
||||
callsign = strtok(message, " ");
|
||||
if (strlen(callsign) < i2) return 0; // guards against pathological case
|
||||
if (i2 == 0 || i2 > strlen(callsign)) return 0; // guards against pathological case
|
||||
powstr = strtok(NULL, " ");
|
||||
int power = atoi(powstr);
|
||||
if (power < 0) power = 0;
|
||||
|
@ -283,8 +276,6 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
// make sure that the 11-byte data vector is unpackable
|
||||
// unpack it with the routine that the decoder will use and display
|
||||
// the result. let the operator decide whether it worked.
|
||||
// char hashtab[32768][13];
|
||||
// memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
char *check_call_loc_pow, *check_callsign, *call, *loc, *pwr;
|
||||
check_call_loc_pow = malloc(sizeof(char) * 23);
|
||||
|
@ -294,21 +285,23 @@ int get_wspr_channel_symbols(char *rawmessage, char *hashtab, unsigned char *sym
|
|||
pwr = malloc(sizeof(char) * 3);
|
||||
signed char check_data[11];
|
||||
memcpy(check_data, data, sizeof(char) * 11);
|
||||
unpk_(check_data, hashtab, check_call_loc_pow, call, loc, pwr, check_callsign);
|
||||
|
||||
unpk_(check_data, hashtab, loctab, check_call_loc_pow, call, loc, pwr, check_callsign);
|
||||
// printf("Will decode as: %s\n",check_call_loc_pow);
|
||||
|
||||
unsigned int nbytes = 11; // The message with tail is packed into 11 bytes.
|
||||
unsigned int nencoded = (nbytes * 2 * 8); // This is how much encode() writes
|
||||
unsigned char channelbits[nencoded];
|
||||
memset(channelbits, 0, sizeof(char) * nencoded);
|
||||
unsigned int nbytes = 11; // The message with tail is packed into almost 11 bytes.
|
||||
unsigned char channelbits[nbytes * 8 * 2]; /* 162 rounded up */
|
||||
memset(channelbits, 0, sizeof(char) * nbytes * 8 * 2);
|
||||
|
||||
encode(channelbits, data, nbytes);
|
||||
|
||||
interleave(channelbits);
|
||||
|
||||
for (i = 0; i < 162; i++) {
|
||||
symbols[i] = 2 * channelbits[i] + pr3[i];
|
||||
symbols[i] = 2 * channelbits[i] + pr3vector[i];
|
||||
}
|
||||
|
||||
free(check_call_loc_pow);
|
||||
free(check_callsign);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
char get_locator_character_code(char ch);
|
||||
char get_callsign_character_code(char ch);
|
||||
long unsigned int pack_grid4_power(char *grid4, int power);
|
||||
long unsigned int pack_call(char *callsign);
|
||||
long unsigned int pack_grid4_power(char const *grid4, int power);
|
||||
long unsigned int pack_call(char const *callsign);
|
||||
void pack_prefix(char *callsign, int32_t *n, int32_t *m, int32_t *nadd);
|
||||
void interleave(unsigned char *sym);
|
||||
int get_wspr_channel_symbols(char *message, char *hashtab, unsigned char *symbols);
|
||||
int get_wspr_channel_symbols(char *rawmessage, char *hashtab, char *loctab, unsigned char *symbols);
|
||||
|
|
Ładowanie…
Reference in New Issue