diff --git a/.github/container/README.md b/.github/container/README.md new file mode 100644 index 0000000..e84b007 --- /dev/null +++ b/.github/container/README.md @@ -0,0 +1,49 @@ +# Rust Cross-Compiling Containers + +[cross-rs](https://github.com/cross-rs/cross) splits the build environment into: + +1. An "outer" build environment, which contains `cargo` and a toolchain. + +2. An "inner" build environment, which includes a gcc cross-compiler, foreign-architecture runtime libraries, and qemu. + +If the outer build environment is containerized, this introduces problems. The inner build environment (2) needs access to the host's Docker or podman socket. This can be done, but it does not mesh well with Github Actions' `jobs:*:container` option. + +Further, with containers, we want all parts of the build environment: + +* Included and ready-to-use +* Fully-defined by the `Containerfile` and the image's `sha256:` hash + +Depending on an external container at runtime defeats some of these design goals. + +Instead of using cross-rs, we create our own environment that includes all of these tools. See + +``` +./build.sh +``` + +to build it. The build instructions are heavily influenced by the cross-rs project but do not depend on it. + +You can use any of these containers offline to build samedec. Define the following volumes: + +* `/src`: the repository root of a Rust project +* `/install`: destination for binaries installed with `cargo install` +* `/src/target` (**optional**): a build directory. +* `/cargohome` (**optional**): a persistent `$CARGO_HOME` directory + +Example: + +```bash +mkdir -p out/aarch64-unknown-linux-gnu + +podman run \ + --security-opt label=disable \ + --userns=keep-id:uid=1001,gid=1001 \ + --rm -it \ + --volume .:/src:ro \ + --volume ./target:/src/target:rw \ + --volume ./out/aarch64-unknown-linux-gnu:/install \ + ghcr.io/cbs228/sameold/builder/aarch64-unknown-linux-gnu \ + cargo install --path crates/samedec +``` + +You should run your build as UID 1001 within the container. The above `--userns` mapping will accomplish this. diff --git a/.github/container/aarch64-unknown-linux-gnu/Dockerfile b/.github/container/aarch64-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000..178e43f --- /dev/null +++ b/.github/container/aarch64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,35 @@ +# +# Debian base image, with arm64 toolchains +# + +FROM ghcr.io/cbs228/sameold/builder/rust:latest + +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ + [ "$(dpkg --print-architecture)" != arm64 ] || exit 0; \ + set -eux; \ + apt-get update; \ + apt-get install -y \ + binutils-aarch64-linux-gnu \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + libc6:arm64 \ + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache + +ARG RUST_TARGET="aarch64-unknown-linux-gnu" + +RUN set -eux; \ + export CARGO_HOME=/usr/local/cargo; \ + rustup target add "$RUST_TARGET"; + +ENV CARGO_BUILD_TARGET="$RUST_TARGET" \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-run-maybe + +USER builder + +LABEL org.opencontainers.image.description="A Debian-based Rust cross-compiling environment." diff --git a/.github/container/armv7-unknown-linux-gnueabihf/Dockerfile b/.github/container/armv7-unknown-linux-gnueabihf/Dockerfile new file mode 100644 index 0000000..5740d43 --- /dev/null +++ b/.github/container/armv7-unknown-linux-gnueabihf/Dockerfile @@ -0,0 +1,35 @@ +# +# Debian base image, with armhf toolchains +# + +FROM ghcr.io/cbs228/sameold/builder/rust:latest + +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ + [ "$(dpkg --print-architecture)" != armhf ] || exit 0; \ + set -eux; \ + apt-get update; \ + apt-get install -y \ + binutils-arm-linux-gnueabi \ + gcc-arm-linux-gnueabihf \ + libc6-dev-armhf-cross \ + libc6:armhf \ + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache + +ARG RUST_TARGET="armv7-unknown-linux-gnueabihf" + +RUN set -eux; \ + export CARGO_HOME=/usr/local/cargo; \ + rustup target add "$RUST_TARGET"; + +ENV CARGO_BUILD_TARGET="$RUST_TARGET" \ + CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ + CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-run-maybe + +USER builder + +LABEL org.opencontainers.image.description="A Debian-based Rust cross-compiling environment." diff --git a/.github/container/base/Dockerfile b/.github/container/base/Dockerfile new file mode 100644 index 0000000..592db44 --- /dev/null +++ b/.github/container/base/Dockerfile @@ -0,0 +1,67 @@ +# +# Debian base image +# + +# or buster-20240612-slim for a snapshot-capable, reproducible image +ARG DEBIAN_TAG=buster-slim + +FROM docker.io/library/debian:${DEBIAN_TAG} + +ARG DEBIAN_TAG +ARG SOURCE_DATE_EPOCH + +# Create a non-root user for running builds +# GHA wants uid 1001 +ARG UID=1001 + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ + set -eux; \ + # create an unprivileged user for builds + groupadd builder -g "$UID"; \ + useradd builder -u "$UID" -g "$UID" --create-home; \ + # build directories for any user + mkdir -m 1777 /src /install /cargo; \ + # re-enable apt caching (we have a cache mount) + rm -f /etc/apt/apt.conf.d/docker-clean; \ + # if tag contains numerics, like buster-20240612-slim, use the + # snapshot URL that's baked into the image + if echo "${DEBIAN_TAG}" | grep -q "[0-9]"; then \ + sed -i -r \ + -e 's/^deb/# deb/' \ + -e 's|^#\s*(.*http://snapshot\.)|\1|' \ + /etc/apt/sources.list; \ + cat >&2 /etc/apt/sources.list; \ + echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/use-snapshot.conf; \ + echo 'Acquire::Retries "10";' >> /etc/apt/apt.conf.d/use-snapshot.conf; \ + echo 'Acquire::Retries::Delay::Maximum "600";' >> /etc/apt/apt.conf.d/use-snapshot.conf; \ + fi; \ + # enable packages from multiple architectures + dpkg --add-architecture amd64; \ + dpkg --add-architecture armhf; \ + dpkg --add-architecture arm64; \ + dpkg --add-architecture i386; \ + # install native C compilers, CI utilities, and qemu + apt-get update; \ + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + gcc \ + git \ + libc6-dev \ + qemu-user \ + qemu-user-binfmt \ + tar \ + zstd; \ + git config --system --add safe.directory '*'; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache + +# Directories for sources and installed binaries +VOLUME ["/src", "/install"] + +LABEL org.opencontainers.image.source="https://github.com/cbs228/sameold" +LABEL org.opencontainers.image.description="A minimal debian cross-compiling environment with good glibc compatibility." + +WORKDIR "/src" diff --git a/.github/container/build.sh b/.github/container/build.sh new file mode 100755 index 0000000..55f1844 --- /dev/null +++ b/.github/container/build.sh @@ -0,0 +1,196 @@ +#!/usr/bin/env bash +# +# (re)build the CI container image +# +# run with --push to push the images. + +# set to disable cache +NO_CACHE="${NO_CACHE:-}" + +DEBIAN_TAG="buster-20240612-slim" +CONTAINER_PREFIX="ghcr.io/cbs228" +CONTAINER_FQNAME="${CONTAINER_PREFIX}/sameold/builder/%s" + +RUST_VERSIONS=("1.84.0") + +usage() { + cat <&2 "$@" + "$@" +} + +container_builder() { + # Usage: automatically detect container platform command + + if [ -x "${BUILDER:-}" ]; then + echo "${BUILDER}" + elif [ -n "${BUILDER:-}" ]; then + command -v "${BUILDER}" + else + { + command -v podman || \ + command -v docker + } 2>/dev/null || { + echo >&2 "FATAL: container platform tools not found" + return 1; + } + fi +} + +container_name() { + # Usage: container_name SUFFIX + + #shellcheck disable=SC2059 + printf "$CONTAINER_FQNAME" "$1" +} + +buildcontainer() { + # Usage: buildcontainer ARGS + # + # Run the $BUILDER to build a container image. Some standardized + # arguments are passed to every build. + + if [[ $BUILDER =~ podman$ ]]; then + run "$BUILDER" build \ + --build-arg SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ + --timestamp "$SOURCE_DATE_EPOCH" \ + ${NO_CACHE:+--no-cache} \ + "$@" + else + # docker mode; 100% untested + run "$BUILDER" buildx build \ + --build-arg SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ + --output type=docker,rewrite-timestamp=true \ + ${NO_CACHE:+--no-cache} \ + "$@" + fi +} + +tagall() { + # Usage: tagall SHORTNAME TAG0 TAG1 ... + # + # Apply all tags to the given image, which must already be tagged as + # "current/container/prefix/$SHORTNAME:$TAG0" + + local prefix + prefix="$(container_name "${1?}")" + shift + + run "$BUILDER" tag "${@/#/"$prefix:"}" +} + +pushall() { + # Usage: pushall SHORTNAME TAG0 TAG1 ... + # + # Push the given image "current/container/prefix/$SHORTNAME" and + # all the tags specified on the command line. The pushes are not + # atomic and will happen sequentially. + + local prefix + prefix="$(container_name "${1?}")" + shift + + local tag + for tag in "$@"; do + run "$BUILDER" push "${prefix}:${tag}" + done +} + +# return if sourced +(return 0 2>/dev/null) && return 0 + +set -euo pipefail + +if ! options="$(getopt -o 'hp' --long help,push -- "$@")"; then + usage >&2 + exit 1 +fi + +eval set -- "${options:-}" +push_images='' +while true; do + case "${1:-}" in + (-h | --help) + usage + exit 0 ;; + (-p | --push) + push_images=y ;; + ('') ;; + esac + shift || break +done + +BUILDER="$(container_builder)" +selfdir="$(dirname "$(realpath -e "${0?}")")" + +# set SOURCE_DATE_EPOCH if possible +SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log -1 --pretty=%ct -- "$selfdir" || date +%s)}" +export SOURCE_DATE_EPOCH + +# tag with "latest" and SOURCE_DATE_EPOCH +CONTAINER_TAGS=("latest" "$(date --date '@'"$SOURCE_DATE_EPOCH" +'%Y-%m-%d')") + +# build the base image +base_tag="$(container_name base):${CONTAINER_TAGS[0]}" + +buildcontainer \ + --build-arg DEBIAN_TAG="$DEBIAN_TAG" \ + --tag "$base_tag" \ + "${selfdir?}/base" + +# add rust to the base image +rust_tag="$(container_name rust):${CONTAINER_TAGS[0]}" + +buildcontainer \ + --from "$base_tag" \ + --build-arg RUST_VERSIONS="${RUST_VERSIONS[*]}" \ + --tag "$rust_tag" \ + "${selfdir?}/rust" + +# build architecture-specific images +for containerdir in "${selfdir?}/"*-*-*; do + [ -d "$containerdir" ] || continue + + platform_triple="$(basename ${containerdir})" + cur_tag="$(container_name "$platform_triple"):${CONTAINER_TAGS[0]}" + + buildcontainer \ + --from "$rust_tag" \ + --tag "${cur_tag}" \ + "${containerdir}" +done + +# if all builds succeed, apply remaining tags... +tagall base "${CONTAINER_TAGS[@]}" +tagall rust "${CONTAINER_TAGS[@]}" +for containerdir in "${selfdir?}/"*-*-*; do + [ -d "$containerdir" ] || continue + + tagall "$(basename "$containerdir")" "${CONTAINER_TAGS[@]}" +done + +[ -n "${push_images:-}" ] || exit 0 + +# ... and push +for containerdir in "${selfdir?}/"*; do + [ -d "$containerdir" ] || continue + + pushall "$(basename "$containerdir")" "${CONTAINER_TAGS[@]}" +done diff --git a/.github/container/i686-unknown-linux-gnu/Dockerfile b/.github/container/i686-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000..0ac2347 --- /dev/null +++ b/.github/container/i686-unknown-linux-gnu/Dockerfile @@ -0,0 +1,35 @@ +# +# Debian base image, with i386 toolchains +# + +FROM ghcr.io/cbs228/sameold/builder/rust:latest + +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ + [ "$(dpkg --print-architecture)" != i386 ] || exit 0; \ + set -eux; \ + apt-get update; \ + apt-get install -y \ + binutils-i686-linux-gnu \ + gcc-i686-linux-gnu \ + libc6-dev-i386-cross \ + libc6:i386 \ + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache + +ARG RUST_TARGET="i686-unknown-linux-gnu" + +RUN set -eux; \ + export CARGO_HOME=/usr/local/cargo; \ + rustup target add "$RUST_TARGET"; + +ENV CARGO_BUILD_TARGET="$RUST_TARGET" \ + CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=i686-linux-gnu-gcc \ + CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_RUNNER=qemu-run-maybe + +USER builder + +LABEL org.opencontainers.image.description="A Debian-based Rust cross-compiling environment." diff --git a/.github/container/rust/Dockerfile b/.github/container/rust/Dockerfile new file mode 100644 index 0000000..b694e14 --- /dev/null +++ b/.github/container/rust/Dockerfile @@ -0,0 +1,59 @@ +# +# Debian base image, with platform-native Rust +# + +FROM ghcr.io/cbs228/sameold/builder/base:latest + +ARG SOURCE_DATE_EPOCH + +# Install rustup and platform-native target +# +# RUST_VERSIONS: list of version numbers or strings +# like `stable`. The first entry becomes the +# default toolchain version. +# +# RUSTUP_ARCH: native architecture as llvm platform triple +# +# RUSTUP_VERSION: version of rustup to download +# +# RUSTUP_SHA256: checksum for this version of rustup on +# ${RUST_ARCH}. +# +# Default values are provided only for x86_64. +ARG RUST_VERSIONS="stable" \ + RUSTUP_ARCH="x86_64-unknown-linux-gnu" \ + RUSTUP_VERSION="1.27.1" \ + RUSTUP_SHA256="6aeece6993e902708983b209d04c0d1dbb14ebb405ddb87def578d41f920f56d" \ + RUSTUP_URL="" + +# Basic cargo/rust configuration, including a `cargo install` +# location of `/install`. +ENV PATH=/install/bin:/usr/local/cargo/bin:$PATH \ + CARGO_INSTALL_ROOT=/install \ + CARGO_HOME=/cargo \ + CARGO_TERM_COLOR=always \ + RUST_BACKTRACE=1 \ + RUSTUP_HOME=/usr/local/rustup + +# Instructions adapted from official Docker image +# +RUN set -eux; \ + export CARGO_HOME=/usr/local/cargo; \ + [ -n "${RUSTUP_URL:-}" ] || RUSTUP_URL="https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/${RUSTUP_ARCH}/rustup-init"; \ + curl -O -sSf "$RUSTUP_URL"; \ + echo "${RUSTUP_SHA256} *rustup-init" | sha256sum -c -; \ + chmod +x rustup-init; \ + default_rust="$(echo "$RUST_VERSIONS" | cut -f1 -d' ')"; \ + ./rustup-init -y --no-modify-path --profile minimal --default-toolchain "$default_rust"; \ + rm rustup-init; \ + rustup --version; \ + cargo --version; \ + rustc --version; \ + rustup set auto-self-update disable; \ + echo "$RUST_VERSIONS" | xargs rustup toolchain add --profile minimal; \ + (umask 022 && echo "$RUSTUP_ARCH" >/etc/rust-native-arch) + +# Install scripts +COPY rootfiles / + +LABEL org.opencontainers.image.description="A pinned Rust toolchain with rustup." diff --git a/.github/container/rust/rootfiles/usr/local/bin/qemu-run-maybe b/.github/container/rust/rootfiles/usr/local/bin/qemu-run-maybe new file mode 100755 index 0000000..807c4cc --- /dev/null +++ b/.github/container/rust/rootfiles/usr/local/bin/qemu-run-maybe @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Runs a Rust binary in qemu user-mode emulation if required. +# +# Not all containerized runtime environments are created +# equal. Some have binfmt configured so that everything +# Just Works. Others do not. This script manually maps +# various Linux Rust triples to their qemu equivalents. + +program="${1?missing PROGRAM}" +shift || true + +if [ ! -x "$program" ]; then + program="$(command -v "$program")" +fi + +case "${CARGO_BUILD_TARGET:-}" in + ("$(cat /etc/rust-native-arch)") + # the build target is the native architecture + exec "$program" "$@" + ;; + (aarch64-unknown-linux-*) + exec qemu-aarch64 -- "$program" "$@" + ;; + (armv7-unknown-linux-*eabihf) + exec qemu-arm -- "$program" "$@" + ;; + (i686-unknown-linux-*) + exec qemu-i386 -- "$program" "$@" + ;; + (x86_64-unknown-linux-*) + exec qemu-x86_64 -- "$program" "$@" + ;; + ('') + # unset; assume native + exec "$program" "$@" + ;; + (*) + echo >&2 "FATAL: Unknown CARGO_BUILD_TARGET=${CARGO_BUILD_TARGET}" + exit 101; + ;; +esac diff --git a/.github/container/x86_64-unknown-linux-gnu/Dockerfile b/.github/container/x86_64-unknown-linux-gnu/Dockerfile new file mode 100644 index 0000000..0d003d2 --- /dev/null +++ b/.github/container/x86_64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,35 @@ +# +# Debian base image, with amd64 toolchains +# + +FROM ghcr.io/cbs228/sameold/builder/rust:latest + +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ + --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ + [ "$(dpkg --print-architecture)" != amd64 ] || exit 0; \ + set -eux; \ + apt-get update; \ + apt-get install -y \ + binutils-x86-64-linux-gnu \ + gcc-x86-64-linux-gnu \ + libc6-dev-amd64-cross \ + libc6:amd64 \ + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache + +ARG RUST_TARGET="x86_64-unknown-linux-gnu" + +RUN set -eux; \ + export CARGO_HOME=/usr/local/cargo; \ + rustup target add "$RUST_TARGET"; + +ENV CARGO_BUILD_TARGET="$RUST_TARGET" \ + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc \ + CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER=qemu-run-maybe + +USER builder + +LABEL org.opencontainers.image.description="A Debian-based Rust cross-compiling environment." diff --git a/.github/workflows/rust_release.yml b/.github/workflows/rust_release.yml deleted file mode 100644 index f217d4b..0000000 --- a/.github/workflows/rust_release.yml +++ /dev/null @@ -1,343 +0,0 @@ -name: Release - -on: - push: - branches: [ "release/**", "develop", "staging/**" ] - tags: [ "samedec-*" ] - -permissions: - contents: write - -env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: 1 - -jobs: - # run `cargo vendor` and cache it - vendor_sources: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - uses: actions/cache@v3 - name: Update crate cargo-vendor cache - id: vendor_cache - with: - path: | - .cargo - vendor - key: cargo-vendor-release-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - cargo-vendor-release - cargo-vendor - enableCrossOsArchive: true - - - uses: actions/cache@v3 - name: Update cargo registry cache - if: steps.vendor_cache.outputs.cache-hit != 'true' - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-cache-release-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-cache-release - ${{ runner.os }}-cargo-cache - - - name: Vendor sources - if: steps.vendor_cache.outputs.cache-hit != 'true' - run: | - mkdir -p .cargo - mkdir -p vendor - cargo vendor --versioned-dirs --locked >.cargo/config.toml - - # Linux builds, with Docker and qemu as required - release_linux: - runs-on: ubuntu-latest - - needs: vendor_sources - - # qemu cross-compiling is very slow - timeout-minutes: 60 - - env: - # See for list of tags - BUILD_RUST_TAG: 1.70.0 - BUILD_OS_GNU: slim-buster - BUILD_OS_MUSL: alpine - CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse - - strategy: - matrix: - include: - - docker: linux/amd64 - os: slim-buster - rust: x86_64-unknown-linux-gnu - - - docker: linux/amd64 - os: alpine - rust: x86_64-unknown-linux-musl - - - docker: linux/arm64 - os: slim-buster - rust: aarch64-unknown-linux-gnu - - - docker: linux/arm64 - os: alpine - rust: aarch64-unknown-linux-musl - - - docker: linux/arm/v7 - os: slim-buster - rust: armv7-unknown-linux-gnueabihf - - steps: - - uses: actions/checkout@v3 - - - uses: actions/cache/restore@v3 - name: Restore crate cargo-vendor cache - with: - path: | - .cargo - vendor - key: cargo-vendor-release-${{ hashFiles('**/Cargo.lock') }} - enableCrossOsArchive: true - fail-on-cache-miss: true - - - name: Set swap space - uses: pierotofy/set-swap-space@v1.0 - with: - swap-size-gb: 10 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: all - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Prepare output directory - run: | - mkdir -m 700 -p "install/bin" - - # Builds a special target in our Dockerfile which builds - # an empty image containing only our Rust binary. This task - # exports the file to - # install/bin/samedec-x86_64-unknown-linux-gnu - # and the like. - - name: Build - uses: docker/build-push-action@v5 - with: - context: . - push: false - load: false - cache-from: type=gha,scope=${{ matrix.os }}_${{ matrix.rust }} - cache-to: type=gha,mode=max,scope=${{ matrix.os }}_${{ matrix.rust }} - tags: samedec:latest - target: localfile - build-args: | - CARGO_BUILD_TARGET=${{ matrix.rust }} - CARGO_NET_OFFLINE=true - BUILD_OS_TAG=${{ matrix.os }} - BUILD_RUST_TAG=${{ env.BUILD_RUST_TAG }} - platforms: ${{ matrix.docker }} - outputs: "type=local,dest=install/bin" - - - name: Copy artifact - run: | - cp install/bin/samedec install/bin/samedec-${{ matrix.rust }} - - - name: Store artifact - uses: actions/upload-artifact@v3 - with: - name: samedec-${{ matrix.rust }} - path: install/bin/samedec-${{ matrix.rust }} - retention-days: 3 - - - name: Upload tagged release - uses: svenstaro/upload-release-action@v2 - if: startsWith(github.ref, 'refs/tags/samedec-') - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: install/bin/samedec-${{ matrix.rust }} - overwrite: true - - - name: Update tag for nightly release - uses: richardsimko/update-tag@v1 - if: github.ref == 'refs/heads/develop' - with: - tag_name: latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload nightly release - uses: svenstaro/upload-release-action@v2 - if: github.ref == 'refs/heads/develop' - with: - tag: "latest" - release_name: "Nightly Release" - body: "This is a rolling release built from the latest `develop` branch." - prerelease: true - file: install/bin/samedec-${{ matrix.rust }} - overwrite: true - - # Win32 build, on whatever machine github has available - release_windows: - runs-on: windows-latest - - needs: vendor_sources - - env: - CARGO_BUILD_TARGET: x86_64-pc-windows-msvc - CARGO_NET_OFFLINE: "true" - CARGO_INSTALL_ROOT: "install/" - RUSTFLAGS: '-C strip=symbols -C target-feature=+crt-static' - samedec_exe: 'install/bin/samedec.exe' - samedec_target_exe: install/bin/samedec-x86_64-pc-windows-msvc.exe - - steps: - - uses: actions/checkout@v3 - - - name: Record environment - shell: bash - run: cargo version - - - uses: actions/cache/restore@v3 - name: Restore crate cargo-vendor cache - with: - path: | - .cargo - vendor - key: cargo-vendor-release-${{ hashFiles('**/Cargo.lock') }} - enableCrossOsArchive: true - fail-on-cache-miss: true - - - name: Build - shell: bash - run: | - mkdir -p 'install' && - cargo build --offline --tests --frozen --release --workspace - - - name: Test and install - shell: bash - run: | - cargo test --offline --frozen --release --workspace && - cargo install --offline --frozen --path=crates/samedec - - - name: Run integration tests - shell: bash - run: | - pushd sample && - ./test.sh && - popd - - - name: Copy artifact - shell: bash - run: | - cp "$samedec_exe" "$samedec_target_exe" - - - name: Store artifact - uses: actions/upload-artifact@v3 - with: - name: samedec-${{ env.CARGO_BUILD_TARGET }} - path: ${{ env.samedec_target_exe }} - retention-days: 3 - - - name: Upload tagged release - uses: svenstaro/upload-release-action@v2 - if: startsWith(github.ref, 'refs/tags/samedec-') - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ${{ env.samedec_target_exe }} - overwrite: true - - - name: Upload nightly release - uses: svenstaro/upload-release-action@v2 - if: github.ref == 'refs/heads/develop' - with: - tag: "latest" - release_name: "Nightly Release" - body: "This is a rolling release built from the latest `develop` branch." - prerelease: true - file: ${{ env.samedec_target_exe }} - overwrite: true - - # MacOS build, on whatever machine github has available - release_macos: - runs-on: macos-latest - - needs: vendor_sources - - env: - CARGO_BUILD_TARGET: x86_64-apple-darwin - CARGO_NET_OFFLINE: "true" - CARGO_INSTALL_ROOT: "install/" - RUSTFLAGS: '-C strip=symbols' - samedec_exe: 'install/bin/samedec' - samedec_target_exe: install/bin/samedec-x86_64-apple-darwin - - steps: - - uses: actions/checkout@v3 - - - name: Record environment - run: cargo version - - - uses: actions/cache/restore@v3 - name: Restore crate cargo-vendor cache - with: - path: | - .cargo - vendor - key: cargo-vendor-release-${{ hashFiles('**/Cargo.lock') }} - enableCrossOsArchive: true - fail-on-cache-miss: true - - - name: Build - run: | - mkdir -p 'install' && - cargo fetch --locked && - cargo build --offline --tests --frozen --release --workspace - - - name: Test and install - run: | - cargo test --offline --frozen --release --workspace && - cargo install --offline --frozen --path=crates/samedec - - - name: Run integration tests - run: | - pushd sample && - ./test.sh && - popd - - - name: Copy artifact - run: | - cp "$samedec_exe" "$samedec_target_exe" - - - name: Store artifact - uses: actions/upload-artifact@v3 - with: - name: samedec-${{ env.CARGO_BUILD_TARGET }} - path: ${{ env.samedec_target_exe }} - retention-days: 3 - - - name: Upload tagged release - uses: svenstaro/upload-release-action@v2 - if: startsWith(github.ref, 'refs/tags/samedec-') - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ${{ env.samedec_target_exe }} - overwrite: true - - - name: Upload nightly release - uses: svenstaro/upload-release-action@v2 - if: github.ref == 'refs/heads/develop' - with: - tag: "latest" - release_name: "Nightly Release" - body: "This is a rolling release built from the latest `develop` branch." - prerelease: true - file: ${{ env.samedec_target_exe }} - overwrite: true diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml deleted file mode 100644 index 30781d9..0000000 --- a/.github/workflows/rust_test.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Test - -on: - push: - branches: [ "release/**" ] - pull_request: - branches: [ "develop" ] - -env: - CARGO_TERM_COLOR: always - RUST_BACKTRACE: 1 - -jobs: - # run `cargo vendor` and cache it - vendor_sources: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - uses: actions/cache@v3 - name: Update crate cargo-vendor cache - id: vendor_cache - with: - path: | - .cargo - vendor - key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - cargo-vendor - enableCrossOsArchive: true - - - uses: actions/cache@v3 - name: Update cargo registry cache - if: steps.vendor_cache.outputs.cache-hit != 'true' - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-cache-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo-cache - - - name: Vendor sources - if: steps.vendor_cache.outputs.cache-hit != 'true' - run: | - mkdir -p .cargo - mkdir -p vendor - cargo vendor --versioned-dirs --locked >.cargo/config.toml - - test_sameold: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - features: ['', 'chrono'] - - runs-on: ${{ matrix.os }} - - needs: vendor_sources - - env: - CARGO_NET_OFFLINE: "true" - - steps: - - uses: actions/checkout@v3 - - - name: Record environment - shell: bash - run: cargo version - - - uses: actions/cache/restore@v3 - name: Restore crate cargo-vendor cache - with: - path: | - .cargo - vendor - key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} - enableCrossOsArchive: true - fail-on-cache-miss: true - - - name: Build and test sameold - shell: bash - run: | - cargo test --frozen -p sameold --verbose --no-default-features --features "${{ matrix.features }}" - - test_samedec: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - runs-on: ${{ matrix.os }} - - needs: vendor_sources - - env: - CARGO_NET_OFFLINE: "true" - - steps: - - uses: actions/checkout@v3 - - - name: Record environment - shell: bash - run: cargo version - - - uses: actions/cache/restore@v3 - name: Restore crate cargo-vendor cache - with: - path: | - .cargo - vendor - key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} - enableCrossOsArchive: true - fail-on-cache-miss: true - - - name: Build and unit-test samedec - shell: bash - run: | - cargo test --frozen -p samedec --verbose - - - name: Run integration tests - shell: bash - run: | - pushd sample - ./test.sh - popd diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..78117cb --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,333 @@ +name: Build and Release + +on: + push: + branches: [ "release/**", "develop", "staging/**" ] + tags: [ "samedec-*" ] + pull_request: + branches: [ "develop" ] + +permissions: + contents: write + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + +jobs: + # perform basic code quality checks, + # then run `cargo vendor` and cache it + check_and_vendor: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Checking for whitespace errors (PRs only) + if: github.event.pull_request.base.sha + run: | + git diff --check "${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" || { + echo >&2 "Your pull request introduces whitespace errors,"; + echo >&2 "which is not allowed. Please run:"; + echo >&2; + echo >&2 " git rebase --whitespace=fix"; + echo >&2 " git push -f"; + echo >&2; + echo >&2 "to correct and resubmit."; + exit 1; + } + + - name: Checking for cargo-fmt errors (PRs only) + if: github.event.pull_request.base.sha + run: | + cargo fmt --check || { \ + echo >&2 "Your pull request does not conform to cargo-fmt"; + echo >&2 "Rust format, which is not allowed. Please run:"; + echo >&2; + echo >&2 " cargo fmt"; + echo >&2 " git commit -a --amend"; + echo >&2 " git push -f"; + echo >&2; + echo >&2 "to correct and resubmit. If \`cargo fmt\` touches"; + echo >&2 "code which is not part of your MR, please let us"; + echo >&2 "know in the comments."; + exit 1; + } + + - uses: actions/cache@v4 + name: Update crate cargo-vendor cache + id: vendor_cache + with: + path: | + .cargo + vendor + key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + cargo-vendor + enableCrossOsArchive: true + + - uses: actions/cache@v4 + name: Update cargo registry cache + if: steps.vendor_cache.outputs.cache-hit != 'true' + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: ${{ runner.os }}-cargo-cache-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-cache + + - name: Vendor sources + if: steps.vendor_cache.outputs.cache-hit != 'true' + run: | + mkdir -p .cargo + mkdir -p vendor + cargo vendor --versioned-dirs --locked >.cargo/config.toml + + # test sameold with all crate feature combinations, + # in our Linux container + test_sameold: + strategy: + matrix: + features: ['', 'chrono'] + + runs-on: ubuntu-latest + + needs: check_and_vendor + + container: + image: ghcr.io/cbs228/sameold/builder/x86_64-unknown-linux-gnu:latest + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + env: + CARGO_NET_OFFLINE: "true" + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + + steps: + - uses: actions/checkout@v3 + + - name: Record environment + run: cargo version + + - uses: actions/cache/restore@v4 + name: Restore crate cargo-vendor cache + with: + path: | + .cargo + vendor + key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} + enableCrossOsArchive: true + fail-on-cache-miss: true + + - name: Build and test sameold + shell: bash + run: | + cargo test --frozen -p sameold --verbose --no-default-features --features "${{ matrix.features }}" + + # Test and release samedec on Linux, via containers + release_samedec_linux: + runs-on: ubuntu-latest + + needs: check_and_vendor + + name: linux-${{ matrix.target }} + + strategy: + matrix: + include: + - target: x86_64-unknown-linux-gnu + - target: aarch64-unknown-linux-gnu + - target: armv7-unknown-linux-gnueabihf + - target: i686-unknown-linux-gnu + + container: + image: ghcr.io/cbs228/sameold/builder/${{ matrix.target }}:latest + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + env: + CARGO_NET_OFFLINE: "true" + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + RUSTFLAGS: '-C strip=symbols' + + steps: + - uses: actions/checkout@v3 + + - uses: actions/cache/restore@v4 + name: Restore crate cargo-vendor cache + with: + path: | + .cargo + vendor + key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} + enableCrossOsArchive: true + fail-on-cache-miss: true + + - name: "debug: cross-compile and cross-test" + run: | + cargo test --offline --frozen --workspace + + - name: "release: cross-compile, cross-test, and install" + run: | + cargo test --offline --frozen --release --workspace && + cargo install --offline --frozen --path=crates/samedec + + - name: Run integration tests on release-mode build + run: | + qemu-run-maybe samedec --version && + ./sample/test.sh qemu-run-maybe samedec + + - name: Copy artifact + run: | + cp /install/bin/samedec /install/bin/samedec-${{ matrix.target }} + + - name: Store artifact + uses: actions/upload-artifact@v4 + with: + name: samedec-${{ matrix.target }} + path: /install/bin/samedec-${{ matrix.target }} + retention-days: 3 + + - name: Upload tagged release (tags only) + uses: svenstaro/upload-release-action@v2 + if: startsWith(github.ref, 'refs/tags/samedec-') + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: /install/bin/samedec-${{ matrix.target }} + overwrite: true + + - name: Update tag for nightly release (develop-branch only) + uses: richardsimko/update-tag@v1 + if: github.ref == 'refs/heads/develop' + with: + tag_name: latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload nightly release (develop-branch only) + uses: svenstaro/upload-release-action@v2 + if: github.ref == 'refs/heads/develop' + with: + tag: "latest" + release_name: "Nightly Release" + body: "This is a rolling release built from the latest `develop` branch." + prerelease: true + file: /install/bin/samedec-${{ matrix.target }} + overwrite: true + + # MacOS and Windows builds + release_samedec_nonlinux: + strategy: + matrix: + include: + - os: windows-latest + os_short: windows + target: x86_64-pc-windows-msvc + rustflags: '-C strip=symbols -C target-feature=+crt-static' + dotexe: '.exe' + - os: macos-latest + os_short: macos + target: aarch64-apple-darwin + rustflags: '-C strip=symbols' + dotexe: '' + - os: macos-latest + os_short: macos + target: x86_64-apple-darwin + rustflags: '-C strip=symbols' + dotexe: '' + + runs-on: ${{ matrix.os }} + + name: ${{ matrix.os_short }}-${{ matrix.target }} + + needs: check_and_vendor + + env: + CARGO_BUILD_TARGET: ${{ matrix.target }} + CARGO_NET_OFFLINE: "true" + CARGO_INSTALL_ROOT: "install/" + RUSTFLAGS: ${{ matrix.rustflags }} + samedec_exe: "install/bin/samedec${{ matrix.dotexe }}" + samedec_target_exe: "install/bin/samedec-${{ matrix.target}}${{ matrix.dotexe }}" + + steps: + - uses: actions/checkout@v3 + + - name: Record environment + shell: bash + run: cargo version + + - uses: actions/cache/restore@v4 + name: Restore crate cargo-vendor cache + with: + path: | + .cargo + vendor + key: cargo-vendor-${{ hashFiles('**/Cargo.lock') }} + enableCrossOsArchive: true + fail-on-cache-miss: true + + - name: "debug: compile and test" + shell: bash + run: | + rustup target add "${CARGO_BUILD_TARGET}" && + cargo test --offline --frozen --workspace + + - name: "release: cross-compile, cross-test, and install" + shell: bash + run: | + mkdir -p "${CARGO_INSTALL_ROOT}" && + export PATH="$(realpath ${CARGO_INSTALL_ROOT})/bin:${PATH}" + cargo test --offline --frozen --release --workspace && + cargo install --offline --frozen --path=crates/samedec + + - name: Run integration tests on release-mode build + shell: bash + run: | + export PATH="$(realpath ${CARGO_INSTALL_ROOT})/bin:${PATH}" + samedec --version && + pushd ./sample && ./test.sh samedec && popd + + - name: Copy artifact + shell: bash + run: | + cp "$samedec_exe" "$samedec_target_exe" + + - name: Store artifact + uses: actions/upload-artifact@v4 + with: + name: samedec-${{ env.CARGO_BUILD_TARGET }} + path: ${{ env.samedec_target_exe }} + retention-days: 3 + + - name: Upload tagged release (tags only) + uses: svenstaro/upload-release-action@v2 + if: startsWith(github.ref, 'refs/tags/samedec-') + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: ${{ env.samedec_target_exe }} + overwrite: true + + - name: Update tag for nightly release (develop-branch only) + uses: richardsimko/update-tag@v1 + if: github.ref == 'refs/heads/develop' + with: + tag_name: latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload nightly release (develop-only) + uses: svenstaro/upload-release-action@v2 + if: github.ref == 'refs/heads/develop' + with: + tag: "latest" + release_name: "Nightly Release" + body: "This is a rolling release built from the latest `develop` branch." + prerelease: true + file: ${{ env.samedec_target_exe }} + overwrite: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..52d5286 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,202 @@ +# CHANGELOG + +## samedec-0.4.1: Maintenance Release + +This minor maintenance release helps keep our dependencies +up-to-date and building smoothly with the latest Rust. + +BREAKING + +* Due to low demand, CI binaries are no longer built for `-musl` + Linux ABIs. We continue to support `-gnu` ABIs, which offer + the best performance when available. We continue to require + glibc >= 2.28, which makes our binaries compatible with + Debian 10 (buster), AlmaLinux 8, and more modern distros. If + you require a musl build, open an issue. + +* Update MSRVs: + + * `sameold`: 1.70 + * `samedec`: 1.74 + +ENHANCEMENTS + +* cargo: update dependencies to the latest-available versions. + Minor refactors were necessary. + +* ci: new builds for: + + * `aarch64-apple-darwin` (for M1 macs) + * `i686-unknown-linux-gnu` + +* doc: add [CHANGELOG.md](./CHANGELOG.md) + +FIXES + +* sameold: permit dead code for Demod::push() + +* ci: Linux non-x86 architectures are now built by cross-compiling + instead of emulated "native" toolchains. This is *much* faster. + We have created custom container images for this purpose. + +## samedec-0.4.0: The Spring 2024 Update + +Are you "Weather Ready?" This release is mostly compatible with +previous versions but adds more SAME codes and environment +variables. + +ENHANCEMENTS + +* Support the following new SAME codes: + + * EAN: Renamed to National Emergency Message + * NAT: National Audible Test + * NST: National Silent Test + * FSW: Flash Freeze Warning + * FZW: Freeze Warning + * HLS: Hurricane Local Statement + * SQW: Snow Squall Warning + +* Discontinue the `SAMEDEC_SIGNIFICANCE` level of "`M`" + (Message), which is not found anywhere in the standards + document. The following messages are upgraded to + Statement: + + * ADR: Administrative Message + * NMN: Network Message Notification + +* Improved detection of National Weather Service vs + Environment Canada. samedec will no longer output a + generic `SAMEDEC_ORIGINATOR` of "`Weather Service`." + Instead, samedec will output either + "`National Weather Service`" or "`Environment Canada`." + +* New environment variables for child processes + + * `SAMEDEC_IS_NATIONAL`: "`Y`" for national activations; + otherwise present but empty + + * `SAMEDEC_SIG_NUM`: a numeric representation of the + significance level + +* Add proper integration test scripts for child processes + +FIXES + +* IMPORTANT: Fix code entry for ADR (Administrative Message), + which was previously wrong. + +* Handle EOF within the main app. Child processes are now + spawned even for very short input files. + +* Update to Edition 2021 + +* Replace is-terminal with terminal_size + +## samedec-0.3.0: Add fallback decoding + +ENHANCEMENTS + +* CLI-BREAKING: Suppress duplicate messages which follow + each other quickly in time. This mainly affects Fast EOMs: + now only one "`NNNN`" line will be printed per SAME + message. Some users may consider this breaking. + +* CLI: Add fallback decoding which can decode SAME headers using + only two bursts. The improved decoder adds a delay of + **1.311 seconds** when reporting a Start Of Message. Since the + SAME voice message is often prefixed with an extended period of + silence and/or a Warning Alarm Tone, the additional delay + should not impact most applications. + +FIXES + +* Fix decoding of back-to-back SAME messages when either or both + have missed bursts + +* Update dependencies + +## samedec-0.2.5: CLI Improvements + +ENHANCEMENTS + +* Update to chrono 0.4.23 and replace + deprecated functions. + +* Update to clap v4. Improve help text and + general CLI behaviors. + +FIXES + +* samedec now errors on startup if reading + from stdin and stdin is a terminal + +## samedec-0.2.4: Maintenance release + +CI binaries are now available on the Github +Releases tab. These binaries are built with +Github Actions on Github Workers. + +ENHANCEMENTS + +* Log the full text of each SAME burst + +FIXES + +* RUSTSEC-2022-0078: bump bumpalo to 3.12.0 + +* RUSTSEC-2021-0047: replace slice-deque with + slice-ring-buffer + +* Documentation improvements + +## samedec-0.2.3: Message bugfix release + +FIXES + +* Support additional message characters +* Support lowercase event codes +* Use an 8-character callsign for + built-in DMO messages. + +## samedec-0.2.2: Dependency update + +No source code changes are made. + +* Discontinue use of the `time` dependency of `chrono`, which has + unresolved security issues [1]. + +* Update all dependencies. + +References +1. https://rustsec.org/advisories/RUSTSEC-2020-0071 + +## samedec-0.2.1: Dependency update + +FIXES + +* Update dependencies to versions which correct + security vulnerabilities. Previous versions + of sameold are *not* known to be vulnerable. + +## samedec-0.2.0: Fast end-of-message detection + +ENHANCEMENTS + +* BREAKING: Output one `NNNN` line for every + EOM/`NNNN` which successfully decodes. The + previous behavior was to require all three + bursts before outputting a single `NNNN`. + The behavior for the header (`ZCZC-`) is + unchanged. The `--demo` option mimics the + new behavior. + +FIXES + +* `--help` documentation + +## samedec-0.1.0: Initial version + +* Decodes SAME signals from `i16` inputs +* Dispatches alerts and streaming audio to child + processes diff --git a/Cargo.lock b/Cargo.lock index ea61e01..1d58499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -28,57 +28,59 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "approx" @@ -91,15 +93,15 @@ dependencies = [ [[package]] name = "arraydeque" -version = "0.4.5" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ffd3d69bd89910509a5d31d1f1353f38ccffdd116dd0099bbd6627f7bd8ad8" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert_approx_eq" @@ -109,27 +111,27 @@ checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" [[package]] name = "byteorder" @@ -139,9 +141,12 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.87" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -151,21 +156,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.3", + "windows-targets", ] [[package]] name = "clap" -version = "4.4.18" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" dependencies = [ "clap_builder", "clap_derive", @@ -173,9 +178,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" dependencies = [ "anstream", "anstyle", @@ -186,33 +191,33 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "env_logger" @@ -229,25 +234,25 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "humantime" @@ -257,9 +262,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -280,47 +285,54 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ "hermit-abi", "libc", "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" -version = "0.4.20" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "mach2" @@ -333,9 +345,9 @@ dependencies = [ [[package]] name = "matrixmultiply" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" dependencies = [ "autocfg", "rawpointer", @@ -343,20 +355,20 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "nalgebra" -version = "0.32.4" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" dependencies = [ "approx", "matrixmultiply", "nalgebra-macros", - "num-complex 0.4.5", + "num-complex", "num-rational", "num-traits", "simba", @@ -365,29 +377,30 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] -name = "num-complex" -version = "0.3.1" +name = "num-bigint" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ + "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -403,41 +416,41 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", + "num-bigint", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", "phf_shared", @@ -445,9 +458,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand", @@ -455,22 +468,22 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] @@ -487,18 +500,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -526,9 +539,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "regex" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -538,9 +551,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -549,41 +562,41 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "safe_arch" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" dependencies = [ "bytemuck", ] [[package]] name = "samedec" -version = "0.4.0" +version = "0.4.1" dependencies = [ "anyhow", "byteorder", @@ -597,7 +610,7 @@ dependencies = [ [[package]] name = "sameold" -version = "0.4.0" +version = "0.5.0" dependencies = [ "arraydeque", "arrayvec", @@ -606,7 +619,7 @@ dependencies = [ "lazy_static", "log", "nalgebra", - "num-complex 0.3.1", + "num-complex", "num-traits", "phf", "regex", @@ -616,14 +629,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simba" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" dependencies = [ "approx", - "num-complex 0.4.5", + "num-complex", "num-traits", "paste", "wide", @@ -631,15 +650,15 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slice-ring-buffer" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7081c7e452cb62f5f0c32edd4e265391bdbb23e90905df8bb88a23d3b5166b77" +checksum = "84ae312bda09b2368f79f985fdb4df4a0b5cbc75546b511303972d195f8c27d6" dependencies = [ "libc", "mach2", @@ -648,45 +667,34 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.1" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723b93e8addf9aa965ebe2d11da6d7540fa2283fcea14b3371ff055f7ba13f5f" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" -version = "0.26.1" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.50", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "syn", ] [[package]] name = "syn" -version = "2.0.50" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -704,32 +712,32 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.57" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", ] [[package]] @@ -740,46 +748,47 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.50", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -787,28 +796,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.50", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wide" -version = "0.7.15" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22" dependencies = [ "bytemuck", "safe_arch", @@ -832,11 +844,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -851,16 +863,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.3", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -869,119 +872,78 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Dockerfile b/Dockerfile index 83a95ad..b0064ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -105,7 +105,7 @@ COPY sample sample RUN samedec --version && \ cd sample && \ - SAMEDEC=/usr/local/bin/samedec ./test.sh && \ + ./test.sh /usr/local/bin/samedec && \ cd .. ### diff --git a/README.md b/README.md index e94808c..9023318 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,17 @@ alerts. Binary builds are available on the [releases](https://github.com/cbs228/sameold/releases) page for a variety of -platforms. Linux binaries are currently built against glibc 2.28 and should be +platforms, including: + +* `aarch64-apple-darwin` +* `aarch64-unknown-linux-gnu` +* `armv7-unknown-linux-gnueabihf` +* `i686-unknown-linux-gnu` +* `x86_64-pc-windows-msvc` +* `x86_64-unknown-linux-gnu` +* `x86_64-apple-darwin` + +GNU/Linux binaries are currently built for glibc 2.28 and should be portable to most distros. ### Building @@ -52,6 +62,11 @@ portable to most distros. You will need a working [rust toolchain](https://www.rust-lang.org/learn/get-started). +```bash +cargo install samedec +samedec --help +``` + To build and install binaries from this repository, run ```bash diff --git a/crates/samedec/Cargo.toml b/crates/samedec/Cargo.toml index 2d6e7d0..ae4855e 100644 --- a/crates/samedec/Cargo.toml +++ b/crates/samedec/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "samedec" -rust-version = "1.70" +rust-version = "1.74" description = "A SAME/EAS digital receiver and alerting program" -version = "0.4.0" +version = "0.4.1" authors = ["Colin S <3526918+cbs228@users.noreply.github.com>"] license = "MIT OR Apache-2.0" edition = "2021" @@ -11,11 +11,11 @@ repository = "https://github.com/cbs228/sameold.git" readme = "README.md" [dependencies] -sameold = {path = "../sameold", version = "^0.4.0"} +sameold = {path = "../sameold", version = "^0.5.0"} anyhow = "^1" byteorder = "^1.4" -clap = {version = "=4.4.18", features = ["color", "derive", "wrap_help"]} -terminal_size = "^0.3" +clap = {version = "^4.5", features = ["color", "derive", "wrap_help"]} +terminal_size = "^0.4" log = "^0.4" pretty_env_logger = "^0.5" diff --git a/crates/samedec/README.md b/crates/samedec/README.md index 5cb1a5c..0b38644 100644 --- a/crates/samedec/README.md +++ b/crates/samedec/README.md @@ -114,20 +114,43 @@ pw-record --channels 1 --format s16 --rate 22050 -- - \ ### Via a Software-Defined Radio +> For easy use with rtl-sdr dongles, first identify a weather station that you +> can receive and hear clearly. +> +> ```bash +> rtl_fm -f 162.4M -M fm -s 48k -o 4 -E dc -g 0 -F 9 | \ +> play -t raw -r 48k -e signed -b 16 -c 1 - +> ``` +> +> Adjust the `-g GAIN` value, `-F FIR_SIZE`, and `-E` options until you have +> clean audio that is largely free of noise and glitches. The gain is +> particularly important. +> +> Then you can pipe the audio into samedec: +> +> ```bash +> rtl_fm -f 162.4M -M fm -s 48k -o 4 -E dc -g 0 -F 9 | \ +> samedec -r 48000 +> ``` + Use any compatible SDR software to demodulate and recover passband audio from a station of interest. You will need a way to pipe passband audio into `samedec`. * Some programs, like `rtl_fm`, support piping output directly. -* Some programs, like `gqrx`, can output audio via UDP. You can obtain UDP input - with either +* [gqrx](https://www.gqrx.dk/) can output demodulated audio via UDP. Tune to the + station you want, then click the `UDP` button in the Audio pane. You can + receive the UDP audio with either [`netcat`](https://manpages.debian.org/testing/netcat-traditional/nc.1.en.html) - or [`socat`](https://manpages.debian.org/testing/socat/socat.1.en.html). + or [`socat`](https://manpages.debian.org/testing/socat/socat.1.en.html) + and pipe it into samedec. ```bash nc -l -u 7355 | samedec -r 48000 ``` + You can then `Mute` the audio in gqrx. + * For some programs, you may need to create a virtual audio device and direct the audio output to that. PulseAudio can do this "out of the box" with [`module-null-sink`](https://freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#module-null-sink). diff --git a/crates/samedec/src/main.rs b/crates/samedec/src/main.rs index 591e31f..7b5b672 100644 --- a/crates/samedec/src/main.rs +++ b/crates/samedec/src/main.rs @@ -102,15 +102,15 @@ or similar into this program." #[cfg(not(target_os = "windows"))] fn is_terminal(stream: &S) -> bool where - S: std::os::fd::AsRawFd, + S: std::os::fd::AsFd, { - terminal_size::terminal_size_using_fd(stream.as_raw_fd()).is_some() + terminal_size::terminal_size_of(stream).is_some() } #[cfg(target_os = "windows")] fn is_terminal(stream: &S) -> bool where - S: std::os::windows::io::AsRawHandle, + S: std::os::windows::io::AsHandle, { - terminal_size::terminal_size_using_handle(stream.as_raw_handle()).is_some() + terminal_size::terminal_size_of(stream).is_some() } diff --git a/crates/sameold/Cargo.toml b/crates/sameold/Cargo.toml index 4f06396..3e25caf 100644 --- a/crates/sameold/Cargo.toml +++ b/crates/sameold/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "sameold" -rust-version = "1.65" +rust-version = "1.70" description = "A SAME/EAS digital receiver library" -version = "0.4.0" +version = "0.5.0" authors = ["Colin S <3526918+cbs228@users.noreply.github.com>"] license = "MIT OR Apache-2.0" edition = "2021" @@ -12,19 +12,19 @@ readme = "README.md" [dependencies] arrayvec = "^0.7.1" -arraydeque = "^0.4.5" +arraydeque = "^0.5" assert_approx_eq = "1.1.0" lazy_static = "^1.4.0" log = "0.4" -nalgebra = "^0.32.2" -num-complex = "^0.3.1" +nalgebra = "^0.33.2" +num-complex = "^0.4" num-traits = "^0.2" phf = {version = "^0.11", features = ["macros"]} regex = "^1.5.5" slice-ring-buffer = "^0.3" strum = "^0.26" strum_macros = "^0.26" -thiserror = "^1.0" +thiserror = "^2.0" [dependencies.chrono] version = "^0.4" diff --git a/crates/sameold/src/receiver/codesquelch.rs b/crates/sameold/src/receiver/codesquelch.rs index e5a8dce..1853703 100644 --- a/crates/sameold/src/receiver/codesquelch.rs +++ b/crates/sameold/src/receiver/codesquelch.rs @@ -142,10 +142,10 @@ pub struct CodeAndPowerSquelch { power_track: PowerTracker, // sample history - sample_history: ArrayDeque<[f32; 64], arraydeque::Wrapping>, + sample_history: ArrayDeque, // power threshold history - power_history: ArrayDeque<[bool; 32], arraydeque::Wrapping>, + power_history: ArrayDeque, // lifetime total count of symbols received symbol_counter: u64, diff --git a/crates/sameold/src/receiver/demod.rs b/crates/sameold/src/receiver/demod.rs index aa2667e..3fe717f 100644 --- a/crates/sameold/src/receiver/demod.rs +++ b/crates/sameold/src/receiver/demod.rs @@ -41,20 +41,23 @@ pub trait Demod: Clone + std::fmt::Debug + Sized { /// Push samples into the demodulator /// /// Appends a fresh slice of `input` samples to the - /// demodulator's history. + /// demodulator's history. This method does not perform any + /// demodulation. If you want to demodulate these samples, + /// you must also invoke [`demod()`](Demod::demod). /// /// In the ideal case, `input` consists of modulated /// samples of exactly one symbol, which is fully aligned /// to the sending system's *symbol clock*. If you can - /// achieve this, it suffices to demodulate exactly one - /// sample per symbol. (This is unrealistic) + /// achieve this, it suffices to [`demod()`](Demod::demod) + /// exactly one sample per symbol. This is unrealistic. /// - /// You can also feed each sample to `push()` individually + /// You can also feed every sample to `push()` individually /// and [`demod()`](#method.demod) each one. This is /// wasteful, but you can do it. /// /// A typical solution will use a timing error detector and /// demodulate two or three samples per symbol. + #[allow(dead_code)] fn push(&mut self, input: S) where S: AsRef<[f32]>; diff --git a/crates/sameold/src/receiver/symsync.rs b/crates/sameold/src/receiver/symsync.rs index 569c5bb..bb7b0b9 100644 --- a/crates/sameold/src/receiver/symsync.rs +++ b/crates/sameold/src/receiver/symsync.rs @@ -247,7 +247,7 @@ impl TimingLoop { /// Zero-crossing timing error detector #[derive(Clone, Debug)] pub struct ZeroCrossingTed { - history: ArrayDeque<[f32; 3], arraydeque::Wrapping>, + history: ArrayDeque, sample_counter: u32, } diff --git a/sample/test.sh b/sample/test.sh index 370732f..62bfd33 100755 --- a/sample/test.sh +++ b/sample/test.sh @@ -6,29 +6,24 @@ # ./test.sh # # By default, this will build and run a debug-mode samedec -# with cargo. You may also set SAMEDEC to the path to an -# existing executable. +# with cargo. If you want to run an installed samedec binary, +# instead invoke it as: +# +# ./test.sh path/to/samedec # # The integration tests ensure that samedec's child process # spawning and environment variable assignment works. set -eu -if [ -z "${SAMEDEC:-}" ]; then - SAMEDEC="cargo" - ARGS="run -q -p samedec --" -else - ARGS="" -fi - run_samedec() { - # Usage: run_samedec FILE + # Usage: run_samedec FILE ARGS # Runs `samedec` on given input file stem infile="$1" + shift - #shellcheck disable=SC2086 - "$SAMEDEC" $ARGS \ + "$@" \ --rate 22050 \ --file "${infile}.bin" \ -- \ @@ -36,12 +31,19 @@ run_samedec() { "${infile}.sh" } +if [ "$#" -lt 1 ]; then + exec "$0" cargo run -q -p samedec -- +fi + +exe="${0?no executable path}" +cd "$(dirname "$exe")" + for file in $(basename -s .bin -- *.s16le.bin); do [ -e "${file}.bin" ] || exit 1 printf '[%s]\n' "$file" - output="$(run_samedec "$file")" + output="$(run_samedec "$file" "$@")" expect="$(cat "${file}.txt")" echo "$output"