Skip to content

Web-888 Airband Audio Clock Mismatch Bug #95

Description

@satdelight

Preface

I am currently working on an ACARS decoding implementation for the Web-888 SDR. As part of this work I built and ran acarsdec against the Web-888's audio output. Without any changes to the code, acarsdec is unable to decode ACARS signals received via the Web-888, because of the timebase error described below.

Summary

In Airband (VHF) mode, the Web-888 delivers audio with a timebase error of ~2.5%. All audio tones are scaled by a factor of 0.9756 (e.g. a 2400 Hz ACARS mark tone appears at ~2341.5 Hz, a 1200 Hz tone at ~1170 Hz). This is not a receiver frequency offset and not a demodulation error - it is a sample-rate mismatch introduced by the firmware commit that changed the VHF ADC clock.

Root cause

The Web-888 derives its audio sample rate from the ADC clock via:

rx_decim = (int)(ADC_CLOCK / snd_rate)        // main.cpp:237
decim    = rx_decim / 256                     // peri.cpp:205 (fpga_start_rx)

The FPGA decimates the ADC clock in steps of 256. The audio rate is therefore always ADC_CLOCK / (decim * 256).

Commit bafc446 ("Change ADC rate to 100.7616Mhz", Jan 6 2025) changed the VHF ADC clock from 98.304 MHz to 100.7616 MHz in init/clk.h:

#define ADC_CLOCK_HF  (122.88 * MHz)
#define ADC_CLOCK_VHF (100.7616 * MHz)

100.7616 MHz was chosen to cover the full VHF Airband, but it is NOT an exact multiple of 12000 * 256 = 3,072,000 Hz.

Worked example (Airband, snd_rate = 12000):
ADC clock = 100.7616 MHz
rx_decim = (int)(100761600 / 12000) = 8396 (8396.8 truncated)
decim = 8396 / 256 = 32 (32.79 truncated)
real rate = 100.7616 MHz / (32 * 256) = 100.7616 MHz / 8192 = 12300 Hz

So the FPGA actually produces audio at 12300 Hz while the software declares 12000 Hz (and kiwirecorder records a nominal 12001 Hz header).

real_rate / declared_rate = 12300 / 12000 = 1.025
-> all tones appear scaled by 12000/12300 = 0.9756

This exactly matches the observed factor of ~1.025.

Why only Airband mode is affected

  • HF mode: 122.88 MHz / (12000 * 256) = 40.0 exactly integer
    audio rate = 122.88 MHz / 10240 = 12000 Hz -> correct

  • Airband: 100.7616 MHz / (12000 * 256) = 32.79 not integer
    audio rate = 100.7616 MHz / 8192 = 12300 Hz -> 2.5% error

Therefore all HF-mode receivers (HFDL, DRM, FAX, ...) are unaffected; every audio output in Airband mode (AM, NFM, and all other modes) carries the 2.5% timebase error. ACARS/VHF-band decoders (acarsdec, dumpvdl2, ...) are the ones that hit it.

References

  • init/clk.h:29-30 ADC_CLOCK_HF / ADC_CLOCK_VHF definitions
  • main.cpp:236-237 snd_rate and rx_decim computation
  • zynq/peri.cpp:205 fpga_start_rx() passes rx_decim/256 to the FPGA
  • commit bafc446 "Change ADC rate to 100.7616Mhz"

Suggested fixes

  1. Choose an ADC clock that is an exact multiple of 12000 * 256:
    e.g. 98.304 MHz (= 32 * 12000 * 256, the previous value) or 122.88 MHz (= 40 * 12000 * 256)
  2. Or adapt the decimation path so that the resulting audio rate is exactly 12000 Hz for the chosen ADC clock.
  3. Until fixed in firmware, client-side resampling by ~1.025 restores the correct audio rate (e.g. a streaming linear-interpolation resampler in front of the ACARS decoder).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions