Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
* Test error detection and correction etc.
* Run tests on all CI platforms
  • Loading branch information
windytan committed Jun 27, 2024
1 parent 81eea4b commit b143821
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 89 deletions.
27 changes: 25 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ name: build

on:
push:
branches: [ master ]
branches: [ master, dev ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]

Expand All @@ -20,8 +21,24 @@ jobs:
run: meson setup -Dwerror=true build
- name: compile
run: cd build && meson compile
- name: test
run: cd build && meson test

build-deb:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Install Debian packaging tools
run: sudo apt install build-essential devscripts debhelper equivs
- name: Install Build-Depends
run: sudo mk-build-deps --install --tool 'apt-get --yes'
- name: Build .deb
run: debuild -us -uc
- name: Install .deb
run: sudo dpkg -i redsea_*.deb

macos-build-and-test:
macos-build:
runs-on: macos-latest

steps:
Expand Down Expand Up @@ -66,6 +83,9 @@ jobs:
shell: msys2 {0}
run: |
meson setup -Dwerror=true build && cd build && meson compile
- name: test
shell: msys2 {0}
run: cd build && meson test
- name: Package into distrib
shell: msys2 {0}
run: >-
Expand Down Expand Up @@ -118,3 +138,6 @@ jobs:
- name: Build redsea
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
run: meson setup -Dwerror=true build && cd build && meson compile
- name: test
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
run: cd build && meson test
16 changes: 11 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Contributing guidelines

## Editing the wiki
## Edit the wiki

It would be nice to have accessible, up-to-date documentation in the
[wiki](https://github.com/windytan/redsea/wiki). It can be edited by
anyone, and I invite you to improve it.
anyone, and you're invited to improve it.

## Creating an issue
## Create an issue

[Bug reports](https://github.com/windytan/redsea/issues) are very useful
for the development of redsea.
Expand All @@ -21,11 +21,17 @@ Some guidelines for making good bug reports:
* Did you compile the libraries (liquid-dsp, sndfile) yourself or are they
from package repositories?
* If there is an error message, please include the error message verbatim in
the bug report. If it is very long, consider putting it in a file or gist
instead.
the bug report. If it is very long, consider putting it in a file or
[gist](https://gist.github.com/) instead.
* Be sure to check back with GitHub afterwards to see if I've asked any
clarifying questions. I may not have access to an environment similar to
yours and can't necessarily reproduce the bug myself, and that's why I
may have many questions at first.
* If you fixed the problem yourself, it would be helpful to hear your
solution! It's possible that others will also run into similar problems.
* Please be patient with it; Redsea is a single-maintainer hobby project.

## Join the discussion

We have a [discussion section](https://github.com/windytan/redsea/discussions)
on GitHub for questions and brainstorming.
39 changes: 16 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ redsea is a lightweight command-line FM-RDS decoder that supports many [RDS feat
[![release](https://img.shields.io/github/release/windytan/redsea.svg)](https://github.com/windytan/redsea/releases/latest)
![build](https://github.com/windytan/redsea/workflows/build/badge.svg)

Its terminal output is [line-delimited JSON](https://jsonlines.org/) where
It prints [newline-delimited JSON](https://jsonlines.org/) where
each line corresponds to one RDS group. It can also print "raw" undecoded hex blocks (`--output hex`).
Please refer to the wiki for [input data formats][Wiki: Input].

Expand Down Expand Up @@ -45,28 +45,33 @@ Example output:
These commands should be run in the terminal. Don't type the `$` in the
beginning.

1. Install the prerequisites. On Ubuntu:
### Install dependencies

$ sudo apt install git ninja-build build-essential python3-pip libsndfile1-dev libliquid-dev
$ pip3 install --user meson
On Ubuntu:

$ sudo apt install git build-essential meson libsndfile1-dev libliquid-dev

Or on macOS using Homebrew:

$ brew install meson libsndfile liquid-dsp nlohmann-json
$ xcode-select --install

Meson will download nlohmann-json for you if it can't be found in the package repositories.
Meson will later download nlohmann-json for you if it can't be found in the package repositories.

### Get redsea

2. Clone the repository (unless you downloaded a release zip file):
If you wish to have the latest snapshot you can clone this git repository. The
snapshot might be more work-in-progress than the releases, but we attempt to
keep the main branch stable.

$ git clone https://github.com/windytan/redsea.git
$ cd redsea

3. Compile redsea:
### Compile redsea

$ meson setup build && cd build && meson compile

How to later get the latest updates and recompile:
To later get the latest updates and recompile:

$ git pull
$ cd build && meson compile
Expand All @@ -82,7 +87,7 @@ an .exe with MSYS2/MinGW; Instructions are in [the wiki][Wiki: Windows build].

By default, an MPX signal is expected via stdin (raw 16-bit signed-integer PCM).

The simplest way to view RDS groups using `rtl_fm` is:
This command listens to 87.9 MHz using `rtl_fm` and displays the RDS groups:

rtl_fm -M fm -l 0 -A std -p 0 -s 171k -g 20 -F 9 -f 87.9M | redsea -r 171k

Expand Down Expand Up @@ -166,25 +171,13 @@ redsea -f WAVEFILE
-x, --output-hex Same as --output hex (for backwards compatibility).
```

### Formatting and filtering the JSON output

You can get tidier json output using `jq`:

$ rtl_fm ... | redsea | jq

It's also useful for extracting only certain fields, for instance the program
type:

$ rtl_fm ... | redsea | jq '.prog_type'


## Requirements

### Runtime

* Linux/macOS/Windows
* For realtime decoding, a Raspberry Pi 1 or faster
* ~8 MB of free memory (~128 MB for RDS-TMC)
* libiconv 1.16
* libsndfile 1.0.31
* [liquid-dsp][liquid-dsp] release 1.3.2
Expand Down Expand Up @@ -220,8 +213,8 @@ Try running this in the terminal:

## Contributing

Bug reports are welcome. See [CONTRIBUTING](CONTRIBUTING.md) for more
information.
We welcome bug reports and documentation contributions. See
[CONTRIBUTING](CONTRIBUTING.md) for more information.

Also, if a station in your area is transmitting an interesting RDS feature
that should be implemented in redsea, I would be happy to see a minute or
Expand Down
2 changes: 1 addition & 1 deletion debian/install
Original file line number Diff line number Diff line change
@@ -1 +1 @@
build/redsea /usr/bin
redsea /usr/bin
2 changes: 1 addition & 1 deletion src/redsea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <iostream>
#include <memory>

#include "build/config.h"
#include "config.h"
#include "src/channel.h"
#include "src/common.h"
#include "src/dsp/subcarrier.h"
Expand Down
67 changes: 44 additions & 23 deletions test/test_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using HexData = std::vector<uint64_t>;
using BinaryData = std::vector<uint32_t>;

// Convert synchronized hex data into groups. Error correction is omitted and ignored.
inline std::vector<redsea::Group> makeGroupsFromHex(const HexData& hexdata) {
inline std::vector<redsea::Group> hex2groups(const HexData& hexdata) {
std::vector<redsea::Group> groups;
groups.reserve(hexdata.size());

Expand All @@ -34,37 +34,53 @@ inline std::vector<redsea::Group> makeGroupsFromHex(const HexData& hexdata) {
return groups;
}

inline std::vector<nlohmann::ordered_json> decodeBinary(const BinaryData& bindata,
const redsea::Options& options) {
// Convert string of unsynchronized ASCII bits into JSON.
inline std::vector<nlohmann::ordered_json> asciibin2json(const std::string& bindata,
const redsea::Options& options) {
std::vector<nlohmann::ordered_json> result;

std::stringstream json_stream;
redsea::Channel channel(options, 0, json_stream);

for (const auto& word : bindata) {
constexpr auto wordsize_bits{sizeof(word) * 8};
for (const auto& ascii_bit : bindata) {
const int bit{ascii_bit == '1' ? 1 : 0};

for (size_t nbit{}; nbit < wordsize_bits; nbit++) {
int bit = (word >> (wordsize_bits - 1 - nbit)) & 0b1;
channel.processBit(bit);
if (!json_stream.str().empty()) {
nlohmann::ordered_json jsonroot;
json_stream >> jsonroot;
result.push_back(jsonroot);
channel.processBit(bit);
if (!json_stream.str().empty()) {
nlohmann::ordered_json jsonroot;
json_stream >> jsonroot;
result.push_back(jsonroot);

json_stream.str("");
json_stream.clear();
}
}

json_stream.str("");
json_stream.clear();
}
return result;
}

// Convert string of unsynchronized ASCII bits into groups.
inline std::vector<redsea::Group> asciibin2groups(const std::string& bindata,
const redsea::Options& options) {
std::vector<redsea::Group> result;
redsea::BlockStream block_stream(options);

for (const auto& ascii_bit : bindata) {
const int bit{ascii_bit == '1' ? 1 : 0};

block_stream.pushBit(bit);
if (block_stream.hasGroupReady()) {
result.push_back(block_stream.popGroup());
}
}

return result;
}

// Run redsea's decoder and convert the ascii json output into json objects.
inline std::vector<nlohmann::ordered_json> decodeGroups(const std::vector<redsea::Group>& data,
const redsea::Options& options,
uint16_t pi) {
// Run redsea's full decoder and convert the ASCII JSON output back into JSON objects.
inline std::vector<nlohmann::ordered_json> groups2json(const std::vector<redsea::Group>& data,
const redsea::Options& options,
uint16_t pi) {
std::vector<nlohmann::ordered_json> result;

std::stringstream json_stream;
Expand All @@ -83,10 +99,10 @@ inline std::vector<nlohmann::ordered_json> decodeGroups(const std::vector<redsea
return result;
}

inline std::vector<nlohmann::ordered_json> decodeGroups(const HexData& hexdata,
const redsea::Options& options,
uint16_t pi) {
return decodeGroups(makeGroupsFromHex(hexdata), options, pi);
// Convert synchronized hex data (without offset words) into JSON.
inline std::vector<nlohmann::ordered_json> hex2json(const HexData& hexdata,
const redsea::Options& options, uint16_t pi) {
return groups2json(hex2groups(hexdata), options, pi);
}

template <typename T>
Expand All @@ -105,4 +121,9 @@ bool listEquals(nlohmann::ordered_json json, std::initializer_list<T> list) {
return true;
}

// Flip a bit in a string of ASCII bits.
void flipAsciiBit(std::string& str, size_t bit_index) {
str[bit_index] = str[bit_index] == '0' ? '1' : '0';
}

#endif // TEST_HELPERS_H_
Loading

0 comments on commit b143821

Please sign in to comment.